> ## Documentation Index
> Fetch the complete documentation index at: https://docs.slipway.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy an Express app

> Deploy a Node and Express API with a live URL.

Express runs on slipway as a `web` service on the Node runtime.

## Prerequisites

An Express app in a GitHub or GitLab repository.

## Configure the app

Bind to `0.0.0.0` and read `PORT`:

```javascript index.js theme={"system"}
const express = require("express");
const app = express();

app.get("/healthz", (req, res) => res.send("ok"));

const port = process.env.PORT || 3000;
app.listen(port, "0.0.0.0", () => console.log(`listening on ${port}`));
```

If your app sits behind slipway's edge and you read client IPs or use secure cookies, trust
the proxy:

```javascript theme={"system"}
app.set("trust proxy", 1);
```

## Add slipway.yaml

```yaml slipway.yaml theme={"system"}
version: 1

services:
  - name: api
    runtime: node
    runtimeVersion: "22"
    buildCommand: npm ci
    command: ["node", "index.js"]
    ports:
      - port: 3000
        public: true
    healthCheckPath: /healthz
    env:
      NODE_ENV: production
      PORT: "3000"
```

If your app has a build step, add it:

```yaml slipway.yaml theme={"system"}
    buildCommand: npm ci && npm run build
    command: ["node", "dist/index.js"]
```

## Add a database and a cache

```yaml slipway.yaml theme={"system"}
databases:
  - name: db
    engine: postgres
    diskSizeGB: 10
  - name: cache
    engine: redis

services:
  - name: api
    runtime: node
    env:
      DATABASE_URL: ${service.db.url}
      REDIS_URL: ${service.cache.url}
```

Redis needs no `diskSizeGB` when you are using it as a cache. See [Redis](/data/redis).

## Graceful shutdown

Handle `SIGTERM` so in-flight requests finish during a rollout:

```javascript theme={"system"}
const server = app.listen(port, "0.0.0.0");
process.on("SIGTERM", () => server.close(() => process.exit(0)));
```

slipway allows 30 seconds by default. Raise it with `maxShutdownDelaySeconds` up to 300.

## Next steps

> **[Scaling](/services/scaling)**
>
> Run several replicas behind the load balancer.

> **[Logs and shell](/observability/logs-and-shell)**
>
> Watch output and exec into the container.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.