# ROMarr. # # curl -O https://raw.githubusercontent.com/BlizzHacker/romarr/main/docker-compose.yml # ROMARR_ROMS=/mnt/roms ROMARR_DOWNLOADS=/mnt/downloads docker compose up -d # # Then open http://localhost:6868 and set a password. Everything else can be # configured from the UI afterwards; the values below are the shortcut. # # Prowlarr, your download client and your game library are not started here -- # you already run them, and a compose file that spawned its own copies would # fight the stack it is meant to join. # # There used to be a second file, docker-compose-alt.yml, contributed by Ren # with the right idea in it: refuse to start rather than start misconfigured. # Its `${VAR:-?ERROR}` spelling did not do that -- `:-` supplies a default, so # it quietly set the API key to the literal string "?ERROR" -- and two files # that open with the same sentence gave nobody a way to choose. The idea is # kept here, in the one place it fails silently, with the `:?` form that # actually stops the run. services: romarr: image: ghcr.io/snapetech/romarrng:latest container_name: romarr restart: unless-stopped ports: - "6868:6868" environment: # Who owns the ROMs ROMarr writes. Use the same ids as your library app, # or `id -u` / `id -g` for your media user. PUID: 1000 PGID: 1000 # New ROMarr files: 0664, directories: 0775. Existing downloads are # never chmod'd or chown'd by ROMarr. UMASK: "002" TZ: Etc/UTC # Authentication. ROMarr requires a credential by default; leave this # commented and the first visit to the web UI asks you to set a # password. Uncomment to claim the install before it ever serves a # request, so there is no unclaimed window at all. # ROMARR_PASSWORD: choose-something-long # # The key scripts and other *arrs use. Generated on first run and shown # under Settings -> General; set it here to pin it to your own value. # ROMARR_API_KEY: # # Already behind an authenticating proxy? ROMARR_AUTH=forward keeps that # proxy as the authority and verifies requests came through it. See # .env.example for the full set of forward-auth variables. # Prowlarr -- how ROMarr finds releases. PROWLARR_URL: http://prowlarr:9696 PROWLARR_API_KEY: "" # Your game library. LIBRARY_KIND is romm, gaseous, retrom or folder. # `folder` needs no URL and no account -- only LIBRARY_PATH -- and is # what Batocera, ES-DE, EmuDeck and friends want. LIBRARY_KIND: romm LIBRARY_URL: http://romm:8080 LIBRARY_USERNAME: romarr LIBRARY_PASSWORD: "" # Where finished ROMs are filed, as seen inside THIS container. It is the # container path, not the host path -- see the volume below. Leave it as # /roms unless you also change the right-hand side of that mount. LIBRARY_PATH: /roms # Download client. At least one is required: a release found with no # client that speaks its protocol is ranked and then refused. QBITTORRENT_URL: http://qbittorrent:8080 QBITTORRENT_USER: "" QBITTORRENT_PASS: "" # Optional usenet clients. # SABNZBD_URL: http://sabnzbd:8080 # SABNZBD_API_KEY: "" # NZBGET_URL: http://nzbget:6789 # NZBGET_USER: "" # NZBGET_PASS: "" # What ROMarr labels its own downloads with, per client. Defaults to # "romarr". The category does NOT have to exist in the client first -- # SABnzbd keeps an undefined one verbatim and ROMarr still matches it. # Define it there anyway if you want its own folder or a post-processing # script, or point this at a built-in like "software". When you do create # one in SABnzbd, the indexer category ROMarr searches under is 'console'. # SABNZBD_CATEGORY: romarr # QBITTORRENT_CATEGORY: romarr # NZBGET_CATEGORY: romarr # Optional request front-end, shown and pinged on the System page. This # is NOT the request-delivery setting. In GG Requestz's own container set # REQUEST_WEBHOOK_URL to the value built on ROMarr's System page, e.g.: # http://romarr:6868/api/v1/webhook/ggrequestz?apikey= # GGREQUESTZ_URL: http://ggrequestz:3000 # Optional headless RetroArch stream server. ROMarr only ever reads from # it -- one GET asking which platforms it can play -- and uses the answer # to report PS2, GameCube, Wii, Dreamcast and 3DS as playable instead of # download-only. Everything works without it, minus those routes. # STREAM_SERVER_URL: http://romm-stream:8090 # Optional DAT directory. Loose .dat/.xml files AND the ZIP archives # No-Intro distributes are read. Mount the host directory below and # point this at the container path. # DAT_PATH: /dats # Optional Compressatorium service, for the Decompress task: batch # decompress a compressed library, verify every output against the # DATs, delete only the originals that verified. The library must be # mounted into BOTH containers at the same path. # https://github.com/pacnpal/compressatorium # COMPRESSATORIUM_URL: http://compressatorium:8080 # COMPRESSATORIUM_API_KEY: "" # Switch validation via TitleDB. On by default (1.7MB, cached). Set # TITLED_NAMES: "1" to also load title names -- a 65-95MB region file, # cached on disk, costing seconds of parse time and a few hundred MB # of RAM, which is why it stays opt-in. # TITLED_NAMES: "1" # TITLED_REGION: US.en LOG_LEVEL: INFO volumes: # History, settings, indexer configuration and any installed plugins. # Keep this one: delete it and every restart is a fresh install, which # includes a new API key and an unclaimed password prompt. # # A named volume works just as well and survives `docker compose down` # the same way -- add `volumes: {romarr_config:}` at the top level and # use `romarr_config:/config` here. The bind mount is the default # because you can read and back up ./config without asking Docker where # it put anything. - ./config:/config # Your library root on the HOST. # # There is deliberately no default. A placeholder like /path/to/roms is # not inert: Docker creates missing bind-mount sources, so an unedited # file used to start, report healthy, and file ROMs into a directory no # library server has ever scanned -- with every status on the System # page green. Of everything in this file that can be wrong, the two # paths are the only ones that are wrong *silently*, so they are the # only ones that stop the run. - ${ROMARR_ROMS:?set ROMARR_ROMS to your library root on the host, e.g. ROMARR_ROMS=/mnt/roms}:/roms # Your download client's completed directory. # # Left side is the host. The RIGHT side must be the path your download # client reports, character for character -- ROMarr asks the client where # a finished download is and then opens that path itself, so the two have # to agree. The host side only has to be the directory actually holding # those files; it does not have to resemble the container path. # # So if the files live at /mnt/downloads/complete on the host and SABnzbd # reports /downloads/complete, set ROMARR_DOWNLOADS to the first and # change the right-hand side to the second: # # - ${ROMARR_DOWNLOADS}:/downloads/complete # # A client running on the host rather than in a container reports host # paths, which makes the two sides identical: # # - ${ROMARR_DOWNLOADS}:/mnt/downloads # # Not sure what your client reports? qBittorrent shows it as "Save path" # in Options -> Downloads; SABnzbd as "Completed Download Folder" in # Config -> Folders. ROMarr uses whatever the client's API returns, which # is that setting. # # When the paths genuinely cannot be made to match, leave this as-is and # add a mapping under Settings -> Media Management, which rewrites the # client's prefix into a local one. - ${ROMARR_DOWNLOADS:?set ROMARR_DOWNLOADS to your download client's completed directory on the host, e.g. ROMARR_DOWNLOADS=/mnt/downloads}:/downloads # The two ROMARR_* names above are read by compose, not by ROMarr. Put them in # a `.env` file beside this one and `docker compose up -d` needs no arguments: # # ROMARR_ROMS=/mnt/roms # ROMARR_DOWNLOADS=/mnt/downloads # # Prefer to keep every setting there too? Delete the `environment:` block and # use `env_file: .env` -- compose turns those entries into real environment # variables, which is what ROMarr reads. .env.example in this repo is a # complete one, with every variable documented.