Post-Deploy Setup¶
Configure your domain, HTTPS, firewall, OAuth, and verify everything is working after deployment.
Prerequisites¶
- Completed deployment via DigitalOcean or BYOS
- Admin email and password from the deployment wizard
- Optional: a domain name you want to point at the server
1. Verify Deployment¶
Check Server Status¶
All services should show as running:
Server: 143.198.xxx.xxx
Status: healthy
Services:
✓ Dango web server (running)
✓ Metabase (running)
✓ Caddy (running)
✓ Docker (running)
Log In to the Web UI¶
Open http://<your-server-ip> in a browser. Log in with the admin email and password from the deployment wizard.
Tip
The first page load may take 30–60 seconds while Metabase finishes its initial startup. Subsequent loads are fast.
Check Initial Sync¶
Your data sources should already be syncing from the initial sync during deployment. Check the Sources page in the web UI or run:
2. Custom Domain¶
Setting up a domain gives you automatic HTTPS via Let's Encrypt and a human-readable URL.
Configure DNS¶
Add an A record pointing your domain to the server IP:
| Type | Name | Value | TTL |
|---|---|---|---|
| A | analytics (or @) | 143.198.xxx.xxx | 300 |
Wait for DNS propagation (usually 1–5 minutes, up to 48 hours for some providers).
Set the Domain¶
What happens:
- DNS preflight check — resolves the domain via
socket.getaddrinfoand verifies it points to your server's IP - Update Caddyfile — switches from IP-based HTTP to domain-based HTTPS configuration
- Reload Caddy — applies the new configuration
- TLS provisioning — Caddy automatically obtains a Let's Encrypt certificate
- Update cloud.yml — stores the domain for future reference
Checking DNS for analytics.yourcompany.com...
✓ Resolves to 143.198.xxx.xxx (matches server IP)
Updating Caddy configuration...
✓ Caddyfile updated for HTTPS
✓ Caddy reloaded
✓ TLS certificate provisioning started
Domain set: https://analytics.yourcompany.com
HTTPS Headers
When a domain is configured, Caddy enables HSTS (HTTP Strict Transport Security) with a 2-year max-age. This tells browsers to always use HTTPS for your domain. All other security headers (X-Content-Type-Options, X-Frame-Options, Referrer-Policy) are always active regardless of domain configuration.
Remove a Domain¶
To revert to IP-based HTTP access:
This reverts the Caddyfile to HTTP-only mode and clears the domain from cloud.yml.
3. Firewall¶
Restrict network access to your server to improve security.
DigitalOcean deployments use the DO cloud firewall, managed via the Dango CLI.
Default rules (created during deployment):
| Direction | Protocol | Port | Source |
|---|---|---|---|
| Inbound | TCP | 22 | All IPv4 + IPv6 |
| Inbound | TCP | 80 | All IPv4 + IPv6 |
| Inbound | TCP | 443 | All IPv4 + IPv6 |
| Outbound | TCP/UDP/ICMP | All | All |
Restrict SSH to your IP:
# Allow only your IP for SSH
dango remote firewall allow-ip 203.0.113.50
# List current rules
dango remote firewall list
Allow access from anywhere (default for HTTP/HTTPS):
IPv4 Only
The dango remote firewall commands only accept IPv4 addresses and CIDR ranges. IPv6 addresses are rejected with error code DANGO-D020. The default rules include IPv6 access via the DO console — use the DO web UI to manage IPv6 firewall rules.
BYOS deployments install UFW (Uncomplicated Firewall) directly on the server.
Default rules (configured during deployment):
- Default deny incoming, allow outgoing
- Allow SSH (port 22)
- Allow HTTP (port 80)
- Allow HTTPS (port 443)
Manage UFW directly via SSH:
dango remote ssh
# Check status
sudo ufw status verbose
# Allow a specific IP for SSH only
sudo ufw allow from 203.0.113.50 to any port 22
# Deny SSH from all (after adding specific IPs)
sudo ufw delete allow 22
# Reload
sudo ufw reload
If your server is behind a cloud provider's security group (AWS, GCP, etc.), configure network rules there as well — UFW and cloud security groups are independent layers.
4. OAuth Re-authentication¶
OAuth sources (Google Sheets, Google Analytics, Google Ads, Facebook Ads, GitHub) require re-authentication after deployment. This is because OAuth redirect URIs change from http://localhost:... to your server's URL.
Why It's Needed¶
During local development, OAuth tokens are issued with http://localhost:8800/oauth/callback as the redirect URI. When you deploy to a server with a domain, the redirect URI must be updated to https://analytics.yourcompany.com/oauth/callback in your OAuth provider's console (Google Cloud, Facebook Developer, etc.) and new tokens must be obtained.
Re-authenticate via CLI¶
This opens a browser for the OAuth consent flow. After authorizing, the new tokens are saved directly to the server.
Re-authenticate via Web UI¶
- Navigate to the Secrets & Admin page in the web UI
- Find the OAuth source
- Click Re-authenticate
- Complete the OAuth flow in the browser
Update Redirect URIs First
Before re-authenticating, update the Authorized redirect URI in your OAuth provider's developer console to match your server's URL:
- With domain:
https://analytics.yourcompany.com/oauth/callback - Without domain:
http://143.198.xxx.xxx/oauth/callback
5. Scheduled Syncs¶
Cloud deployments typically use scheduled syncs instead of the local file watcher (which is not available on cloud).
Configure schedules via the web UI Schedules page or the CLI:
Common cron expressions: 0 */6 * * * (every 6 hours), 0 2 * * * (daily at 2am), 0 9 * * 1 (weekly on Monday at 9am).
See Scheduled Syncs for full documentation on schedule configuration, cron syntax, and misfire handling.
6. Push Updates¶
After making local changes to configuration or dbt models, push them to the server:
What gets synced
dango remote push syncs these files to the server:
.dango/sources.yml— source definitions.dango/schedule.yml— sync schedulesdbt_project/— all dbt models, tests, and configurationdocker-compose.yml— Metabase container definitionDockerfile.metabase— Metabase image configurationentrypoint.sh— Metabase startup script
Not synced (managed separately):
.env— environment variables.dlt/secrets.toml— API credentialswarehouse.duckdb— DuckDB database
Deploy Lock
Only one push can run at a time. If another push is in progress, you'll see an error. Wait for it to complete or check dango remote status.
Verification Checklist¶
After completing post-deploy setup, verify everything:
-
dango remote statusshows all services healthy - Web UI is accessible and login works
- Domain resolves correctly (if configured):
nslookup analytics.yourcompany.com - HTTPS certificate is valid (if domain configured): check browser lock icon
- Firewall rules are restrictive (SSH not open to all, if possible)
- OAuth sources re-authenticated and syncing
- Scheduled syncs configured and running
-
dango remote pushsucceeds from local machine
Troubleshooting¶
DNS not resolving¶
- Verify the A record is correct in your DNS provider
- Wait for propagation:
nslookup analytics.yourcompany.comordig analytics.yourcompany.com - Some DNS providers cache aggressively — try a public resolver:
nslookup analytics.yourcompany.com 8.8.8.8
TLS certificate not issuing¶
Common causes:
- DNS not propagated — Caddy can't verify domain ownership until DNS resolves
- Ports 80/443 blocked — Let's Encrypt uses HTTP-01 challenge (port 80 must be open)
- Rate limited — Let's Encrypt has rate limits (50 certificates per domain per week)
Check Caddy logs:
OAuth re-authentication failing¶
- Verify the redirect URI matches exactly in your OAuth provider's console (including protocol, domain, and path)
- For Google: update in Google Cloud Console > OAuth 2.0 Client IDs > Authorized redirect URIs
- For Facebook: update in Facebook Developer Console > App Settings > Valid OAuth Redirect URIs
Deploy lock stuck¶
If no other push is running, the lock may be stale:
Warning
Only delete the lock file if you are certain no push is in progress. Deleting it during an active push could leave the server in an inconsistent state.
Then on the server:
Next Steps¶
- Remote Management — day-to-day server management commands
- Backups — configure automated backups
- Server Operations — systemd, logs, and maintenance
- Scheduled Syncs — configure automated data syncs
- Authentication — manage users, sessions, and 2FA