Deployment Guide

How to Deploy AirMultiLocks on Railway: The Easiest Way to Host Your Airbnb Lock Sync

AirMultiLocks is a Python web app with a background scheduler that checks for new Airbnb guest codes every 15 minutes and syncs them to every door at your property. For it to work, it needs to run continuously, 24 hours a day, every day. That means it needs to live somewhere on the internet, not just on your laptop.

Most hosting options turn this into a surprisingly complicated project. You end up managing servers, configuring Nginx, wrestling with environment variables, and worrying whether your app will still be running when your next guest arrives. Railway eliminates almost all of that. It is the fastest and most user-friendly way to deploy AirMultiLocks, and this guide explains exactly why and how to do it in under 20 minutes.

What Is Railway?

Railway is a modern application hosting platform that takes the complexity out of deploying web apps and background services. You connect it to a GitHub repository, and Railway detects the language, installs dependencies, builds the app, and gives it a live public URL with virtually no configuration required from you.

Think of it as the gap between "code on your computer" and "code running on a server" being closed by a product that actually understands what modern apps look like. It handles builds, deploys, environment variables, persistent storage, logs, and restarts through a clean dashboard that does not require any command-line expertise.

No DevOps Experience Needed Railway is designed for people who want to run their app, not manage infrastructure. If you can navigate a web dashboard and paste an API key into a text field, you can deploy AirMultiLocks on Railway.

Why Railway Is the Right Home for AirMultiLocks

AirMultiLocks has three specific requirements that make some hosting options a poor fit: it needs to run continuously, it needs to store configuration data between restarts, and it needs to serve a web dashboard for initial setup. Railway handles all three natively.

1. Automatic Python detection with zero configuration

Railway uses a build system called Nixpacks that scans your repository and automatically detects that AirMultiLocks is a Python app. It finds the requirements.txt, installs all dependencies, and figures out the start command without you writing a Dockerfile or any configuration file.

With other platforms, you would spend an hour just getting the build to succeed. On Railway, connecting your repo and clicking deploy is often enough for the app to be running within two to three minutes.

2. Always-on services with no sleeping

