不少中小型技术团队在业务规模上来之后,都会把容器化部署提上日程。它确实能让环境一致、扩缩容更灵活,但真要落地,并不是把服务塞进镜像就完事了。结合带团队落地过的几个项目,聊点实际踩过的坑和该有的准备。
我们之前有个内部订单服务,开发本地用 SQLite 做缓存,上线镜像里没带这个文件,结果容器启动就崩。后来规范要求每次构建前先列清楚服务依赖:系统库、配置文件、外部端口。下面是一个基础但稳妥的 Dockerfile 片段:
FROM openjdk:17-slim
WORKDIR /app
COPY ./target/order-service.jar /app/
COPY ./config/application.yml /app/config/
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "order-service.jar"]
这种显式拷贝比挂载宿主机路径更可控,也方便在测试环境复现问题。
小团队常以为装个 Docker 就够了。当服务超过五个,手动重启、看日志就会吃不消。我们对比过两种做法:
| 方式 | 运维成本 | 适用阶段 |
|---|---|---|
| 单机 Docker | 低,但易丢容器 | 验证期 |
| Kubernetes | 高,需专人 | 多服务稳定期 |
如果人力紧,先用 docker-compose 把依赖串起来,比直接上 K8s 更现实。示例配置:
version: "3"
services:
web:
image: nginx:alpine
ports:
- "80:80"
api:
image: order-service:1.2
depends_on:
- db
db:
image: postgres:14
有一次我们构建出的 Java 镜像接近 600MB,每次发版推仓库要三分钟。后来切到 slim 基础镜像,并加多层缓存,降到 220MB。容器化部署的体验好坏,很多时候卡在传输效率上。用 .dockerignore 忽略本地日志和构建目录,也很关键。
容器默认跑 root,被扫到就麻烦。我们在入口加非 root 用户:
RUN addgroup -S app && adduser -S app -G app
USER app
日志方面,别只写在容器内。接个统一收集组件,比如向量化输出到外部存储,查问题时不用逐个 exec 进去翻。
容器化不是银弹,它把环境问题转成了配置和运维问题。
团队落地前,把依赖、编排边界、镜像大小和权限这几项聊透,后面会省掉很多凌晨救火的功夫。
评论
加载中...