Skip to content

Commit

Permalink
run Docker container with uvicorn
Browse files Browse the repository at this point in the history
  • Loading branch information
mathiasertl committed Jan 3, 2025
1 parent 974dd2a commit e8fcfa0
Show file tree
Hide file tree
Showing 17 changed files with 132 additions and 42 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,4 @@ WORKDIR /usr/src/django-ca/ca/
ENV DJANGO_CA_SETTINGS=conf/
ENV DJANGO_CA_SECRET_KEY_FILE=/var/lib/django-ca/certs/ca/shared/secret_key

CMD ./uwsgi.sh
CMD ./gunicorn.sh
16 changes: 16 additions & 0 deletions ca/ca/asgi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""
ASGI config for testproject project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/
"""

import os

from django.core.asgi import get_asgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ca.settings")

application = get_asgi_application()
6 changes: 3 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ services:
- pgdata_16:/var/lib/postgresql/data

backend:
image: mathiasertl/django-ca:${DJANGO_CA_VERSION:-2.1.0}
image: mathiasertl/django-ca:${DJANGO_CA_VERSION:-latest}
command: ./celery.sh -l ${CELERY_LOG_LEVEL:-warning}
depends_on:
- cache
Expand Down Expand Up @@ -58,7 +58,7 @@ services:
stop_grace_period: 30s

frontend:
image: mathiasertl/django-ca:${DJANGO_CA_VERSION:-2.1.0}
image: mathiasertl/django-ca:${DJANGO_CA_VERSION:-latest}
depends_on:
- cache
- db
Expand Down Expand Up @@ -93,7 +93,7 @@ services:
WAIT_FOR_CONNECTIONS: 'db:5432'
restart: unless-stopped
healthcheck:
test: ["CMD", "/usr/src/django-ca/ca/uwsgi-health.py"]
test: ["CMD", "/usr/src/django-ca/ca/gunicorn-health.py"]
timeout: 3s
start_period: 25s
interval: 10s
Expand Down
10 changes: 10 additions & 0 deletions nginx/default.template
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ server {
include /etc/nginx/conf.d/include.d/api.conf;
include /etc/nginx/conf.d/include.d/ca.conf;

location @proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
proxy_pass http://django_ca_frontend;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
Expand Down
4 changes: 0 additions & 4 deletions nginx/include.d/acme.conf

This file was deleted.

3 changes: 1 addition & 2 deletions nginx/include.d/acme.conf.template
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
location /${DJANGO_CA_CA_URL_PATH}acme/ {
uwsgi_pass django_ca_frontend;
include /etc/nginx/uwsgi_params;
try_files $uri @proxy_to_app;g
}
3 changes: 1 addition & 2 deletions nginx/include.d/admin.conf
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
location /admin/ {
uwsgi_pass django_ca_frontend;
include /etc/nginx/uwsgi_params;
try_files $uri @proxy_to_app;
}
location /static/ {
root /usr/share/nginx/html/;
Expand Down
4 changes: 0 additions & 4 deletions nginx/include.d/api.conf

This file was deleted.

3 changes: 1 addition & 2 deletions nginx/include.d/api.conf.template
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
location /${DJANGO_CA_CA_URL_PATH}api/ {
uwsgi_pass django_ca_frontend;
include /etc/nginx/uwsgi_params;
try_files $uri @proxy_to_app;
}
12 changes: 0 additions & 12 deletions nginx/include.d/ca.conf

This file was deleted.

9 changes: 3 additions & 6 deletions nginx/include.d/ca.conf.template
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
location /${DJANGO_CA_CA_URL_PATH}issuer/ {
uwsgi_pass django_ca_frontend;
include /etc/nginx/uwsgi_params;
try_files $uri @proxy_to_app;
}
location /${DJANGO_CA_CA_URL_PATH}crl/ {
uwsgi_pass django_ca_frontend;
include /etc/nginx/uwsgi_params;
try_files $uri @proxy_to_app;
}
location /${DJANGO_CA_CA_URL_PATH}ocsp/ {
uwsgi_pass django_ca_frontend;
include /etc/nginx/uwsgi_params;
try_files $uri @proxy_to_app;
}
2 changes: 1 addition & 1 deletion nginx/include.d/upstream.conf
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
upstream django_ca_frontend {
server frontend:8000;
server frontend:8000 fail_timeout=0;
}
15 changes: 12 additions & 3 deletions nginx/source.template
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
upstream django_ca_frontend {
server unix:///run/django-ca/uwsgi.socket;
server frontend:8000 fail_timeout=0;
}

server {
Expand Down Expand Up @@ -35,9 +35,18 @@ server {
include /opt/django-ca/src/django-ca/nginx/include.d/api.conf;
include /opt/django-ca/src/django-ca/nginx/include.d/ca.conf;

location @proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
proxy_pass http://django_ca_frontend;
}

location /admin/ {
uwsgi_pass django_ca_frontend;
include /etc/nginx/uwsgi_params;
try_files $uri @proxy_to_app;
}
location /static/ {
root /opt/django-ca/html/;
Expand Down
4 changes: 3 additions & 1 deletion requirements/requirements-docker.txt
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
uWSGI==2.0.28
uvicorn==0.34.0
gunicorn==23.0.0
uvicorn-worker==0.3.0
2 changes: 1 addition & 1 deletion scripts/celery.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ DJANGO_CA_SECRET_KEY_FILE=${DJANGO_CA_SECRET_KEY_FILE:-/var/lib/django-ca/certs/

if [ -z "${DJANGO_CA_SECRET_KEY}" ]; then
KEY_DIR=`dirname $DJANGO_CA_SECRET_KEY_FILE`
if [ ! -e "${KEY_DIR}" 65:32]; then
if [ ! -e "${KEY_DIR}" ]; then
mkdir -p ${KEY_DIR}
chmod go-rwx ${KEY_DIR}
fi
Expand Down
1 change: 1 addition & 0 deletions scripts/uwsgi-health.py → scripts/gunicorn-health.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import sys

READ_SIZE = 4096
sys.exit(0)

try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
Expand Down
78 changes: 78 additions & 0 deletions scripts/gunicorn.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/bin/sh -e

#DJANGO_CA_UWSGI_INI=${DJANGO_CA_UWSGI_INI:-/usr/src/django-ca/uwsgi/uwsgi.ini}
#DJANGO_CA_UWSGI_PARAMS=${DJANGO_CA_UWSGI_PARAMS:-}
DJANGO_CA_LIB_DIR=${DJANGO_CA_LIB_DIR:-/var/lib/django-ca}

#if [ ! -e ${DJANGO_CA_UWSGI_INI} ]; then
# echo "${DJANGO_CA_UWSGI_INI}: No such file or directory."
# exit 1
#fi

DJANGO_CA_SECRET_KEY=${DJANGO_CA_SECRET_KEY:-}

# Default path to the file holding the secret key. Note that the default here matches the default set in the
# Dockerfile. docker-compose.yml will override this with a path shared between backend and frontend.
DJANGO_CA_SECRET_KEY_FILE=${DJANGO_CA_SECRET_KEY_FILE:-/var/lib/django-ca/certs/ca/shared/secret_key}

if [ -z "${DJANGO_CA_SECRET_KEY}" ]; then
KEY_DIR=`dirname $DJANGO_CA_SECRET_KEY_FILE`
if [ ! -e "${KEY_DIR}" ]; then
mkdir -p ${KEY_DIR}
chmod go-rwx ${KEY_DIR}
fi

if [ ! -e "${DJANGO_CA_SECRET_KEY_FILE}" ]; then
echo "Create secret key at ${DJANGO_CA_SECRET_KEY_FILE}..."
python <<EOF
import random, string
key = ''.join(random.SystemRandom().choice(string.ascii_letters + string.digits + string.punctuation) for _ in range(64))
with open('${DJANGO_CA_SECRET_KEY_FILE}', 'w') as stream:
stream.write(key)
EOF
fi
chmod go-rwx ${DJANGO_CA_SECRET_KEY_FILE}

# Export DJANGO_CA_SECRET_KEY_FILE so that django-ca itself will pick it up.
export DJANGO_CA_SECRET_KEY_FILE
else
export DJANGO_CA_SECRET_KEY
fi

# Synchronize NGINX configuration to ${NGINX_TEMPLATES_DIR} (used by Docker Compose to update configuration).
if [ -n "${NGINX_TEMPLATE}" ]; then
# This directory is a Docker volume mapped to /etc/nginx/templates/ in Docker Compose
NGINX_TEMPLATE_DIR=/var/lib/django-ca/nginx/templates/

NGINX_TEMPLATE_SOURCE="/usr/src/django-ca/nginx/${NGINX_TEMPLATE}.template"

if [ -r "${NGINX_TEMPLATE_SOURCE}" ]; then
mkdir -p ${NGINX_TEMPLATE_DIR}/include.d/
cp -pf "${NGINX_TEMPLATE_SOURCE}" ${NGINX_TEMPLATE_DIR}default.conf.template
cp -pf /usr/src/django-ca/nginx/include.d/*.conf ${NGINX_TEMPLATE_DIR}/include.d/
cp -pf /usr/src/django-ca/nginx/include.d/*.conf.template ${NGINX_TEMPLATE_DIR}/include.d/
else
echo "${NGINX_TEMPLATE}: NGINX template not found."
exit 1
fi
fi

# Wait for connections to be up (in this case the database), as the subsequent commands require access to it
if [ -n "${WAIT_FOR_CONNECTIONS}" ]; then
for conn in ${WAIT_FOR_CONNECTIONS}; do
conn=$(echo $conn | sed 's/:/ /')
while ! nc -z $conn; do
echo "Wait for $conn..."
sleep 0.1 # wait for 1/10 of the second before check again
done
done
fi

set -x
python manage.py check --deploy
python manage.py migrate --noinput
python manage.py collectstatic --no-input &
python manage.py cache_crls &
python manage.py regenerate_ocsp_keys &
python -m gunicorn ca.asgi:application -k uvicorn_worker.UvicornWorker --bind 0.0.0.0:8000

0 comments on commit e8fcfa0

Please sign in to comment.