Deploying a Django Site Via Docker
Before you start make sure and create a requirements.txt file in your projects root folder. Also make sure
you have Gunicorn installed along with your Django app. pip install gunicorn
Requirements.txt
pip freeze > requirements.txt
Dockerfile For Django APP
Next write out the Dockerfile. I stepped back once from the projects root folder. So cd ../
. Then create a
Dockerfile touch Dockerfile
. And add the following.
FROM python:3-alpine
RUN pip install --upgrade pip
COPY ./mysite/requirements.txt .
RUN pip install -r requirements.txt
COPY ./mysite /app
WORKDIR /app
COPY ./entrypoint.sh /
ENTRYPOINT ["sh", "/entrypoint.sh"]
Entrypoint.sh
In the same directory lets write the entrypoint.sh file really quick. This will run as a last step when we build the app.
#!/bin/bash
python manage.py makemigrations --no-input
python manage.py migrate --no-input
python manage.py collectstatic --no-input
gunicorn mysite.wsgi:application --bind 0.0.0.0:8000
When you see mysite
change it to the name of your project.
Nginx
We will need Nginx to proxy the container. So we will need to build an image so we can stuff a default.conf file inside of it.
So create a new directory in the same folder you created your Dockerfile from earlier. mkdir nginx
then cd nginx
.
Now create another Dockerfile touch Dockerfile
. Add the following to it.
FROM nginx:latest
COPY ./default.conf /etc/nginx/conf.d/default.conf
Next you'll need to create the default.conf file. Create the file in the nginx directory. touch default.conf
.
upstream django {
server django_gunicorn:8000;
}
server {
listen 80;
location / {
proxy_pass http://django;
# I needed to add this line in order to upload video files.
client_max_body_size 100M;
}
location /static/ {
alias /static/;
}
# In order to serve media files, we'll need this line
location /media/ {
alias /media/;
}
}
Django Settings
Next there are some settings we'll need to change in the Django settings.py file.
import os
from dotenv import load_dotenv
load_dotenv()
# Use your .env file for this.
SECRET_KEY = os.environ.get('SECRET_KEY')
# Make sure this is set to false for production, best to set with your .env file
DEBUG = False
ALLOWED_HOSTS = ['https://yourdomainname.com']
# You will need this in order to use the Admin panel.
CSRF_TRUSTED_ORIGINS = ['https://yourdomainname.com']
# Near the bottom of the settings file add these.
STATIC_ROOT = "/static/"
STATIC_URL = "/static/"
Docker Compose
Almost to the final step. We need to create a docker-compose.yml file to glue it all together. In the directory
you created your first Dockerfile, create your docker-compose.yml. touch docker-compose.yml
. Add the following
to it.
version: "3.7"
services:
django_gunicorn:
container_name: django_gunicorn
volumes:
- static:/static
- media:/app/media
env_file:
- ./mysite/.env
build:
context: .
ports:
- "8500:8000"
nginx:
build: ./nginx
volumes:
- static:/static
- media:/media
ports:
- "85:80"
depends_on:
- django_gunicorn
volumes:
static:
media:
Change the ports if need be. At this point, everything should be good to go. Just run docker-compose up --build
to test it out. If you're still running on your local computer, you'll need to change ALLOWED_HOSTS to
ALLOWED_HOSTS = ['*']
in your settings.py file. When everything is built you can just use docker-compose up -d
.