Skip to content

Instantly share code, notes, and snippets.

@rogersdepelle
Last active January 11, 2023 03:37
Show Gist options
  • Save rogersdepelle/dca9f87f0786ee5aae82fddc1c518417 to your computer and use it in GitHub Desktop.
Save rogersdepelle/dca9f87f0786ee5aae82fddc1c518417 to your computer and use it in GitHub Desktop.
Docker + Django + Gunicorn + Nginx + PostgreSQL + GitLab CI/CD
stages:
- codequality
- tests
- deploy
variables:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- .cache/pip
- venv/
.virtualenv:
image: python:3.9.2-buster
before_script:
- pip3 install virtualenv
- virtualenv venv
- source venv/bin/activate
- pip install -r django/core/requirements/dev.txt
variables:
MODE: development
codequality:
stage: codequality
extends: .virtualenv
script:
- black --check --line-length=100 django
- flake8 --max-line-length 100 django
- bandit -l -r django
- safety check --full-report -r django/core/requirements/dev.txt
tests:
stage: tests
extends: .virtualenv
script:
- cd django
- coverage erase
- coverage run --source=website,documents --omit="**/tests/*,**/migrations/*,*/apps.py,*/admin.py" ./manage.py test
- coverage report -m --fail-under=100
dependencies:
- codequality
.deploy:
script:
- docker-compose -f docker-compose.yml -f docker-compose.production.yml build
- docker-compose -f docker-compose.yml -f docker-compose.production.yml down
- docker-compose -f docker-compose.yml -f docker-compose.production.yml up -d
variables:
GIT_STRATEGY: clone
dependencies:
- tests
# DEPLOY staging.startdok.com
# ------------------------------------------------------------------------------
staging:
stage: deploy
extends: .deploy
tags:
- staging
- startdok
variables:
SITE_URL: example.com
SITE_URL_NGINX: example.com=django:8000
ENVIRONMENT: staging
only:
- develop
FROM python:3.9.2-buster
WORKDIR /django/
ARG MODE
ENV MODE $MODE
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
RUN apt update && apt install postgresql-client -y
COPY ./core/requirements/ /django/
RUN if [ "$MODE" = "production" ]; then pip install -r main.txt; else pip install -r dev.txt; fi
COPY . /django/
ENTRYPOINT ["/django/entrypoint.sh"]
version: "3.9"
services:
django:
build:
args:
MODE: development
command: python manage.py runserver 0.0.0.0:8000
env_file:
- ./env/dev.env
version: '3.9'
services:
django:
build:
args:
MODE: production
command: gunicorn --bind :8000 --workers 5 core.wsgi:application
environment:
DROPBOX_TOKEN: ${DROPBOX_TOKEN}
SECRET_KEY: ${SECRET_KEY}
SITE_URL: ${SITE_URL}
ENVIRONMENT: ${ENVIRONMENT}
nginx:
container_name: startdok-nginx
build: ./nginx
restart: always
ports:
- 80:80
- 443:443
volumes:
- ssl_data:/etc/resty-auto-ssl
- staticfiles:/django/core/staticfiles
- mediafiles:/django/core/mediafiles
environment:
ALLOWED_DOMAINS: ${SITE_URL}
SITES: ${SITE_URL_NGINX}
depends_on:
- django
volumes:
ssl_data:
staticfiles:
mediafiles:
version: "3.9"
services:
django:
container_name: startdok-django
restart: always
build:
context: ./django
volumes:
- ./django/:/django/
- staticfiles:/django/core/staticfiles
- mediafiles:/django/core/mediafiles
ports:
- 8000:8000
env_file:
- ./env/database.env
depends_on:
postgres:
condition: service_healthy
postgres:
container_name: startdok-postgres
restart: always
image: postgres:11-alpine
volumes:
- postgres_data:/var/lib/postgresql/data/
env_file:
- ./env/database.env
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
volumes:
mediafiles:
staticfiles:
postgres_data:
FROM valian/docker-nginx-auto-ssl
COPY server-proxy.conf /usr/local/openresty/nginx/conf/server-proxy.conf
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# Expires map
map $sent_http_content_type $expires {
default off;
text/html epoch;
text/css max;
application/javascript max;
~image/ max;
}
server {
listen 443 ssl http2;
server_name $SERVER_NAME;
include resty-server-https.conf;
expires $expires;
location /staticfiles/ {
alias /django/core/staticfiles/;
}
location /mediafiles/ {
alias /django/core/mediafiles/;
}
location /robots.txt {
alias /django/core/staticfiles/robots.txt;
}
location / {
proxy_http_version 1.1;
proxy_pass http://$SERVER_ENDPOINT;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_cache_bypass $http_upgrade;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment