Docker post 运行 配置的最佳方式

Best way for Docker post run provisioning

我是 Docker 的新手,我正在尝试寻找容器启动后 Docker 配置的最佳方式。 我们使用 docker-compose 文件来构建我们的容器,我们的 compose 文件如下所示。

version: "3"

  php:
    image: wodby/drupal-php:$PHP_TAG
    container_name: "${PROJECT_NAME}_php"
    environment:   
      DB_HOST: $DB_HOST
      DB_PORT: $DB_PORT
      DB_USER: $DB_USER
      DB_PASSWORD: $DB_PASSWORD
      DB_NAME: $DB_NAME
      DB_DRIVER: $DB_DRIVER
      PHP_FPM_USER: wodby
      PHP_FPM_GROUP: wodby
      COLUMNS: 80 # Set 80 columns for docker exec -it.
    volumes:
      - ./Insider:/var/www/html

  nginx:
    image: wodby/nginx:$NGINX_TAG
    container_name: "${PROJECT_NAME}_nginx"
    depends_on:
      - php
    environment:
      NGINX_STATIC_OPEN_FILE_CACHE: "off"
      NGINX_ERROR_LOG_LEVEL: debug
      NGINX_BACKEND_HOST: php
      NGINX_SERVER_ROOT: /var/www/html/web
      NGINX_VHOST_PRESET: $NGINX_VHOST_PRESET
    ports:
      - '8000:80'
    volumes:
      - ./Insider:/var/www/html

现在我们需要在 PHP 容器启动后执行一些设置任务。现在我需要了解在此容器中执行配置的最佳方式是什么。我们有2个想法,它们如下。

  1. 编写一个shell脚本并将其作为我们构建过程中的任务之一。
  2. 使用 ansible 并从不同的服务器连接以进行设置。

但理想的过程是,如果我们能以某种方式从我们的 docker-compose.yml 文件中将 shell 脚本包含在 PHP 容器中,并且当我们 运行 docker-compose up -d 它应该 运行 作为容器启动过程的一部分并准备好一切,所以我们不需要经历第二个 command/process 等等。

有一个为此使用入口点脚本的标准模式。

无论您指定什么作为容器的入口点,都将 运行 作为主容器进程,并作为命令行参数传递给容器的命令。一个非常典型的入口点脚本具有

形式
#!/bin/sh

# ... do startup-time setup ...

# Then launch the main container command
exec "$@"

在您的 Docker 文件中,您需要照常复制它

COPY entrypoint.sh ./
# RUN chmod 0755 entrypoint.sh # if not already executable
ENTRYPOINT ["./entrypoint.sh"] # MUST be JSON-array form
CMD ["./my-app"]

入口点脚本可以访问 docker-compose.yml 中设置的环境变量等每次执行设置,并联系 Docker 中的其他服务 运行ning。它可以 export 主容器进程将看到的环境变量。 (这些不会出现在其他面向调试的路径中,如 docker inspectdocker exec,但 docker run --rm -it myimage sh 会看到它们。)一个重要的警告是入口点脚本将是唯一的东西运行此时在容器中,因此它无法与主容器进程交互,除非它特意启动它(这很棘手)。

我认为 ENTRYPOINT 的这种用法非常有用和重要,因此我倾向于保留该指令用于此目的。如果您只有一个 ENTRYPOINT(就像许多 Java SO 问题一样),您可以将其更改为 CMD 而不会产生不良影响。如果您使用 ENTRYPOINT 来命名解释器和 CMD 脚本(就像许多 Python SO 问题一样),您可以将它们组合成一个 CMD 行。

在这种情况下,一种典型的方法是构建您自己的映像。力争在构建时将所有必需的设置放入您的映像中;然后通过环境变量配置剩余的参数。不要依赖外部脚本来使现有容器进入工作状态 - 这会使您的部署过程更加复杂。

您可以基于 wodby/drupal-php 基础映像构建您自己的,并且只添加您的脚本并执行它。

FROM wodby/drupal-php:7

ADD ./my-script.sh /my-script.sh

ENTRYPOINT exec /my-script.sh // && do whatever the entrypoint of the base image does