每年开年,很多人都会做同一件事:重装系统、清理旧项目、给本机开发环境来一次大扫除。但扫完之后没多久,又会陷入熟悉的循环——换了台电脑跑不起来、同事说”我这是好的”、半年前的项目因为本地某个版本对不上而报错。问题往往不在代码,而在”环境”。今年想认真解决一下这件事,思路其实不复杂:把环境也当成代码,用 Docker 固定下来。
为什么要把环境装进容器
传统做法里,我们直接在本机装语言运行时、数据库、各种依赖库。时间一长,本机就变成一个谁也说不清装了什么的”黑水”:这个项目要 Node 12,那个项目要 Node 14;这个要用 MySQL 5.7,那个要用 8.0。靠版本管理工具来回切换,总有顾不过来的时候。
Docker 的思路是把应用和它依赖的整个运行环境——代码、运行时、系统库、配置——一起打包成一个镜像。容器跑起来之后,不管是在你本机、同事的电脑还是线上服务器,看到的都是同一个环境。”在我机器上能跑”这件事,从此有了可复制的保证。

最小可行的一步:写一个 Dockerfile
不用一上来就追求完美,先从一个最简单的项目开始。以一个常见的 Web 后端为例,在项目根目录新建一个 Dockerfile:
第一行选定基础镜像,也就是这个项目要跑的语言版本,比如一个装好了对应运行时的官方镜像。第二行把工作目录设到容器里的某个路径。第三行先拷贝依赖清单并安装依赖,这样做的好处是只要依赖清单没变,这一层就会被缓存下来,下次构建快很多。最后一行声明容器对外暴露的端口和启动命令。
关键在于:这个 Dockerfile 要和代码一起提交进版本库。别人克隆下项目,不用再去查”需要装哪个版本的运行时”,直接照着 Dockerfile 构建就行。环境的定义从”口口相传的经验”变成了”仓库里的一份文件”。
用 Compose 把多服务串起来
真实项目很少只有一个进程。后端要连数据库、可能还要缓存队列。手动一个个启动容器很麻烦,这时候 Docker Compose 就派上用场了。在项目里写一个 compose 配置文件,把几个服务都声明出来:应用服务、数据库服务、缓存服务。每个服务用哪个镜像、挂载哪个目录、暴露哪个端口、服务之间用什么名字互相访问,都写在这一个文件里。
配好之后,日常开发就变成两条命令:一条把整套环境拉起来,一条用完关掉。数据库的数据可以通过目录挂载留在本机,容器删了重建,数据还在。更重要的是,这套编排文件同样提交进仓库,团队所有人启动的都是同一套服务拓扑。
几个容易踩的坑
第一,别把容器当成虚拟机来配。容器应该是”一次性、可丢弃”的。需要存的数据放到挂载卷里,而不是塞进容器内部;容器坏了,删了重建一个就好。如果开始在运行中的容器里手动改东西,就又回到了”黑水”老路。
第二,注意挂载目录的权限和性能。把代码目录挂载进容器做热重载很方便,但在不同操作系统上,文件权限和文件系统监听的表现可能不一样,遇到”改了代码不自动重启”这类问题,先怀疑挂载和监听配置。
第三,镜像要尽量小、尽量干净。别在生产镜像里塞编译工具和调试软件。基础镜像选精简版,构建时把不需要的中间产物清理掉。镜像小,拉取和启动才快,部署也更省心。
一套可以照抄的日常工作流
把上面的东西串起来,一个典型的开发生命周期是这样的:拿到一个新项目,先看仓库里有没有 Dockerfile 和 compose 文件。有的话,本地装好 Docker 之后,进入项目目录敲一条启动命令,数据库、缓存、应用就都起来了。需要初始化数据库结构,就再执行一条命令进入应用容器跑迁移脚本。
平时改代码,因为代码目录是挂载进容器的,编辑器里保存之后,应用进程的热重载会自动生效,不用手动重启。要加一个新依赖,就在宿主机上对着项目加,然后重新构建应用那一层。跑完代码要清理,敲一条停止命令,容器就都停掉了,而你本机除了 Docker 本身什么多余的东西都没装过。
这套流程最大的好处是可复现。三个月后你换了电脑,或者要在一台新服务器上临时跑这个项目,流程一模一样:装 Docker、克隆仓库、启动。不会出现”少装了一个系统库”这种无从下手的问题。对个人开发者来说,这等于给自己留了一份随时能搬走的开发环境。
容器化和上线其实是同一套语言
还有一个长远的好处值得说:本地用容器跑,和线上部署用的是同一套镜像。这意味着本地验证过的东西,推到线上不需要再换一种打包方式。很多团队过去在本地用一套环境、上线又用另一套,中间经常出现”本地好好的,线上就报错”的差异。把两边统一到同一份 Dockerfile 之后,这种环境差异就被压到了最小。
进一步,这份镜像还能喂给持续集成流水线:每次提交代码,自动构建镜像、跑测试。镜像既是开发环境,又是测试环境,将来还是部署产物。一条线打通,环境的概念就从”各说各话”变成了”一处定义、处处运行”。
从一个项目开始就好
不必指望一口气把所有老项目都容器化。挑一个你今年要持续维护的新项目,从第一天起就把 Dockerfile 和 compose 文件写进去。跑顺了,再慢慢把这套做法复制到别的项目上。容器化真正的回报,不在”写文件”那一天,而在三个月后你换电脑、或者新同事入职时——他只需要克隆仓库、敲两条命令,就能把整个项目跑起来。这正是开年做这件事的意义:把一次性的辛苦,换成长期的省心。
0 条评论
还没有评论,快来抢沙发吧!
发表评论