Deployment guide

Gameyfin

Overview

Gameyfin is a self-hosted game library manager, often described as the "Jellyfin for games". It scans your game collection, enriches each title with cover art and metadata, and presents a web library where you can browse, search, organise into collections and download your games. It also includes an administration panel and optional OIDC single sign-on.

This SecureAnyCloud image runs the official Gameyfin container image ghcr.io/gameyfin/gameyfin:2.4.0, managed by Docker with a restart policy. The web UI is bound to loopback port 127.0.0.1:8080 and the Spring management and health endpoint to 127.0.0.1:8081, all behind an nginx reverse proxy on port 80. Persistence uses an embedded H2 file database under /opt/gameyfin/db, so there is no separate database service to run, credential or patch.

Upstream Gameyfin ships without bootstrapping: the first visitor to a fresh instance is sent to /setup to self-register as the super administrator. On a public cloud VM this is a takeover risk, so the image closes it. A per-VM administrator account is seeded automatically on the first boot of every VM, so /setup is already satisfied and redirects to the sign-in page. You retrieve the generated password from a root-only file and sign in. The game library ships empty, so you add your own games.

What you get:

  • Gameyfin 2.4.0 running as the official container image, managed by Docker
  • Docker Engine and nginx preinstalled and enabled
  • The Gameyfin web UI on :80, fronted by nginx with the WebSocket upgrade the UI uses
  • An embedded H2 database under /opt/gameyfin/db, with no separate database service
  • A unique administrator account (username admin) seeded on first boot and recorded in a root-only file
  • A unique application key (APP_KEY, used for token encryption and session signing) and embedded-database password generated per VM
  • First-visitor /setup self-registration closed, with a redirect to the sign-in page
  • An empty game library mounted at /opt/gameyfin/library for you to fill with your own games
  • The app bound to loopback only, with nginx as the sole public surface, using server_tokens off and an $http_host allowlist
  • docker.service, gameyfin.service and nginx.service as enabled, active systemd units
  • An unauthenticated /actuator/health endpoint for Azure Load Balancer health probes
  • 24/7 SecureAnyCloud support

Prerequisites

You need an active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region.

Standard_B2s (2 vCPU / 4 GiB RAM) is a comfortable starting size for personal or small-team use. The Java application, the embedded database and nginx run well within it.

Configure the network security group (NSG) to allow inbound 22/tcp from your management network and 80/tcp. Gameyfin serves plain HTTP on port 80, so for production terminate TLS in front of it with your own domain (see Maintenance). Game libraries can be large, so plan to grow the OS disk or attach a data disk for /opt/gameyfin/library (see Maintenance).

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Gameyfin by SecureAnyCloud, and select Create.

On the Basics tab, pick your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22) and HTTP (80).

Select Review + create, then Create.

Step 2 - Deploy from the Azure CLI

# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:gameyfin-ubuntu-24-04:default:latest
az vm create \
  --resource-group <your-rg> \
  --name gameyfin \
  --image sac1647283583153:gameyfin-ubuntu-24-04:default:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/id_ed25519.pub \
  --vnet-name <your-vnet> --subnet <your-subnet> \
  --public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name gameyfin --port 80 --priority 1010

Step 3 - Connect to your VM

Connect to the VM over SSH as azureuser:

ssh azureuser@<vm-public-ip>

Step 4 - Confirm the services are running

Check that Docker, Gameyfin and nginx are active:

systemctl is-active docker.service gameyfin.service nginx.service

All three services report active. Docker runs the Gameyfin container, bound to the loopback ports 127.0.0.1:8080 for the UI and 127.0.0.1:8081 for health. nginx fronts the UI on port 80. Gameyfin stores its library metadata and state in the embedded H2 database under /opt/gameyfin/db.

Step 5 - Retrieve your administrator credential

The administrator account is seeded uniquely on the first boot of your VM. The generated password is written to a root-only file. The file holds only the plaintext password, while the database keeps just a bcrypt hash. Read the file with sudo:

sudo cat /root/gameyfin-credentials.txt

The file shows the sign-in URL, the username (admin) and the per-VM password. Store this password safely, because it belongs to the super administrator of your Gameyfin instance.

Step 6 - Verify the app is serving

Gameyfin exposes an unauthenticated health endpoint. The image also ships a self-test that checks the per-VM administrator gate end to end:

curl -s http://127.0.0.1:8081/actuator/health; echo
sudo /usr/local/sbin/gameyfin-selftest

