Deploy self-hosted Retool using Docker Compose to run Retool inside your own infrastructure. The official Docker Compose configuration runs four containers (api, db_connector, jobs-runner, Postgres) and connects directly to VPC databases without IP whitelisting. Configure environment variables for secrets, SSL, and external database connections.
| Fact | Value |
|---|---|
| Tool | Docker |
| Category | DevOps |
| Method | Development Workflow |
| Difficulty | Intermediate |
| Time required | 45 minutes |
| Last updated | April 2026 |
Deploy Self-Hosted Retool with Docker Compose
Retool Cloud is the fastest way to get started, but many organizations require their Retool instance to run inside their own infrastructure — for compliance reasons, to access databases that cannot be exposed to the internet, or to eliminate IP whitelisting management. Docker is the primary mechanism for self-hosted Retool deployments, ranging from Docker Compose on a single VM to Kubernetes with Helm for production-grade deployments.
The self-hosted architecture runs four containers: the main 'api' container serving the Retool web application, 'db_connector' handling database query proxying, 'jobs-runner' executing background jobs and Workflow runs, and a local PostgreSQL database for Retool's own metadata (app definitions, user sessions, audit logs). An optional Temporal server adds Workflow execution support.
The critical advantage over Retool Cloud is network connectivity: self-hosted Retool runs alongside your databases and internal services, so it can connect to PostgreSQL on localhost, MySQL on internal hostnames, or Redis on private IP addresses — no public exposure, no IP whitelisting, no SSH tunnels needed.
Integration method
Docker is the deployment mechanism for self-hosted Retool. Retool provides official Docker images and a Docker Compose configuration that runs all required services. The self-hosted approach keeps Retool inside your VPC, enabling direct database connections without IP whitelisting and ensuring sensitive data never leaves your network.
Prerequisites
- A Linux server or VM (AWS EC2, GCP Compute Engine, DigitalOcean Droplet) with at least 4 GB RAM and 2 vCPUs
- Docker Engine and Docker Compose installed on the server
- A Retool license key (from Retool's team for Team/Business/Enterprise plans; also works with trial)
- A domain name and SSL certificate (or Let's Encrypt) for production deployments
- SSH access to the server for initial configuration
Step-by-step guide
Download and configure the Retool Docker Compose file
On your server, clone Retool's official Docker repository or download the docker-compose.yml file directly from Retool's GitHub repository (github.com/tryretool/retool-onpremise). The repository contains the docker-compose.yml and a .env.template file. Copy .env.template to .env — this file contains all configuration variables for the deployment. The critical required variables are: DEPLOYMENT_TEMPLATE_TYPE (set to 'docker-compose'), JWT_SECRET (generate a random 64-character string using: openssl rand -hex 32), ENCRYPTION_KEY (generate another random 64-character string using: openssl rand -hex 32), POSTGRES_DB (Retool's internal database name, typically 'hammerhead_production'), POSTGRES_PASSWORD (a strong password for the internal Postgres database), and LICENSE_KEY (your Retool license key from the Retool team). The JWT_SECRET signs user session tokens and ENCRYPTION_KEY encrypts stored credentials — both must be preserved if you ever need to restore from a backup. If these keys are lost, all stored resource credentials must be re-entered.
1# Key environment variables in .env file:23# Security keys (generate random values, NEVER share or lose these)4JWT_SECRET=your_64_char_random_string5ENCRYPTION_KEY=your_64_char_random_string67# Internal Postgres database8POSTGRES_DB=hammerhead_production9POSTGRES_PASSWORD=strong_internal_db_password1011# Retool configuration12COOKIE_INSECURE=false13NODE_ENV=production14FORCE_DEPLOYMENT_SPECIFIC_ROTATION=false1516# License17LICENSE_KEY=your_retool_license_key1819# Optional: base domain for OAuth callbacks20BASE_DOMAIN=https://retool.yourcompany.comPro tip: Back up the .env file (specifically JWT_SECRET and ENCRYPTION_KEY) to a secure secrets manager like AWS Secrets Manager or HashiCorp Vault immediately after generating them. These values cannot be recovered if lost.
Expected result: The .env file is configured with all required variables. The docker-compose.yml file references these variables and is ready to run.
Start the Retool containers with Docker Compose
With the .env file configured, start all Retool services by running docker compose up -d from the directory containing docker-compose.yml. Docker pulls the Retool images from Docker Hub (retool/retool) on first run — this may take 5-10 minutes depending on network speed. After the pull completes, Docker starts four containers: retool-api (the main application), retool-db_connector (database proxy), retool-jobs-runner (background tasks), and retool-postgres (internal metadata database). Monitor startup logs with docker compose logs -f api to watch for any startup errors. The api container is ready when you see a log line containing 'Listening on port 3000'. By default, Retool is accessible on port 3000 of your server. Set up a reverse proxy (nginx or Caddy) or load balancer in front of port 3000 to handle SSL termination and serve Retool on port 443.
1# Start all containers in detached mode2docker compose up -d34# Check container status5docker compose ps67# Watch api container startup logs8docker compose logs -f api910# Check all containers are healthy:11# retool-api running12# retool-db_connector running13# retool-jobs-runner running14# retool-postgres runningPro tip: After first startup, access Retool on port 3000 (HTTP) temporarily to create your admin account, then configure SSL before allowing team access. Never expose Retool over plain HTTP in production.
Expected result: All four Docker containers are running. Accessing http://SERVER_IP:3000 in a browser loads the Retool setup page for creating the first admin account.
Configure SSL with nginx reverse proxy
For production, place nginx or Caddy in front of Retool to handle SSL termination. The simplest approach uses Caddy, which automatically provisions Let's Encrypt certificates. Install Caddy on your server and create a Caddyfile that proxies traffic to Retool's port 3000. If you use nginx, configure it with an SSL certificate from Let's Encrypt (using certbot) or your organization's certificate authority. The nginx or Caddy server listens on port 443 and forwards traffic to Retool's docker container on port 3000. Set the BASE_DOMAIN environment variable in Retool's .env to the HTTPS URL you will use (e.g., https://retool.yourcompany.com) — this is required for OAuth callback URLs to work correctly. After configuring SSL, update COOKIE_INSECURE=false in the .env file (the default) to ensure session cookies are marked as Secure and SameSite.
1# Caddyfile configuration for Retool:2retool.yourcompany.com {3 reverse_proxy localhost:30004}56# Or nginx configuration:7# /etc/nginx/sites-available/retool8server {9 listen 443 ssl;10 server_name retool.yourcompany.com;1112 ssl_certificate /etc/letsencrypt/live/retool.yourcompany.com/fullchain.pem;13 ssl_certificate_key /etc/letsencrypt/live/retool.yourcompany.com/privkey.pem;1415 location / {16 proxy_pass http://localhost:3000;17 proxy_http_version 1.1;18 proxy_set_header Upgrade $http_upgrade;19 proxy_set_header Connection 'upgrade';20 proxy_set_header Host $host;21 proxy_set_header X-Real-IP $remote_addr;22 proxy_cache_bypass $http_upgrade;23 }24}Pro tip: WebSocket support is required for Retool's real-time features. Ensure your nginx configuration includes the Upgrade and Connection headers as shown, otherwise the Retool editor may not load correctly.
Expected result: Retool is accessible at https://retool.yourcompany.com with a valid SSL certificate. HTTP traffic redirects to HTTPS automatically.
Connect self-hosted Retool to internal databases
The primary benefit of self-hosted Retool is direct database connectivity without IP whitelisting. In the Retool admin panel (Resources → Create New), create database Resources using internal hostnames or private IP addresses. For an RDS database, use the private DNS endpoint (yourdb.xxxxxxxx.us-east-1.rds.amazonaws.com) rather than the public endpoint — this only works if Retool runs in the same VPC. For a database running on the same server as Retool, use the Docker network hostname. By default, Retool containers run on a Docker bridge network, so 'localhost' from inside the container does not reach the host. Use the special hostname 'host.docker.internal' (on Docker Desktop) or the host's Docker bridge IP (typically 172.17.0.1) to reach services on the host machine. For security, configure the database to accept connections only from the Retool container's IP or Docker subnet, restricting access further.
1# Database connection examples for self-hosted Retool:23# RDS in same VPC (use private DNS endpoint):4# Host: mydb.cluster-abc123.us-east-1.rds.amazonaws.com5# Port: 54326# (No IP whitelisting needed - same VPC)78# Database on same Docker host:9# Host: host.docker.internal (Docker Desktop)10# Host: 172.17.0.1 (Linux Docker bridge default)11# Port: 54321213# Other service in Docker Compose:14# Host: service_name (uses Docker DNS)15# Example: adding your own postgres container16# host: my-app-postgresPro tip: For production deployments, consider using Docker Compose networks to place your application databases and Retool containers on the same named Docker network, enabling service-name DNS resolution between containers.
Expected result: Database Resources in Retool can connect to internal databases using private hostnames. The test connection succeeds without needing to whitelist any IP addresses.
Update Retool to new versions
Retool releases new versions regularly. Self-hosted instances use Docker image tags to manage versions. Retool's docker-compose.yml specifies the image version as a tag on the retool/retool image. To update, change the image tag to the new version number, run docker compose pull to download the new images, then docker compose up -d to restart containers with the new version. Retool's database migrations run automatically on startup — the api container applies any required schema changes to the internal Postgres database before accepting traffic. Always take a backup of the internal Postgres database before major version updates. The Retool release notes at docs.retool.com/changelog document breaking changes between versions. Self-hosted instances trail Cloud by approximately 2 weeks (Edge channel) or 13 weeks (Stable quarterly releases) — choose your update cadence based on your team's risk tolerance.
1# Update steps:23# 1. Check current version4docker compose exec api cat /usr/local/lib/node_modules/retool/package.json | grep version56# 2. Backup internal Postgres before updating7docker compose exec postgres pg_dump -U postgres hammerhead_production > retool_backup_$(date +%Y%m%d).sql89# 3. Update version tag in docker-compose.yml:10# image: tryretool/backend:3.XX.X1112# 4. Pull new images13docker compose pull1415# 5. Restart with new version (brief downtime)16docker compose up -d1718# 6. Watch migration logs19docker compose logs -f apiPro tip: Pin Retool to a specific version tag in docker-compose.yml rather than using 'latest' — this prevents automatic version bumps from a docker compose pull and gives you control over when updates are applied.
Expected result: Retool updates to the new version without data loss. The web application shows the new version number in the account settings page.
Common use cases
Deploy Retool within a VPC for secure database access
Run self-hosted Retool inside an AWS VPC or GCP VPC network so it can connect directly to RDS, Aurora, or Cloud SQL databases without exposing them to the internet. Team members access Retool through a VPN or internal load balancer, and database credentials never leave the private network.
Deploy self-hosted Retool on an EC2 instance inside the same VPC as an RDS PostgreSQL database, configure Retool to connect to RDS using the private DNS endpoint, and set up an internal load balancer so the team can access Retool via an internal URL.
Copy this prompt to try it in Retool
Set up a staging and production Retool environment
Run separate Docker Compose deployments for staging and production Retool instances, each connecting to their respective database environments. Use Retool's source control integration with Git to promote app changes from staging to production, maintaining a safe development workflow.
Set up two Docker Compose deployments of Retool on separate servers — one for staging connected to a staging database, one for production — with shared app definitions managed through Git source control sync.
Copy this prompt to try it in Retool
Run Retool for HIPAA-compliant healthcare applications
Deploy Retool inside a HIPAA-compliant AWS environment (no PHI leaves the VPC) to build internal tools for healthcare teams. Self-hosted Retool allows PHI data from clinical databases to flow through Retool queries without transiting Retool's cloud infrastructure, satisfying HIPAA requirements.
Deploy self-hosted Retool inside a HIPAA-compliant AWS VPC with encrypted EBS volumes, connect to an RDS database containing patient records, and configure Retool audit logging to CloudWatch Logs for HIPAA audit trail requirements.
Copy this prompt to try it in Retool
Troubleshooting
Containers start but Retool web UI fails to load (connection refused or 502)
Cause: The api container is still starting up, the nginx/Caddy reverse proxy is misconfigured, or the api container crashed due to a configuration error. Startup can take 30-60 seconds on first run.
Solution: Run docker compose logs api to check for errors. Common causes: ENCRYPTION_KEY or JWT_SECRET missing from .env, Postgres connection failure if POSTGRES_PASSWORD is wrong, or port 3000 already in use. If nginx returns 502, verify Retool is actually listening on port 3000 with: docker compose exec api curl http://localhost:3000/health.
1# Check if Retool API is healthy:2docker compose exec api wget -qO- http://localhost:3000/healthResource connections succeed from Retool Cloud but fail from self-hosted
Cause: Self-hosted Retool is on a different network path than Retool Cloud. The database may have firewall rules allowing Retool Cloud's IP ranges but not the self-hosted server's IP address.
Solution: Verify the database allows connections from your Retool server's IP address. For internal databases in the same VPC, no firewall changes are needed. For external databases or databases on other cloud accounts, add the Retool server's IP to the database security group or firewall allowlist.
After updating Docker image version, all stored resource credentials stop working
Cause: The ENCRYPTION_KEY changed between deployments, making previously encrypted credentials unreadable. This happens if the .env file was regenerated or ENCRYPTION_KEY was accidentally changed during an update.
Solution: Restore the original ENCRYPTION_KEY from your secure backup. All resource credentials are encrypted using this key — if the key changes, credentials become unreadable and must be re-entered. Never regenerate ENCRYPTION_KEY on an existing Retool deployment.
Retool Workflows are not executing on schedule (scheduled triggers not firing)
Cause: The jobs-runner container is not running, or it is not connected to the same internal Postgres database as the api container. Workflows require the jobs-runner service to be healthy.
Solution: Run docker compose ps to verify the jobs-runner container is running and healthy. Check its logs with docker compose logs jobs-runner for connection errors. Ensure the POSTGRES_DB, POSTGRES_PASSWORD, and related database environment variables are identical in both the api and jobs-runner containers.
1# Check jobs-runner container health:2docker compose ps jobs-runner3docker compose logs jobs-runner --tail=50Best practices
- Back up ENCRYPTION_KEY and JWT_SECRET immediately after generating them — store in AWS Secrets Manager, HashiCorp Vault, or a secure password manager. Loss of these keys requires re-entering all resource credentials.
- Use a dedicated external PostgreSQL database (AWS RDS, Cloud SQL) for Retool's internal data rather than the bundled Postgres container in production — the bundled container loses data if the Docker host fails
- Pin Docker image versions to specific release tags in docker-compose.yml rather than using 'latest' — this gives you controlled update windows and the ability to roll back easily
- Set up automated daily backups of Retool's internal Postgres database using pg_dump, even if you use the bundled container — app definitions, user accounts, and audit logs are stored there
- Place a reverse proxy (nginx or Caddy) in front of Retool for SSL termination, health checks, and request buffering — never expose Retool's Node.js process directly on port 443
- Monitor container health with Docker healthchecks or an external monitoring tool — alert on container restarts or the api container becoming unhealthy before users experience outages
- Use Retool's source control sync (Git) to export app definitions to a repository — this provides an additional backup layer independent of the Postgres database
Alternatives
Jenkins is for building Retool app deployment pipelines and CI/CD workflows, while Docker handles the actual Retool server infrastructure and hosting.
Git integrates with self-hosted Retool for version-controlling Retool app definitions, complementing the Docker deployment with a code review and change management workflow.
CircleCI can automate Docker image builds and deployment scripts for Retool updates, adding automated testing and deployment pipelines to your self-hosted infrastructure.
Frequently asked questions
What is the minimum server size for running Retool with Docker?
For development or small teams, a server with 4 GB RAM and 2 vCPUs is sufficient. For production with 10+ active users, Retool recommends at least 8 GB RAM and 4 vCPUs. The db_connector container uses the most memory as it maintains connection pools to all configured databases. Monitor memory usage after onboarding your team and scale up if needed.
Can I run self-hosted Retool without internet access?
Partial offline functionality is possible but not fully supported. Retool's Docker images must be pulled from Docker Hub, which requires internet access initially. The running application requires internet access for license validation on startup. Some features (AI assistance, third-party OAuth flows) also require internet access. For air-gapped deployments, contact Retool's enterprise team for specific guidance.
How does self-hosted Retool handle database connection security?
All database connections are made from Retool's db_connector container, running inside your infrastructure. Credentials are stored encrypted in Retool's internal Postgres database using the ENCRYPTION_KEY. Connections support SSL/TLS for all database types. Since the db_connector runs inside your VPC, connections to internal databases never traverse the public internet.
Should I use Docker Compose or Kubernetes for production Retool?
Docker Compose is suitable for small to medium teams (under 50 users) on a single server. For larger deployments requiring high availability, automatic failover, or horizontal scaling, use Kubernetes with Retool's official Helm chart (github.com/tryretool/retool-helm). Kubernetes also enables zero-downtime updates using rolling deployments.
Can self-hosted Retool connect to Retool Cloud services like Retool Database?
No. Retool Database, Retool Storage, and Retool Vectors are managed cloud services only available on Retool Cloud. Self-hosted Retool does not have access to these managed services. Self-hosted deployments use the bundled Postgres container or an external database for Retool's internal data.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation