Deploy K7
Self-host movies, music and TV with K7 and private Postgres.
Postgres
Just deployed
/var/lib/postgresql
Just deployed
/data
Deploy and Host self hosted K7 (Private Media Server) on Railway
This guide describes a third-party Railway template that packages K7, an open-source self-hosted media server for a small circle of family and friends.
About Hosting K7 open-source software on Railway
K7 is a self-hosted media server for movies, TV series and music, licensed under AGPL-3.0.
This template packages the upstream 1.17.2 image through the onepush-dev packaging repository at https://github.com/onepush-dev/k7. The image wraps upstream K7 with a start wrapper and an optional dufs uploader; it is not an official image.
Why Deploy K7 on Railway
The template generates secrets and references for the rest of the wiring.
Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.
By deploying K7 on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.
K7 must still run as one instance: this is an application-specific constraint, and platform boilerplate does not make K7 horizontally scalable.
Railway vs Other Hosting Providers and VPS for K7 self hosting
| Consideration | Railway (this template) | DigitalOcean, AWS, Hetzner or similar VPS |
|---|---|---|
| Setup effort | Template generates secrets and wires services | You install Docker, configure networking and TLS yourself |
| Operational control | Platform-managed runtime and networking | Full control over host, kernel, storage and firewall |
| Persistent storage | Volumes attached to services | You manage disks, filesystems and snapshots |
| Scaling model | Platform controls scaling; K7 must stay single instance | You choose instance size and placement |
| Ongoing maintenance | Platform handles much of the host layer | You own OS patching, backups and monitoring |
Common Use Cases for hosted K7
- A private shelf of movies and TV series shared with family members who sign in with their own accounts.
- A music library served to phones and desktops, with OpenSubsonic-style access through app passwords.
- Shared watch-along sessions for a small group using the Sync Play feature.
- A federated link between two K7 instances so friends can stream each other's media without copying files.
Dependencies for K7 Docker hosted on Railway
The template runs the K7 application container alongside a private Postgres 18 database.
The optional uploader is not a third service.
Deployment Dependencies for K7 and Postgres
| Variable | Service | Purpose |
|---|---|---|
| Database__Server | K7 | Reference to the private Postgres hostname |
| Database__Password | K7 | Reference to the Postgres password |
| K7_ADMIN_PASSWORD | K7 | Generated first-boot password for the admin account |
| MEDIA_UPLOAD_PASSWORD | K7 | Generated uploader password, user admin; remove it and redeploy to disable the uploader |
| Security__ApiKeys__HashSecret | K7 | Generated 64-character secret for API key hashing; rotating it invalidates existing API keys |
| POSTGRES_PASSWORD | Postgres | Generated 32-character database secret |
| PGDATA | Postgres | Reference to the volume mount at /var/lib/postgresql plus /18/docker, effective path /var/lib/postgresql/18/docker |
The optional BaseUrl setting is separate from the seven template variables. It is image-configured from the main public Railway domain.
Implementation Details for the onepush-dev K7 image
The image is ghcr.io/onepush-dev/k7:1.17.2.
On first start, bootstrap uses the generated K7_ADMIN_PASSWORD, so you do not need to visit /setup to create the first admin on Railway. Persistent application files live under /data, which holds configuration, metadata, logs, transcode scratch and media folders, while Postgres keeps its data on a private mount at /var/lib/postgresql. The app listens on 7080 and exposes /health.
How does K7 compare against other media servers
K7 vs Jellyfin
- Packaging: K7 here runs as a two-service Railway stack with Postgres, which keeps the deployment small.
- Purpose: K7 is aimed at a small private circle, with accounts, libraries and federation under your control.
K7 vs Plex
- Licensing: K7 is open source under AGPL-3.0 and its source is available upstream.
- Purpose: K7 is aimed at a shared home shelf that you run yourself on infrastructure you control.
K7 vs Navidrome
- Focus: Navidrome is music-focused, while K7 covers movies and series as well as music.
- Music access: Both can serve music to client apps, so check each client's compatibility against the server you choose.
How to use K7 on Railway
-
Deploy the template and wait for the K7 and Postgres services to show success.
-
Open the K7 service in Railway, go to Variables and copy the value of K7_ADMIN_PASSWORD. Treat it as a secret.
-
Open the main public domain for the K7 service, which targets port 7080.
-
Sign in with the username admin and the generated K7_ADMIN_PASSWORD. Only the password is generated; the username is admin.
-
Go to Settings and change the admin password to one you choose. The bootstrap variable does not reset an existing password, so changing it is recommended, though not technically required.
-
Optional: to use the uploader, open the Railway dashboard, select the K7 SERVICE Settings (not the K7 app Settings), go to Networking and select Generate Domain targeting port 5000. This creates a second HTTPS domain.
-
Open the second uploader domain and sign in as admin using MEDIA_UPLOAD_PASSWORD. Do not use K7_ADMIN_PASSWORD on the uploader domain.
-
Upload only media you have the rights to store and stream, into the movies, series or music folders on the uploader.
-
In the main K7 site, go to Admin, then Libraries, and add a library pointing at the matching /data/media folder: /data/media/movies, /data/media/series or /data/media/music.
-
Run a library scan, or enable realtime monitoring. Folder watching depends on filesystem support, so do not expect uploaded files to appear immediately.
A safe health check for your deployment uses your own domain:
curl https://your-domain/health
Replace your-domain with the public domain Railway assigned to your K7 service. /health also checks the database, while /alive only checks that the process is running.
Privacy note: by default, shared media links may show a title, overview and poster to unauthenticated crawlers. To suppress media details in link previews, go to Admin / Experience / General and set MediaLinkPreviewsEnabled off.
Uploader note: the uploader uses a distinct security boundary with its own credentials, separate from the admin login. It can modify and delete files in its media root. To disable it, remove MEDIA_UPLOAD_PASSWORD and redeploy.
How to self host K7 on other VPS Services
The following steps are derived from upstream documentation and have not been run or tested as part of this write-up.
-
Obtain the upstream repository at https://github.com/kaybi-gh/K7 and check out the release you want.
-
Copy the .env.example file to .env and set the documented database and API key hash secret values to strong values you generate yourself.
-
Start the stack from the repository directory with docker compose up -d.
-
Open port 7080 in a browser on the host. The upstream setup wizard differs from the Railway bootstrap, so complete the browser setup flow or supply the documented bootstrap variables.
Secure the deployment with TLS in front of port 7080 and keep the database private.
Official Pricing of K7
K7 is free software licensed under AGPL-3.0, so the software itself has no license fee.
AGPL-3.0 requires that modified versions offered over a network make their source available to users.
Resource and storage planning for K7 hosting
- CPU: Transcoding on this template is CPU-only, and Railway does not provide GPU passthrough. Prefer direct play where clients support the file, since software encoding can be CPU-heavy.
- Concurrency: Run a single K7 instance, because the scheduler and counters are not shared between instances. This is an application constraint; platform scaling does not change it.
- Storage: Size the /data volume for configuration, metadata, logs, transcode scratch and uploaded media. Transcode scratch is cache, but media and the database must be kept.
- Backups: Plan backups of the Postgres database and the persistent files together, copy them off-platform and test a restore in an isolated environment. A volume alone is not a backup.
- Capacity: This template makes no capacity or performance guarantees. Upstream memory estimates are generic guidance, not measured Railway numbers. Adjust resources only after observing real library scans and playback.
Frequently Asked Questions
What are the admin credentials?
The admin username is admin. The password is the generated K7_ADMIN_PASSWORD value from the K7 service Variables on Railway.
Do I need a paid K7 key?
No. K7 is free under AGPL-3.0 and the template does not require a paid key. Infrastructure usage on Railway is billed separately.
Which domain should I use for the uploader?
Generate a second domain on the K7 service that targets port 5000. Sign in to that domain as admin using MEDIA_UPLOAD_PASSWORD.
Does this template support GPU transcoding?
No. Railway does not provide GPU or VAAPI/NVENC passthrough for this template, so transcoding runs on the CPU with software encoding.
How should I back up my K7 data?
Back up the Postgres database and the persistent files under /data together. A volume alone is not a backup.
Can I use a custom domain?
Yes. Attach a custom domain to the K7 service in Railway and set BaseUrl to that public site so OIDC and federation work correctly.
Template Content
