1. 简介

Docker 是一个用于创建、部署和运行应用的工具。它可以帮助我们将应用打包并在一个被称为 容器 的隔离环境中运行。容器体积小巧,且包含了运行所需的一切依赖。

容器可以在任何环境中运行,这使得软件交付更加快速,也避免了常见的 “在我电脑上能跑” 的问题。我们通常通过在容器启动时执行一系列命令来启动服务。

在本文中,我们将探讨如何在 Docker 容器中自动启动服务。

2. 使用 Dockerfile

Dockerfile 包含一系列 Docker 构建镜像时执行的命令。这些命令作用在一个基础镜像上,构建出我们自定义的镜像。基础镜像作为我们构建的起点。

我们可以通过编写启动脚本来定义服务在容器启动时自动运行。这个脚本通常包括配置、初始化任务或服务启动命令。我们使用 ENTRYPOINTCMD 指令来指定启动命令。

来看一个 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 中的 CMDENTRYPOINT 指定启动命令
  • ✅ 使用 docker-compose.yaml 中的 restart 策略实现服务自启与自动重启

随着 Docker 生态的发展,还有更多工具可以实现类似功能。因此,在选择方案时,建议根据团队熟悉程度和项目需求综合考虑。


原始标题:Automatically Starting Services in a Docker Container