定制泊坞窗图像不运行postgres
我正在尝试为circleci v2创build自己的自定义泊坞窗文件。 但是,我遇到了postgres服务器没有运行的问题。 我已经运行service postgresql start
没有可用。
我得到的消息是:
psql: could not connect to server: Connection refused Is the server running locally and accepting connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
Dockerfile:
FROM ubuntu:16.04 ENV NODEJS_VERSION 6 ENV POSTGRESQL_VERSION 9.6 RUN apt-get update && apt-get -y install curl RUN curl -sL https://deb.nodesource.com/setup_$NODEJS_VERSION.x | bash - RUN apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8 RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdg main" > /etc/apt/sources.list.d/pgdg.list RUN apt-get update RUN apt-get install -y \ nodejs \ make \ git \ g++ \ python-software-properties \ software-properties-common \ postgresql-$POSTGRESQL_VERSION \ postgresql-client-$POSTGRESQL_VERSION \ postgresql-contrib-$POSTGRESQL_VERSION RUN echo "host all all 0.0.0.0/0 md5" >> /etc/postgresql/$POSTGRESQL_VERSION/main/pg_hba.conf RUN echo "listen_addresses='*'" >> /etc/postgresql/$POSTGRESQL_VERSION/main/postgresql.conf USER postgres RUN service postgresql start && \ psql -c "create database pgdb;" && \ psql -c "create role pgrole with login password 'pgrole'; grant all privileges on database pgdb to pgrole;"
也可以看看:
- GitHub: https : //github.com/jonathanong/docker-nodejs-postgres
- CircleCI: https ://circleci.com/gh/jonathanong/docker-nodejs-postgres/tree/master
谢谢
问题
问题是你没有定义你的映像应该运行哪个命令,所以它默认为在Ubuntu基本映像中设置的命令: /bin/bash
。
看看CMD的文档:
注意:不要将
RUN
与CMD
混淆。RUN
实际上运行一个命令并提交结果;CMD
不会在构build时执行任何操作,而是指定图像的预期命令。
所以你的RUN service postgresql start
在构build时被执行,并且该命令的结果被作为一个图层提交给图像。 当您启动图像时,例如在CircleCI上,图像的CMD
被执行。 而且由于你没有设置,它使用了Ubuntu指定的: /bin/bash
。 这意味着在运行时 ,实际上是在运行Postgres。
另外要记住的是CMD
不能是守护进程。 只要在前台执行一个进程,Docker就会保持一个容器运行,所以如果你使用CMD service postgresql start
,Docker将在命令返回后退出容器。
解决scheme
我build议你重做你的整个configuration。 如果您在CMD
启动Postgres,则不能覆盖该命令来运行testing(否则Postgres将不会再运行)。
相反,使用两个图像,一个用于您的应用程序,一个用于Postgres。 你启动Postgres,等待它接受连接,然后在你的app
容器中运行testing。
您可以重新使用现有的postgresql
映像,在启动它时为您创build一个数据库和用户。 你需要添加一个脚本来等待数据库准备好,否则你的testing将在数据库接受连接之前运行。 看到这个职位: https : //discuss.circleci.com/t/waiting-for-database/10946
使用这种方法,一次运行多个服务变得更加容易,并且仍然可以完全自由地在Circle CI上运行哪些命令。
替代scheme
稍微简单些,但只是为了testing,可以select创build一个启动Postgres的入口点,并等待它准备就绪。 创build一个脚本,将其复制到Dockerfile
,并将ENTRYPOINT
指向它。 在脚本中,运行services postgresql start
,创build数据库,然后等待Postgres接受连接。 一旦完成,使用exec $@
来执行你传递给容器的任何命令。
你可以在这里find一个我们用来等待Postgres的脚本: https : //gist.github.com/jdno/09377bde65095773e5daf1aaa8e62ef4
这个脚本也可以很容易地扩展为一个ENTRYPOINT
。
- 用
services postgresql start
启动Postgres。 - 等待Postgres接受连接(即脚本现在做什么)。
- 运行
psql
命令来创build你的数据库。 - 用
exec $@
结束脚本来执行DockerCMD
。
这是一个更容易设置,但不适合生产。