docker - 使用多个 docker-compose 文件覆盖图像标签
问题描述
我遇到的问题是,当我构建/运行服务时,我的覆盖尝试image
被忽略了。rails
保留的图像名称是okamii/paas:dev
。但是,如果我构建/运行服务,则无论我是否覆盖它( )app
,图像的名称都是预期的( )。okamii/paas:ci
okamii/paas:dev
我错过了什么吗?
我使用的命令:
docker-compose -f docker-compose.yml -f docker-compose.ci.yml up -d rails
这是我正在使用的两个 Compose 文件:
缩短docker-compose.yml
version: '3.8'
services:
app: &app
build:
context: .
dockerfile: Dockerfile.dev
args:
BUNDLER_VERSION: '2.1.4'
NODE_MAJOR: '12'
PG_MAJOR: '13'
RUBY_VERSION: '2.7.2-jemalloc'
YARN_VERSION: '1.22.5'
BUILDKIT_INLINE_CACHE: 1
S3_ACCESS_KEY_ID: "${ACCESS_KEY:?err}"
S3_SECRET_ACCESS_KEY: "${SECRET_KEY:?err}"
image: okamii/paas:dev
tmpfs:
- /tmp
backend: &backend
<<: *app
stdin_open: true
tty: true
volumes:
- .:/app:cached
- rails_cache:/app/tmp/cache
- bundle:/usr/local/bundle
- node_modules:/app/node_modules
- packs:/app/public/packs
- .dockerdev/.psqlrc:/root/.psqlrc:ro
environment:
- NODE_ENV=development
- RAILS_ENV=${RAILS_ENV:-development}
- REDIS_URL=redis://redis:6379/
- DATABASE_URL=postgres://postgres:postgres@postgres:5432
- BOOTSNAP_CACHE_DIR=/usr/local/bundle/_bootsnap
- WEBPACKER_DEV_SERVER_HOST=webpacker
- HISTFILE=/app/log/.bash_history
- PSQL_HISTFILE=/app/log/.psql_history
- EDITOR=vi
- MALLOC_ARENA_MAX=2
- WEB_CONCURRENCY=${WEB_CONCURRENCY:-1}
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
rails:
<<: *backend
entrypoint: ./.dockerdev/rails-entrypoint.sh
ports:
- '3000:3000'
满的docker-compose.ci.yml
version: '3.8'
services:
app: &app
build:
cache_from:
- okamii/paas:ci
image: okamii/paas:ci
解决方案
YAML 锚语法 ( &app
, *backend
) 是特定文件的本地语法,并在 YAML 读取器读取文件时进行解释。这意味着您的主docker-compose.yml
文件,一旦 Compose 真正开始查看它,就会具有三个单独的服务,其中包含三个单独的image:
行。第二个文件有自己的&app
锚点(从不引用),并且只声明一个图像。
# Base docker-compose.yml, after YAML anchor expansion
version: '3.8'
services:
app:
image: okamii/paas:dev
backend:
image: okamii/paas:dev
rails:
image: okamii/paas:dev
# docker-compose.ci.yml, after YAML anchor expansion
version: '3.8'
services:
app:
image: okamii/paas:ci
如果您要覆盖的唯一内容是图像标签,则可以为此使用环境变量。如果您在每个构建中使用唯一的图像标签,这也会很好地工作,这通常是一个很好的做法。
# Base docker-compose.yml file
services:
app: &app
image: okamii/paas:${TAG:-latest}
# There is no docker-compose.ci.yml file
TAG=ci docker-compose up -d
如果您真的想在单独的 YAML 文件中指定它,则需要在那里重新创建 YAML 锚结构,或者确保所有服务都指定了它们的值。
# docker-compose.ci.yml, the complex version
version: 3.8
services:
app: &app
image: okamii/paas:ci
backend: &backend
<<: *app
rails:
<<: *backend
您还可以考虑简化此设置的方法。在这个构建中有很多选项,其中大多数可能可以在 Dockerfile 中修复(例如,BUNDLER_VERSION
必须与文件中的内容完全Gemfile.lock
匹配;没有理由在外部指定它)。在所有环境中使用相同的 Docker 映像而不构建特殊的仅 CI 映像也是一种典型做法。
推荐阅读
- go-cd - 在 GoCD 中 mvn clean install 给出 mvn' 不是内部或外部命令,但正常的 cmd 项目构建成功
- ios - 带有 Janus iOS swift 的 webRTC
- c# - ASP.NET Core IIS Express AD 服务权限错误
- javascript - 没有任何 YouTube javascript 加载到 html 页面中
- html - 子锚标记获得焦点时的大纲列表项
- google-cloud-platform - 需要获取自上次在 gcp 中停止实例以来的时间数据
- c# - 在虚拟助手上启用 QnA 跟进提示
- sql - 如何从 Microsoft SQL Server 中的字符串中修剪字符?
- python - 多个按钮在 PyQt5 python 中不起作用
- angular - 角度复选框状态检查经常触发