Skip to content

Commit 2087b98

Browse files
authored
Merge pull request OSMCha#719 from OSMCha/jlow/docker-improvements
Improve Docker development workflow
2 parents 329df5f + c283529 commit 2087b98

19 files changed

+94
-194
lines changed

.github/workflows/django.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ jobs:
88
strategy:
99
max-parallel: 4
1010
matrix:
11-
python-version: [3.9, '3.10']
11+
python-version: ['3.9', '3.10']
1212

1313
steps:
1414
- uses: actions/checkout@v2
@@ -33,7 +33,7 @@ jobs:
3333
run: |
3434
coverage run manage.py test --settings=config.settings.tests
3535
env:
36-
OAUTH_OSM_KEY: ${{ secrets.OAUTH_OSM_KEY }}
37-
OAUTH_OSM_SECRET: ${{ secrets.OAUTH_OSM_SECRET }}
38-
POSTGRES_USER: ${{ secrets.POSTGRES_USER }}
39-
POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }}
36+
OAUTH2_OSM_KEY: ${{ secrets.OAUTH_OSM_KEY }}
37+
OAUTH2_OSM_SECRET: ${{ secrets.OAUTH_OSM_SECRET }}
38+
PGUSER: ${{ secrets.POSTGRES_USER }}
39+
PGPASSWORD: ${{ secrets.POSTGRES_PASSWORD }}

.github/workflows/docker-publish.yml

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,50 @@ name: Build Docker Image, Push to GHCR
22

33
on:
44
push:
5-
branches:
6-
- master
5+
branches: [ "main" ]
6+
tags: [ 'v*.*.*' ]
7+
8+
env:
9+
REGISTRY: ghcr.io
10+
IMAGE_NAME: osmcha/osmcha-django
711

812
jobs:
913
build:
1014
runs-on: ubuntu-latest
1115

1216
steps:
1317
- name: Checkout code
14-
uses: actions/checkout@v2
18+
uses: actions/checkout@v4
1519

20+
# Enable BuildKit for docker builds. This enables building
21+
# multi-platform images and exporting the layer cache
22+
# https://github.com/docker/setup-buildx-action
1623
- name: Set up Docker Buildx
17-
uses: docker/setup-buildx-action@v1
24+
uses: docker/setup-buildx-action@v3
1825

19-
- name: Login to GitHub Container Registry
20-
uses: docker/login-action@v2
26+
# https://github.com/docker/login-action
27+
- name: Login to Registry ${{ env.REGISTRY }}
28+
uses: docker/login-action@v3
2129
with:
22-
registry: ghcr.io
30+
registry: ${{ env.REGISTRY }}
2331
username: ${{ github.actor }}
2432
password: ${{ secrets.GITHUB_TOKEN }}
2533

34+
# Extract metadata (tags, labels) for Docker
35+
# https://github.com/docker/metadata-action
36+
- name: Extract Docker metadata
37+
id: meta
38+
uses: docker/metadata-action@v5
39+
with:
40+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
41+
42+
# https://github.com/docker/build-push-action
2643
- name: Build and push Docker image
27-
uses: docker/build-push-action@v4
44+
uses: docker/build-push-action@v5
2845
with:
2946
context: .
3047
push: true
31-
tags: |
32-
ghcr.io/osmcha/osmcha-django:latest
33-
ghcr.io/osmcha/osmcha-django:${{ github.sha }}
48+
tags: ${{ steps.meta.outputs.tags }}
49+
labels: ${{ steps.meta.outputs.labels }}
3450
cache-from: type=gha
35-
cache-to: type=gha,mode=max
51+
cache-to: type=gha,mode=max

Dockerfile

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
FROM python:3.10-slim-bookworm
22
ARG DEBIAN_FRONTEND=noninteractive
3+
ARG REQUIREMENTS_FILE=production.txt
4+
ARG DJANGO_SETTINGS_MODULE=config.settings.production
35

46
RUN apt-get update -qq -y \
57
&& apt-get install -y curl wget python3 python3-dev python3-pip git \
@@ -10,21 +12,24 @@ RUN apt-get update -qq -y \
1012

1113
# Requirements have to be pulled and installed here, otherwise caching won't work
1214
COPY ./requirements /requirements
13-
14-
RUN pip install -r /requirements/production.txt
15+
RUN pip install -r /requirements/$REQUIREMENTS_FILE
1516

1617
COPY . /app
1718
RUN useradd django
1819
RUN chown -R django:django /app
20+
WORKDIR /app
21+
22+
RUN python manage.py collectstatic --noinput
1923

20-
COPY ./compose/django/gunicorn.sh /gunicorn.sh
2124
COPY ./compose/django/entrypoint.sh /entrypoint.sh
22-
RUN sed -i 's/\r//' /entrypoint.sh \
23-
&& sed -i 's/\r//' /gunicorn.sh \
24-
&& chmod +x /entrypoint.sh \
25-
&& chmod +x /gunicorn.sh
25+
RUN chmod +x /entrypoint.sh
2626

