What this guide covers
This guide covers a Django deployment flow where Pystrano clones your Git repository into a timestamped release directory, installs Python dependencies, links shared files, optionally runs migrations and static collection, updates the current symlink, restarts a systemd service, and prunes old releases.
Server assumptions
- You have a VPS-style Linux server where you can SSH as
rootfor setup. - The server can reach your Git repository over SSH.
- System packages can be installed with
apt. - Gunicorn is managed by a systemd service file that you provide.
- Database, TLS, firewall, backups, and monitoring are handled outside Pystrano.
Django project assumptions
- Your repository contains a
requirements.txtfile. - Your Django project can run
manage.py migrateandmanage.py collectstatic --noinput. - Your production settings read environment variables from the environment Pystrano loads from your dotenv file.
- Your Gunicorn systemd service points at the release exposed through the
currentsymlink.
Example deployment config
common:
source_code_url: "git@github.com:example/example-django-app.git"
project_root: "apps/example-django-app"
project_user: "deploy"
venv_dir: ".venv"
keep_releases: 5
system_packages: |
libpq-dev
python3-dev
build-essential
env_file: "./deploy/api/production/.env"
ssh_known_hosts: "github.com"
service_file: "./deploy/api/production/gunicorn.service"
secrets: "./deploy/api/production/django-secret-key.txt"
branch: "main"
clone_depth: 1
servers:
- host: "app1.example.com"
port: 22
run_migrations: true
collect_static_files: true
Gunicorn and systemd notes
When service_file is configured, setup copies it to /etc/systemd/system/<service_file_name>, reloads systemd, and enables the service. Deploy restarts that service after promoting the new release.
Your service should be written for your app. In many setups it will use the virtualenv under /home/<project_user>/<venv_dir> and the app code under /home/<project_user>/<project_root>/current.
Environment variables and secrets
Pystrano copies the configured env_file into the server's shared directory during deploy and links the active shared dotenv path. Optional files listed in secrets are copied during setup and linked into each release during deploy. Do not commit real secrets to Git.
Running migrations
Set run_migrations: true on the server that should run Django migrations. Pystrano runs:
python manage.py migrate
In multi-server deployments, usually only one app server should run migrations.
Collecting static files
Set collect_static_files: true on servers where static collection should run. Pystrano runs:
python manage.py collectstatic --noinput
Deploying
Preview first:
pystrano deploy production api --dry-run
Deploy when ready:
pystrano deploy production api
Rolling back
Pystrano keeps timestamped release directories and promotes a release by updating the current symlink. It does not currently include a rollback CLI command. Keep keep_releases high enough for your recovery window and document a tested manual rollback procedure for your servers.
Troubleshooting
- Use
--dry-runbefore live changes to inspect remote commands. - Use
--verbosewhen Fabric, Invoke, or Paramiko output is needed. - Check SSH access for both
rootand the configuredproject_user. - Confirm your Git host is included in
ssh_known_hostsand that the server can clone the repository. - Confirm local paths referenced by
env_file,service_file, andsecretsexist before running setup or deploy.