An open API service indexing awesome lists of open source software.

https://github.com/chinchalinchin/dockerized-django

boilerplate setup for a containerized django-rest-framework application
https://github.com/chinchalinchin/dockerized-django

Last synced: 7 months ago
JSON representation

boilerplate setup for a containerized django-rest-framework application

Awesome Lists containing this project

README

          

# django-docker-starter kit

This repository is a template for a [django](https://docs.djangoproject.com/en/3.2/)-[django-rest-framework](https://www.django-rest-framework.org/) project. It has been containerized with [Docker](https://docs.docker.com/) through the Dockerfile in the project root directory and orchestrated with a [Postgres](https://www.postgresql.org/docs/) 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.

## Quickstart

### Step 1: Configure Enviroment

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.

### Step 2: Install Dependencies

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.

### Step 3: Launch Application Server

#### Local

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 '-'`

#### Container

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`

## Shell Scripts

Included in this repository are a collection of shell scripts (written for BASH) that perform common, repetitious tasks.

1. /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

2. /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.

3. /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.

4. /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.

5. /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.

6. /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.

## Application Structure

### Django

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.

### Docker

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.

## TODO

1. start session app. set up superuser data migration.

## Container Orchestration

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.

## Documentation
- [django](https://docs.djangoproject.com/en/3.2/)
- [django-rest-framework](https://www.django-rest-framework.org/)
- [docker](https://docs.docker.com/)
- [gunicorn](https://docs.gunicorn.org/en/stable/)
- [postgres](https://www.postgresql.org/docs/)