docker compose up -d

Docker Compose Generator

Turn a service into a compose file. Set the image, ports, volumes, and environment once and get YAML you can drop straight into a stack.

host:container, comma separated. Prefix with 127.0.0.1: to keep it local.
One per line, host:container[:ro].
One KEY=value per line.

Bind mounts, ports, and the two things that bite

Two mistakes account for most self-hosting frustration. First, publishing a port as 8080:80 binds it to every interface, so the service is reachable from your whole network and, if the machine is exposed, the internet, regardless of what your firewall thinks: use 127.0.0.1:8080:80 and put a reverse proxy in front. Second, bind-mounted directories are created as root if they do not exist, so a container running as UID 1000 then cannot write to them. Create the directories yourself with the right owner before the first up.

Generate a docker-compose.yml for self-hosted services

This Docker Compose generator produces a service definition with the parts a self-hosted application actually needs: bind-mounted config and data volumes, port mappings, a timezone and PUID/PGID environment, a restart policy that survives reboots, and optional hardening through read_only, no-new-privileges, and a healthcheck. Use the docker run builder if you would rather have a one-line command instead.

Docker Compose FAQ

Do I still need the version key at the top?

No. The version field is obsolete in Compose V2 and current versions warn if you include it. Start the file at services: and everything works.

What are PUID and PGID and does every image use them?

They are a convention popularised by linuxserver.io images, which read those variables and run the process as that user so bind-mounted files end up owned by you rather than root. Images outside that ecosystem generally ignore them and use the user: key instead. Check the image documentation.

Should I use named volumes or bind mounts?

Bind mounts for anything you want to read, edit, or back up with normal tools, which for self-hosting is usually configuration and data. Named volumes for databases and anything where you do not care about the on-disk layout, since Docker manages permissions and they perform better on some storage drivers.

How do I put this behind a reverse proxy?

Bind the port to 127.0.0.1 or drop the ports section entirely and attach the container to a shared external network the proxy is also on. Then proxy to the container name and internal port. The reverse proxy config builder generates the nginx or Caddy side.