Containerized (docker) database (PostgresSQL) and python app for a simple CRUD (Create, Read, Update and Delete) operation.
- Python V3.10+
- Docker V4.17+
- Clone the repository
- Create a
.env
file in the project directory to define and set the value of the required variables used in docker-compose.yml. cd
into the project directory from terminal.
- Enter
docker-compose up --exit-code-from app
to run/test the project. The terminal will show the logs of the database and app containers. Near the end of log output should show Ran 4 tests if there's no error.--exit-code-from app
stops the database service when theapp
service is exited.- pass
--build
argument if any of the Dockerfiles is modified.docker-compose up
only build the Dockerfiles if there are no preexisting images for the docker-compose.
- Remove or comment out the part of
app
service from the docker-compose.yml. - Enter
docker-compose up --build
to start the database container.- pass
-d
argument to detach and see the logs from separately.
- pass
- Enter
docker-compose down
to shut off the containers.
Create a file name .env
. This file is used to define and setting the value of the required environment variables used
in docker-compose.yml.
DATABASE_NAME = eg_db_name
DATABASE_USER = eg_db_user
DATABASE_PASSWORD = eg_db_pass
DATABASE_TYPE = postgresql // driver for postgresql don't change unles you know what you are doing
DATABASE_HOST_PORT = 5500
DATABASE_CONTAINER_PORT = 5432 // port of the database from docker-compose.yml, don't change unles you know what you are doing
DATABASE_HOST = database // service name of the database from docker-compose.yml, don't change unles you know what you are doing
Caution
.env
file cannot have any comments. Therefore, remove comments before
copying.
Important
For any docker instruction with source (host) path (Dockerfile#line 3) is dependent on the context
path in docker-compose.yml
(docker-compose#line 5)
A Dockerfile for the database is created.
bitnami/postgresql
image is used- Line 1 ->
FROM bitnami/postgresql
- Line 1 ->
COPY
command is used to copy the file py_pg_crud.sql to/docker-entrypoint-initdb.d/
from host to docker. py_pg_crud.sql initialize the PostgreSQL database.- Line 2 ->
COPY /container-scripts/database/postgresql/data/py_pg_crud.sql /docker-entrypoint-initdb.d/py_pg_crud.sql
- Line 2 ->
A Dockerfile for the app is created.
-
bitnami/python
image is used- Line 1 ->
FROM bitnami/python
- Line 1 ->
-
WORKDIR
instruction sets the working directory for any other instructions that follow it in the Dockerfile.- Line 2 ->
WORKDIR /Python_CRUD/
- Line 2 ->
-
COPY
command is used to Copy therequirements.txt
and source code to a directory in docker e.g.Python_CRUD
-
Set environment variable
PYTHONPATH
to provide guidance to the Python interpreter about where to find various libraries and applications.- Line 5 ->
ENV PYTHONPATH .
- Line 5 ->
-
Use the
requirements.txt
to install required dependencies to run or test the project.- Line 6 ->
RUN pip install -r ./requirements.txt
- Line 6 ->
-
Run the unit-tests to test the app.
- Line 12 ->
CMD ["python", "-u", "-m", "unittest"]
- Line 12 ->
docker-compose.yml uses the Dockerfiles to build images then spin up the database and app services.
- In the services, specification name of the services is defined. This project used database and app.
- The individual service specifies the abstract definition of the computing resources.
- Each service needs a build specification either in the form of
Dockerfile
or theimage
url. context
defines path/url to a directory containing a Dockerfile. Alternatively, it can also be used as the buildcontext
, this project uses project directory as the build context to resolve relative paths. e.g. Line 5 ->context: ./
dockerfile
sets an alternate Dockerfile. The relative path is resolved from the buildcontext
e.g. Line 6 ->dockerfile: container-scripts/database/postgresql/Dockerfile
ports
exposes container ports. (Line 7)ports: - "${DATABASE_HOST_PORT}:${DATABASE_CONTAINER_PORT}"
environment
defines environment variables set in the container.database
service requires the few environment variables to start. (Line 9)environment: POSTGRES_DB: $DATABASE_NAME POSTGRES_USER: $DATABASE_USER POSTGRES_PASSWORD: $DATABASE_PASSWORD
app
service requires the few environment variables to work. (Line 25)environment: DATABASE_TYPE: $DATABASE_TYPE DATABASE_NAME: $DATABASE_NAME DATABASE_USER: $DATABASE_USER DATABASE_PASSWORD: $DATABASE_PASSWORD DATABASE_HOST: $DATABASE_HOST DATABASE_PORT: $DATABASE_PORT IS_DOCKER: true
networks
defines the name of the network. This project configured both database and app services in one network. (Line 13 and Line 32)networks: - crud-net
healthcheck
declares a check that runs to determine whether the service containers are "healthy". To determine if thedatabase
service is ready to accept connection a test is run. The test runs twice with an interval of 10s and timeout of 5s if the first run was failed. (Line 15)healthcheck: test: ["CMD-SHELL", "sh -c 'pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}'"] interval: 10s timeout: 5s retries: 2
app
service is dependent ondatabase
service. Therefore, the following section is added (Line 34)depends_on: db: condition: service_healthy
Tip
Check docker documentation for more details