如何在 docker 和 docker-compose 中分离项目的环境

How to separate environments of a project in docker and docker-compose

我有几个关于网络应用环境的基本概念问题

我正在尝试构建一个 docker 化的 Rails 应用程序,具有:测试、开发、暂存和生产。

  1. 我的第一个问题是,Dockerfile 和 docker-compose 是否应该在每个环境中都相同?

唯一会改变的是,当我想做测试时,我在创建容器时通过 RAILS_ENV=测试,当我想做开发时,我通过 RAILS_ENV=发展等等。

这是它背后的正确想法吗? 或者它们可以不同吗(在我的例子中,我在生产环境中与 appdb 一起构建 nginx 但我只有一个简单的设置,只有 appdb 用于测试和开发)

  1. 我的第二个问题是,当我通过 RAILS_ENV=test 时,我是否应该在 Dockerfile 上进行(构建图像时有条件地通过不同的环境):
# Set environment
ARG BUILD_DEVELOPMENT
# if --build-arg BUILD_DEVELOPMENT=1, set RAILS_ENV to 'development' or set to null otherwise.
ENV RAILS_ENV=${BUILD_DEVELOPMENT:+development}
# if RAILS_ENV is null, set it to 'production' (or leave as is otherwise).
ENV RAILS_ENV=${RAILS_ENV:-production}

或者保持相同的图像并在执行 docker-compose 时传递 RAILS_ENV? :

docker-compose -f docker-compose.production.yml run rake db:create db:migrate  RAILS_ENV=production

谢谢!

Should the Dockerfile be the same for every environment?

是的。构建单个映像并在所有环境中重复使用它。不要使用 Dockerfile ARG 传递“是生产环境”、主机名或 host-specific 用户 ID。特别是您应该在 pre-production 和生产环境中使用相同的环境,以避免部署未经测试的图像。

Should docker-compose.yml be the same for every environment?

这是您必须控制 deploy-time 选项的主要地方,例如,您的数据库所在的位置,或者应该输出什么级别的日志。因此,每个环境都有一个单独的 Compose 文件是有意义的。

Compose 支持 multiple Compose files。您可以多次使用 docker-compose -f ... 来指定要使用的特定 Compose 文件;或者,如果您没有该选项,那么 Compose 将读取 docker-compose.ymldocker-compose.override.yml。因此,您可能有一个基本 docker-compose.yml 文件来命名要使用的图像

# docker-compose.yml
version: '3.8'
services:
  app:
    image: registry.example.com/app:${APP_TAG:-latest}

在你提出的问题中docker-compose.prod.yml。这可以设置 $RAILS_ENV 并指向您的生产数据库:

# docker-compose.prod.yml
services:
  app:
    environment:
      - RAILS_ENV=production
      - DB_HOST=db.example.com
      - DB_USERNAME=...
    # (but don't repeat image:)

您可以单独拥有一个 docker-compose.dev.yml 来启动本地数据库,并提供有关如何构建映像的说明:

# docker-compose.dev.yaml
version: '3.8'
services:
  app:
    build: .
    environment:
      - RAILS_ENV=development
      - DB_HOST=db
      - DB_USERNAME=db
      - DB_PASSWORD=passw0rd
  db:
    image: postgres:14
    environment:
      - POSTGRES_USER=db
      - POSTGRES_PASSWORD=passw0rd
    volumes:
      - dbdata:/var/lib/postgresql/data
volumes:
  dbdata:

如果您使用 docker-compose -f 选项,您需要始终提及您正在使用的两个 个文件

docker-compose \
  -f docker-compose.yml \
  -f docker-compose.dev.yml \
  run app \
  rake db:migrate

您还可以符号链接 docker-compose.override.yml 指向 environment-specific 文件,然后 Compose 将能够默认找到它。

ln -sf docker-compose.test.yml docker-compose.override.yml
docker-compose run app rspec