Production Checklist
Databases are critical infrastructure. Verify every item on this list before going live. ./queryglow install configures most of these, and ./queryglow doctor checks many of them for you, but you should verify them yourself.
Start with doctor and status
./queryglow doctor # host and install checks, exit 1 when problems exist
./queryglow status # versions, containers, certificate, last backup and updatedoctor checks Docker, the tools, .env permissions and secrets, containers, health, versions, ports, the nginx config, DNS, the certificate and free disk. In integration mode it also reports a site file without the /api/health or /api/mcp block. --fix applies four safe repairs; --report prints a support report without any .env value.
The "Zero Breach" Rules
Mandatory. Non-negotiable.
Access Control
Basic Auth is Active
Without credentials, requests should return 401. Test: curl https://your-domain.com should return "401 Unauthorized". Use a strong password: Basic Auth is not rate limited, so let fail2ban watch nginx for repeated 401s.
CSRF Protection is Active
Cross-origin POST requests should be blocked. Test with:
curl -X POST https://your-domain.com/api/connections -H "Origin: https://malicious-site.com" -u admin:passwordShould return "403 CSRF validation failed"
Network Isolation
QueryGlow binds to 127.0.0.1 only (set on the start command). The containers share the host network, so nginx reaches it on 127.0.0.1 and nothing else can.
Least Privilege Database Users
Use dedicated database users with limited permissions when possible, not the postgres superuser.
Connections
Live databases are marked Production
Set the connection's environment to Production. It shows in red everywhere, and the Query Editor asks before any INSERT, UPDATE, DELETE or DDL on it (on by default, switchable in Preferences).
SSH host keys are the ones you expect
QueryGlow pins each SSH server's host key on the first connect, in data/ssh-known-hosts.json. A changed key is refused with both fingerprints in the error. Investigate a mismatch before you remove the entry.
SSL connections verify the certificate where they can
Tick "Verify server certificate" on SSL connections whose certificate comes from a publicly trusted authority. It is off by default for new connections; certificates from a private authority (Amazon RDS, Google Cloud SQL) need it off.
Agents (if you use Agent Access)
- Tokens are read-only unless an agent really has to write, and every token has an expiry.
- Production connections are on a token only when you added them on purpose.
- You know where to look: every agent call is in the Activity tab, and you can pause one token or all of them there.
Safe Mode
Safe Mode is Enabled (Default)
By default, Safe Mode blocks these statements in the Query Editor:
- •
DROP TABLE(and DROP INDEX, VIEW, SEQUENCE, SCHEMA) - •
TRUNCATE - •
DELETE/UPDATEwithout WHERE clause
Always blocked in both modes: DROP DATABASE and statements that run commands or touch files on the server.
Verify: grep QUERYGLOW_ALLOW_DESTRUCTIVE .env should show false or nothing.
Where Safe Mode applies
Safe Mode covers the Query Editor and every Agent Access call. The Data Browser's edit and delete row buttons work normally: they act on single rows with proper WHERE clauses, and deletes ask for confirmation.
Search Engine Blocking
X-Robots-Tag Header is Set
nginx adds X-Robots-Tag: noindex, nofollow, noarchive to prevent search engine indexing.
Test: curl -I https://your-domain.com and look for the X-Robots-Tag header.
Verify After 24 Hours
Search site:your-domain.com on Google. Should return no results.
Data Persistence & Backup
Backups Run
./queryglow backup writes .env, the app data and (in standalone mode) the nginx files to backups/<timestamp>/. Every update makes one as well. Keep a copy off the server.
Docker Volume is Mounted
Verify /app/data is persisted: docker volume ls | grep queryglow
A Backup Holds Both Data AND .env
What a complete backup includes:
- •
connections.json: encrypted connection profiles - •
saved-queries.json: saved SQL snippets - •
query-history.json: query history (last 1,000 queries) - •
agent-tokens.jsonandagent-activity.json: agent tokens (hashed) and their calls - •
ai-settings.json: AI keys and models entered in the app (encrypted) - •
ssh-known-hosts.json: pinned SSH host keys - •
.env: CRITICAL, contains SESSION_SECRET and ENCRYPTION_SALT
Warning: Without SESSION_SECRET and ENCRYPTION_SALT from your .env file, you cannot decrypt saved database passwords, SSH keys or AI keys entered in the app. Back up .env separately and securely.
Updates
./queryglow update --checkruns on a schedule (cron or your monitor). It exits with code 10 when a newer release is available.- You apply releases with
./queryglow update: backup first, version check, automatic rollback on failure. How updating works - Integration mode: your nginx site has the
/api/mcp,/api/healthand browser icon blocks. The blocks
Verification Commands
Run these commands to verify your deployment:
# 1. HTTPS works (the health check needs no login)
curl https://your-domain.com/api/health# Should return JSON with "status":"ok" plus timestamp and uptime
# 2. HTTP redirects to HTTPS
curl -I http://your-domain.com# Should return: 301 redirect to https://
# 3. Auth is required
curl https://your-domain.com# Should return: 401 Unauthorized
# 4. The app port is NOT exposed (run from another machine)
curl http://your-server-ip:3000# Should return: Connection refused
# 5. Database ports are closed
sudo ufw status | grep -E "5432|3306"# Should return: nothing (ports not listed)
# 6. Safe Mode is ON
grep QUERYGLOW_ALLOW_DESTRUCTIVE .env# Should return: false (or nothing = defaults to false)
What ./queryglow install Configures Automatically
See Security Overview for the complete security architecture.