2

I'm attempting to create a Dockerfile that will use a init.sql file to populate a database. However, it doesn't work and from the other answers on this site and elsewhere I don't see the solution. It's simple, so it must be something dumb. The backend is written in Python/Django.

Here's the Dockerfile -

version: "3.9"

services:
  db:
    restart: always
    image: postgres
    volumes:
      - ./init.sql:/docker-entrypoint-initdb.d
      - ./data/db:/var/lib/postgresql/data
    environment:
      - POSTGRES_NAME=dev-postgres
      - POSTGRES_USER=pixel
      - POSTGRES_PASSWORD=stardust
  web:
    build: .
    restart: always
    command: sh -c "./waitfor.sh db:5432 -- python3 manage.py runserver"
    volumes:
      - .:/code
    ports:
      - "8001:8001"
    environment:
      - POSTGRES_NAME=dev-postgres
      - POSTGRES_USER=pixel
      - POSTGRES_PASSWORD=stardust
    depends_on:
      - db

And here's the init.sql file in the docker-entrypoint-initdb.d directory:

CREATE DATABASE lightchan;

One table to make this as simple as possible.

Here's the output of sudo docker-compose build && docker-compose up:

sudo docker-compose build && docker-compose up
Password:
[+] Building 3.3s (15/15) FINISHED                                                                            
 => [internal] load build definition from Dockerfile                                                     0.0s
 => => transferring dockerfile: 32B                                                                      0.0s
 => [internal] load .dockerignore                                                                        0.0s
 => => transferring context: 2B                                                                          0.0s
 => [internal] load metadata for docker.io/library/python:3.8-alpine                                     0.6s
 => [ 1/10] FROM docker.io/library/python:3.8-alpine@sha256:97aa60a6e663a7751eed676e880d51ab351a6d310c9  0.0s
 => [internal] load build context                                                                        1.0s
 => => transferring context: 18.01MB                                                                     1.0s
 => CACHED [ 2/10] RUN apk update && apk add --no-cache     gcc python3-dev     postgresql-libs postgre  0.0s
 => CACHED [ 3/10] RUN mkdir /code                                                                       0.0s
 => CACHED [ 4/10] COPY requirements.txt /code                                                           0.0s
 => CACHED [ 5/10] WORKDIR /code                                                                         0.0s
 => CACHED [ 6/10] RUN apk add --no-cache --upgrade bash                                                 0.0s
 => CACHED [ 7/10] RUN apk add python3 py3-pip                                                           0.0s
 => CACHED [ 8/10] RUN apk add libffi-dev                                                                0.0s
 => CACHED [ 9/10] RUN pip3 install -r ./requirements.txt --verbose                                      0.0s
 => [10/10] COPY . /code/                                                                                0.7s
 => exporting to image                                                                                   0.9s
 => => exporting layers                                                                                  0.9s
 => => writing image sha256:02d475029beff23d51d83daec6abb72205149f8d3eae2e90eb5d4f1353b26a7e             0.0s
 => => naming to docker.io/library/lightchan_web                                                         0.0s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
[+] Running 2/0
 ⠿ Container lightchan-db-1   Created                                                                    0.0s
 ⠿ Container lightchan-web-1  Recreated                                                                  0.1s
