Setup with Docker Compose
This project uses Docker Compose to manage its container environment. With Docker Compose, you can easily set up and run all the required services and dependencies for this project with a single command.
The following figure illustrates how the default costellation of muliple containers is meant to
be reviewed. The compose file is named docker-compose.local.yml
and all relevant configuration
files are located in the /compose/local/
directory.
Local Development
To get started locally, follow these steps:
Ensure that you have Docker and Docker Compose installed on your machine. If you do not have them installed, please refer to the official Docker documentation for installation instructions at Docker.com.
Open the
docker-compose.yml
file in the root directory of the project to review the available services and their configuration.Generate a self signed certificate and private key to enable HTTPS. Save the generated files to
/compose/local/nginx/
:openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365
Note
If you have Git installed on your Windows system, open Git Bash, navigate to the project’s directory and execute the command above.
Run the following command to start all the required services and dependencies:
docker compose up -d
Note
The first time you run this command, Docker Compose will build the required images for your services, which may take some time depending on your internet speed and system resources. Subsequent runs will use the pre-built images.
Once the services are running, you can access your application by navigating to https://localhost:<port> in your web browser, where <port> is the port number specified in the docker-compose.yml file (default
8443
).Warning
If the port you specified in the docker-compose.yml file is already in use by another application on your machine, you may need to change it to a different port number.
You now have a fully functional development environment for this project, powered by Docker Compose. Before setting up a production environment, consider reading the following sections which address different configuration options.
Service Configuration
Database
As per default, there is a container named backend-db
which is basically a PostgreSQL server
within the backend Docker network. The following code snippet shows what configurations should
be applied to the service:
40backend-db:
41 image: postgres:13.0-alpine
42 volumes:
43 # The target data volume (may be a shared directory)
44 - postgres_data:/var/lib/postgresql/data/
45 environment:
46 # Specify environment variables here or place them in an
47 # environment file. Make sure to keep the password private
48 # in production environments!
49 - POSTGRES_USER=mastf_django
50 - POSTGRES_PASSWORD=supersecretpassword
51 - POSTGRES_DB=mastf_backend_db
52 networks:
53 - backend
POSTGRES_USER=mastf_django
:Sets the username of the default PostgreSQL user that will be used by the application. The value of this variable is set to mastf_django, which is the default user used by the django application.
POSTGRES_PASSWORD=supersecretpassword
:This configuration variable sets the password for the default PostgreSQL user that will be used by the application. The default value is set to supersecretpassword, which is a strong password that should be replaced with a unique and secure password before deploying the application.
POSTGRES_DB=mastf_backend_db
:Sets the name of the default PostgreSQL database that will be used by the application. The value of this variable is set to
mastf_backend_db
, which is the name of the default database used by the django backend application.
Note that these configuration variables are used to set up the PostgreSQL database for the django application. It is important to keep these configuration variables secure and not share them with unauthorized users. Additionally, it is recommended to replace the default values of these configuration variables with unique and secure values before deploying the project.
Note
The environment variables POSTGRES_USER
and POSTGRES_DB
must point to the same value
as DB_USER
and DB_NAME
do defined in your environment file.
By default, the following section of the configuration file describes how to place the mentioned environment variables:
# Specify user and password only once
DB_DATABASE=mastf_backend_db
DB_USER=mastf_django
DB_PASSWORD=supersecretpassword
POSTGRES_USER=${DB_USER}
POSTGRES_PASSWORD=${DB_PASSWORD}
POSTGRES_DB=${DB_DATABASE}
Broker
We use a Redis service instance as our message broker and result backend. Configuration variables used wihtin the django application should be set in the environment file of this project:
CELERY_BROKER_URL = "redis://redis:6379/0"
:This environment variable sets the URL of the Redis instance that will be used as the broker for Celery tasks. The value of this variable is set to
redis://redis:6379/0
, which indicates that the Redis instance is running on the same Docker network as the Celery worker container and that it is accessible at the addressredis:6379
. The/0
at the end of the URL specifies the Redis database that will be used for Celery tasks.
CELERY_RESULT_BACKEND="redis://redis:6379/0"
:This environment variable sets the URL of the Redis instance that will be used as the backend for storing Celery task results. The value of this variable is also set to
redis://redis:6379/0
, which indicates that the same Redis instance that is used as the broker will also be used as the backend for storing task results.
Nginx
The Nginx reverse proxy is a powerful tool for directing incoming network traffic to backend servers. This chapter provides a detailed guide on configuring the Nginx service using the available configuration variables. It also includes recommendations for accepting only HTTPS traffic and generating a self-signed certificate and private key for the Nginx server.
Configuration Steps
- Install Nginx:
Ensure that Nginx is installed on your server or local machine if you don’t want to use docker. Otherwise, take a quick look at the pre-defined docker-compose configuration
nginx: # build context with configuration files build: ./compose/local/nginx/ env_file: # environment variables - ./.env/.dev-example ports: - ${NGINX_HTTP_PORT}:80 - ${NGINX_HTTPS_PORT}:443 environment: NGINX_ENVSUBST_TEMPLATE_SUFFIX: ".conf" depends_on: - web-django networks: - frontend
- Nginx Configuration File:
There are two pre-defined nginx configuration files: one for HTTP-only servers and one for strict HTTPS servers. Note that there will be only HTTPS-traffic allowed with the default configuration (recommended).
Hint
You can use environment variables declared in your environment file
./.env/.dev-example
in the Nginx configuration file:upstream django { server web-django:${DJANGO_PORT}; }
However, if you want to enforce HTTP traffic, you have to apply the following changes to the Dockerfile placed in
compose/nginx
:# Instead of preparing SSL (remove the following directives) COPY default.conf.conf /etc/nginx/templates/default.conf.conf RUN mkdir -p /etc/ssl/ COPY cert.pem /etc/ssl/cert.pem COPY key.pem /etc/ssl/key.pem # Just copy the HTTP configuration (add thid line) COPY nginx.http.conf /etc/nginx/conf.d/default.conf
Generate Self-Signed Certificate
Note
Ensure that OpenSSL is installed on your system. Use the package manager or download it from the official website. For Windows users: If you have git installed on your system, make sure that you have also installed Git Bash. Run Git Bash in order to start a new window with a bash shell in it. You can now execute the command described below.
In a new terminal, run the following commands to generate a self-signed certificate and private key:
openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout /path/to/key.pem -out /path/to/cert.pem
In order to use the generated private key and certificate, copy them into the
compose/nginx/
directory of this repository.
Caution
These steps provide a simplistic overview of how HTTPS can be enabled via a nginx reverse proxy. It is not meant to be complete in any ways. For more HTTPS security related information, please refer to the NGINX Guide.
Environment Options
NGINX_HTTP_PORT=8080
:This configuration variable specifies the port number on which the Nginx server listens for incoming HTTP connections. The default value is set to
8080
, but it can be modified to any available port number.Any HTTP traffic received on this port will be directed to the backend servers configured in the Nginx reverse proxy.
NGINX_HTTPS_PORT=8443
:This configuration variable defines the port number on which the Nginx server listens for incoming HTTPS connections. The default value is set to
8443
, but it can be changed to any available port number.HTTPS traffic received on this port will be securely handled by the Nginx server using SSL/TLS encryption.
It is important to configure the Nginx server with a valid SSL/TLS certificate and private key to enable HTTPS communication on this port.
Typically, the backend servers behind the Nginx reverse proxy will communicate over plain HTTP, while the Nginx server itself handles the SSL/TLS encryption for incoming HTTPS requests.
Django
The following environment variables apply to all services using the environment file. For frontend specific configurations, please refer to the Django Settings documentation.
Note
All described environment variables cannot be used in local development.
- DJANGO_DEBUG: int = 1
Control whether the web instance should be running in debug mode to provide detailed exception descriptions.
Warning
Never enable this option in production environments as it would potentially leak important and sensitive configuration vairables.
- DJANGO_SECRET_KEY: str
Specifies the secret key that Django will use. For more information about secret keys in Django, please refer to the chapter Cryptographic signing of the Django documentation.
- DJANGO_ALLOWED_HOSTS: str = "*"
Make sure to edit the allowed host variable to specify which host should be able to connect to your web instance. Sperate them with
:
to add multiple hosts.
- DJANGO_CSRF_TRUSTED_ORIGINS: str = "https://localhost:8443|https://127.0.0.1:8443"
Trusted origins when configuring Django to run with HTTPS.
Important
Configure the trusted hosts if you are using a reverse proxy like nginx. Replace hostnames of the given URLs to match your own ones.
- DJANGO_SESSION_EXPIRE_AT_BROWSER_CLOSE: int = 1
Use this configuration to control whether django should remove active sessions when the browser is closed.
- DJANGO_SESSION_COOKIE_AGE: int = 3600
Control the TTL of a session cookie default will be 3600s = 1h
- DJANGO_HTTPS: bool = True
Control whether you want to start your services with HTTPS enabled. Enable this option only if you want to use HTTPS.
- DJANGO_STORAGE_URL: str = "/app_storage/"
The storage URL where all project data should be saved separately. Note the trailing
/
that is needed by Django. Remove this connfiguration if you work locally.
- DJANGO_STORAGE_ROOT: str = "/app_storage"
Same as described in
DJANGO_STORAGE_URL
without traling slash.
- DJANGO_PORT: int = 8000
The port django should be served on.