I'd rather not touch the command line.
You'll install Docker once, then Arcane, and manage everything else from a web page after that. Arcane is a Docker manager with buttons instead of commands.
- One-time terminal setup, then never again
- Start, stop and update containers by clicking
- Paste stacks in, watch logs, see what's broken
- Best if this is your first server
I already have Docker. Just give me the files.
Skip all the setup. Use the generator to pick your services and download a Compose file, or run the install script and answer a few questions.
- Nothing to install beyond what you have
- Generator in the browser, or script in a terminal
- Dependencies and secrets handled for you
- Best if you know your way around a stack
Setting up with Arcane
Docker doesn't come with a screen. Arcane gives it one — a web page where your containers are things you can see and click, rather than commands you have to remember. You'll need the terminal for the first two steps, then you're done with it.
-
Install Docker
This part depends on what you're running, so it has its own page with proper instructions for each system — including the two Windows and macOS gotchas that are much easier to handle now than to unpick later.
WindowsWSL2 and Docker Desktop, plus where to keep your files so scans aren't painfully slow.macOSDocker Desktop or lighter alternatives, folder sharing, and Apple Silicon notes.LinuxOne command, plus hardware transcoding — the only platform where that works.NASSynology, QNAP, unRAID and TrueNAS, with their own paths and reserved ports.Come back here once
docker run hello-worldworks. -
Install Arcane
Arcane needs two secrets of its own. Generate them, then paste them into the file you're about to make.
# Run this twice — you need two different values openssl rand -base64 32Make a folder and a Compose file:
mkdir -p ~/arcane && cd ~/arcane nano docker-compose.yml
Paste this in, replacing the two secrets and the timezone:
services: arcane: image: ghcr.io/getarcaneapp/arcane:latest container_name: arcane ports: - "3552:3552" volumes: - /var/run/docker.sock:/var/run/docker.sock - arcane-data:/app/data - ./projects:/app/data/projects environment: - APP_URL=http://localhost:3552 - PUID=1000 - PGID=1000 - ENCRYPTION_KEY=paste-your-first-secret - JWT_SECRET=paste-your-second-secret restart: unless-stopped volumes: arcane-data:Save with
Ctrl+O, exit withCtrl+X, then start it:docker compose up -d
Open
http://your-server-address:3552. Create your admin account on first visit. That's the last command you need to run. -
Find your way around
Before adding anything, have a look at what Arcane shows you. Everything below is a page in the sidebar.
ContainersEvery running service. Start, stop, restart and remove them here.ProjectsYour Compose stacks. This is where you'll paste the generated file.ImagesThe downloaded application templates. Update and clean up old ones.VolumesWhere container data actually lives on disk.NetworksHow containers talk to each other.LogsWhat a container is saying. The first place to look when something breaks. -
Get your stack file
Now choose what you want to run. The generator asks a few questions and gives you a Compose file and an environment file.
You'll end up with two things that matter:
docker-compose.yml, which describes your services, and.env, which holds your paths and passwords. -
Deploy it in Arcane
In Arcane, go to Projects and create a new one. Give it a name like
media. Paste yourdocker-compose.ymlinto the Compose field and your.envcontents into the environment field.Press deploy. Arcane pulls the images and starts everything. The first run downloads several gigabytes, so give it a few minutes.
If a container keeps restarting, open its logs before changing anything. The answer is almost always in there, and it's usually one of three things: a folder that doesn't exist, a permissions mismatch, or a port already in use. -
Set your apps up
Each service now has its own web page. Open each one and set a password — some start with no protection at all.
Service Address First thing to do Jellyfin :8096 Create your account, add media folders Jellyseerr :5055 Connect it to Jellyfin, then to Sonarr and Radarr Sonarr :8989 Add your download client and indexers Radarr :7878 Same as Sonarr, for films Bazarr :6767 Connect to Sonarr and Radarr, pick languages qBittorrent :8080 Change the default password immediately Jackett :9117 Add indexers, copy the API key into the *arr apps Immich :2283 Create your account, install the phone app Uptime Kuma :3001 Add a monitor for each of the above Services find each other by container name, not by
localhost. Inside Sonarr, your download client lives atgluetunorqbittorrent— not127.0.0.1. This is the single most common setup mistake. -
Keeping it running
Updating in Arcane is: open the project, pull, redeploy. Do it every month or so, and read release notes before major version jumps.
Arcane can control your whole machine. It mounts the Docker socket, which is effectively root access to the host. Keep it on your home network or behind a VPN like Tailscale. Don't forward port 3552 to the internet.
The generator, or one script
If Docker is already running, you don't need any of the above. Two options, same output — a Compose file, an environment file, and a README, ready to bring up however you normally do.
Pick services in the browser, fill in your paths, download the files. Nothing runs on your machine until you bring the stack up yourself.
Open the generatorSame result without leaving the terminal. Asks a handful of questions, or takes a preset and answers nothing. Supports a dry run.
Download install.shRunning the script
# Fetch it, read it, then run it. Please actually read it. curl -fsSL https://parkertools.github.io/Modular-Media-Server/install.sh -o install.sh less install.sh bash install.sh
Options
| Flag | What it does |
|---|---|
| --preset <name> | Skip the menu and use a ready-made selection |
| --dir <path> | Where to write the stack |
| --dry-run | Print the Compose file, write nothing |
| --yes | Accept every default, ask nothing |
| --deploy | Bring the stack up when finished |
| --help | Everything above, plus the preset list |
Presets
| Name | What you get |
|---|---|
| player | Jellyfin on its own |
| basic | Arcane, Jellyfin, Jellyseerr |
| automated | The full media stack with downloads behind a VPN |
| music | Jellyfin, Lidarr, Kima, downloads |
| photos | Immich and its database |
| archive | ArchiveBox and Tube Archivist |
| monitoring | Uptime Kuma |
See exactly what a preset produces without writing anything:
bash install.sh --preset automated --dry-run
What it writes
docker-compose.yml— your services, with every value pulled from the environment file.env— real paths and generated secrets, written mode 600.env.example— the same shape with placeholders, safe to commit.gitignore— already ignoring.envREADME.md— your service addresses and the commands you'll want
Secrets come from openssl rand, falling back to /dev/urandom. Each one is generated separately, so no two services share a password. An existing .env is backed up with a timestamp rather than overwritten.
CHANGEME placeholders and tells you the stack won't start until you fill them in — it won't quietly generate a torrent client with a direct connection to your home address.After it finishes
If you used a VPN, check it's actually carrying traffic before downloading anything:
docker compose exec gluetun wget -qO- https://ipinfo.io/ip
That should not be your home address. If it is, stop and fix Gluetun first.
Things that catch everyone
Most of these images want a PUID and PGID matching the user that owns your media folders. Run id to find yours. Mismatched ownership is behind a large share of "it can't write to the folder" problems.
Inside a container, localhost means that container. Services reach each other by container name. Sonarr connects to qbittorrent, not 127.0.0.1:8080.
If your downloads folder and your media folder sit on the same filesystem and are mounted consistently, files can be moved instantly instead of copied. Split them across different mounts and you'll copy everything twice and wonder where the disk went.
Your config folder holds every setting, key and connection you've patiently set up. It's small, and it's the thing you'd most hate to redo. Media can be re-acquired; your Immich library often can't.