← All posts
7 min readDashCaddy Team

One-Click Docker Deployment: From Blank Server to Running App

one-click docker deploymentdeploy docker appdocker deployment tooldocker templatesdocker install

"One-click deploy" sounds like marketing until you have done the manual version. Then it sounds like a description of a very long list of things you no longer have to do.

This article breaks down what actually happens between "I want to run Immich" and "Immich is live at a real URL with a valid certificate" — and why doing it by hand is where most homelab evenings go.

The nine things that happen when you deploy a container

A container is the easy part. Everything around it is the work:

  1. Pick the image and pin it. :latest is convenient and occasionally a surprise. A platform should know the image it is going to pull.
  2. Decide the persistent paths. Which directories must survive a container rebuild? Get this wrong and your photo library lives inside a container that disappears on the next update.
  3. Map ports. Host port 8080 is taken. Again.
  4. Set environment variables and secrets. Database passwords, admin users, API tokens, claim tokens.
  5. Create or attach a network. So the container can talk to its database and nothing else it should not.
  6. Write a reverse-proxy entry. Caddy or Nginx config that routes app.example.com to the right container port.
  7. Create the DNS record. The subdomain has to resolve, and it has to resolve to the right host.
  8. Issue and install a TLS certificate. Then renew it forever.
  9. Wait for a health check. "Started" is not "working." The container can be running and still return 500s.

You can do all nine by hand. People do. It is also the reason so many homelabs have a service that has been "almost done" since March.

What "one-click" should mean

A deployment button that only covers step 1 is not one-click; it is docker run with a nicer font. Genuine one-click deployment covers the whole list, in order, with a real result at the end: a URL that opens, over HTTPS, with a green health check.

DashCaddy's deploy path does exactly that. You pick a template from the app catalog, fill in the few values that are genuinely yours (a subdomain, maybe a media path or a claim token), and press Deploy. DashCaddy then:

  • pulls the pinned image;
  • creates the persistent volumes;
  • attaches the container to its network;
  • writes the reverse-proxy route;
  • creates the DNS record;
  • issues the certificate;
  • and polls the app's health endpoint before reporting success.

If the health check does not pass, you get a failure — not a container that is technically running and practically broken.

The same deploy, two ways

Every template is available through the dashboard and through the REST API. The API path is what makes automation possible. A deploy is a single authenticated POST whose body names the app and the handful of settings that matter:

curl -X POST https://your-host/api/v1/apps/deploy \
  -H "X-API-Key: <your key>" \
  -H "Content-Type: application/json" \
  -d '{
    "appId": "immich",
    "config": { "subdomain": "photos" }
  }'

Because the endpoint is a normal REST route, the same call works from a shell script, a CI job, or an AI assistant connected over the MCP server. The install guides in the catalog document the exact payload for each app — see the Plex guide or the Jellyfin guide for the pattern.

Where manual deployment still makes sense

Automation is not a religion. Reach for the manual path when:

  • you are evaluating a new app and want to poke at it without a permanent footprint;
  • the image needs a custom build or a patch the template does not cover;
  • you are debugging and need to run the container with different flags than the template uses.

That is also why a platform should let you attach to an existing container rather than forcing every service to be born inside it. DashCaddy supports adopting an already-running container so existing work is not thrown away.

A deployment checklist that fits on a napkin

Whatever tool you use, verify these five things after the first deploy:

  • The URL opens over HTTPS with a valid, non-self-signed certificate.
  • The data path is a host directory you recognize — check with docker inspect if unsure.
  • The DNS record is yours and points where you think it does.
  • The health check is green, not merely "running."
  • A restart brings it back. reboot the host and confirm the service returns without you.

If all five hold, you have done real one-click deployment, regardless of which tool did it.

Getting started

Install DashCaddy on any Linux host:

curl -fsSL https://get.dashcaddy.net | bash

Then open the dashboard, browse the catalog, and deploy something. The installation docs cover host requirements, and First Service walks through the very first deploy in detail.

Once the first app is up, the natural next questions are how to access it remotely and how to know when it goes down.