27-
WORKDIR /app
2827
USER django
28+
VOLUME /app/staticfiles
29+
30+
# Default number of gunicorn worker processes. Using an env var instead of --workers
31+
# in the command below lets users of this docker image override the default easily.
32+
ENV WEB_CONCURRENCY 4
2933

3034
ENTRYPOINT ["/entrypoint.sh"]
35+
CMD ["gunicorn", "config.wsgi", "-t", "120", "-b", "0.0.0.0:5000", "--access-logfile", "-"]

Procfile

Lines changed: 0 additions & 1 deletion
This file was deleted.

README.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,11 @@ DJANGO_DEFAULT_FROM_EMAIL DEFAULT_FROM_EMAIL n/a
5050
DJANGO_SERVER_EMAIL SERVER_EMAIL n/a "osmcha-django <[email protected]>"
5151
DJANGO_EMAIL_SUBJECT_PREFIX EMAIL_SUBJECT_PREFIX n/a "[osmcha-django] "
5252
DJANGO_CHANGESETS_FILTER CHANGESETS_FILTER None None
53-
POSTGRES_USER POSTGRES_USER None None
54-
POSTGRES_PASSWORD POSTGRES_PASSWORD None None
55-
PGHOST PGHOST localhost localhost
56-
OAUTH_OSM_KEY SOCIAL_AUTH_OPENSTREETMAP_KEY None None
57-
OAUTH_OSM_SECRET SOCIAL_AUTH_OPENSTREETMAP_SECRET None None
53+
PGUSER DATABASES None None
54+
PGPASSWORD DATABASES None None
55+
PGHOST DATABASES localhost localhost
56+
OAUTH2_OSM_KEY SOCIAL_AUTH_OPENSTREETMAP_KEY None None
57+
OAUTH2_OSM_SECRET SOCIAL_AUTH_OPENSTREETMAP_SECRET None None
5858
DJANGO_ANON_USER_THROTTLE_RATE ANON_USER_THROTTLE_RATE None 30/min
5959
DJANGO_COMMON_USER_THROTTLE_RATE COMMON_USER_THROTTLE_RATE None 180/min
6060
DJANGO_NON_STAFF_USER_THROTTLE_RATE NON_STAFF_USER_THROTTLE_RATE 3/min 3/min

compose/django/entrypoint.sh

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,12 @@
1-
#!/bin/bash
1+
#!/bin/sh
22
set -e
3-
cmd="$@"
43

5-
# This entrypoint is used to play nicely with the current cookiecutter configuration.
6-
# Since docker-compose relies heavily on environment variables itself for configuration, we'd have to define multiple
7-
# environment variables just to support cookiecutter out of the box. That makes no sense, so this little entrypoint
8-
# does all this for us.
9-
export REDIS_URL=redis://redis:6379
10-
# the official postgres image uses 'postgres' as default user if not set explictly.
11-
if [ -z "$POSTGRES_USER" ]; then
12-
export POSTGRES_USER=postgres
13-
fi
14-
15-
if [ -z "$POSTGRES_HOST" ]; then
16-
export POSTGRES_HOST=postgres
17-
fi
18-
19-
export PGHOST=$POSTGRES_HOST
20-
export POSTGRES_USER=$POSTGRES_USER
21-
export POSTGRES_PASSWORD=$POSTGRES_PASSWORD
22-
# export DATABASE_URL=postgres://$POSTGRES_USER:$POSTGRES_PASSWORD@postgres:5432/$POSTGRES_USER
23-
24-
function postgres_ready(){
4+
postgres_ready() {
255
python << END
266
import sys
277
import psycopg2
288
try:
29-
conn = psycopg2.connect(dbname="$POSTGRES_USER", user="$POSTGRES_USER", password="$POSTGRES_PASSWORD", host="$POSTGRES_HOST")
9+
conn = psycopg2.connect("") # use environment variables for connection
3010
except psycopg2.OperationalError:
3111
sys.exit(-1)
3212
sys.exit(0)
@@ -39,4 +19,4 @@ until postgres_ready; do
3919
done
4020

4121
>&2 echo "Postgres is up - continuing..."
42-
exec $cmd
22+
exec $@

compose/django/gunicorn.sh

Lines changed: 0 additions & 3 deletions
This file was deleted.

compose/django/start-dev.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
#!/bin/sh
22
python manage.py migrate
3-
python manage.py runserver_plus 0.0.0.0:8000
3+
python manage.py runserver_plus 0.0.0.0:5000

compose/nginx/Dockerfile

Lines changed: 0 additions & 4 deletions
This file was deleted.

compose/nginx/nginx.conf

Lines changed: 0 additions & 52 deletions
This file was deleted.

config/settings/aws_production.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -43,22 +43,6 @@
4343
]),
4444
]
4545