AirMultiLocks runs an internal scheduler that fires every 15 minutes. For it to catch a guest code as soon as Airbnb sets it, which could happen at any hour, the app needs to be awake continuously. Many free hosting tiers (Render's free tier, for example) put apps to sleep after 15 minutes of inactivity, which would make the scheduler completely unreliable.

Railway's Hobby plan keeps your service running at all times. There is no sleep behavior, no cold-start delay, and no missed syncs because the app went idle. Your lock codes get synced on schedule, every time, whether it is 2 PM or 3 AM.

3. Persistent volumes for configuration storage

AirMultiLocks stores its configuration (your Seam API key, your lock assignments, your sync preferences) in a config.json file on disk. On platforms without persistent storage, that file disappears every time the app redeploys or restarts, forcing you to go through the setup wizard again.

Railway volumes are persistent block storage that survive deploys, restarts, and even service deletions until you explicitly remove them. Mount a volume to the path where AirMultiLocks stores its config and your settings will be there, unchanged, no matter how many times you push a code update.

4. A public URL from day one

Railway generates a public *.up.railway.app URL for every service automatically. The AirMultiLocks setup wizard runs in a web browser, so you need a real URL to access it, not just a localhost address. On Railway, that URL is ready the moment your first deploy finishes, no DNS configuration required.

If you already own a custom domain, Railway lets you add it in two clicks. But even the auto-generated URL works perfectly for running AirMultiLocks.

5. Real-time logs and one-click redeploys

When something goes wrong, such as a failed sync, a lock timeout, or an expired Seam API key, AirMultiLocks logs what happened. Railway surfaces those logs in a real-time dashboard view that looks clean and is easy to read. You can see exactly what the last sync found, what it changed, and whether any errors occurred.

Pushing a new version is equally simple. Connect Railway to your GitHub repo once, and every push to your main branch triggers an automatic redeploy. Zero manual intervention required.

How to Deploy AirMultiLocks on Railway

The full process takes about 15 to 20 minutes the first time. Here is every step.

  1. 1
    Fork the AirMultiLocks repository to your GitHub account. Railway deploys from GitHub, so you need your own copy of the repo. Go to the AirMultiLocks GitHub page and click Fork. This creates a private copy under your account that you can connect to Railway and push updates to.
  2. 2
    Create a free Railway account. Go to railway.app and sign up with your GitHub account. Using GitHub for sign-in makes the repo connection in the next step much smoother. Railway can list your repositories directly without extra authorization steps.
  3. 3
    Create a new project and deploy from your repo. In the Railway dashboard, click New Project → Deploy from GitHub repo. Select the AirMultiLocks repo you forked. Railway will scan it, detect Python, and begin the first build automatically. The build takes two to three minutes on the first run while dependencies install.
  4. 4
    Add a persistent volume for configuration storage. In your Railway service settings, go to Volumes and click Add Volume. Set the mount path to /data (or whichever path AirMultiLocks is configured to use for its config file). Railway provisions the volume immediately and it persists through all future deploys.
  5. 5
    Set the required environment variables. In your service's Variables tab, add the environment variables AirMultiLocks needs: your session secret, the config file path pointing to your volume mount, and the port. Railway injects these into the running process automatically with no config files to edit manually.
  6. 6
    Generate a public URL. In the service settings, go to Networking → Generate Domain. Railway assigns a *.up.railway.app URL to your service. Copy this URL. You will use it to open the AirMultiLocks setup wizard in your browser.
  7. 7
    Complete the AirMultiLocks setup wizard. Open the public URL in your browser. The setup wizard walks you through connecting your Seam account, selecting your primary (Airbnb-connected) lock, and designating your secondary locks. Once complete, AirMultiLocks begins syncing automatically on its 15-minute schedule.
Upgrade to Hobby Before Going Live Railway's free trial gives you $5 of credits to test everything. Before your first guest arrives, upgrade to the Hobby plan to ensure your service stays awake continuously. The scheduler needs to run reliably 24/7. The trial tier may pause services once the credit is exhausted.

Key Environment Variables to Set

Railway's variable management is one of its strongest features. Variables are encrypted at rest, injected at runtime, and never exposed in your logs or build output. Here are the ones AirMultiLocks needs.

Variable What It Does Where to Get the Value
SESSION_SECRET Signs session cookies for the web dashboard Generate any random 32-character string
CONFIG_PATH Path to config.json on the volume Set to /data/config.json if your volume mounts at /data
PORT Port the app listens on Railway sets this automatically (no action needed)
Keep SESSION_SECRET Private Your session secret signs authentication cookies. Never commit it to your GitHub repository and never share it. Railway's encrypted variables store is the right place for it, not a .env file in your repo.

Keeping the Sync Scheduler Running

The most important thing to understand about AirMultiLocks on Railway is the relationship between the hosting plan and the background scheduler.

AirMultiLocks uses an in-process scheduler (APScheduler) that fires a sync job every 15 minutes. This scheduler starts when the app starts and runs inside the same Python process as the web server. As long as the process is running, syncs happen. If the process is killed or paused, syncs stop.

On Railway's Hobby plan, your service process runs continuously. Railway monitors it and restarts it automatically if it crashes. There is nothing else to configure. The scheduler just works.

This is meaningfully different from platforms that put apps to sleep after a period of inactivity. On a sleep-enabled platform, the scheduler would fire once, then go dormant. Your guest codes would only sync when someone happened to visit the dashboard and wake the app up, which is obviously not reliable behavior for lock automation.

What Happens on Redeploy When Railway redeploys your service after a GitHub push, it starts the new version of the app with zero downtime using a rolling deploy. The scheduler restarts with the new process. Any sync that was in progress during the cutover will run again on the next scheduled interval, typically within 15 minutes of the redeploy completing.

Want us to handle the deployment for you?

The Assisted Setup includes Railway deployment, configuration, lock pairing, and a test sync, done by the AirMultiLocks team in under 24 hours.

Monitoring Your Deployment

Once AirMultiLocks is live on Railway, you have two ways to verify that syncs are happening correctly.

The AirMultiLocks dashboard

The web dashboard at your Railway URL shows the last sync result: when it ran, which codes it found on the primary lock, and which codes it wrote to each secondary lock. Check this after your first reservation's codes are set by Airbnb to confirm the sync is working end to end.

Railway logs

Railway surfaces real-time application logs in its dashboard. Each sync run writes a log line with a timestamp and the outcome. If a sync fails because a lock is offline or a Seam API call times out, the error message appears here. You can filter by time range and search for specific error strings, useful if you want to investigate a specific reservation.

Railway also sends email alerts if your service crashes or becomes unhealthy. Combined with the AirMultiLocks dashboard showing the last successful sync time, you have enough visibility to catch problems before your guests do.

Frequently Asked Questions

Railway offers a free trial with $5 of usage credit, which is enough to test the full setup. For production use, where the sync scheduler must run around the clock, the Hobby plan at $5/month is recommended. Most single-property AirMultiLocks deployments will fit comfortably within that plan's resource allocation.
No. Railway uses Nixpacks to automatically detect that AirMultiLocks is a Python app, install its dependencies, and determine the start command. You do not need to write a Dockerfile, understand containers, or configure any build tooling. Railway handles all of that transparently.
Yes, on Railway's Hobby plan. The service runs as a long-lived process regardless of web traffic. The scheduler is part of that process and fires every 15 minutes whether or not anyone has visited the dashboard recently. This is one of the key reasons Railway is a better fit for AirMultiLocks than platforms that sleep idle services.
Add a Railway volume and mount it to the directory where AirMultiLocks stores its config.json file. Railway volumes persist across deploys and restarts until you explicitly delete them. Set the CONFIG_PATH environment variable to point to the config file inside the mounted volume path.
Yes. In your Railway service's Networking settings, click Add Custom Domain and follow the DNS instructions. Railway provisions a TLS certificate for the custom domain automatically through Let's Encrypt. The generated *.up.railway.app domain continues working alongside the custom domain.
If Railway is temporarily unavailable, the sync scheduler pauses until the service comes back online. Once restored, AirMultiLocks runs a sync on its next scheduled interval and catches up on any codes that were set during the outage. Because Seam queues access code operations, codes will reach your locks reliably even if there was a brief gap in sync runs. Railway maintains a strong uptime track record and publishes a public status page at status.railway.app.

The Takeaway

Deploying AirMultiLocks means choosing a home where a Python app can run continuously, store a small configuration file safely across restarts, and serve a setup dashboard to a web browser. Railway handles all three requirements without asking you to become a DevOps engineer in the process.

The auto-detected Python build means your first deploy is as simple as connecting a GitHub repo. The persistent volumes mean your lock configuration survives every code update you push. The always-on service means your guests' codes sync reliably at 3 AM just as well as they do at noon. And the real-time logs mean that if something goes wrong, you will know about it before your next guest arrives.

If you prefer not to manage the deployment yourself, the Assisted Setup option handles Railway provisioning, lock configuration, and a verified test sync for you. If you are comfortable following the steps above, the DIY Kit gives you everything you need to self-host. Either way, your property will be running fully automated multi-door guest code sync.

Not yet sure which locks to use? Start with our guide on how to connect a smart lock to your Airbnb listing, then come back here once you are ready to deploy.