1. 简介
Docker 是一个用于创建、部署和运行应用的工具。它可以帮助我们将应用打包并在一个被称为 容器 的隔离环境中运行。容器体积小巧,且包含了运行所需的一切依赖。
容器可以在任何环境中运行,这使得软件交付更加快速,也避免了常见的 “在我电脑上能跑” 的问题。我们通常通过在容器启动时执行一系列命令来启动服务。
在本文中,我们将探讨如何在 Docker 容器中自动启动服务。
2. 使用 Dockerfile
Dockerfile 包含一系列 Docker 构建镜像时执行的命令。这些命令作用在一个基础镜像上,构建出我们自定义的镜像。基础镜像作为我们构建的起点。
我们可以通过编写启动脚本来定义服务在容器启动时自动运行。这个脚本通常包括配置、初始化任务或服务启动命令。我们使用 ENTRYPOINT
或 CMD
指令来指定启动命令。
来看一个 Spring Boot 应用的简单示例:
FROM gradle:jdk13 AS build
COPY --chown=gradle:gradle . /home/gradle/project
WORKDIR /home/gradle/project
CMD ["gradle", "migrateLocal", "clean", "bootRun", "--info", "--no-daemon"]
COPY
:将当前目录内容复制到镜像中。WORKDIR
:设置后续命令的工作目录。CMD
:指定容器启动时默认执行的命令。这里执行的是 Gradle 的migrateLocal
,clean
,bootRun
命令。
构建镜像:
$ docker build api
Building api
Step 1/4 : FROM gradle:jdk13 AS build
jdk13: Pulling from library/gradle
Digest: sha256:5c97028e6418d720ba5c669d9ccc3623ba332f2887fa37d342e38ca40336bc61
Status: Downloaded newer image for gradle:jdk13
---> 2678064c31a2
Step 2/4 : COPY --chown=gradle:gradle . /home/gradle/project
---> 20706d98f062
Step 3/4 : WORKDIR /home/gradle/project
---> Running in dc21d77656b8
Removing intermediate container dc21d77656b8
---> f45a39dcd905
Step 4/4 : CMD ["gradle", "migrateLocal", "clean", "bootRun", "--info", "--no-daemon"]
---> Running in a1a9a2aab156
Removing intermediate container a1a9a2aab156
---> fe6a70d28e4e
Successfully built fe6a70d28e4e
Successfully tagged localhost:5000/spring-boot-api:v1
✅ 这个 Dockerfile 构建的镜像会运行一个基于 Gradle 的应用,并在容器启动时自动执行 migrateLocal
, clean
, bootRun
命令。我们传入 --info
和 --no-daemon
参数是为了以非守护模式运行,便于查看详细日志。
3. 使用 Docker Compose
Docker Compose 是一个用于管理多个容器的工具。我们可以通过 docker-compose.yaml
文件定义我们想要运行的服务。
下面是一个包含 PostgreSQL 和 Adminer 的 docker-compose.yaml
示例:
version: '3.5'
services:
postgresql:
image: postgres:9.6.6
ports:
- 9932:5432
expose:
- "5432"
environment:
- POSTGRES_PASSWORD=pass
restart: always
volumes:
- /data:/var/lib/postgresql/data
adminer:
image: adminer
restart: always
ports:
- "8888:8080"
restart: always
表示无论服务是否异常退出,Docker 都会自动重启它。- 如果你希望仅在服务失败时重启,可以设置为
on-failure
。
构建并启动服务:
$ docker-compose up -d
Creating network "adminer_default" with the default driver
Creating adminer_postgresql_1 ... done
Creating adminer_adminer_1 ... done
-d
表示以守护模式运行,即后台运行。
查看容器状态:
$ docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------------------
adminer_adminer_1 entrypoint.sh php -S [::]: ... Up 0.0.0.0:8888->8080/tcp
adminer_postgresql_1 docker-entrypoint.sh postgres Up 0.0.0.0:9932->5432/tcp
✅ 可以看到两个容器都处于运行状态。如果其中某个容器异常退出,Docker Compose 也会自动重启它。
4. 总结
本文我们介绍了几种在 Docker 容器中自动启动服务的方法:
- ✅ 使用
Dockerfile
中的CMD
或ENTRYPOINT
指定启动命令 - ✅ 使用
docker-compose.yaml
中的restart
策略实现服务自启与自动重启
随着 Docker 生态的发展,还有更多工具可以实现类似功能。因此,在选择方案时,建议根据团队熟悉程度和项目需求综合考虑。