Setup guide

Two ways in. Pick the one that sounds like you.

There's no single correct route. If the terminal makes you nervous, take the first path and never open one. If you already have Docker running and just want the files, take the second and be done in a couple of minutes.

Running Windows or a Mac? Both work — start with the platform guide to get Docker in place, then come back here.

Path one

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
Path two

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
Path one · No command line after this

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.

What you need before starting: a machine that stays on — a mini PC, an old laptop, a NAS that runs Docker, or a VPS. Not sure? The hardware page walks through the options.
  1. 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.

    Docker setup for your system

    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-world works.

  2. 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 32

    Make 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 with Ctrl+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.

  3. 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.
  4. 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.

    Open the generator

    You'll end up with two things that matter: docker-compose.yml, which describes your services, and .env, which holds your paths and passwords.

  5. Deploy it in Arcane

    In Arcane, go to Projects and create a new one. Give it a name like media. Paste your docker-compose.yml into the Compose field and your .env contents 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.
  6. 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.

    ServiceAddressFirst thing to do
    Jellyfin:8096Create your account, add media folders
    Jellyseerr:5055Connect it to Jellyfin, then to Sonarr and Radarr
    Sonarr:8989Add your download client and indexers
    Radarr:7878Same as Sonarr, for films
    Bazarr:6767Connect to Sonarr and Radarr, pick languages
    qBittorrent:8080Change the default password immediately
    Jackett:9117Add indexers, copy the API key into the *arr apps
    Immich:2283Create your account, install the phone app
    Uptime Kuma:3001Add a monitor for each of the above

    Services find each other by container name, not by localhost. Inside Sonarr, your download client lives at gluetun or qbittorrent — not 127.0.0.1. This is the single most common setup mistake.

  7. 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.
Path two · You know what you're doing

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.

The web generator

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 generator
The install script

Same result without leaving the terminal. Asks a handful of questions, or takes a preset and answers nothing. Supports a dry run.

Download install.sh

Running 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
It won't install Docker for you, on purpose. If Docker is missing it tells you the command and stops. Piping a downloaded script into a root shell should be something you decide to do, not something that happens as a side effect of running something else.

Options

FlagWhat it does
--preset <name>Skip the menu and use a ready-made selection
--dir <path>Where to write the stack
--dry-runPrint the Compose file, write nothing
--yesAccept every default, ask nothing
--deployBring the stack up when finished
--helpEverything above, plus the preset list

Presets

NameWhat you get
playerJellyfin on its own
basicArcane, Jellyfin, Jellyseerr
automatedThe full media stack with downloads behind a VPN
musicJellyfin, Lidarr, Kima, downloads
photosImmich and its database
archiveArchiveBox and Tube Archivist
monitoringUptime Kuma

See exactly what a preset produces without writing anything:

bash install.sh --preset automated --dry-run

What it writes

In the directory you choose
  • 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 .env
  • README.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.

qBittorrent will not be written without a VPN. Select it and Gluetun is added automatically. If you don't supply credentials, the script writes 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

cd into the directoryread the .envdocker compose up -dset passwords

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.

Either way

Things that catch everyone

Permissions

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.

Containers don't share your idea of localhost

Inside a container, localhost means that container. Services reach each other by container name. Sonarr connects to qbittorrent, not 127.0.0.1:8080.

Downloads and libraries want to live together

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.

Back up config, not just media

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.

The same rules apply on both paths. Only obtain and share content you're legally entitled to. Downloaded files can carry malware, and a VPN routes your traffic without making any file safe. Keep your host and images updated, don't expose admin interfaces to the internet, and keep backups of anything you'd be upset to lose.

Read the full documentation   Hardware & hosting