Bring Your Own Server¶
Deploy Dango to any Ubuntu server you already have — AWS, GCP, Hetzner, on-premise, or any other provider.
Prerequisites¶
Your server must meet these requirements:
| Requirement | Minimum | Recommended |
|---|---|---|
| OS | Ubuntu 22.04 LTS | Ubuntu 22.04 or 24.04 LTS |
| RAM | 4 GB | 4 GB+ |
| CPU | 1 vCPU | 2+ vCPU |
| Disk | 20 GB free | 50 GB+ free |
| Access | SSH access (root or sudo) | Root access |
| Ports | 22 (SSH) | 22, 80, 443 open |
Additionally, you need:
- A configured Dango project with at least one source in
sources.yml - Credentials configured in
.dlt/secrets.tomlfor your sources - SSH key — existing key or the wizard generates one
Docker Not Required
You do not need Docker pre-installed. The wizard installs Docker automatically via get.docker.com during server setup.
Quick Start¶
The wizard connects to your server via SSH, validates the environment, and installs everything. The rest of this page explains each step.
Wizard Walkthrough¶
Step 1: Server Connection¶
Provide your server's connection details:
- IP address or hostname — the server's public IP or DNS name
- SSH user — defaults to
root - SSH key — path to your private key, or the wizard generates a new keypair
Server IP or hostname: 203.0.113.50
SSH user [root]: root
SSH key path [~/.ssh/id_rsa]: ~/.ssh/id_rsa
Step 2: Validate SSH¶
The wizard tests the SSH connection and checks the server environment:
Testing SSH connection to 203.0.113.50...
✓ SSH connection successful
✓ Ubuntu 22.04 detected
✓ 4 GB RAM, 2 vCPU
Non-Ubuntu Warning
If the server is not running Ubuntu, the wizard shows a warning but allows you to proceed. Dango is tested on Ubuntu 22.04 and 24.04 — other distributions may work but are not officially supported.
Ubuntu 22.04 vs 24.04
Both versions are fully supported. The SSH service name differs between versions (sshd on 22.04, ssh on 24.04) — Dango detects this automatically during setup.
The wizard auto-detects your server's hardware using nproc (CPU count) and free (RAM) to tune dbt performance settings in profiles.yml.
Step 3: Admin Account¶
Same as the DigitalOcean wizard — set an admin email (double-confirmed) and receive an auto-generated password.
Admin email: [email protected]
Confirm email: [email protected]
╭─────────────────────────────────────────╮
│ Admin Password: xK7_mN2pQ9rT4wY6zA8b │
│ │
│ Save this password now — it will not │
│ be shown again. │
╰─────────────────────────────────────────╯
Step 4: Data Sources¶
Same as the DigitalOcean wizard — lists your configured sources and checks for credentials.
Step 5: OAuth Sources¶
Always skipped. Configure OAuth post-deploy. See Post-Deploy Setup.
What BYOS Does (and Doesn't Do)¶
The BYOS wizard installs and configures Dango on your server. It does not manage infrastructure outside the server itself.
| Capability | DigitalOcean | BYOS |
|---|---|---|
| Provision VM | Yes | No — you provide the server |
| Install Docker, Caddy, Python | Yes | Yes |
| Configure fail2ban, unattended-upgrades | Yes | Yes |
| Cloud firewall (DO API) | Yes | No — installs UFW instead |
| Automated backups (DO Spaces) | Yes | No — use manual snapshots |
dango deploy destroy | Yes (destroys droplet) | No — you manage the server |
dango remote firewall | Yes (DO cloud firewall) | No — manage UFW directly |
| DNS/domain setup | Yes | Yes |
| HTTPS via Caddy | Yes | Yes |
Server Setup Steps¶
After the wizard validates your SSH connection, the following is installed and configured on your server (approximately 2–4 minutes):
- System packages —
aptupdate and install build dependencies - Dango user — creates a
dangosystem user - Docker — installed via
get.docker.com,dangouser added todockergroup - Caddy — installed from the official apt repository (reverse proxy + auto-TLS)
- Project directories — creates
/srv/dango/structure - Python venv — creates virtual environment and installs
getdangofrom PyPI - SSH hardening — disables root password login, enforces key-only authentication
- Docker daemon — configures logging (json-file driver, 10MB max, 3 rotated files)
- journald — caps log retention at 500 MB
- Log rotation — configures
logrotatefor Dango activity logs - systemd service — installs
dango.servicefor process management and auto-restart - Caddyfile — writes reverse proxy configuration (HTTP initially, HTTPS after domain setup)
- fail2ban — SSH brute-force protection (ban after failed attempts)
- Unattended upgrades — automatic security patches
- UFW firewall — allows SSH (22), HTTP (80), HTTPS (443); denies all other inbound
- Sync project files — pushes configuration and dbt files to the server
- dbt profiles — generates
profiles.ymltuned for detected hardware - Push credentials — securely transfers
.dlt/secrets.tomland.env - Create admin — sets up admin user and enables authentication
- Start services — launches Dango and Metabase via systemd
- Health check — verifies the web UI is responding
- Initial sync — triggers the first data sync
UFW is BYOS-only
DigitalOcean deployments use the DO cloud firewall (managed via API). BYOS deployments install UFW directly on the server since there's no cloud-level firewall to manage.
Cloud Provider Notes¶
Different providers have different defaults. Keep these in mind when provisioning your server:
| Factor | DigitalOcean | Hetzner | GCP | AWS |
|---|---|---|---|---|
| Default disk | 80 GB | 40 GB | 10 GB | Varies by instance |
| SSH user | root | root | Your username | ubuntu |
| Root SSH | Yes | Yes | Disabled by default | Disabled by default |
| Min RAM | 4 GB recommended | 4 GB recommended | 4 GB recommended | 4 GB recommended |
GCP default disk is too small
GCP instances default to 10 GB disk, which is not enough for Dango (DuckDB + Metabase + Docker images). Increase to at least 20 GB when creating the instance.
Non-root SSH users
GCP and AWS disable root login by default. Use your cloud username as the SSH user and ensure it has passwordless sudo access. The wizard runs setup commands via sudo.
Minimum RAM: 4 GB. Servers with 2 GB RAM cause Metabase out-of-memory crashes and are not supported.
Non-Interactive Mode¶
dango deploy \
--byos \
--non-interactive \
--server-ip 203.0.113.50 \
--ssh-user root \
--ssh-key ~/.ssh/id_rsa \
--admin-email [email protected] \
--admin-password "$DANGO_ADMIN_PASSWORD"
BYOS-Specific Flags¶
| Flag | Description | Default |
|---|---|---|
--byos | Enable BYOS mode (required) | Off |
--server-ip | Server IP address or hostname | Prompted |
--ssh-user | SSH username | root |
--ssh-key | Path to SSH private key | Prompted |
All common flags also apply (--non-interactive, --admin-email, --admin-password, --domain).
Verification¶
After deployment completes, verify everything is working:
Expected output:
Server: 203.0.113.50
Status: healthy
Services:
✓ Dango web server (running)
✓ Metabase (running)
✓ Caddy (running)
✓ Docker (running)
Last sync: 2 minutes ago
Sources: 3 configured, 3 healthy
Open http://<your-server-ip> in a browser and log in with the admin credentials from Step 3.
Troubleshooting¶
SSH connection refused¶
- Verify the server is running and reachable:
ping 203.0.113.50 - Check that port 22 is open in your cloud provider's security group / firewall
- Verify your SSH key:
ssh -i ~/.ssh/id_rsa [email protected] - If using a non-standard port, configure it in your
~/.ssh/config
Non-Ubuntu warning¶
Dango is tested on Ubuntu 22.04 and 24.04 LTS. Other Debian-based distributions (Debian 11+) may work. Non-Debian distributions (CentOS, Fedora, Arch) are not supported and will likely fail during package installation.
Setup step failed¶
If server setup fails partway through:
# SSH into the server to check what happened
ssh -i ~/.ssh/id_rsa [email protected]
# Check logs
journalctl -u dango --no-pager -n 50
docker ps # Is Metabase running?
systemctl status caddy
Unlike DigitalOcean deployments, BYOS does not automatically clean up on failure (since it didn't create the server). You can fix the issue and re-run dango deploy --byos — the wizard is idempotent and will skip steps that already completed successfully.
Services not starting¶
Then on the server:
# Check service status
sudo systemctl status dango
sudo systemctl status caddy
sudo docker ps
# Restart services
sudo systemctl restart dango
sudo systemctl restart caddy
Common causes:
- Port conflict — another service already using port 8800, 80, or 443
- Docker not running —
sudo systemctl start docker - Disk full —
df -hto check available space
Quick recovery¶
Before SSH-ing in manually, try the built-in recovery commands:
# Diagnose and fix common issues (disk, RAM, services, Metabase)
dango remote repair
# If Metabase is completely broken (SSO loop, H2 corruption)
dango remote reset-metabase
See Recovery Commands for details.
Next Steps¶
- Post-Deploy Setup — configure domain, HTTPS, firewall, and OAuth
- Remote Management — managing your deployed server day-to-day
- Server Operations — systemd, logs, and server maintenance