Skip to content

Commit 3145492

Browse files
authored
Talking to a PostgreSQL service container from inside a Docker container
1 parent 87059eb commit 3145492

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Talking to a PostgreSQL service container from inside a Docker container
2+
3+
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.
4+
5+
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).
6+
7+
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](https://docs.github.com/en/actions/guides/creating-postgresql-service-containers) to run the tests.
8+
9+
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?
10+
11+
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.
12+
13+
So here's the recipe I ended up using:
14+
15+
```yaml
16+
name: Build, test and deploy
17+
18+
on:
19+
push:
20+
21+
jobs:
22+
build_test_deploy:
23+
runs-on: ubuntu-latest
24+
services:
25+
postgres:
26+
image: postgres
27+
env:
28+
POSTGRES_USER: postgres
29+
POSTGRES_DB: postgres
30+
POSTGRES_PASSWORD: postgres
31+
ports:
32+
- 5432:5432
33+
# Health checks to wait until postgres has started
34+
options: >-
35+
--health-cmd pg_isready
36+
--health-interval 10s
37+
--health-timeout 5s
38+
--health-retries 5
39+
steps:
40+
- uses: actions/checkout@v2
41+
- name: Build the tagged Docker image
42+
run: |-
43+
docker build -t my-tag .
44+
- name: Run tests
45+
run: |-
46+
docker run \
47+
-e DATABASE_URL="postgres://postgres:[email protected]:5432/postgres" \
48+
--entrypoint=/app/github-actions-runtests.sh \
49+
my-tag
50+
```
51+
My `github-actions-runtests.sh` file uses [django-pytest](https://pytest-django.readthedocs.io/) and looks like this:
52+
```bash
53+
#!/bin/bash
54+
cd /app
55+
pytest --ds=config.test_settings
56+
```

0 commit comments

Comments
 (0)