Talking to a PostgreSQL service container from inside a Docker container#
I have a Django application which uses PostgreSQL. I build the Django application into its own Docker container, push that built container to the GitHub package registery and then deploy that container to production.
I wanted to run the tests inside the container as part of the deployment process, to make sure the container that I build is ready to be deployed (via continuous deployment).
In production I’m using Digital Ocean PostgreSQL rather than running PostgreSQL in a container. For running the tests I decided to use GitHub’s PostgreSQL service containers to run the tests.
But how do you set it up so tests running inside a Docker container can talk to the PostgreSQL service container provided by the GitHub Actions environment?
This took a while to figure out. The key insight was that Docker containers (at least on Linux) have a magic IP address, 172.17.0.1
, which can be used to access their host environment - and GitHub’s PostgreSQL container is available to that host environment on localhost port 5432.
So here’s the recipe I ended up using:
1name: Build, test and deploy2
3on:4 push:5
6jobs:7 build_test_deploy:8 runs-on: ubuntu-latest9 services:10 postgres:11 image: postgres12 env:13 POSTGRES_USER: postgres14 POSTGRES_DB: postgres15 POSTGRES_PASSWORD: postgres16 ports:17 - 5432:543218 # Health checks to wait until postgres has started19 options: >-20 --health-cmd pg_isready21 --health-interval 10s22 --health-timeout 5s23 --health-retries 524 steps:25 - uses: actions/checkout@v226 - name: Build the tagged Docker image27 run: |-28 docker build -t my-tag .29 - name: Run tests30 run: |-31 docker run \32 -e DATABASE_URL="postgres://postgres:postgres@172.17.0.1:5432/postgres" \33 --entrypoint=/app/github-actions-runtests.sh \34 my-tag
My github-actions-runtests.sh
file uses django-pytest and looks like this:
1#!/bin/bash2cd /app3pytest --ds=config.test_settings