Deploy Uptimy Agent on Railway
Deploy the agent into your Railway project from the template, sign in, and monitor every service in the project over private networking. About five minutes.
Overview
Uptimy Agent is an open-source monitor (Apache-2.0, on GitHub) that runs as a service in your Railway project. On the project's private network it checks what an outside monitor can't reach:
- Services without a public domain, at
<service>.railway.internal. - Postgres, MySQL, MariaDB and Redis, by logging in and running a query, so a full connection limit or a rejected password is caught too.
- Cron services, as heartbeats that alert when a run doesn't check in.
It has its own UI, alert channels and public status page, and needs no account. The template is the quickest way to run it:
Uptimy Agent template on Railway
One service with a volume, a generated admin password and a public domain. Deploy it into the project you want to monitor.
What the template deploys
| Image | ghcr.io/uptimy/agent:latest |
| Volume | Mounted at /data and backed up daily. The agent keeps everything here in one SQLite database: monitors, history, settings and users. |
| Public domain | A generated *.up.railway.app domain on port 8080, for the UI and the status page at /status. |
| Healthcheck | /healthz |
| Replicas | 1. SQLite has a single writer, so don't scale it out. |
Environment variables
The template sets these. Keep the defaults when you deploy.
${{secret(24)}}The admin's password: 24 random characters, generated once when you deploy the template (at least 8 if you set your own).
0Runs the container as root so it can write to the volume, which Railway mounts as root. The image otherwise runs as a non-root user.
adminThe admin's username.
Variables you can add later:
Connection URLs for database checks, as reference variables such as ${{Postgres.DATABASE_URL}}. Monitors use them as ${POSTGRES_URL}, so database passwords stay in Railway and never reach the agent's database. The import below tells you which to add.
Monitors as YAML, kept in Railway with the rest of the project. See Monitors as code.
How the agent is labeled in Uptimy Cloud. On Railway the hostname is a container ID, so set a name if you connect it.
30How long check results, heartbeat runs, events and alerts are kept. Daily uptime history is kept for 400 days either way.
Leave PORT unset: the domain points at 8080, where the agent listens by default. Railway sets RAILWAY_PROJECT_ID, RAILWAY_ENVIRONMENT_ID and RAILWAY_SERVICE_ID on every deployment, and the agent reads them to know which project it's in. All settings are in the configuration reference.
1. Deploy the template
Click Deploy on Railway above, keep the variables as they are and deploy. To add the agent to a project you already have, open the project and choose + New → Template, then search for Uptimy Agent.
ℹ️ Same project, same environment
The deploy takes about a minute. Railway marks it active once /healthz answers.
2. Sign in
Open the service's domain, shown on the service and under Settings → Networking. Sign in as admin with the value of ADMIN_PASSWORD from the service's Variables tab.
While ADMIN_PASSWORD is set, that password is managed in Railway, not in the agent: change the variable and redeploy to set a new one. That's also how you get back in after losing it.
Add the people who need access under Users, as admins or viewers. Each of them can turn on two-factor sign-in under Account.
3. Add an alert channel
Under Notifications, add a channel: Slack, Discord, Teams, Telegram, email, ntfy, PagerDuty, a webhook, or one of 30+ more through Shoutrrr. New channels alert for every monitor, including the ones you add later, so one channel is all the alerting setup you need.
4. Import the services in your project
- In Railway, create a project token under Project → Settings → Tokens, for the environment the agent runs in.
- In the agent, open Settings → Import from Railway, paste the token and click Preview services.
- Review the monitors, fill in anything missing, and click Import.
Every other service in the environment becomes a monitor:
- Web services: an HTTP check at
<service>.railway.internalon the service's healthcheck path. If Railway doesn't know the port the service listens on, the review asks for it. Switch to Public to check the public domain instead. - Postgres, MySQL, MariaDB and Redis: a database check through a variable on the agent, named after the service. For a service called Postgres, add
POSTGRES_URLwith the value${{Postgres.DATABASE_URL}}to the agent and deploy the change. - Cron services: a heartbeat on the service's cron schedule, in UTC like Railway runs it. Add
curl -fsS <ping URL>as the job's last step. After importing, the new heartbeats are listed with links to their pages, which show the ping URL to admins.
The token is only used to read the services and isn't stored. Importing again skips services already imported, so run it again after adding services.
Monitors as code
Instead of importing, or next to it, put monitors in the MONITORS_YAML variable. Railway fills in ${{...}} references when it deploys, so a target follows the service's private hostname. The agent fills in ${...} in database targets when a check runs.
healthchecks:
- name: API
type: http
target: http://${{api.RAILWAY_PRIVATE_DOMAIN}}:8080/health
- name: Postgres
type: postgres
target: ${POSTGRES_URL}
heartbeats:
- name: Nightly backup
cron: "0 3 * * *"
grace: 30mMonitors from YAML are matched by name, so editing one keeps its history. They show read-only in the UI. A mistake doesn't stop the agent: the rest is applied and the error is shown on the dashboard.
5. Publish the status page
Under Status page, add the monitors visitors should see. It's public at https://<your-domain>/status and never shows targets or internal hostnames. To serve it on a domain such as status.example.com, add the domain to the service in Railway's networking settings and enter it under Status page → Custom domain. That domain serves only the status page, so sign-in stays on the Railway one. Here's the live demo, an agent running on Railway.
When the agent itself goes down
A monitor can't report its own outage. In the agent, Settings → Uptimy Cloud connects it to a free Uptimy account. The agent uploads its results every minute (every 5 minutes on Free), and Uptimy alerts you from outside when the uploads stop. Its monitors show up in your workspace for status pages, SLA reports and workflows, without counting toward your plan's limits. See Connect to Uptimy Cloud.
Troubleshooting
- A private check fails but the public domain works: compare the hostname with the service's private networking settings and check the port. In Railway environments created before October 16, 2025, private names resolve to IPv6 only, so the service has to listen on
::. - A database check says a variable isn't set: add the reference variable it names to the agent service and deploy the change.
- Monitors are gone after a redeploy: the volume must be mounted at
/data. - The admin password doesn't work: it's the current value of
ADMIN_PASSWORD. Set a new one there and redeploy.
Next steps
- Uptimy Agent docs: other installs, importing from Uptime Kuma, and the full reference
- Every check type and heartbeat setting
- Monitoring Railway cron jobs
- How to monitor a Railway app with Uptimy Cloud: deploy events as incidents and automatic restarts