Skip to content

Comments

feat: add support for external PostgreSQL and Redis services#3707

Open
VidhyaSanjeevi wants to merge 1 commit intoDokploy:canaryfrom
VidhyaSanjeevi:feat/external-database-redis
Open

feat: add support for external PostgreSQL and Redis services#3707
VidhyaSanjeevi wants to merge 1 commit intoDokploy:canaryfrom
VidhyaSanjeevi:feat/external-database-redis

Conversation

@VidhyaSanjeevi
Copy link

@VidhyaSanjeevi VidhyaSanjeevi commented Feb 14, 2026

Summary

Add environment variable support for connecting to external PostgreSQL and Redis instances instead of the built-in Docker Swarm services. This enables deploying Dokploy on Kubernetes and other container orchestrators where running Docker Swarm services for infrastructure isn't practical or possible.

Closes #2611

Motivation

When deploying Dokploy on Kubernetes (e.g., K3s, EKS, GKE), the built-in Docker Swarm services for PostgreSQL and Redis can't be used. Additionally, production environments often prefer managed database services (RDS, Cloud SQL, etc.) for reliability, backups, and scaling.

The current codebase already supports \DATABASE_URL\ for the database connection (as of the recent centralization in \packages/server/src/db/constants.ts), but there was no way to:

  1. Skip creating the built-in Docker Swarm Postgres/Redis services when external services are configured
  2. Connect to external Redis with authentication, custom ports, or TLS
  3. Prevent runtime env vars from being hardcoded at build time by esbuild
  4. Perform backups/restores against external PostgreSQL instances

Changes

Core

  • **\packages/server/src/db/constants.ts**: Added \isExternalDatabase()\ and \isExternalRedis()\ helper functions, exported for use across the codebase
  • **\packages/server/src/setup/postgres-setup.ts**: Skip Docker Swarm service creation when \DATABASE_URL\ points to a non-internal host
  • **\packages/server/src/setup/redis-setup.ts**: Skip Docker Swarm service creation when \REDIS_URL\ or external \REDIS_HOST\ is configured

Redis Connection

  • **\�pps/dokploy/server/queues/redis-connection.ts**: Support \REDIS_URL\ (full connection string with auth/TLS), \REDIS_PORT, and \REDIS_PASSWORD\ env vars

Build

  • **\�pps/dokploy/esbuild.config.ts*: Prevent all database/Redis env vars (\DATABASE_URL, \REDIS_URL, \POSTGRES_, \REDIS_*) from being replaced at build time, ensuring they resolve at runtime

Settings API

  • **\�pps/dokploy/server/api/routers/settings.ts**: Guard \cleanRedis\ and
    eloadRedis\ admin operations when using external Redis

Backup & Restore

  • **\packages/server/src/utils/backups/web-server.ts**: Support external PostgreSQL via direct \pg_dump\ with \PGPASSWORD\ env var
  • **\packages/server/src/utils/restore/web-server.ts**: Support external PostgreSQL via direct \psql/\pg_restore\ with \PGPASSWORD\ env var

Documentation

  • *.env.example* and **.env.production.example**: Added documentation for all external DB/Redis env vars

New Environment Variables

Variable Description Example
\DATABASE_URL\ Full PostgreSQL connection URL (already supported) \postgres://user:pass@host:5432/db\
\POSTGRES_PASSWORD_FILE\ Docker secret path for DB password (already supported) /run/secrets/postgres_password\
\REDIS_URL\ Full Redis connection URL with auth/TLS \
edis://:password@host:6379\ or \
ediss://...\
\REDIS_HOST\ Redis hostname (already existed) \my-redis.example.com\
\REDIS_PORT\ Redis port (new) \6379\
\REDIS_PASSWORD\ Redis password (new) \secret\

Backward Compatibility

All changes are fully backward compatible:

  • Without any new env vars, behavior is identical to current (uses built-in Docker Swarm services)
  • The \isExternalDatabase()\ check uses hostname comparison (!= dokploy-postgres)
  • The legacy hardcoded credentials fallback path is unchanged
  • Existing \REDIS_HOST\ env var continues to work as before

