定制泊坞窗图像不运行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的文档:

注意:不要将RUNCMD混淆。 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 $@结束脚本来执行Docker CMD

这是一个更容易设置,但不适合生产。

Interesting Posts