{"id":24989054,"url":"https://github.com/engineervix/django-deployment-tutorial","last_synced_at":"2025-04-12T00:20:43.283Z","repository":{"id":81444603,"uuid":"534689431","full_name":"engineervix/django-deployment-tutorial","owner":"engineervix","description":null,"archived":false,"fork":false,"pushed_at":"2025-02-22T00:43:37.000Z","size":135,"stargazers_count":3,"open_issues_count":8,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-25T20:05:03.322Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/engineervix.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-09T15:01:30.000Z","updated_at":"2024-03-14T14:09:27.000Z","dependencies_parsed_at":"2023-10-03T15:14:06.043Z","dependency_job_id":"677abb9b-0b03-45e0-9187-75d4bd06d932","html_url":"https://github.com/engineervix/django-deployment-tutorial","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/engineervix%2Fdjango-deployment-tutorial","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/engineervix%2Fdjango-deployment-tutorial/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/engineervix%2Fdjango-deployment-tutorial/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/engineervix%2Fdjango-deployment-tutorial/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/engineervix","download_url":"https://codeload.github.com/engineervix/django-deployment-tutorial/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248498077,"owners_count":21114032,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-02-04T12:14:31.360Z","updated_at":"2025-04-12T00:20:43.248Z","avatar_url":"https://github.com/engineervix.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Welcome to mysite\n\n\u003e A simple Django project created as part of a tutorial to demonstrate deployment of a Django project using Dokku\n\n[![python3.10](https://img.shields.io/badge/python-3.10-brightgreen.svg)](https://python.org/#sections50-why)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)\n[![Conventional Changelog](https://img.shields.io/badge/changelog-conventional-brightgreen.svg)](http://conventional-changelog.github.io)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n**Contents**  *generated with [DocToc](https://github.com/thlorenz/doctoc)*\n\n- [Deployment](#deployment)\n  - [Prerequisites](#prerequisites)\n  - [Steps](#steps)\n  - [Running commands like `createsuperuser`](#running-commands-like-createsuperuser)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n## Deployment\n\n### Prerequisites\n\n- You have a domain, with DNS records configured as described [here](https://github.com/engineervix/pre-dokku-server-setup)\n- You have a Linux (Ubuntu) server \"in the cloud\", already setup as described at [engineervix/pre-dokku-server-setup](https://github.com/engineervix/pre-dokku-server-setup)\n- You have an [AWS S3](https://aws.amazon.com/s3/) account (or use other S3-compatible services like [Backblaze](https://www.backblaze.com/), [MinIO](https://min.io/), [Filebase](https://filebase.com/), etc.), with at least two buckets; one private (for your database backups) and one public (for media assets). Here, we're using [Backblaze](https://www.backblaze.com/), because it's pretty easy and quick to set up, plus it has a generous free tier to get you started.\n- You have a [Sentry](https://sentry.io/) account for automatic reporting of errors and exceptions, and have [configured a Django project](https://docs.sentry.io/platforms/python/guides/django/).\n- You have a [Mailgun](https://www.mailgun.com/) / [Sendgrid](https://sendgrid.com/) / [Mailjet](https://www.mailjet.com/) 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](https://anymail.dev/en/stable/)\n\n### Steps\n\n1. SSH into your server\n2. Check the latest version of Dokku from \u003chttps://dokku.com/\u003e\n3. Run Dokku setup script based on latest version\n\n    ```bash\n    wget https://raw.githubusercontent.com/dokku/dokku/v0.28.1/bootstrap.sh \u0026\u0026 \\\n    sudo DOKKU_TAG=v0.28.1 bash bootstrap.sh\n    ```\n\n4. 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):\n   - you named your VPS as **dokku** in `~/.ssh/config`\n   - your SSH key is also called **dokku**, and is in `~/.ssh/`\n\n    ```bash\n    cat ~/.ssh/dokku.pub | ssh dokku sudo dokku ssh-keys:add admin\n    ```\n\n5. create your app (in this example, we'll call it `mysite`)\n\n    ```bash\n    sudo dokku apps:create mysite\n    ```\n\n6. add a domain to your app\n\n    ```bash\n    sudo dokku domains:add mysite example.com\n    ```\n\n    You can check domains report as follows\n\n    ```bash\n    sudo dokku domains:report mysite\n    sudo dokku domains:report --global\n    ```\n\n7. setup postgres service (see \u003chttps://github.com/dokku/dokku-postgres\u003e for reference\n\n    ```bash\n    sudo dokku plugin:install https://github.com/dokku/dokku-postgres.git postgres\n    # You can choose the image \u0026 image version of your choice here\n    sudo dokku postgres:create postgres-mysite --image \"postgres\" --image-version \"14.5\"\n    sudo dokku postgres:link postgres-mysite mysite\n    # Note: DATABASE_URL is automagically set for you, so no need to worry about it\n    ```\n\n    **NOTE**: if you're migrating your app from somewhere, you can import your database dump:\n\n    ```bash\n    sudo dokku postgres:import postgres-mysite \u003c path/to/your/dabasase-backup-file\n    ```\n\n8. 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](https://www.backblaze.com/), [MinIO](https://min.io/), [Filebase](https://filebase.com/), etc.\n\n    ```bash\n    # sudo dokku postgres:backup-auth \u003cservice\u003e \u003caws-access-key-id\u003e \u003caws-secret-access-key\u003e \u003caws-default-region\u003e \u003caws-signature-version\u003e \u003cendpoint-url\u003e\n    sudo dokku postgres:backup-auth postgres-mysite access-key-id secret-access-key eu-central-003 v4 https://s3.eu-central-003.backblazeb2.com\n    # postgres:backup postgres-mysite \u003cbucket-name\u003e\n    sudo dokku postgres:backup postgres-mysite my-bucket\n    # for example, we wanna backup everyday at 2:30AM, 10:30AM, 6:30 PM\n    sudo dokku postgres:backup-schedule postgres-mysite \"30 2,10,18 * * *\" my-bucket\n    # check: cat the contents of the configured backup cronfile for the service\n    sudo dokku postgres:backup-schedule-cat postgres-mysite\n    ```\n\n9. setup redis service (see \u003chttps://github.com/dokku/dokku-redis\u003e for reference)\n\n    ```bash\n    sudo dokku plugin:install https://github.com/dokku/dokku-redis.git redis\n    sudo dokku redis:create redis-mysite\n    sudo dokku redis:link redis-mysite mysite\n    # Note: REDIS_URL is automagically set, just like DATABASE_URL\n    ```\n\n10. set environment variables for your app\n\n    \u003e **Note 1**: by default, the Python buildpack runs `./manage.py collectstatic` automatically\n    \u003e   If you want to do certain things before running collectstatic, or perhaps customize\n    \u003e   how collectstatic itself is run, the set DISABLE_COLLECTSTATIC=1 and run collectstatic as a post-compile step\n    \u003e **Note 2**: feel free to adjust WEB_CONCURRENCY based on the memory requirements of your processes\n    \u003e   ref: \u003chttps://docs.gunicorn.org/en/stable/settings.html\u003e\n    \u003e   The suggested number of workers is (2 * CPU) + 1\n\n    ```bash\n    sudo dokku config:set --no-restart mysite WEB_CONCURRENCY=3 \u0026\u0026 \\\n    sudo dokku config:set --no-restart mysite DISABLE_COLLECTSTATIC=1 \u0026\u0026 \\\n    sudo dokku config:set --no-restart mysite PYTHONHASHSEED=random \u0026\u0026 \\\n    sudo dokku config:set --no-restart mysite DJANGO_SECRET_KEY=YOURSECRETKEY \u0026\u0026 \\\n    sudo dokku config:set --no-restart mysite DJANGO_SETTINGS_MODULE=mysite.settings.production \u0026\u0026 \\\n    sudo dokku config:set --no-restart mysite DEBUG=False \u0026\u0026 \\\n    sudo dokku config:set --no-restart mysite ALLOWED_HOSTS=example.com \u0026\u0026 \\\n    sudo dokku config:set --no-restart mysite BASE_URL=https://example.com \u0026\u0026 \\\n    sudo dokku config:set --no-restart mysite REDIS_KEY_PREFIX=mysite \u0026\u0026 \\\n    sudo dokku config:set --no-restart mysite AWS_STORAGE_BUCKET_NAME=my-bucket \u0026\u0026 \\\n    sudo dokku config:set --no-restart mysite AWS_ACCESS_KEY_ID=access-key-id \u0026\u0026 \\\n    sudo dokku config:set --no-restart mysite AWS_SECRET_ACCESS_KEY=secret-access-key \u0026\u0026 \\\n    sudo dokku config:set --no-restart mysite AWS_S3_REGION_NAME=eu-central-003 \u0026\u0026 \\\n    sudo dokku config:set --no-restart mysite AWS_S3_ENDPOINT_URL=https://my-bucket.s3.eu-central-003.backblazeb2.com \u0026\u0026 \\\n    sudo dokku config:set --no-restart mysite SENTRY_DSN=https://xxxxxxxxxxxxxx@yyyyyy.ingest.sentry.io/zzzzzzz \u0026\u0026 \\\n    sudo dokku config:set --no-restart mysite SENTRY_ENVIRONMENT=production \u0026\u0026 \\\n    sudo dokku config:set --no-restart mysite SENTRY_TRACES_SAMPLE_RATE=0.5 \u0026\u0026 \\\n    sudo dokku config:set --no-restart mysite DJANGO_SENTRY_LOG_LEVEL=20 \u0026\u0026 \\\n    sudo dokku config:set --no-restart mysite EMAIL_RECIPIENTS='MySite Technical Team \u003ctechnical@example.com\u003e,johndoe@example.com,janedoe@example.com,anotheremail@example.com' \u0026\u0026 \\\n    sudo dokku config:set --no-restart mysite DEFAULT_FROM_EMAIL='MySite Powered By Django \u003cdo-not-reply@mailgun.example.com\u003e' \u0026\u0026 \\\n    sudo dokku config:set --no-restart mysite MAILGUN_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \u0026\u0026 \\\n    sudo dokku config:set --no-restart mysite MAILGUN_DOMAIN=mailgun.mysite.com \u0026\u0026 \\\n    sudo dokku config:set --no-restart mysite MAILGUN_API_URL=https://api.eu.mailgun.net/v3\n    ```\n\n11. configure buildpacks\n\n    In this case, we are only using the python buildpack:\n\n    ```bash\n    sudo dokku buildpacks:add --index 1 mysite https://github.com/heroku/heroku-buildpack-python.git\n    ```\n\n    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:\n\n    ```bash\n    sudo dokku buildpacks:add --index 1 mysite https://github.com/heroku/heroku-buildpack-nodejs.git\n    sudo dokku buildpacks:add --index 2 mysite https://github.com/heroku/heroku-geo-buildpack.git\n    sudo dokku buildpacks:add --index 3 mysite https://github.com/heroku/heroku-buildpack-python.git\n    ```\n\n    You can list your app's buildpacks as follows:\n\n    ```bash\n    sudo dokku buildpacks:list mysite\n    ```\n\n12. configure NGIИX\n\n    ```bash\n    sudo ufw allow 'Nginx Full'\n    sudo rm -fv /etc/nginx/sites-enabled/default\n    sudo systemctl restart nginx\n    sudo dokku nginx:validate-config\n    sudo dokku nginx:show-config mysite\n    # Customize Nginx | set `client_max_body_size`, to make upload feature work better in Django projects, for example\n    sudo dokku nginx:set mysite client-max-body-size 50m\n    # regenerate config\n    sudo dokku proxy:build-config mysite\n    ```\n\n13. (on local machine) add a remote `dokku` to your git repo, and deploy 🚀\n\n    ```bash\n    # remember from step 4, here the assumption is that you named your VPS as **dokku** in `~/.ssh/config`\n    # otherwise change the @dokku to the @ \u003cserver's IP address\u003e or \u003cwhatever you named it in `~/.ssh/config`\u003e\n    git remote add dokku dokku@dokku:mysite\n    git push dokku\n    ```\n\n14. SSL\n\n    ```bash\n    sudo dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git\n    sudo dokku config:set --no-restart --global DOKKU_LETSENCRYPT_EMAIL=your@emailaddress.com\n    sudo dokku letsencrypt:enable mysite\n    # this would setup cron job to update letsencrypt certificate\n    sudo dokku letsencrypt:cron-job --add\n    ```\n\nAnd you should be all set!\n\n### Running commands like `createsuperuser`\n\n```bash\nsudo dokku run mysite python manage.py createsuperuser\n```\n\n---\n\nSee [this gist](https://gist.github.com/engineervix/8d1825a7301239e7c4df3af78aaee9a4) for additional notes\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fengineervix%2Fdjango-deployment-tutorial","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fengineervix%2Fdjango-deployment-tutorial","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fengineervix%2Fdjango-deployment-tutorial/lists"}