Home > Software engineering >  Creating Postgres Table in Docker
Creating Postgres Table in Docker

Time:10-15

This is in relation to Error While Attempting to docker-compose a Postgres Image.

In addition to the files described in the question above, init.sh looks like this:

#for line in $(cat .env); do
#  export $line;
#done

#service postgresql-9.3 initdb


psql -d users -U even_financial -f schemas.sql

where schemas.sql looks like this:

CREATE TABLE accounts (
    user_id serial PRIMARY KEY,
    username VARCHAR ( 50 ) UNIQUE NOT NULL,
    password VARCHAR ( 50 ) NOT NULL,
    email VARCHAR ( 255 ) UNIQUE NOT NULL,
    created_on TIMESTAMP NOT NULL,
    last_login TIMESTAMP
);

If I execute init.sh from inside the docker container, postgres populates properly.

How do I do the same thing from my Dockerfile/docker-compose?

My docker-compose looks like this:

version: "3.9"

services:
  postgres:
    build:
      docker/postgres
    ports:
      - "5432:5432"
    env_file:
      docker/postgres/.env
#    command:
#      - /bin/chmod  x /app/init.sh
#      - . /app/init.sh

My docker/postgres/Dockerfile looks like this:

FROM postgres:14.5-alpine

WORKDIR /app

COPY schemas.sql .
COPY init.sh .
COPY .env .

#RUN . init.sh

Attempting to run init.sh from commands in docker-compose (as above) results in:

/usr/local/bin/docker-entrypoint.sh: line 341: /bin/chmod  x /app/init.sh: No such file or directory

Attempting to run init.sh from the Dockerfile itself via RUN results in:

 => ERROR [6/6] RUN . init.sh                                                                                      0.2s
------
 > [6/6] RUN . init.sh:
#0 0.144 psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: No such file or directory
#0 0.144        Is the server running locally and accepting connections on that socket?
------
failed to solve: executor failed running [/bin/sh -c . init.sh]: exit code: 2
`docker-compose` process finished with exit code 17

CodePudding user response:

The official Postgres image can be extended by placing shell and/or sql scripts into /docker-entrypoint-initdb.d:

If you would like to do additional initialization in an image derived from this one, add one or more *.sql, *.sql.gz, or *.sh scripts under /docker-entrypoint-initdb.d (creating the directory if necessary). After the entrypoint calls initdb to create the default postgres user and database, it will run any *.sql files, run any executable *.sh scripts, and source any non-executable *.sh scripts found in that directory to do further initialization before starting the service.

Warning: scripts in /docker-entrypoint-initdb.d are only run if you start the container with a data directory that is empty; any pre-existing database will be left untouched on container startup. One common problem is that if one of your /docker-entrypoint-initdb.d scripts fails (which will cause the entrypoint script to exit) and your orchestrator restarts the container with the already initialized data directory, it will not continue on with your scripts.

You can build these scripts into a custom image, or you can mount them at runtime via bind mounts. For example, if you have your schemas.sql script in a local directory name docker/postgres/init, you could use the following docker-compose.yaml:

version: "3.9"

services:
  postgres:
    image: docker.io/postgres:14
    ports:
      - "5432:5432"
    env_file:
      docker/postgres/.env
    volumes:
      - ./docker/postgres/init:/docker-entrypoint-initdb.d
  • Related