我正在尝试创建一个自定义Docker映像,以将其用作AWS CodeBuild的构建映像。如果我仅在设置环境下对Dockerfile执行docker build
,则效果很好。但是现在我需要添加一个postgres实例来运行测试。因此,我认为使用docker-compose
可以解决问题。但是,我没有弄清楚如何使其工作。当我尝试docker-compose up
时,似乎构图的静态部分(来自Dockerfile的图像)立即停止,因为没有入口点。此时,我可以通过运行docker-compose run db psql -h db -U testdb -d testdb
连接到数据库实例。但是,当我将其构建并提供给AWS提供的脚本时,它可以正常运行,直到我的测试尝试到达数据库服务器为止。这是超时失败的地方,就像没有数据库实例一样。
配置如下:
version: '3.7'
services:
api-build:
tty: true
build: ./api_build
image: api-build
depends_on:
- db
db:
image: postgres:10-alpine
restart: always
environment:
POSTGRES_USER: testdb
POSTGRES_PASSWORD: testdb
和./api_build
下的Dockerfile:
FROM alpine:3.8
FROM ruby:2.3-alpine as rb
RUN apk update && apk upgrade && \
echo @edge http://nl.alpinelinux.org/alpine/edge/community >> /etc/apk/repositories && \
echo @edge http://nl.alpinelinux.org/alpine/edge/main >> /etc/apk/repositories
RUN apk add --no-cache \
alpine-sdk \
tzdata \
libxml2-dev \
libxslt-dev \
libpq \
postgresql-dev \
elixir \
erlang
更新:我刚刚意识到docker-compose build
仅在需要时构建部分合成文件(例如,更新Docker文件),这是否意味着无法使用docker compose创建映像?还是我做错了什么?
答案 0 :(得分:2)
由于没有答案,我会尝试自己回答。我不确定它是否会有用,但是我发现我对Docker有一些误解,这使我看不到解决方案或缺乏解决方案。
1)我没意识到的是docker-compose
用于编排容器组成,它不能内置到包含所需所有服务的单个图像中。
2)多阶段构建听起来令人兴奋并且有些神奇,直到我发现每个下一阶段都从头开始创建图像。您唯一可以做的就是复制以前阶段的某些文件(如果别名为AS
)。它仍然很酷,但是手动复制包含数百个文件的安装可能(并且将)成为噩梦。
3)Docker被设计为仅在容器内部运行一个进程,但这并不意味着它不能运行多个进程。因此,解决我的问题的方法是使用主管。特别是S6,据说重量很轻,这正是我使用微型Alpine图像所需要的。
我最终从s6-overlay
部署了just-containers
:
RUN curl -L -s https://github.com/just-containers/s6-overlay/releases/download/v1.21.4.0/s6-overlay-amd64.tar.gz \
| tar xvzf - -C /
ENTRYPOINT [ "/init" ]
它提供了服务脚本所在的/etc/services.d
目录。例如,对于postgresql,最小的示例是(在/etc/services.d/postgres/run中):
#!/usr/bin/execlineb -P
s6-setuidgid postgres
postgres -D /usr/local/pgsql/data
就是这样。