# 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](https://salus.cloud/docs/deployments/environment-configurations/configuring/).

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 `.env` file usually isn’t in the repository, so its values never reach Salus. Add each one to the project. See [Environment Variables](https://salus.cloud/docs/deployments/environment-configurations/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.
-   **`localhost` addresses.** On your machine the API, the database and the app share `localhost`; on Salus each runs separately. Replace hard-coded `localhost` URLs with variables. A linked database’s address comes in `SALUS_DATABASE_<NAME>_HOST` and the full connection string in `SALUS_DATABASE_<NAME>_CONNECTION_STRING`. See [Connect a Database](https://salus.cloud/docs/deployments/databases/connect/).
-   **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](https://salus.cloud/docs/deployments/databases/), 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](https://salus.cloud/docs/guides/v0/).
-   **“No default process” or “no start command”.** Salus can’t tell how to start the app. Node.js needs a `start` script in `package.json`; Python needs a `Procfile` with a `web:` 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](https://salus.cloud/docs/pipelines/builds/custom-docker/).
-   **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.
