Skip to main content

Dokploy's One-Click Templates Deploy Over HTTP: The TLS Gap in the Catalog and the One-Field Fix

9 min readDora NodaDora Noda
Share
On this page

One click installs n8n from Dokploy's template catalog. Zero clicks get you HTTPS. Every app deployed from the catalog — all 514 blueprints — lands on plain HTTP until a human opens the Domains tab, attaches a real domain, and flips the HTTPS toggle by hand. The template format itself has nowhere to even ask for a certificate.

Here is the whole argument up front: Dokploy's per-app TLS machinery works fine, but its one-click catalog can't reach it, so template fleets pay a per-service HTTPS tax that competing platforms automated away years ago. The fix is one optional field on the template schema. The table below is the summary; the rest of this post is the evidence.

MomentDokploy template deployCoolify one-click deployRender / hosted PaaS
URL on first boothttp:// traefik.me domainhttps:// with auto Let's Encrypthttps:// generated domain, day one
Asking for TLS in the template definitionImpossible — no schema fieldAutomatic on any https:// domainNot the user's job at all
Human steps to reach HTTPSOwn domain + DNS + Domains tab + toggle, per servicePoint DNS, prefix https://Attach domain, done
Cost shapeLinear in number of template appsNear-zero per appZero

What a template deploy actually produces

A Dokploy blueprint is two things: a docker-compose.yml with the service definitions, and a template.toml carrying the Dokploy-specific wiring — variables, environment, and the [[config.domains]] routing entries that tell the Traefik reverse proxy where each service lives. Here is the real routing block from the catalog's n8n blueprint:

toml
[variables]
main_domain = "${domain}"
 
[[config.domains]]
serviceName = "n8n"
port = 5_678
host = "${main_domain}"

Read that block the way Traefik does: service name, port, host. There is no https flag, no certificateResolver, no TLS section of any kind — and that is not an omission in one blueprint, it is the schema. No template in the catalog can declare "serve this over HTTPS," because the format has no words for it. The gap is tracked upstream as Dokploy/templates#1094.

