engineervix / django-deployment-tutorial

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Welcome to mysite

A simple Django project created as part of a tutorial to demonstrate deployment of a Django project using Dokku

python3.10 Code style: black Commitizen friendly Conventional Changelog Conventional Commits

Contents generated with DocToc

Deployment

Prerequisites

  • You have a domain, with DNS records configured as described here
  • You have a Linux (Ubuntu) server "in the cloud", already setup as described at engineervix/pre-dokku-server-setup
  • You have an AWS S3 account (or use other S3-compatible services like Backblaze, MinIO, Filebase, etc.), with at least two buckets; one private (for your database backups) and one public (for media assets). Here, we're using Backblaze, because it's pretty easy and quick to set up, plus it has a generous free tier to get you started.
  • You have a Sentry account for automatic reporting of errors and exceptions, and have configured a Django project.
  • You have a Mailgun / Sendgrid / Mailjet or similar account for transactional email. In this example, we're using Mailgun. You can easily switch to any service provider of your choice, see the documentation for django-anymail

Steps

  1. SSH into your server

  2. Check the latest version of Dokku from https://dokku.com/

  3. Run Dokku setup script based on latest version

    wget https://raw.githubusercontent.com/dokku/dokku/v0.28.1/bootstrap.sh && \
    sudo DOKKU_TAG=v0.28.1 bash bootstrap.sh
  4. Once setup is complete, open a new terminal tab on local machine and your public key to the server via the following comman, which is based on the following assumptions (modify the command according to what is true for your setup):

    • you named your VPS as dokku in ~/.ssh/config
    • your SSH key is also called dokku, and is in ~/.ssh/
    cat ~/.ssh/dokku.pub | ssh dokku sudo dokku ssh-keys:add admin
  5. create your app (in this example, we'll call it mysite)

    sudo dokku apps:create mysite
  6. add a domain to your app

    sudo dokku domains:add mysite example.com

    You can check domains report as follows

    sudo dokku domains:report mysite
    sudo dokku domains:report --global
  7. setup postgres service (see https://github.com/dokku/dokku-postgres for reference

    sudo dokku plugin:install https://github.com/dokku/dokku-postgres.git postgres
    # You can choose the image & image version of your choice here
    sudo dokku postgres:create postgres-mysite --image "postgres" --image-version "14.5"
    sudo dokku postgres:link postgres-mysite mysite
    # Note: DATABASE_URL is automagically set for you, so no need to worry about it

    NOTE: if you're migrating your app from somewhere, you can import your database dump:

    sudo dokku postgres:import postgres-mysite < path/to/your/dabasase-backup-file
  8. Set up authentication for backups on the postgres service. Dokku has built-in support for datastore backups via AWS S3 and S3 compatible services like Backblaze, MinIO, Filebase, etc.

    # sudo dokku postgres:backup-auth <service> <aws-access-key-id> <aws-secret-access-key> <aws-default-region> <aws-signature-version> <endpoint-url>
    sudo dokku postgres:backup-auth postgres-mysite access-key-id secret-access-key eu-central-003 v4 https://s3.eu-central-003.backblazeb2.com
    # postgres:backup postgres-mysite <bucket-name>
    sudo dokku postgres:backup postgres-mysite my-bucket
    # for example, we wanna backup everyday at 2:30AM, 10:30AM, 6:30 PM
    sudo dokku postgres:backup-schedule postgres-mysite "30 2,10,18 * * *" my-bucket
    # check: cat the contents of the configured backup cronfile for the service
    sudo dokku postgres:backup-schedule-cat postgres-mysite
  9. setup redis service (see https://github.com/dokku/dokku-redis for reference)

    sudo dokku plugin:install https://github.com/dokku/dokku-redis.git redis
    sudo dokku redis:create redis-mysite
    sudo dokku redis:link redis-mysite mysite
    # Note: REDIS_URL is automagically set, just like DATABASE_URL
  10. set environment variables for your app

    Note 1: by default, the Python buildpack runs ./manage.py collectstatic automatically If you want to do certain things before running collectstatic, or perhaps customize how collectstatic itself is run, the set DISABLE_COLLECTSTATIC=1 and run collectstatic as a post-compile step Note 2: feel free to adjust WEB_CONCURRENCY based on the memory requirements of your processes ref: https://docs.gunicorn.org/en/stable/settings.html The suggested number of workers is (2 * CPU) + 1

    sudo dokku config:set --no-restart mysite WEB_CONCURRENCY=3 && \
    sudo dokku config:set --no-restart mysite DISABLE_COLLECTSTATIC=1 && \
    sudo dokku config:set --no-restart mysite PYTHONHASHSEED=random && \
    sudo dokku config:set --no-restart mysite DJANGO_SECRET_KEY=YOURSECRETKEY && \
    sudo dokku config:set --no-restart mysite DJANGO_SETTINGS_MODULE=mysite.settings.production && \
    sudo dokku config:set --no-restart mysite DEBUG=False && \
    sudo dokku config:set --no-restart mysite ALLOWED_HOSTS=example.com && \
    sudo dokku config:set --no-restart mysite BASE_URL=https://example.com && \
    sudo dokku config:set --no-restart mysite REDIS_KEY_PREFIX=mysite && \
    sudo dokku config:set --no-restart mysite AWS_STORAGE_BUCKET_NAME=my-bucket && \
    sudo dokku config:set --no-restart mysite AWS_ACCESS_KEY_ID=access-key-id && \
    sudo dokku config:set --no-restart mysite AWS_SECRET_ACCESS_KEY=secret-access-key && \
    sudo dokku config:set --no-restart mysite AWS_S3_REGION_NAME=eu-central-003 && \
    sudo dokku config:set --no-restart mysite AWS_S3_ENDPOINT_URL=https://my-bucket.s3.eu-central-003.backblazeb2.com && \
    sudo dokku config:set --no-restart mysite SENTRY_DSN=https://xxxxxxxxxxxxxx@yyyyyy.ingest.sentry.io/zzzzzzz && \
    sudo dokku config:set --no-restart mysite SENTRY_ENVIRONMENT=production && \
    sudo dokku config:set --no-restart mysite SENTRY_TRACES_SAMPLE_RATE=0.5 && \
    sudo dokku config:set --no-restart mysite DJANGO_SENTRY_LOG_LEVEL=20 && \
    sudo dokku config:set --no-restart mysite EMAIL_RECIPIENTS='MySite Technical Team <technical@example.com>,johndoe@example.com,janedoe@example.com,anotheremail@example.com' && \
    sudo dokku config:set --no-restart mysite DEFAULT_FROM_EMAIL='MySite Powered By Django <do-not-reply@mailgun.example.com>' && \
    sudo dokku config:set --no-restart mysite MAILGUN_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx && \
    sudo dokku config:set --no-restart mysite MAILGUN_DOMAIN=mailgun.mysite.com && \
    sudo dokku config:set --no-restart mysite MAILGUN_API_URL=https://api.eu.mailgun.net/v3
  11. configure buildpacks

    In this case, we are only using the python buildpack:

    sudo dokku buildpacks:add --index 1 mysite https://github.com/heroku/heroku-buildpack-python.git

    If, for example, we used Node.js to build frontend assets, and our project had geospatial features (using PostGIS), then our buildpack setup would have been as follows:

    sudo dokku buildpacks:add --index 1 mysite https://github.com/heroku/heroku-buildpack-nodejs.git
    sudo dokku buildpacks:add --index 2 mysite https://github.com/heroku/heroku-geo-buildpack.git
    sudo dokku buildpacks:add --index 3 mysite https://github.com/heroku/heroku-buildpack-python.git

    You can list your app's buildpacks as follows:

    sudo dokku buildpacks:list mysite
  12. configure NGIИX

    sudo ufw allow 'Nginx Full'
    sudo rm -fv /etc/nginx/sites-enabled/default
    sudo systemctl restart nginx
    sudo dokku nginx:validate-config
    sudo dokku nginx:show-config mysite
    # Customize Nginx | set `client_max_body_size`, to make upload feature work better in Django projects, for example
    sudo dokku nginx:set mysite client-max-body-size 50m
    # regenerate config
    sudo dokku proxy:build-config mysite
  13. (on local machine) add a remote dokku to your git repo, and deploy 🚀

    # remember from step 4, here the assumption is that you named your VPS as **dokku** in `~/.ssh/config`
    # otherwise change the @dokku to the @ <server's IP address> or <whatever you named it in `~/.ssh/config`>
    git remote add dokku dokku@dokku:mysite
    git push dokku
  14. SSL

    sudo dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git
    sudo dokku config:set --no-restart --global DOKKU_LETSENCRYPT_EMAIL=your@emailaddress.com
    sudo dokku letsencrypt:enable mysite
    # this would setup cron job to update letsencrypt certificate
    sudo dokku letsencrypt:cron-job --add

And you should be all set!

Running commands like createsuperuser

sudo dokku run mysite python manage.py createsuperuser

See this gist for additional notes

About

License:MIT License


Languages

Language:Python 73.2%Language:HTML 25.5%Language:CSS 0.8%Language:Shell 0.4%Language:Procfile 0.1%