46-
# DATABASE CONFIGURATION
47-
# ------------------------------------------------------------------------------
48-
# Raises ImproperlyConfigured exception if DATABASE_URL not in os.environ
49-
# DATABASES = {
50-
# 'default': env.db('DATABASE_URL', default='postgres:///osmcha'),
51-
# }
52-
DATABASES = {
53-
'default': {
54-
'ENGINE': 'django.contrib.gis.db.backends.postgis',
55-
'NAME': env('POSTGRES_DATABASE', default='osmcha'),
56-
'USER': env('POSTGRES_USER'),
57-
'PASSWORD': env('POSTGRES_PASSWORD'),
58-
'HOST': env('PGHOST', default='localhost')
59-
}
60-
}
61-
6246
REST_FRAMEWORK = {
6347
'DEFAULT_AUTHENTICATION_CLASSES': (
6448
'rest_framework.authentication.TokenAuthentication',

config/settings/common.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -122,16 +122,14 @@
122122
# DATABASE CONFIGURATION
123123
# ------------------------------------------------------------------------------
124124
# See: https://docs.djangoproject.com/en/dev/ref/settings/#databases
125-
# DATABASES = {
126-
# 'default': env.db('DATABASE_URL', default='postgres:///osmcha'),
127-
# }
128125
DATABASES = {
129126
'default': {
130127
'ENGINE': 'django.contrib.gis.db.backends.postgis',
131-
'NAME': env('POSTGRES_DATABASE', default='osmcha'),
132-
'USER': env('POSTGRES_USER'),
133-
'PASSWORD': env('POSTGRES_PASSWORD'),
134-
'HOST': env('PGHOST', default='localhost')
128+
'HOST': env('PGHOST', default='localhost'),
129+
'PORT': env('PGPORT', default='5432'),
130+
'USER': env('PGUSER', default='postgres'),
131+
'PASSWORD': env('PGPASSWORD', default=''),
132+
'NAME': env('PGDATABASE', default='postgres'),
135133
}
136134
}
137135
DATABASES['default']['ATOMIC_REQUESTS'] = True
@@ -207,7 +205,7 @@
207205
STATIC_ROOT = str(ROOT_DIR('staticfiles'))
208206

209207
# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-url
210-
STATIC_URL = '/static/'
208+
STATIC_URL = '/static/django/'
211209

212210
# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS
213211
STATICFILES_DIRS = []

config/settings/local.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,5 @@
6363
# DATABASE CONFIGURATION
6464
# ------------------------------------------------------------------------------
6565
# See: https://docs.djangoproject.com/en/dev/ref/settings/#databases
66-
DATABASES = {
67-
'default': {
68-
'ENGINE': 'django.contrib.gis.db.backends.postgis',
69-
'NAME': 'osmcha',
70-
'USER': env('POSTGRES_USER'),
71-
'PASSWORD': env('POSTGRES_PASSWORD'),
72-
'HOST': env('PGHOST', default='localhost')
73-
}
74-
}
7566

7667
# Your local stuff: Below this line define 3rd party library settings

config/settings/production.py

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -58,21 +58,6 @@
5858
]),
5959
]
6060

61-
# DATABASE CONFIGURATION
62-
# ------------------------------------------------------------------------------
63-
# Raises ImproperlyConfigured exception if DATABASE_URL not in os.environ
64-
# DATABASES = {
65-
# 'default': env.db('DATABASE_URL', default='postgres:///osmcha'),
66-
# }
67-
DATABASES = {
68-
'default': {
69-
'ENGINE': 'django.contrib.gis.db.backends.postgis',
70-
'NAME': env('POSTGRES_DATABASE', default='osmcha'),
71-
'USER': env('POSTGRES_USER'),
72-
'PASSWORD': env('POSTGRES_PASSWORD'),
73-
'HOST': env('PGHOST', default='localhost')
74-
}
75-
}
7661
# CACHING
7762
# ------------------------------------------------------------------------------
7863
# Configured to use Redis, if you prefer another method, comment the REDIS and

config/urls.py

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,6 @@
1919

2020
urlpatterns = []
2121

22-
# If static files are not intercepted by the web-server, serve them with the dev-server:
23-
if settings.DEBUG is False: # if DEBUG is True it will be served automatically
24-
urlpatterns += [
25-
path(
26-
'static/<path>',
27-
static_views.serve,
28-
{'document_root': settings.STATIC_ROOT}
29-
),
30-
]
31-
3222
api_urls = [
3323
path(
3424
'{}'.format(API_BASE_URL),
@@ -90,8 +80,7 @@ def health_check(request):
9080
'',
9181
include(api_urls)
9282
),
93-
94-
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
83+
]
9584

9685
if settings.DEBUG:
9786
# This allows the error pages to be debugged during development, just visit

0 commit comments

Comments
 (0)