The health endpoint returns {"status":"UP",...}. The self-test confirms that the app is serving and that the per-VM password logs in the seeded administrator. It also confirms that common and blank default passwords are rejected and that first-admin self-registration is guarded.

Step 7 - Review the security posture

The image is locked down by default. The app ports are loopback-only, with nginx as the sole public surface. First-visitor /setup self-registration is closed, and nginx refuses unknown Host headers. Verify each of these:

curl -s -o /dev/null -w 'setup -> HTTP %{http_code} %{redirect_url}\n' http://127.0.0.1:8080/setup ss -lnt | grep -E ':8080|:8081|:80 '
curl -s -o /dev/null -w 'evil-host -> %{http_code}\n' -H 'Host: evil.example.com' http://127.0.0.1/login

/setup returns a 302 redirect to /login, which shows that self-registration is guarded. Ports 8080 and 8081 listen on 127.0.0.1 only, and an unknown Host header receives a bare 404.

Step 8 - Sign in to Gameyfin

In your browser, go to http://<vm-public-ip>/. Gameyfin opens the sign-in screen rather than a setup form, because the administrator is already seeded. Sign in as admin with the password from Step 5.

Step 9 - Browse the library and open the administration panel

After you sign in, Gameyfin opens your game library. On a fresh VM the library is empty, and Gameyfin prompts you to add libraries and games from the administration panel.

Open the Administration area and select Games to manage libraries, collections and library scanning. Here you point Gameyfin at your game folders and tune how titles are matched and enriched.

Select Users to see the per-VM administrator seeded on first boot (role Superadmin) and to invite additional users. Self-service sign-up is disabled by default, so only an administrator can create new accounts.

Step 10 - Add your game library

The image ships with an empty library directory at /opt/gameyfin/library. Copy or mount your game folders there. Gameyfin works best when each game has its own subfolder, for example:

sudo install -d -o 1000 -g 1000 /opt/gameyfin/library/"My Game Title"
# copy your game files into that folder, then rescan from the admin panel

Then go to Administration -> Games -> Libraries, add a library that points at /opt/gameyfin/library, and start a scan. Gameyfin matches each title against its metadata providers and fills in cover art and details.

To enable the metadata providers (IGDB, Steam, SteamGridDB), add their API keys under Administration -> Plugins.

Maintenance

Secure with HTTPS. For production, put your own domain in front of the VM and terminate TLS. Point a DNS record at the VM's public IP, install a certificate (for example with Certbot), and add a TLS server block to nginx that proxies to http://127.0.0.1:8080, mirroring the shipped port-80 vhost.

The nginx server_name allowlist already includes your VM's addresses. Add your domain name to the server_name line so that nginx serves it.

Back up your library metadata. Everything Gameyfin stores is under /opt/gameyfin. The embedded H2 database is in db/, cover art and metadata are in data/, and plugin data is in plugindata/. Stop the service to get a consistent snapshot, then archive the tree:

sudo systemctl stop gameyfin
sudo tar czf /var/tmp/gameyfin-backup.tgz -C /opt gameyfin
sudo systemctl start gameyfin

Grow storage for large libraries. Game files can be large. You can expand the OS disk in the Azure portal and grow the filesystem online with sudo growpart and sudo resize2fs. Alternatively, attach a dedicated Azure data disk, format and mount it, and point your Gameyfin library at its mount point.

Update Gameyfin. New releases ship as new image tags. Pull the new tag, update the gameyfin.service unit to reference it, and restart the service:

sudo docker pull ghcr.io/gameyfin/gameyfin:<new-version>
sudo sed -i 's#ghcr.io/gameyfin/gameyfin:2.4.0#ghcr.io/gameyfin/gameyfin:<new-version>#' /etc/systemd/system/gameyfin.service
sudo systemctl daemon-reload && sudo systemctl restart gameyfin

Some releases run a database migration, so back up first and review the upstream release notes before you upgrade.

Support

SecureAnyCloud maintains this image and provides 24/7 support. For help deploying or operating Gameyfin on Azure, contact SecureAnyCloud support through the Azure Marketplace listing.

Gameyfin is an open source project (AGPL-3.0). This image packages unmodified upstream Gameyfin with SecureAnyCloud configuration and automation. It is not affiliated with or endorsed by the Gameyfin project.

Deploy on Azure

Launch Gameyfin on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure