Put it on the internet
To deploy means to put the code on real servers so other people can use it. RISER runs on Railway, a service that hosts apps and databases for you.
What runs in the cloud
Section titled “What runs in the cloud”We run four things:
- Postgres — the database.
- backend — the API server.
- web — the operator dashboard.
- marketing — the public website.
The backend talks to Postgres over a private network inside Railway. The web app and website talk to the backend over the public internet.
The live site
Section titled “The live site”The project is deployed here:
- Backend API:
https://backend-production-1145.up.railway.app - Operator app:
https://web-production-c1e29.up.railway.app - Marketing site:
https://marketing-production-5ba1.up.railway.app
You can check the backend is alive by opening /health on the backend address. It should say ok.
How a deploy happens
Section titled “How a deploy happens”There are two ways to deploy.
By hand, with the Railway tool. You log in once with railway login. Then you push each part:
cd backend && railway up # build and deploy the backendcd ../web && railway up # build and deploy the web appcd ../marketing && railway up # build and deploy the websiteEach one builds a small container (a packaged-up copy of the app) and starts it.
By itself, with GitHub. We also have a pipeline in .github/workflows/deploy.yml. When code is
saved to the main branch, it runs the tests, updates the database, deploys to a test site, waits
for a human to approve, and then deploys to the real site. This is called CI/CD. It means the
computer does the boring, careful steps for you.
A few gotchas we learned
Section titled “A few gotchas we learned”- The database address from Railway starts with
postgres://. The backend rewrites it so the right driver is used. You do not have to do anything; it is automatic. - The backend runs its database updates (migrations) every time it starts. So a new deploy always has the right tables.
- Web apps in containers must listen on the address
0.0.0.0and the port the host gives them. We set this in the Dockerfiles. If you forget, the app starts but no one can reach it.
Settings and secrets
Section titled “Settings and secrets”A secret is a private value, like a password or a key. We never put secrets in the code. They
live in the server’s settings instead. On Railway you set them in the service’s “Variables.” For
example, the backend needs a JWT_SECRET (used to sign login tokens) and a DATABASE_URL.