I am creating a web application with FastApi using docker. I have two containers: one for the application and another for the database, this is the docker compose:
version: '3.8'
services:
web:
build:
context: .
dockerfile: ./compose/local/Dockerfile
image: fastapi_example_web
# '/start' is the shell script used to run the service
command: /start
# this volume is used to map the files and folders on the host to the container
# so if we change code on the host, code in the docker container will also be changed
volumes:
- .:/app
ports:
- 8020:8000
env_file:
- .env/.dev
depends_on:
- db
db:
build:
context: ./compose/local/postgres
dockerfile: Dockerfile
volumes:
- ./data/postgres:/var/lib/postgresql/data
expose:
- 5432:5432
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
This is the DockerFile and scripts for the web container:
FROM python:3.10-slim-buster
ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1
RUN apt-get update \
# dependencies for building Python packages
&& apt-get install -y build-essential \
# psycopg2 dependencies
&& apt-get install -y libpq-dev \
# Additional dependencies
&& apt-get install -y telnet netcat \
# cleaning up unused files
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
&& rm -rf /var/lib/apt/lists/*
# Requirements are installed here to ensure they will be cached.
COPY ./requirements.txt /requirements.txt
RUN pip install -r /requirements.txt
COPY ./compose/local/entrypoint /entrypoint
RUN sed -i 's/\r$//g' /entrypoint
RUN chmod +x /entrypoint
COPY ./compose/local/start /start
RUN sed -i 's/\r$//g' /start
RUN chmod +x /start
WORKDIR /app
ENTRYPOINT ["/entrypoint"]
entrypoint:
#!/bin/bash
echo "Waiting for postgres..."
while ! nc -z db 5432; do
sleep 0.1
done
echo "PostgreSQL started"
exec "$@"
start:
#!/bin/bash
set -o errexit
set -o pipefail
set -o nounset
uvicorn app.main:app --reload --reload-dir app --host 0.0.0.0
This is the DockerFile and scripts for the db container:
# pull official base image
FROM postgres:14-alpine
# run create.sql on init
ADD create.sql /docker-entrypoint-initdb.d
create.sql
CREATE DATABASE web_dev;
CREATE DATABASE web_test;
In my application, creating users is a protected endpoint, so I want the first user to be created when the containers are built, inserting it into the database. The problem is that first the "db" container starts (at this moment the tables do not yet exist in the database), then the "web" container starts (at this moment the migrations are applied automatically and the tables are created). In which container and in which part should I create the sql record?