Attaching to lightchan-db-1, lightchan-web-1
lightchan-db-1   | 
lightchan-db-1   | PostgreSQL Database directory appears to contain a database; Skipping initialization
lightchan-db-1   | 
lightchan-db-1   | 2022-03-01 20:11:29.180 UTC [1] LOG:  starting PostgreSQL 14.2 (Debian 14.2-1.pgdg110+1) on aarch64-unknown-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
lightchan-db-1   | 2022-03-01 20:11:29.180 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
lightchan-db-1   | 2022-03-01 20:11:29.180 UTC [1] LOG:  listening on IPv6 address "::", port 5432
lightchan-db-1   | 2022-03-01 20:11:29.186 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
lightchan-db-1   | 2022-03-01 20:11:29.231 UTC [28] LOG:  database system was shut down at 2022-03-01 20:09:25 UTC
lightchan-db-1   | 2022-03-01 20:11:29.259 UTC [1] LOG:  database system is ready to accept connections
lightchan-web-1  | Watching for file changes with StatReloader
lightchan-db-1   | 2022-03-01 20:11:30.549 UTC [36] FATAL:  database "lightchan" does not exist
lightchan-web-1  | Exception in thread django-main-thread:
lightchan-web-1  | Traceback (most recent call last):
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 230, in ensure_connection
lightchan-web-1  |     self.connect()
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/django/utils/asyncio.py", line 25, in inner
lightchan-web-1  |     return func(*args, **kwargs)
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 211, in connect
lightchan-web-1  |     self.connection = self.get_new_connection(conn_params)
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/django/utils/asyncio.py", line 25, in inner
lightchan-web-1  |     return func(*args, **kwargs)
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/django/db/backends/postgresql/base.py", line 199, in get_new_connection
lightchan-web-1  |     connection = Database.connect(**conn_params)
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/psycopg2/__init__.py", line 122, in connect
lightchan-web-1  |     conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
lightchan-web-1  | psycopg2.OperationalError: connection to server at "db" (172.23.0.2), port 5432 failed: FATAL:  database "lightchan" does not exist
lightchan-web-1  | 
lightchan-web-1  | 
lightchan-web-1  | The above exception was the direct cause of the following exception:
lightchan-web-1  | 
lightchan-web-1  | Traceback (most recent call last):
lightchan-web-1  |   File "/usr/local/lib/python3.8/threading.py", line 932, in _bootstrap_inner
lightchan-web-1  |     self.run()
lightchan-web-1  |   File "/usr/local/lib/python3.8/threading.py", line 870, in run
lightchan-web-1  |     self._target(*self._args, **self._kwargs)
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/django/utils/autoreload.py", line 64, in wrapper
lightchan-web-1  |     fn(*args, **kwargs)
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/django/core/management/commands/runserver.py", line 127, in inner_run
lightchan-web-1  |     self.check_migrations()
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/django/core/management/base.py", line 505, in check_migrations
lightchan-web-1  |     executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS])
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/django/db/migrations/executor.py", line 18, in __init__
lightchan-web-1  |     self.loader = MigrationLoader(self.connection)
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/django/db/migrations/loader.py", line 53, in __init__
lightchan-web-1  |     self.build_graph()
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/django/db/migrations/loader.py", line 223, in build_graph
lightchan-web-1  |     self.applied_migrations = recorder.applied_migrations()
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/django/db/migrations/recorder.py", line 77, in applied_migrations
lightchan-web-1  |     if self.has_table():
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/django/db/migrations/recorder.py", line 55, in has_table
lightchan-web-1  |     with self.connection.cursor() as cursor:
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/django/utils/asyncio.py", line 25, in inner
lightchan-web-1  |     return func(*args, **kwargs)
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 270, in cursor
lightchan-web-1  |     return self._cursor()
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 246, in _cursor
lightchan-web-1  |     self.ensure_connection()
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/django/utils/asyncio.py", line 25, in inner
lightchan-web-1  |     return func(*args, **kwargs)
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 230, in ensure_connection
lightchan-web-1  |     self.connect()
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/django/db/utils.py", line 90, in __exit__
lightchan-web-1  |     raise dj_exc_value.with_traceback(traceback) from exc_value
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 230, in ensure_connection
lightchan-web-1  |     self.connect()
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/django/utils/asyncio.py", line 25, in inner
lightchan-web-1  |     return func(*args, **kwargs)
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 211, in connect
lightchan-web-1  |     self.connection = self.get_new_connection(conn_params)
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/django/utils/asyncio.py", line 25, in inner
lightchan-web-1  |     return func(*args, **kwargs)
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/django/db/backends/postgresql/base.py", line 199, in get_new_connection
lightchan-web-1  |     connection = Database.connect(**conn_params)
lightchan-web-1  |   File "/usr/local/lib/python3.8/site-packages/psycopg2/__init__.py", line 122, in connect
lightchan-web-1  |     conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
lightchan-web-1  | django.db.utils.OperationalError: connection to server at "db" (172.23.0.2), port 5432 failed: FATAL:  database "lightchan" does not exist
lightchan-web-1  | 

The tl;dr error is:

django.db.utils.OperationalError: connection to server at "db" (172.23.0.2), port 5432 failed: FATAL:  database "lightchan" does not exist

Here is the connection to the database in settings.py:

DATABASES = {
   'default': {
       'ENGINE': 'django.db.backends.postgresql',
       'NAME': 'lightchan',
       'USER': 'pixel',
       'PASSWORD': 'stardust',
       'HOST': 'db',
       'PORT': '5432'
   }
}

Why isn't this working?

EDIT: This question has been closed, but has been continued in another thread (here: Docker-Compose Init Postgres Failing). Thanks!

1
  • 1
    The postgres image only runs the /docker-entrypoint-initdb.d scripts when it starts up the very first time. If it prints the "directory appears to contain a database" message then it's not running the init scripts. Stopping the container and deleting the ./data/db directory on the host should make it run again; the linked question says a little bit more. Commented Mar 1, 2022 at 22:51

1 Answer 1

3

You specify the following for your database container:

    environment:
      - POSTGRES_NAME=dev-postgres
      - POSTGRES_USER=pixel
      - POSTGRES_PASSWORD=stardust

For the postgres image (see its documentation), you specify the database name using either POSTGRES_DB or, if that value isn't set, then POSTGRES_USER is used instead. Your database will end up named pixel, the value of POSTGRES_USER.

Your Django app expects a different name:

DATABASES = {
   'default': {
       'ENGINE': 'django.db.backends.postgresql',
       'NAME': 'lightchan',
       'USER': 'pixel',
       'PASSWORD': 'stardust',
       'HOST': 'db',
       'PORT': '5432'
   }
}

Here your database name is assumed to be lightchan. This explains the error you receive, telling you that the database doesn't exist. It's because Django is looking for a database name different from the one set in the Postgres image.

django.db.utils.OperationalError: connection to server at "db" (172.23.0.2), port 5432 failed: FATAL: database "lightchan" does not exist

The easiest solution is to modify docker-compose.yml to include a database name of lightchan. That should create the database using the name you are expecting.

    environment:
      - POSTGRES_NAME=dev-postgres
      - POSTGERS_DB=lightchan
      - POSTGRES_USER=pixel
      - POSTGRES_PASSWORD=stardust

Sign up to request clarification or add additional context in comments.

3 Comments

That was definitely an issue, thanks for the reply. Still getting errors and I'm not sure why. If I manage to narrow it down more I might post again or PM you. Thanks for the help.
@yosemeti Post another question. Stack Overflow does not have PMs.
Ok I've made a new thread ( stackoverflow.com/questions/71316702/…), with more debugging questions. I'll edit that thread until it's solved and ask for reopens from the mods if it isn't (mods please don't mark that thread as solved until it is - if possible it might be useful for SO to have some full solutions).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.