Gameyfin on Ubuntu 24.04 on Azure User Guide
Overview
Gameyfin is a self-hosted game library manager — the "Jellyfin for games". It scans your own game collection, enriches each title with cover art and metadata, and gives you a fast web library to browse, search, organise into collections and download your games, with an administration panel and optional OIDC single sign-on. The cloudimg image runs the official Gameyfin container image ghcr.io/gameyfin/gameyfin:2.4.0 (managed by Docker with a restart policy), with the web UI bound to the loopback port 127.0.0.1:8080 and the Spring management/health endpoint on 127.0.0.1:8081, all behind an nginx reverse proxy on port 80. Persistence is an embedded H2 file database under /opt/gameyfin/db — there is no separate database service to run, credential or patch.
Upstream Gameyfin ships un-bootstrapped: the very first visitor to a fresh instance is sent to /setup to self-register as the super administrator. On a public cloud VM that is a takeover risk, so this image closes it: a per-VM administrator account is seeded automatically on the first boot of every VM, which means /setup is already satisfied and simply redirects to the sign-in page. You retrieve the generated password from a root-only file and sign in. The game library ships empty — you add your own games. Backed by 24/7 cloudimg support.
What is included:
- 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(no separate database service) - A unique administrator account seeded on first boot and recorded in a root-only file (username
admin) - A unique application key (
APP_KEY, token encryption / session signing) and embedded-database password generated per VM - First-visitor
/setupself-registration closed — it redirects to the sign-in page - An empty game library mounted at
/opt/gameyfin/libraryfor you to fill with your own games - The app bound to loopback only; nginx is the sole public surface, with
server_tokens offand an$http_hostallowlist docker.service+gameyfin.service+nginx.serviceas systemd units, enabled and active- An unauthenticated
/actuator/healthendpoint for Azure Load Balancer health probes - 24/7 cloudimg support
Prerequisites
An active Azure subscription, an SSH key pair, and a VNet + subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a comfortable starting point for personal or small-team use; the Java application, embedded database and nginx run well within it. NSG inbound: allow 22/tcp from your management network and 80/tcp. Gameyfin serves plain HTTP on port 80; 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 cloudimg, and select Create. On Basics 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). Then Review + create -> Create.
Step 2 - Deploy from the Azure CLI
az vm create \
--resource-group <your-rg> \
--name gameyfin \
--image <marketplace-image-urn> \
--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
ssh azureuser@<vm-public-ip>
Step 4 - Confirm the services are running
systemctl is-active docker.service gameyfin.service nginx.service
All three 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), and nginx fronts the UI on port 80. Gameyfin's library metadata and state live 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; the database keeps just a bcrypt hash):
sudo cat /root/gameyfin-credentials.txt
You will see the sign-in URL, the username (admin) and the per-VM password. Keep this password safe — it is the super administrator for your Gameyfin instance.

Step 6 - Verify the app is serving
Gameyfin exposes an unauthenticated health endpoint, and the image ships a self-test that proves the per-VM admin 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",...}, and the self-test confirms the app is serving, the per-VM password logs the seeded administrator in, common and blank default passwords are rejected, and 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 (nginx is the sole public surface), first-visitor /setup self-registration is closed, and nginx refuses unknown Host headers:
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 (self-registration guarded), ports 8080 and 8081 listen on 127.0.0.1 only, and an unknown Host header gets a bare 404.

Step 8 - Sign in to Gameyfin
In your browser, go to http://<vm-public-ip>/. You are taken straight to the sign-in screen (not a setup form — 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 signing in you land on your game library. On a fresh VM the library is empty — Gameyfin invites you to add libraries and games from the administration panel.

Open the administration panel (the Administration area) and select Games to manage libraries, collections and library scanning. This is where you point Gameyfin at your game folders and tune how titles are matched and enriched.

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

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 (each game in its own subfolder works best), 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, in Administration -> Games -> Libraries, add a library pointing at /opt/gameyfin/library and trigger 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, then 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 it is served.
Back up your library metadata. Everything Gameyfin stores is under /opt/gameyfin — the embedded H2 database in db/, cover art and metadata in data/, and plugin data in plugindata/. Stop the service for 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. Either expand the OS disk in the Azure portal and grow the filesystem online with sudo growpart + sudo resize2fs, or 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:
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
Review the upstream release notes before upgrading, as some releases run a database migration — back up first.
Support
This image is maintained by cloudimg with 24/7 support. If you need help deploying or operating Gameyfin on Azure, contact cloudimg support through the Azure Marketplace listing.
Gameyfin is an open source project (AGPL-3.0). This image packages unmodified upstream Gameyfin with cloudimg configuration and automation, and is not affiliated with or endorsed by the Gameyfin project.