-
Notifications
You must be signed in to change notification settings - Fork 3
Containerization and Deployment
flowchart TB
user-device([visitor's device])-- visit site -->reverse-proxy
subgraph localzero-monitoring-vm
subgraph testing
nginx-testing-- forward -->djangoapp-testing
nginx-testing-- forward -->dbeaver-testing
dbeaver-testing
end
subgraph production
nginx-production-- forward -->djangoapp-production
nginx-production-- forward -->dbeaver-production
dbeaver-production
end
subgraph exposed [exposed to web]
reverse-proxy-- forward if HOST==monitoring-test.localzero.net -->nginx-testing
reverse-proxy-- forward if HOST==monitoring.localzero.net -->nginx-production
acme.sh-. configure updated certs .->reverse-proxy
end
end
The application is deployed to the server in the form of three Docker compositions:
- reverse-proxy
- testing environment
- production environment
Each environment consists of:
- the "djangoapp" container that run the gunicorn webserver to host the django app itself,
- its own nginx (a proxy that hosts the static files while providing stability and security),
- a server for the database web client (DBeaver),
Outside the environments and exposed to the web, there's a third "reverse-proxy" composition containing:
- acme.sh, which handles SSL certificate renewal (see here),
- the top-level reverse proxy nginx, which forwards requests to the environments based on the HOST header, or to acme.sh.
The Dockerfile for the django app is based on the following resources:
It uses a multi-stage build to prevent shipping unnecessary files which would increase image size and attack surface.
To build the image, run the following command in the repository root directory:
docker compose build
You might run into errors building the Docker image on a Mac, getting messages like No working compiler found
and Building wheel for cffi (setup.py): finished with status 'error'
.
This is usually caused by certain Python packages not being available prebuilt for download for arm64-based macOS, because the macOS version gets encoded into package names on pypi. This leads to packages not being found after macOS updates until the package authors update their files.
A workaround is to add --platform linux/amd64
to the failing Docker command to simulate an amd64 architecture, so that generic linux packages are downloaded instead of the Apple CPU specific ones.
See also #45.
To run both containers together, run the following command in the repository root directory (the app container will be built automatically if necessary):
docker compose up --detach
This will start both the Django app and the nginx containers in the background. The website can then be reached at https://localhost. You'll have to tell your browser to make an exception for the self-signed certificate we use when running locally, or import it into your browser.
To stop the containers from running in the background, run:
docker compose down --volumes
The --volumes
flag is important to make sure that at the next start, the latest static resources from the app container are served instead of potentially outdated files from the previous run cached by Docker.