DashCaddy Documentation

Install Plex

Stream your personal media collection anywhere

Category: MediaDifficulty: EasyDocker image: plexinc/pms-docker:latest

What is Plex?

Stream your personal media collection anywhere

Plex ships as a self-contained Docker image that DashCaddy provisions with one click. DashCaddy handles the container lifecycle, DNS record, Caddy reverse-proxy entry, and HTTPS certificate so you can focus on using Plex, not installing it.

Prerequisites

  • A running DashCaddy host with the dashboard accessible (default URL: https://status.sami; configurable via the dashboardHost setting in config.json).
  • You must be signed in to the dashboard with an admin session, or have an API key with admin scope (POST /api/v1/auth/keys to create one).
  • A host path containing your media. Default suggestion: /media. The deploy form / API payload config.mediaPath must be readable by the container UID (usually 1000).
  • A Plex Claim Token — get one from https://plex.tv/claim right before you click Deploy.
  • For HTTPS with a real certificate, Technitium DNS must be configured and the host must have port 80/443 reachable from the internet. Otherwise DashCaddy will fall back to direct-IP access or a self-signed certificate.

Install via the DashCaddy dashboard

  1. Sign in at https://status.sami (or your host's dashboard URL).
  2. Click the 📱 App Selector button on the dashboard home page.
  3. Pick Plex from the Media category.
  4. Fill in the deployment form: subdomain (default suggestion: plex), host port (default: 32400), and the media library path, and the claim token.
  5. Click Deploy. DashCaddy will pull the image, create persistent volumes, write a Caddy route, create the DNS record, and wait up to 30 seconds for the container's health check (/web/index.html) to pass.
  6. When the dashboard shows the service as Running, the URL (built from your subdomain and configured TLD) is clickable. The deploy API returns a synchronous response with {success, containerId, url, message, setupInstructions} — there is no separate status-poll endpoint; the dashboard updates live.

Install via the REST API

Authenticate with an API key (or a JWT minted via POST /api/v1/auth/jwt). Send as X-API-Key: dk_... or Authorization: Bearer <jwt>.

curl -X POST https://status.sami/api/v1/apps/deploy \\ -H "X-API-Key: dk_your_api_key" \\ -H "Content-Type: application/json" \\ -d '{ "appId": "plex", "config": { "subdomain": "plex", "port": 32400, "mediaPath": "/media", "plexClaimToken": "<get fresh token from https://plex.tv/claim>" } }'

The full body schema is in src/utilities/validate.js (Joi schema appDeploy). All config.* fields except subdomain are optional. Notable options:

  • config.port — host port (1–65535). Defaults to the template's defaultPort.
  • config.mediaPath — host directory to mount as the media library.
  • config.plexClaimToken — Plex claim token (when the upstream service needs one).
  • config.useExisting: true + existingContainerId — attach DashCaddy metadata to an already-running container instead of pulling a new image.
  • config.tailscaleOnly: true — restrict the reverse-proxy entry to your Tailscale network.
  • config.allowedIPs — array of CIDR ranges allowed past the reverse proxy.
  • config.createDns: false — skip DNS record creation (use when the subdomain already resolves).
  • config.resources{memory, cpus} limits applied to the container.

Install via the AI Intent Router (returns a structured intent)

The Intent Router returns a structured intent, not a deployed container. To deploy via AI, send natural language to:

curl -X POST https://status.sami/api/v1/ai/intent \\ -H "X-API-Key: dk_your_api_key" \\ -H "Content-Type: application/json" \\ -d '{ "message": "Deploy Plex on my home host and expose it at plex.sami" }'

The response includes intent, action, parameters, and followup — your client (or the MCP server) must then call POST /api/v1/apps/deploy with those parameters to actually provision the container.

Install via the MCP Server

For AI agents (Claude Desktop, Hermes, etc.) configure the MCP server (src/mcp/mcp-server.js) with:

DASHCADDY_URL=https://status.sami:3001  # internal API URL, may differ from dashboard URL DASHCADDY_API_KEY=dk_your_api_key

The server exposes dashcaddy_deploy_app. Note: this tool writes the Caddy route and creates the services.json entry, but it does NOT pull the Docker image or start the container. You must run docker pull plexinc/pms-docker:latest and start the container yourself for the URL to actually serve traffic. For a fully-managed deployment, call POST /api/v1/apps/deploy directly from your agent.

Post-install: first-run checklist

  1. Get your claim token from https://plex.tv/claim
  2. Add your media libraries in the web interface
  3. Configure remote access settings

Media library path notes

The media mount path you pass as mediaPath in the deploy payload is mounted as /data inside the container. Bind a host directory containing your media library (movies, TV shows, music, etc.).

  • UID/GID: Plex runs as a non-root user. If you see permission errors in the dashboard Logs tab, run chown -R 1000:1000 /media on the host.
  • Multi-library: bind the parent folder and let Plex discover subfolders.

Plex Claim Token

Get from https://plex.tv/claim - expires in 4 minutes!

Pass it as plexClaimToken inside the config object of the deploy payload (NOT as an environment variable).

Heads up: Plex Claim Token expires within minutes. Get a fresh one from https://plex.tv/claimright before you click Deploy.

Volumes and persistent data

DashCaddy creates these volume mounts in the container spec:

  • /opt/plex/config:/config
  • /opt/plex/transcode:/transcode
  • MEDIA_PATH:/data

All paths are host paths (left side) mapped into the container (right side). Restarting the container preserves data; reinstalling the template preserves it unless you explicitly pass config.useExisting: false AND wipe the volume. Bind mounts use the host-path conventions above (e.g. /opt/plex/config becomes a bind mount to the host directory of the same path).

Environment variables

  • PLEX_CLAIM
  • ADVERTISE_IP
  • PLEX_UID
  • PLEX_GID

These are baked into the template at deploy time and shipped to the container. The deploy handler does NOT allow overriding them via the API payload — to change them you must edit the template definition in dashcaddy-api/src/docker/app-templates.js.

Updating the image

There is no built-in auto-update — DashCaddy does NOT poll for new image digests. To pull a new version:

  1. SSH into the DashCaddy host and run docker pull plexinc/pms-docker:latest.
  2. Restart the container: docker restart <containerId> (find the ID via GET /api/v1/services or the dashboard).
  3. Or deploy Watchtower from this catalog (separate template that polls Docker Hub and updates other containers automatically, default schedule 0 0 4 * * * = 04:00 daily).

Backups

The default backup policy includes the entire /app/data/ directory (services, config, credentials, stats) AND all Docker volumes. Backups are scheduled via backup-config.json — the default schedule is configurable, not "nightly" out of the box. To restore on a fresh host, redeploy the same template and then call POST /api/v1/apps/{appId}/restore with a backup ID from GET /api/v1/backups/history.

Troubleshooting

Common issues with Plex:

  • Container won't start: check the dashboard's Logs panel. Most startup failures are permission errors on the host-path volume.
  • Library shows empty: confirm mediaPath is readable by the container UID and that the directory contains the file extensions Plex indexes.
  • Account linking fails: your claim token probably expired. Get a new one and redeploy.
  • URL not reachable after deploy: the Caddy route was written but DNS hasn't propagated, or port 80/443 is firewalled. Check GET /api/v1/dns/records and systemctl status caddy on the host.
  • Health check timeout (deploy returns 30s after start): the container is starting but /web/index.html is not returning 200. Inspect docker logs <containerId> directly.

For layer-by-layer diagnostics, see the Troubleshooting guide.


Template ID: plex. Source: dashcaddy-api/src/docker/app-templates.js.