Today, we’ll be running a Python Flask app using docker. Since this app has a dependency on a database, we will deploy the application with the docker CLI and then use docker compose to run a container that contains postgres.

The app that we will be using can be found here: app

Set up Postgres via Docker

Let’s start by taking a look at our compose.yaml file.

services:
  postgresql:
    image: postgres:15

    # pass these environment variables into the running container
    environment:
      - POSTGRES_DB
      - POSTGRES_USER
      - POSTGRES_PASSWORD
    ports:
      - ${POSTGRES_PORT}:5432

    # always restart the container if it stops
    restart: always
    volumes:
      - db_data:/var/lib/postgresql/data

    # connect the service to the python network
    networks:
      - python

volumes:
  db_data:

# define a custom network called python
networks:
  python:

    # set a custom name that does not have the project name added to it (eg. <project-name>_python)
    name: python

Create an .envrc file by copying the sample.envrc file:

  • this will create the needed environment variables for docker compose
cp sample.envrc .envrc

Create postgres via docker compose:

  • the -d is to use it in detached mode, so it is created but does not use up the terminal screen
  • since we have 2 separate docker compose files, we specify which file we want to run with -f
docker compose -f compose.yaml up -d
  • to ensure that it is created, run docker ps to list running containers:
$ docker ps
CONTAINER ID   IMAGE                  COMMAND                  CREATED         STATUS         PORTS                                       NAMES
5673a8555e0e   postgres:15            "docker-entrypoint.s…"   4 minutes ago   Up 4 minutes   0.0.0.0:5432->5432/tcp, :::5432->5432/tcp   postgresql-1

Set up App via Docker

Build the app image via Dockerfile

  • the image is built with the poetryanimaldb:1.0 tag
docker build -t poetryanimaldb:1.0 .

Now it is time to run a new container with the newly built app image

  • this uses the network that was built via the docker compose command and exposes the port 5000
  • we need to run the container on the created network that the postgres container is also running on to be able to have them communicate
docker run --network python -p 5000:5000 poetryanimaldb:1.0

The application can communicate with the database because of a hardcoded database URI

  • ideally it would be set via configuration, but this will suffice for something that is being run locally
  • this URI is build from the environment variables that we have in .envrc
app.config["SQLALCHEMY_DATABASE_URI"] = "postgresql://user:password@postgresql:5432/postgres"

Now go to localhost:5000 and you should be able to see the app running. We can now test if the database is connected by clicking Get Cat Fact or Get Dog Fact and the facts should persist after!