前端有了Docker,全栈之路更轻松了
引言
前端工程师常常觉得,后端和运维团队负责部署和维护应用的生产环境,这种想法没有错,但我认为,即使前端工程师不直接负责部署,学习和理解 Docker 以及与其相关的工作流程也是有其价值的,原因如下:
- 跨职能协作:在一个团队中,前端、后端和运维需要密切合作。了解 Docker 和容器化可以帮助前端工程师更好地与团队其他成员沟通。
- 开发和生产的一致性:使用 Docker 可以确保开发环境和生产环境之间的一致性,这可以减少“在我机器上可以运行”的问题。
- 自主部署和测试:有了 Docker,前端工程师可以在本地或在某个测试环境中轻松地部署整个应用堆栈,包括后端服务和数据库。如果你还想学习当全栈,那这个特点完全有理由说服你学习 Docker。
- 持续的学习和职业发展:技术领域总是在不断地发展和变化。学习新技术和工具不仅可以帮助前端工程师保持与时俱进,还可以打开新的职业机会。
Docker demo 分析
在上一篇文章(从Next-Auth到Prisma,用最新潮的技术栈做登录),我们在本地开发时使用Postgres数据库,只需两步:
- 安装 Dcoker
- 配置 docker-compose.yml,执行启动命令
如果没有Docker,我们就需要做这么多工作:
- 下载和安装 Postgres
- 配置数据目录、用户、权限等
- 初始化数据库目录
- 启动 Postgres
- 考虑安全性
- 定期更新和维护
很明显,对于一名前端工程师,如果你想折腾非前端领域的工具,使用 Docker 将为你节约很多时间。
现在重新看一遍上一篇文章的 docker-compose.yml
docker-compose.yml
文件是 Docker Compose 的配置文件,它可以用来定义多容器 Docker 应用程序的服务,网络和依赖关系。
我们一行一行分析下这个文件的配置:
- version: '3.1',指定使用 Docker Compose 3.1 版本的语法。
- services: 定义了两个服务 db 和 adminer
- db:
- image: postgres 使用官方的 postgres 镜像
- volumes: 将宿主机的
./postgres
目录映射到容器内的/var/lib/postgresql/data
目录,用于持久化保存数据库数据。映射目录是 Postgres 的规范要求,填其它路径会报错。 - ports: 将容器的 5432 端口映射到宿主机的 5432 端口。用于从外部访问数据库服务。
- environment: 设置 postgres 数据库的用户名和密码。
- adminer:
- image: adminer 使用 adminer 镜像,这是一个数据库管理界面。
- restart: always 始终重新启动这个服务,实现高可用。
- ports: 将容器 8080 端口映射到宿主机 8080 端口,用于从外部访问 adminer 网页界面。
有了这个配置文件,我们执行docker-compose up
就完成postgres数据库的安装启动,并且可以在8080端口可视化界面查看数据库内容。
还想启动前端
假设我们部署项目时,希望 Docker 一起把前端也启动了,那么加一下配置:
现在执行docker-compose down
再执行docker-compose up
,打开http://localhost:3001
确实可以看到首页了
关于这个配置,有以下需要注意的点:
- 这个例子中,我们配置了 node v18,它能帮助我们实现应用环境一致性,在不同环境中启动服务都会自动加载 node v18。
- 为什么command 增加了
npx prisma generate
?如果不加这条命令,会出现下面的报错:
这是因为修改配置前在本机生成了 Prisma 查询引擎,但在 Docker 容器内运行应用时,容器的平台与本机可能不同,就出现了这个错误。
- 代码里还有个
environment
,这是配置环境变量的地方,如果我们希望统一在env文件里配置,那么就可以改成这样写:
- 现在尝试运行docker compose,然后页面上登录,会发现登录失败,控制台还是报错:
这个错误提示我们应用程序尝试连接到 localhost:5432
,但无法到达数据库服务器。在 Docker Compose 环境中,服务之间不能使用 localhost
来通信,而应该使用服务名称作为主机名。
我们来修改一下env文件
这时候再启动docker compose就不再有报错了。
学到这里你就已经学完了 Docker 的核心概念,下面我们再学习一下 Docker 怎么区分环境。
区分开发和生产环境
实际场景中,我们除了把 Docker 用于开发环境(如前面的demo),还会使用到生产环境部署。但是开发环境和生产环境有很多配置名同实异。这就需要做好两个环境的配置策略。
三种策略
-
使用不同的文件名:
我们可以为开发和生产环境使用不同的
docker-compose
文件。例如:docker-compose.dev.yml
:用于开发环境docker-compose.prod.yml
:用于生产环境
启动服务时,指定要使用的文件:
或者
-
使用环境变量:
我们可以在
docker-compose.yml
文件中使用环境变量,并根据需要为它们提供不同的值。例如,我们可以在.env.dev
和.env.prod
中定义不同的环境变量,并在启动服务时指定要使用的.env
文件: -
使用覆盖文件:
Docker Compose 支持使用多个文件来定义和覆盖服务配置。这意味着我们可以有一个基本的
docker-compose.yml
文件,并为开发和生产环境使用单独的覆盖文件。例如,我们可以使用以下文件结构:
docker-compose.yml
: 基本配置docker-compose.override.yml
: 默认的覆盖文件,通常用于开发环境docker-compose.prod.yml
: 用于生产环境的覆盖文件
在开发环境中,只需运行
docker-compose up
,它会自动使用docker-compose.yml
和docker-compose.override.yml
。在生产环境中,我们可以运行:
这将首先应用
docker-compose.yml
的设置,然后使用docker-compose.prod.yml
中的设置来覆盖它。
这些策略都可以有效地区分开发和生产环境的配置。选择哪种方法取决于具体需求和团队的偏好。
demo演练
基于前文的docker-compose.yml
demo,我们使用第一条策略来做一下环境区分。
开发环境
文件名docker-compose.dev.yml
使用方法:
生产环境
文件名:docker-compose.prod.yml
请注意,我们在生产环境的配置中添加了一个 build
指令,该指令引用一个名为 Dockerfile.prod
的 Dockerfile。为此我们还需要创建 Dockerfile,以确保正确构建和优化生产环境。
一个基本的 Dockerfile.prod
为 Next.js 应用可能是这样的:
使用方法:
-build
参数确保在启动容器之前先构建镜像。
现在重新打开http://localhost:8080
和http://localhost:3001
,会发现http://localhost:8080
无法打开,因为生产配置里没有启动 adminer。
部署到生产服务器
先查看本地有哪些 Docker 镜像
构建本地镜像
保存镜像
image_name:tag
要用实际值,如图:
到处完成后,就可以在根目录看到output_filename.tar
了
上传到服务器后,用load命令加载
确保docker-compose.prod.yml
也上传到服务器了,然后执行启动命令
这样 Docker 的部署流程就算完成了。
结语
Docker 已经成为现代软件开发中的一个不可或缺的工具。它为开发者提供了一个高度一致、隔离且可移植的环境,使得从开发到生产的过程变得更加流畅和可预测。
对于前端工程师而言,虽然 Docker 可能最初看起来有些复杂,但一旦你掌握了其基本概念和操作,你将发现它能极大地提高工作效率和应用的部署稳定性。
在这篇文章中,我们探讨了 Docker 和 Docker Compose 的基本概念、配置和常见问题。希望能为你打开新的大门,帮助你更好地理解和利用 Docker 的强大功能。
源码与演示
源码:👉Docker
在线演示:👉Docker启动项目
专栏资源
专栏介绍:以实战的角度进行Next.js生态圈的技术栈分享,内容包括但不限于:Next.js理论知识、功能模块设计思路、实战中使用到的技术栈。这是一个长期更新的专栏,我会持续把自己的思考和经验提炼分享出来,欢迎关注我的专栏👇
专栏地址:👉Next.js生态圈实战
专栏演示站:👉Next.js Demos
专栏源码仓库:👉Github - Source Code
交个朋友:👉加入「独立全栈交流群」