-
Notifications
You must be signed in to change notification settings - Fork 174
Production Deployment using Dokku
Production stack will include these technologies:
- Postgres as main database for Django
- Celery + Redis + easy scalable workers
- Dokku as PaaS (will build app from sources and deploy it with zero downtime)
All app's services that are going to be launched in production can be found in Procfile
file. It includes Django webserver (Telegram event processing + admin panel) and Celery workers (background and periodic jobs).
Dokku is an open-source version of Heroku.
I really like Heroku deployment approach:
- you push commit to Main branch of your Repo
- in couple minutes your new app is running
- if something breaks during deployment - old app will not be shut down
You can achieve the same approach with Dokku + Github Actions (just to trigger deployment).
Dokku uses buildpacks technology to create a Docker image from the code. No Dockerfile needed. Speaking about Python, it requires requirements.txt
, Procfile
files to run the things up. Also files DOKKU_SCALE
and runtime.txt
are useful to tweak configs to make the deployed app even better. E.g. in DOKKU_SCALE
you can specify how many app instances should be run behind built-in load balancer.
One disadvantage of Dokku that you should be warned about is that it can work with one server only. You can't just scale your app up to 2 machines using only small config change. You still can use several servers by providing correct .env URLs to deployed apps (e.g. DATABASE_URL) but it will require more time to setup.
I assume that you already have Dokku installed on your server. Let's also assume that the address of your server is <YOURDOMAIN.COM> (you will need a domain to setup HTTPs for Telegram webhook support). I'd recommend to have at least 2GB RAM and 2 CPU cores.
dokku apps:create dtb
You might need to added .env
variables to app, e.g. to specify Telegram token:
dokku config:set dtb TELEGRAM_TOKEN=.....
Let's explicitly specify python buildpack to not mess with Dockerfile
which is used mostly for local testing right now.
dokku config:set dtb BUILDPACK_URL=https://github.com/heroku/heroku-buildpack-python.git#v191
Postgres and Redis are configured as Dokku plugins on a server. They will automatically add REDIS_URL & DATABASE_URL .env vars to the app after being linked. You might need to install these Dokku plugins before. Install Postgres, install Redis.
dokku postgres:create dtb
dokku postgres:link dtb dtb
dokku redis:create dtb
dokku redis:link dtb dtb
Go to file .github/workflows/dokku.yml:
- Enter your host name (address of your server),
- Deployed dokku app name (in our case this is
dtb
), - Set
SSH_PRIVATE_KEY
secret variable via GitHub repo settings. This private key should have the root ssh access to your server.
This will trigger Dokku's zero-downtime deployment. You would probably need to fork this repo to change file.
After that you should see a green arrow ✅ at Github Actions tab that would mean your app is deployed successfully. If you see a red cross ❌ you can find the deployed logs in Github Actions tab and find out what went wrong.
Basic pooling approach is really handy and can speed up development of Telegram bots. But it doesn't scale. Better approach is to allow Telegram servers push events (webhook messages) to your server when something happens with your Telegram bot. You can use built-in Dokku load-balancer to parallel event processing.
For Telegram bot API webhook usage you'll need a https which can be setup using Letsencrypt Dokku plugin. You will need to attach a domain to your Django app before and specify a email (required by Letsencrypt) - you will receive notifications when certificates would become old. Make sure you achieved a successful deployment first (your app runs at <YOURDOMAIN.COM>, check in browser).
dokku domains:add dtb <YOURDOMAIN.COM>
dokku config:set --global DOKKU_LETSENCRYPT_EMAIL=<YOUR@EMAIL.COM>
dokku letsencrypt:enable dtb
You need to tell Telegram servers where to send events of your Telegram bot. Just open in the browser:
https://api.telegram.org/bot<TELEGRAM_TOKEN>/setWebhook?url=https://<YOURDOMAIN.COM>/super_secter_webhook/
You can be sure that your app is deployed successfully if you see a green arrow at the latest workflow at Github Actions tab.
You would need to create a superuser to access an admin panel at https://<YOURDOMAIN.COM>/tgadmin. This can be done using a standard way using django shell:
dokku enter dtb web
Being inside a container:
python manage.py createsuperuser
After that you can open admin panel of your deployed app which is located at https://<YOURDOMAIN.COM>/tgadmin.
dokku logs dtb -t