<p>First, use alpine images if possible.</p>

<p>Second, use ENV variables for prepare database configuration. <a href="https://hub.docker.com/_/postgres/#environment-variables" rel="noreferrer">More info</a>.</p>

<p>Third, use <code>/docker-entrypoint-initdb.d</code> directory for extend image. <a href="https://hub.docker.com/_/postgres/#how-to-extend-this-image" rel="noreferrer">More info</a>.</p>

<p>Example stack with devlopment environment.</p>

<pre><code>version: '3.2'
services:
  example:
    image: "${EXAMPLE_SERVICE}:${EXAMPLE_SERVICE__VERSION}-development"
    build:
      context: .
      dockerfile: Dockerfile.development
    networks:
      - net
    ports:
      - 5000:5000
    depends_on:
      - example__migrator
    stdin_open: true
    tty: true
    environment:
      POSTGRES_PASSWORD: example
      POSTGRES_DB: example
      POSTGRES_USER: example
      POSTGRES_HOST: pg.example_net
      POSTGRES_PORT: 5432
      FLASK_APP: app.py
      FLASK_DEBUG: 1
    volumes:
      - .:/home/example
  example__migrator:
    image: "${EXAMPLE_SERVICE}:${EXAMPLE_SERVICE__VERSION}-development"
    build:
      context: .
    command: sh -c './wait-for pg.example_net:5432 -- python manage.py db upgrade'
    networks:
      - net
    depends_on:
      - pg
    environment:
      POSTGRES_PASSWORD: example
      POSTGRES_DB: example
      POSTGRES_USER: example
      POSTGRES_HOST: pg.example_net
      POSTGRES_PORT: 5432
  pg:
    image: postgres:10.0-alpine
    networks:
      - net
    ports:
      - 5432:5432
    volumes:
      - pg_data:/var/lib/postgresql/data/pg_data
    environment:
      POSTGRES_PASSWORD: example
      POSTGRES_DB: example
      POSTGRES_USER: example
      POSTGRES_HOST: pg.example_net
      POSTGRES_PORT: 5432
      PGDATA: /var/lib/postgresql/data/pg_data
networks:
  net:
volumes:
  pg_data:
</code></pre>

CC BY-SA 4.0
2019-07-29T03:48:46.310Z
Why to use Alpine? What is the advantages?
Suncatcher
CC BY-SA 4.0
2019-07-29T17:53:57.993Z
First, a light-weight 4-5 MB by default . As examlpe, `postgres:9.6.14` is 84 MB, `postgres:9.6.14-alpine` is 15 MB, with same functionality. Second, Alpine Linux ships with a hardened kernel by default and all userspace binaries come pre-compiled with stack-smashing protection.
AfsmNGhr
CC BY-SA 4.0
2018-12-24T11:50:23.470Z
2018-12-24T11:50:23.470Z
AfsmNGhr
<p>I have a docker-compose script which starts a Postgres container and an app container like so</p>

<pre><code>db:
  image: postgres:10.6
  restart: always
  ports:
    - 5432:5432
app:
  image: test_app:latest
  restart: always
  depends_on:
    - db
</code></pre>

<p>This all works fine and 'app' can talk to 'db'. However, the postgres server is in a basically unusable state as it has no configuration with regards to having databases, users, etc. setup (apart from the defaults). It appears that the recommended way of fixing this is to create your own 'db image' pulling from postgres and running some shell script to take care of business (and then your composition uses this image), but this seems very hacky and convoluted to me. </p>

<p>Does anyone have a better way of setting up a postgres server with a known configuration inside a docker-compose based system?</p>

<docker><docker-compose><postgresql>
Best practice for Postgres setup with docker-compose
Madden
# Best practice for Postgres setup with docker-compose

(Asked by: username_0 on 2018-12-14)

I have a docker-compose script which starts a Postgres container and an app container like so
db:
  image: postgres:10.6
  restart: always
  ports:
    - 5432:5432
app:
  image: test_app:latest
  restart: always
  depends_on:
    - db

This all works fine and 'app' can talk to 'db'. However, the postgres server is in a basically unusable state as it has no configuration with regards to having databases, users, etc. setup (apart from the defaults). It appears that the recommended way of fixing this is to create your own 'db image' pulling from postgres and running some shell script to take care of business (and then your composition uses this image), but this seems very hacky and convoluted to me. 
Does anyone have a better way of setting up a postgres server with a known configuration inside a docker-compose based system?

**Tags:** docker, docker-compose, postgresql


---

## 1 answers

### Answer by username_1 on 2018-12-24. Score: 5

First, use alpine images if possible.
Second, use ENV variables for prepare database configuration. More info.
Third, use /docker-entrypoint-initdb.d directory for extend image. More info.
Example stack with devlopment environment.
version: '3.2'
services:
  example:
    image: "${EXAMPLE_SERVICE}:${EXAMPLE_SERVICE__VERSION}-development"
    build:
      context: .
      dockerfile: Dockerfile.development
    networks:
      - net
    ports:
      - 5000:5000
    depends_on:
      - example__migrator
    stdin_open: true
    tty: true
    environment:
      POSTGRES_PASSWORD: example
      POSTGRES_DB: example
      POSTGRES_USER: example
      POSTGRES_HOST: pg.example_net
      POSTGRES_PORT: 5432
      FLASK_APP: app.py
      FLASK_DEBUG: 1
    volumes:
      - .:/home/example
  example__migrator:
    image: "${EXAMPLE_SERVICE}:${EXAMPLE_SERVICE__VERSION}-development"
    build:
      context: .
    command: sh -c './wait-for pg.example_net:5432 -- python manage.py db upgrade'
    networks:
      - net
    depends_on:
      - pg
    environment:
      POSTGRES_PASSWORD: example
      POSTGRES_DB: example
      POSTGRES_USER: example
      POSTGRES_HOST: pg.example_net
      POSTGRES_PORT: 5432
  pg:
    image: postgres:10.0-alpine
    networks:
      - net
    ports:
      - 5432:5432
    volumes:
      - pg_data:/var/lib/postgresql/data/pg_data
    environment:
      POSTGRES_PASSWORD: example
      POSTGRES_DB: example
      POSTGRES_USER: example
      POSTGRES_HOST: pg.example_net
      POSTGRES_PORT: 5432
      PGDATA: /var/lib/postgresql/data/pg_data
networks:
  net:
volumes:
  pg_data:

> **Comments:**
> **username_2**: Why to use Alpine? What is the advantages?  
> **username_1**: First, a light-weight 4-5 MB by default . As examlpe, `postgres:9.6.14` is 84 MB, `postgres:9.6.14-alpine` is 15 MB, with same functionality. Second, Alpine Linux ships with a hardened kernel by default and all userspace binaries come pre-compiled with stack-smashing protection.  

---

