Docker 用于 postgresql 和 java 用于 bitbucket 管道

Docker with postgresql and java for bitbucket pipelines

我在设置 docker 图像时遇到了一些问题,该图像最终将在 bitbucket 管道上用于 运行 测试我从事的一些 API 项目。

我们本地开发人员的设置非常简单,机器上 Java 8 + Maven + PostgreSQL 9.6 运行ning。

对于 运行 的集成测试,数据库必须 运行ning。并且部分maven构建在服务器上创建必要的数据库和表。

我试图在 docker 图像上复制它,这是我目前所拥有的。

FROM maven:3.5.3-jdk-8-slim

#Install postgresql
RUN apt update && \
    mkdir -p /usr/share/man/man1 &&\
    mkdir -p /usr/share/man/man7 &&\
    apt install -y postgresql-9.6

#Update config
RUN echo "host  all all 127.0.0.1/32  trust" >> /etc/postgresql/9.6/main/pg_hba.conf

#Start server
RUN service postgresql start

#Create readonly role for DB
USER postgres
RUN psql -c "CREATE ROLE readonly"

如果我通过第一个 运行:

在容器内手动 运行 这些步骤似乎工作得很好
docker run -it maven:3.5.3-jdk-8-slim /bin/bash

但是当我尝试构建图像时,这是我得到的:

▶ docker build -t pipelines .
Sending build context to Docker daemon  2.048kB
Step 1/6 : FROM maven:3.5.3-jdk-8-slim
 ---> 25f97112c73f
Step 2/6 : RUN apt update &&     mkdir -p /usr/share/man/man1 &&    mkdir -p /usr/share/man/man7 &&    apt install -y postgresql-9.6
 ---> Using cache
 ---> 5fa381f73c9d
Step 3/6 : RUN echo "host  all all 127.0.0.1/32  trust" >> /etc/postgresql/9.6/main/pg_hba.conf
 ---> Using cache
 ---> 0721966e7749
Step 4/6 : RUN service postgresql start
 ---> Using cache
 ---> 9ca8e7a270e0
Step 5/6 : USER postgres
 ---> Using cache
 ---> 50a99c6cac20
Step 6/6 : RUN psql -c "CREATE ROLE readonly"
 ---> Running in 572b2b8fa754
psql: could not connect to server: No such file or directory
    Is the server running locally and accepting
    connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
The command '/bin/sh -c psql -c "CREATE ROLE readonly"' returned a non-zero code: 2

我读过一些资料,这意味着容器正在尝试访问主机上的端口,而不是容器。但我无法理解 运行 手动命令和让 Dockerfile "run" 命令之间的区别。

我也尝试过从 postgres:9.6 基础映像构建它,然后安装 java+maven 但是当我需要在数据库上创建角色时,问题是一样的。

考虑到我的意图是在 bitbucket 管道上使用它,我在这里做错了什么。

在构建映像时使用 RUN,例如安装 postgress。每个 RUN 在之前的 RUN 指令之上构建一个层。

当你想默认执行一个命令时使用CMD,当你运行一个镜像(创建一个容器)时。因此,当您 运行 在容器中执行该命令时,相当于 Dockerfile 中的 CMD

我建议使用一个脚本,该脚本将 运行 您的命令作为 ENTRYPOINTcreate rolestablesinsert test data...在一个 Dockerfile 中,您通常有多个 RUN 指令构建在最后一层之上,但是 CMD 覆盖 之前的 CMD 指令。

There can only be one CMD instruction in a Dockerfile. If you list more than one CMD then only the last CMD will take effect.

我也鼓励您阅读 answer explaining RUN, CMD and ENTRYPOINT

总结

RUN 指令实际上是 运行 图像构建期间的命令

CMD指令在构建时不执行,它在容器启动时执行除非用户提供命令