Testing

  • Verified backward compatibility: without new env vars, setup creates built-in Postgres/Redis services as before
  • Tested with external PostgreSQL via \DATABASE_URL\ pointing to managed instance
  • Tested with external Redis via \REDIS_URL\ with password authentication

Greptile Overview

Greptile Summary

This PR adds support for connecting Dokploy to external PostgreSQL and Redis instances via environment variables (DATABASE_URL, REDIS_URL, REDIS_HOST, REDIS_PORT, REDIS_PASSWORD). When these are configured, the built-in Docker Swarm service creation is skipped, and backup/restore operations use direct CLI tools instead of docker exec. The esbuild config is updated to prevent these env vars from being inlined at build time, and admin Redis operations are guarded against external instances.

Key issues found:

  • Command injection in backup/restore: Credentials extracted from DATABASE_URL (host, port, user, database) are interpolated directly into shell command strings passed to execAsync() without any escaping. The codebase already uses shell-quote elsewhere for this purpose. While the threat model is limited to operator-controlled env vars, this is a defense-in-depth concern that should be addressed before merging.
  • SQL injection in restore: The creds.database value is interpolated into SQL string literals within shell commands (e.g., WHERE datname = '${creds.database}'), creating a potential SQL injection vector.
  • Code duplication: getPostgresCredentials() is identically duplicated across backups/web-server.ts and restore/web-server.ts. Consider extracting it to the shared constants module.
  • Minor: isExternalDatabase() returns true for the default development DATABASE_URL (which uses localhost), which may be unexpected for contributors running the setup script locally.

Confidence Score: 2/5

  • This PR introduces shell command injection vectors in backup/restore code paths that should be addressed before merging.
  • Score of 2 reflects the command injection risk in the backup and restore files where user-controllable values from DATABASE_URL are interpolated directly into shell commands without escaping. While the threat model is somewhat limited (env vars are set by operators, not end users), the codebase already has the shell-quote library available and uses it in other files, so there is no reason not to apply it here. The rest of the PR (setup guards, Redis connection refactor, esbuild config, settings guards) is well-implemented.
  • Pay close attention to packages/server/src/utils/backups/web-server.ts and packages/server/src/utils/restore/web-server.ts for unsanitized shell command interpolation.

Last reviewed commit: ee06956

(4/5) You can add custom instructions or style guidelines for the agent here!

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

10 files reviewed, 5 comments

Edit Code Review Agent Settings | Greptile

@VidhyaSanjeevi VidhyaSanjeevi force-pushed the feat/external-database-redis branch 2 times, most recently from 6618c61 to ffb49d7 Compare February 14, 2026 10:00
Add environment variable support for connecting to external PostgreSQL and
Redis instances instead of the built-in Docker Swarm services. This enables
deploying Dokploy on Kubernetes and other container orchestrators where
running Docker Swarm services for infrastructure isn't possible.

Changes:
- Skip built-in Postgres/Redis Docker Swarm service creation when external
  services are configured (DATABASE_URL pointing to external host, or
  REDIS_URL/REDIS_HOST set)
- Add REDIS_URL support for full connection string with auth, TLS, port
- Add REDIS_PORT and REDIS_PASSWORD individual env var support
- Prevent runtime env vars (DATABASE_URL, REDIS_URL, POSTGRES_* etc) from
  being hardcoded at build time by esbuild
- Update backup/restore to work with external PostgreSQL via pg_dump/
  pg_restore using PGPASSWORD env var
- Guard cleanRedis/reloadRedis admin operations when using external Redis
- Export isExternalDatabase() and isExternalRedis() helpers from constants
- Update .env.example and .env.production.example with documentation

Closes Dokploy#2611
@VidhyaSanjeevi VidhyaSanjeevi force-pushed the feat/external-database-redis branch from ffb49d7 to 46267b9 Compare February 14, 2026 10:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update installation script to use docker secrets for DATABASE_URL

1 participant