What fills ${domain} at install time is a generated traefik.me subdomain, and those are HTTP. This is documented behavior, not a bug report: when users asked why template services had no HTTPS (Dokploy/dokploy#216), the maintainer answer was that templates are served with traefik.me domains which are HTTP, and anyone wanting HTTPS should attach their own domain per the domains guide. Fair enough as a statement of how it works — but notice what it concedes. The catalog's default output is unencrypted, and encryption is a manual post-install project, one service at a time.

None of this is a knock on Dokploy's actual TLS stack. For a hand-built app, the flow is genuinely good: open the app, go to Domains, add a host, flip the HTTPS toggle, pick Let's Encrypt, and issuance plus renewal are handled from then on. Traefik does the ACME work; the certificate renews itself. The problem is purely a reach problem: the one-click path — the path a team standardizes on precisely to avoid per-service snowflakes — cannot touch any of that machinery.

What the gap costs a team standardizing on templates

Nobody adopts a template catalog to deploy one app. The team that standardizes on catalog deploys is running n8n for automation, a Postgres admin UI, an uptime monitor, a wiki, a form backend — five, ten, twenty small services that were each supposed to cost one click. For every one of them, "reach HTTPS" is the same manual checklist:

  1. Buy or pick a subdomain and point DNS at the Dokploy host.
  2. Open the compose service's Domains tab and register host, path, and container port.
  3. Enable HTTPS with Let's Encrypt and wait for issuance.
  4. Verify renewal is actually scheduled, not just issued.

None of these steps is hard. All of them are per-service, per-deploy, and human. At ten template apps that is forty hand-executed steps standing between the team and "everything we run is encrypted" — and every step is a chance to end up with the failure mode the catalog default quietly normalizes: an internal tool that stays on HTTP because it works fine on HTTP and nobody got around to step two.

The cost is not just hygiene. Real integrations refuse to work without HTTPS, and they tend to be exactly the integrations template apps exist for:

  • OAuth callbacks. An n8n or wiki instance behind Google/GitHub OAuth needs an https:// redirect URI. HTTP-only means auth simply does not complete.
  • Webhooks. Stripe, GitHub, and most signed-webhook senders require HTTPS endpoints. An automation app that cannot receive webhooks is a very expensive cron runner.
  • Secure cookies and mixed content. Session cookies flagged Secure never transmit over HTTP, so "log in over HTTP, break mysteriously" is the support ticket this gap manufactures. Anything embedding the tool in an HTTPS page hits mixed-content blocking too.

Multiply each of those by the catalog count and the picture sharpens: the team that chose templates to move fast now owns a standing backlog item — "HTTPS-ify the catalog apps" — that re-opens every time someone installs one more blueprint or re-deploys one they already fixed. A platform whose default output needs post-install remediation per unit is taxing exactly the behavior it wants to encourage.

How everyone else handles the same moment

The comparison matters because nobody in this space treats first-boot HTTP as acceptable anymore — including Dokploy itself for non-template apps. The difference is only whether the one-click path participates.

Coolify makes TLS declarative at the domain string: set a domain with the https:// prefix and the proxy issues a Let's Encrypt certificate automatically via the ACME HTTP-01 challenge. There is no separate "now do TLS" step because the scheme prefix is the TLS request. A one-click service with an https:// domain boots encrypted.

Render and the hosted PaaS tier removed the question entirely. Generated domains serve HTTPS from the first boot; custom domains get certificates issued and renewed with no toggle to remember. The user never expresses "I want TLS" because there is no supported way to not have it.

Dokploy for hand-built apps sits between the two: automatic issuance and renewal once a human flips the toggle per domain. Good machinery, manual reach — which is precisely why the template gap stings. The platform already built the hard part (ACME integration, Traefik wiring, renewal). The catalog just has no address for it.

For a sense of scale on the miss: Dokploy ships around 514 blueprints against Coolify's comparable catalog and CapRover's 354 one-click apps, with roughly 36,500 GitHub stars to Coolify's 60,500. The catalog is a flagship surface — it is the thing a new user touches in the first ten minutes. First-boot HTTP on the flagship surface is the kind of default that teaches every evaluator, correctly or not, what the platform considers finished.

The smallest upstream fix that closes it

This is a one-field problem, which is what makes it worth writing about rather than just complaining about. The [[config.domains]] entries already carry serviceName, port, and host. The fix is an optional TLS declaration on the same block — something like:

toml
[[config.domains]]
serviceName = "n8n"
port = 5_678
host = "${main_domain}"
https = true

with Dokploy honoring it at deploy time by doing exactly what the manual Domains-tab flow does today: register the route with its Traefik certificate resolver and request the Let's Encrypt certificate. Concretely, the implementation surface is small because every hard piece already exists:

  • The ACME path exists. The manual toggle already drives Traefik's letsencrypt certificate resolver per router. Honoring https = true means stamping the same labels the Domains tab stamps — no new issuance infrastructure.
  • Back-compat is free. Optional field, default false. Every existing blueprint behaves exactly as today; catalog maintainers opt services in one line at a time.
  • Validation is local. The failure mode to guard is https = true on a generated traefik.me host, where HTTP-01 issuance against a wildcard-ish shared domain cannot succeed. Dokploy should reject that combination at template-install validation with a message naming the fix ("set a custom domain to enable HTTPS"), rather than failing silently mid-issuance.

Two honest edge cases belong in the design. First, HTTP-01 challenges require the host to actually resolve to the Dokploy server, so install-time issuance can fail for DNS that has not propagated yet — the deploy should treat TLS as a reconciled state (retry issuance, show "pending certificate" in the UI) rather than a blocking install step. Second, teams behind DNS that cannot do HTTP-01 (wildcard or proxied setups) will eventually want a dnsChallenge escape hatch, mirroring the existing cert-resolver customization discussion upstream — but that is a follow-up, not a reason to hold the common case hostage. Ship the boolean, reconcile asynchronously, add DNS-01 later.

Until that lands, the workaround for template-standardized teams is procedural, not technical: never accept the generated domain as the final state. Make "custom domain + HTTPS toggle verified" part of the team's definition of a finished template install — a checklist item in the runbook, ideally verified by a periodic audit that curls every catalog app's URL and flags anything still answering on port 80. It is toil, but named toil beats the silent kind.

The seam this reveals

Step back and the TLS gap is an instance of a general single-box-PaaS seam: the catalog optimizes for install-time delight (one click, running app) while the platform's production-readiness features — TLS, backups, access control — live one manual step away, reachable only through the dashboard. Every self-hosted panel has some version of this seam. The platforms that win teams are the ones that keep moving capabilities into the declarative definition until the one-click output and the production output are the same thing.

That is also the standard a multi-machine PaaS has to clear from day one: per-service TLS that is automatic, per-tenant, and expressed in the app definition rather than applied afterward by a human with a checklist. A git-push platform cannot afford forty hand-executed steps per ten services when the fleet holds hundreds of tenant apps — the reconciliation loop has to own certificates the way it owns routing, because at fleet scale there is nobody available to click the toggle.

Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. Star the repo on GitHub or deploy your first app today.

Related articles

Run this on infrastructure you own

bex is the open-source, AI-native Render alternative — push a git repo and get a running HTTPS service on your own machines.

Get started with bex