It works locally but not on Salus
Your machine and Salus differ in a handful of ways that catch people and coding agents alike. Check these in order.
The pipeline passed, but the URL returns 502
The port. Salus sends traffic to the port in the environment’s configuration and doesn’t pass a PORT variable, so an app that falls back to a default listens on that default, such as 3000 for Next.js (next start) and most Express apps. The pipeline doesn’t check the port, so a wrong one still deploys “successfully”. Set the port to the one your app actually listens on, and redeploy. See Configure an Environment.
If the app was just deployed, give it a minute: a new deployment can return 502 for up to a minute while it starts.
The app starts, then fails on its first request
- Missing environment variables. Your
.envfile usually isn’t in the repository, so its values never reach Salus. Add each one to the project. See Environment Variables. - A variable is set, but the browser doesn’t see it. Variables the front end reads (
VITE_…,NEXT_PUBLIC_…) are baked in when the app builds, so they must be build-time variables. Change one, then redeploy so the app builds again. localhostaddresses. On your machine the API, the database and the app sharelocalhost; on Salus each runs separately. Replace hard-codedlocalhostURLs with variables. A linked database’s address comes inSALUS_DATABASE_<NAME>_HOSTand the full connection string inSALUS_DATABASE_<NAME>_CONNECTION_STRING. See Connect a Database.- The database variables are missing during the build. Linked-database variables exist only while the app runs. Don’t connect to the database, or run migrations, from the build step; do it when the app starts.
Files disappear
The container’s disk is temporary: anything the app writes is lost when it restarts or redeploys, and each instance has its own. Keep data in a managed database, not in local files. That includes SQLite: move to PostgreSQL before deploying.
The build fails, or the app won’t start
- Next.js: “Symlink node_modules could not be resolved”. Next.js 16 builds with Turbopack by default, which fails on Salus buildpacks. Use
next build --webpack. See Deploy an app built with v0. - “No default process” or “no start command”. Salus can’t tell how to start the app. Node.js needs a
startscript inpackage.json; Python needs aProcfilewith aweb:line. A static site (Vite, Create React App) needs to be at the root of the repository, where Salus looks for it. - A Dockerfile can’t find files to
COPY. The build context is the repository root, even when the project builds from a subfolder. See Custom Docker Builds. - You can’t see why the build failed. Open the pipeline in the Salus console: each stage has its own logs. A coding agent reads them with
get_build_logs; if that comes back empty, the console still has them.
The app restarts every few minutes
Check its logs. If it’s running out of memory, raise the memory on the release configuration; new deployments start with 128 MB, the smallest size, which suits small apps. If it crashes on start, the cause is usually one of the variables above.