Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run script after container entrypoint in docker-compose

I have a postgres:9.5.6-alpine container, and another container, named web, which has to be linked to it. I want to run a script named create_db.sh in postgres container after it has been started and docker-entrypoint.sh has been executed, in order to create a db and a user and restore a backup. My docker-compose.yml (postgres part):

  postgres:
    build: ./postgres
    container_name: postgres
    volumes:
      - /shared_folder/postgresql:/var/lib/postgresql
    ports:
      - "5432:5432"    
    command:  sh /home/create_db.sh

The content of create_db.sh is:

#!/bin/sh

psql -d template1 -U postgres
psql --command "CREATE USER user WITH PASSWORD 'userpassword';" 
psql --command "CREATE DATABASE userdb;"
psql --command "GRANT ALL PRIVILEGES ON DATABASE userdb to user;"
psql --command "\q;"  
psql -U user -d userdb -f /var/lib/postgresql/backup.sql

exit

When i run docker-compose build and then docker-compose up i get this:

Attaching to postgres, web
postgres    | psql: could not connect to server: No such file or directory
postgres    |   Is the server running locally and accepting
postgres    |   connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?

I've understood this is because when I launch create_db.sh postgres server is not ready, but so how can i run it after the docker-entrypoint.sh of the container?

like image 369
SegFault Avatar asked May 15 '17 08:05

SegFault


People also ask

How do I keep a docker container running after ENTRYPOINT?

The easiest way to keep the container running is to change its entry point to a command that will continue running forever. Let's use tail -f /dev/null . Rechecking the running container via docker ps -a we can see that our container has been up and running for several seconds and hasn't stopped yet.

Does docker compose command override ENTRYPOINT?

All About Docker Compose Override Entrypoint Entrypoint helps use set the command and parameters that executes first when a container is run. In fact, the command line arguments in the following command become a part of the entrypoint command, thereby overriding all elements mentioned via CMD.


1 Answers

You are overriding the original command and you do not start postgres in this script which is why your database is not available.

You can put your database initialization into the container's entrypoint directory: /docker-entrypoint-initdb.d. This executes all *.sh and *.sql files in this directory and does not touch the original command.
All files in this directory are automatically executed in the alphabetical order on container creation. Therefore, create a volume to add your scripts / sql files to the entrypoint and let the container execute them. This is described in the official postgres documentation, section "How to extend this image".

Your compose file then changes to something like this:

postgres:
  build: ./postgres
  volumes:
    - /shared_folder/postgresql:/var/lib/postgresql
    - ./db-init-scripts:/docker-entrypoint-initdb.d
  ports:
    - "5432:5432"

whereas a local directory, e.g. db-init-scripts, contains your initialization scripts (rename it if you want). Copy create_db.sh to this folder and it will be automatically executed when you create a new container.

Several database-images watch this entrypoint-directory, which is very convenient.

Your container_name: postgres seems redundant.

like image 141
n2o Avatar answered Oct 18 '22 08:10

n2o