This repository is a template for a django-django-rest-framework project. It has been containerized with Docker through the Dockerfile in the project root directory and orchestrated with a Postgres instance via the docker-compose.yml in the project root directory. The application comes pre-configured to connect to this instance when running as a container. It can also be sure run locally, in which case, it will switch to a SQLite model backend.
Copy the /env/.sample.build.env and /env/.sample.runtime.env into new /env/build.env and /env/runtime.env files respectively. Adjust the environment variables in these files to your specific situation. The build.env get injected into the /scripts/docker/build-image.sh shell script to configure the docker build
. The runtime.env gets into injected into the /scripts/run-server.sh, /scripts/docker/entrypoint.sh and the /scripts/docker/run-container.sh shell scripts. These define the different starting points of the application.
The main environment variable of interest is APP_ENV. This variables is parsed in the /app/core/settings.py and determines how Django will configure its application settings. If set to local
, Django will use a SQLite database and set the CORS and ALLOWED_HOSTS to their most permissive settings. The DEBUG setting will be set to True in local
mode.
If set to container
, Django will configure a Postgres connection through the POSTGRES_* environment variables and restrict the allowed origins to the comma separated list defined by the ALLOWED_ORIGINS environment variable. The DEBUG setting be set to False in container
mode.
If running locally, activate your virtual environment (if using one) and install the python dependencies from the project root directory,
pip install -r requirements.txt
This step is captured in the Dockerfile and is not required if running the application as a container.
All of the necessary steps to start a local server have been included in the /scripts/run-server.sh shell script, but if you want to do it manually, initialize the environment file, migrate your models (if you have any) and collect your static files.
First, source the /env/runtime.env environment file to load these variables into your shell session,
source ./env/runtime.env
Next, from the /app/ directory, perform the necessary pre-startup tasks for a Django application,
python manage.py collectstatic --noinput
python manage.py makemigrations
python manage.py migrate
After these preliminary steps have been taken care of, you can either start the server in development mode,
python manage.py runserver
Or deploy the server onto a WSGI application server like gunicorn,
gunicorn core:wsgi.appplcation --bind localhost:8000 --workers 3 --access-logfile '-'
All of the necessary steps to start a server inside of a container have been included in the /scripts/docker/build-image.sh and /scripts/docker/run-container.sh. These steps have been separated because sometime it is desirable to build an image without running a container and visa versa. If you wish to build and run the application manually,
docker build -t docker-django-starter:latest .
To start up the container, make sure you pass in the /env/runtime.env file,
docker run --env-file ./env/runtime.env --publish 8000:8000 django-docker-starter:latest
Included in this repository are a collection of shell scripts (written for BASH) that perform common, repetitious tasks.
- /scripts/run-server.
Arguments: Accepts an argument of either dev or gunicorn. If no argument is provided, the argument defaults to gunicorn.
Description: Performs start up tasks, like collecting static files and migrating django models, and then starts up a local application server. If an argument of dev is provided, the script will invoke python manage.py runserver
to start up a live development server. If an argument of gunicorn or no argument at all is provided, the script will deploy the application on the WSGI server, gunicorn
- /scripts/docker/build-image.sh
Description: Initializes the build.env variables and uses them in calling docker build
. Creates a Docker image of the application.
- /scripts/docker/run-container.sh
Description: Initializes the runtime.env variables and feeds them into the container runtime. Starts up a container with the image name and tag created by the build-image script.
- /scripts/docker/entrypoint.sh.
Description: Tne entrypoint script that gets copied into the Docker image. Analogous to the run-server script in a containerized environment. Starts up the Docker container from inside of the container.
- /scripts/util/env-vars.sh
Arguments: The name of the enviroment file in the /env/ directory you wanted loaded into the current shell session.
Description: Used to load in environment variables from a particular .env file.
- /scripts/util/sys-util.sh
Description: Useful functions. Source this script, source ./scripts/util/sys-util.sh
, to load these functions into your current shell session. clean_docker is a particularly useful function for cleaning up dangling Docker images, cleaning the cache and pruning orphaned volumes and networks.
The core app contains all the Django configuration. The defaults app creates suitable defaults for various Django features using data migrations; It will create default groups, create a super user and assign that user to the administrator group.
The groups are configured by the GROUPS environment variable. This variable is a comma-separated list of all the default groups you want to create. It must include atleast administrator
or else the migration which creates the superuser will err out; it expects the administrator
group to exist before it assigns the superuser to that group.
The /app/ and /scripts/ folder are copied in the /home/ directory of the Docker file system. A user with the name chinchalinchin is assigned to the group admin during the Docker build. This user is granted ownership of the application files. The permissions on the application files are set to read and write for everyone and execute for this user only.
The Dockerfile exposes port 8000, but the environment variable APP_PORT is what determines the port on which the application server listens. This variable is used to start up the gunicorn server in the entrypoint.sh script.
The Dockerfile installs dependences for Postgres clients. These are the system dependencies required by the python library, psycopg2, which django uses under the hood to manage the model migrations when the model backend has been set to postgres.
- start session app. set up superuser data migration.
The docker-compose in the project root directory will bring up an application container and orchestrate it with a postgres container. Both containers use the runtime.env environment file to configure their environments. The POSTGRES_* variables injected at runtime are used by the postgres container to configure the root user, the default database name and the port the database container listens on internally.