# Docker (/docs/guides/deployment/docker)

Location: Guides > Deployment > Docker

This guide walks you through setting up a Prisma ORM application within a Docker environment. You'll learn how to configure a Node.js project, integrate Prisma for database management, and orchestrate the application using Docker Compose. By the end, you'll have a fully functional Prisma application running in a Docker container.

Prerequisites [#prerequisites]

* [Docker](https://docs.docker.com/) and [Docker Compose](https://docs.docker.com/compose/) installed
* Node.js version: A [compatible Node.js version](/guides/upgrade-prisma-orm/v6#minimum-supported-nodejs-versions), required for Prisma 6.

See our [system requirements](/orm/reference/system-requirements) for all minimum version requirements.

Before starting, ensure that no PostgreSQL services are running locally, and that the following ports are free to avoid conflicts: `5432` (PostgreSQL), `3000` (application server) or `5555` (Prisma Studio server).

To stop existing PostgreSQL services, use:

```bash
sudo systemctl stop postgresql  # Linux
brew services stop postgresql   # macOS
net stop postgresql             # Windows (Run as Administrator)
```

To stop all running Docker containers and free up ports:

```bash
docker ps -q | xargs docker stop
```

1. Set up your Node.js and Prisma application [#1-set-up-your-nodejs-and-prisma-application]

Let's start by creating a simple Node.js application with Prisma ORM and [Express.js](https://expressjs.com/).

1.1. Initialize your project [#11-initialize-your-project]

First, create a new project directory and initialize a Node.js project:

  

  #### npm

```bash
mkdir docker-test
cd docker-test
npm init
```

  #### pnpm

```bash
mkdir docker-test
cd docker-test
pnpm init
```

  #### yarn

```bash
mkdir docker-test
cd docker-test
yarn init
```

  #### bun

```bash
mkdir docker-test
cd docker-test
bun init
```

This will generate a `package.json` file:

```json title="package.json"
{
  "name": "docker-test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {},
  "keywords": [],
  "author": "",
  "license": "ISC"
}
```

1.2. Install required dependencies [#12-install-required-dependencies]

Next, install the Prisma CLI as a development dependency and Express.js for the server:

  

  #### npm

```bash
npm install prisma @types/pg --save-dev
```

  #### pnpm

```bash
pnpm add prisma @types/pg --save-dev
```

  #### yarn

```bash
yarn add prisma @types/pg --dev
```

  #### bun

```bash
bun add prisma @types/pg --dev
```

  

  #### npm

```bash
npm install @prisma/client @prisma/adapter-pg pg dotenv express
```

  #### pnpm

```bash
pnpm add @prisma/client @prisma/adapter-pg pg dotenv express
```

  #### yarn

```bash
yarn add @prisma/client @prisma/adapter-pg pg dotenv express
```

  #### bun

```bash
bun add @prisma/client @prisma/adapter-pg pg dotenv express
```

> [!INFO]
> If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).

1.3. Set up Prisma ORM [#13-set-up-prisma-orm]

Now, initialize Prisma to generate the necessary files:

  

  #### npm

```bash
npx prisma init --output ../generated/prisma
```

  #### pnpm

```bash
pnpm dlx prisma init --output ../generated/prisma
```

  #### yarn

```bash
yarn dlx prisma init --output ../generated/prisma
```

  #### bun

```bash
bunx --bun prisma init --output ../generated/prisma
```

This creates:

* A `prisma` folder containing `schema.prisma`, where you will define your database schema.
* An `.env` file in the project root, which stores environment variables.

Add a `User` model to the `schema.prisma` file located in the `prisma/schema.prisma` folder:

```prisma title="prisma/schema.prisma"
datasource db {
  provider = "postgresql"
}

generator client {
  provider = "prisma-client"
  output = "../generated/prisma_client" // [!code ++]
}

model User { // [!code ++]
  id        Int      @id @default(autoincrement()) // [!code ++]
  createdAt DateTime @default(now()) // [!code ++]
  email     String   @unique // [!code ++]
  name      String? // [!code ++]
} // [!code ++]
```

> [!INFO]
> In the `schema.prisma` file, we specify a [custom `output` path](/orm/reference/prisma-schema-reference#fields-for-prisma-client-provider) where Prisma will generate its types. This ensures Prisma's types are resolved correctly across different package managers and can be accessed by application consistently inside the container without any permission issues. In this guide, the types will be generated in the `./generated/prisma_client` directory.

Now, create a `prisma.config.ts` file in the root of your project:

```typescript title="prisma.config.ts"
import "dotenv/config";
import { defineConfig, env } from "prisma/config";

export default defineConfig({
  schema: "prisma/schema.prisma",
  migrations: {
    path: "prisma/migrations",
  },
  datasource: {
    url: env("DATABASE_URL"),
  },
});
```

> [!INFO]
> You'll need to install the `dotenv` package to load environment variables:
> 
> 
>   
> 
>   #### npm

>     ```bash
>     npm install dotenv
>     ```
>
> 
>   #### pnpm

>     ```bash
>     pnpm add dotenv
>     ```
>
> 
>   #### yarn

>     ```bash
>     yarn add dotenv
>     ```
>
> 
>   #### bun

>     ```bash
>     bun add dotenv
>     ```
>
> 

1.4. Create an Express.js server [#14-create-an-expressjs-server]

With the Prisma schema in place, let's create an Express.js server to interact with the database. Start by creating an `index.js` file:

```bash
touch index.js
```

Add the following code to set up a basic Express server:

```js title="index.js"
const express = require("express"); // [!code ++]
const { PrismaClient } = require("./generated/prisma_client/client"); // [!code ++]
const { PrismaPg } = require("@prisma/adapter-pg"); // [!code ++]
// [!code ++]
const adapter = new PrismaPg({
  // [!code ++]
  connectionString: process.env.DATABASE_URL, // [!code ++]
}); // [!code ++]
// [!code ++]
const app = express(); // [!code ++]
const prisma = new PrismaClient({
  // [!code ++]
  adapter, // [!code ++]
}); // [!code ++]
app.use(express.json()); // [!code ++]
// [!code ++]
// Get all users // [!code ++]
app.get("/", async (req, res) => {
  // [!code ++]
  const userCount = await prisma.user.count(); // [!code ++]
  res.json(
    // [!code ++]
    userCount == 0 // [!code ++]
      ? "No users have been added yet." // [!code ++]
      : "Some users have been added to the database.", // [!code ++]
  ); // [!code ++]
}); // [!code ++]
// [!code ++]
const PORT = 3000; // [!code ++]
// [!code ++]
app.listen(PORT, () => {
  // [!code ++]
  console.log(`Server is running on http://localhost:${PORT}`); // [!code ++]
}); // [!code ++]
```

Update the `package.json` scripts to include commands for running the server and deploying migrations:

```json title="package.json"
"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1", // [!code --]
  "dev": "node index.js", // [!code ++]
  "db:deploy": "npx prisma migrate deploy && npx prisma generate" // [!code ++]
}
```

Now that the application is set up, let's move on to configuring a PostgreSQL database using Docker Compose.

2. Set up a PostgreSQL database with Docker Compose [#2-set-up-a-postgresql-database-with-docker-compose]

To perform database migrations, we'll create a standalone PostgreSQL database using Docker Compose.

2.1. Create a Docker Compose file for PostgreSQL [#21-create-a-docker-compose-file-for-postgresql]

Create a `docker-compose.postgres.yml` file in the root directory:

```yml title="docker-compose.postgres.yml"
version: '3.7' // [!code ++]
 // [!code ++]
services: // [!code ++]
  postgres: // [!code ++]
    image: postgres:15 // [!code ++]
    restart: always // [!code ++]
    environment: // [!code ++]
      - POSTGRES_DB=postgres // [!code ++]
      - POSTGRES_USER=postgres // [!code ++]
      - POSTGRES_PASSWORD=prisma // [!code ++]
    ports: // [!code ++]
      - "5432:5432" // [!code ++]
    networks: // [!code ++]
      - prisma-network // [!code ++]
    healthcheck: // [!code ++]
      test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"] // [!code ++]
      interval: 5s // [!code ++]
      timeout: 2s // [!code ++]
      retries: 20 // [!code ++]
    volumes: // [!code ++]
      - postgres_data:/var/lib/postgresql/data // [!code ++]
    command: postgres -c listen_addresses='*' // [!code ++]
    logging: // [!code ++]
      options: // [!code ++]
        max-size: "10m" // [!code ++]
        max-file: "3" // [!code ++]
 // [!code ++]
networks: // [!code ++]
  prisma-network: // [!code ++]
 // [!code ++]
volumes: // [!code ++]
  postgres_data: // [!code ++]
```

2.2. Start the PostgreSQL container [#22-start-the-postgresql-container]

Run the following command to start the database:

```bash
docker compose -f docker-compose.postgres.yml up -d
```

2.3. Perform database migrations [#23-perform-database-migrations]

With the database running, update the `.env` file with the following database connection url:

```bash title=".env"
DATABASE_URL="postgresql://postgres:prisma@localhost:5432/postgres?schema=public" # [!code highlight]
```

Run the migration to create the database schema:

  

  #### npm

```bash
npx prisma migrate dev --name init
```

  #### pnpm

```bash
pnpm dlx prisma migrate dev --name init
```

  #### yarn

```bash
yarn dlx prisma migrate dev --name init
```

  #### bun

```bash
bunx --bun prisma migrate dev --name init
```

Then generate Prisma Client:

  

  #### npm

```bash
npx prisma generate
```

  #### pnpm

```bash
pnpm dlx prisma generate
```

  #### yarn

```bash
yarn dlx prisma generate
```

  #### bun

```bash
bunx --bun prisma generate
```

This should generate a `migrations` folder in the `prisma` folder and the Prisma Client in the `generated/prisma_client` directory.

2.4. Test the application [#24-test-the-application]

Start the server and verify it works:

  

  #### npm

```bash
npm run dev
```

  #### pnpm

```bash
pnpm run dev
```

  #### yarn

```bash
yarn dev
```

  #### bun

```bash
bun run dev
```

Visit [`http://localhost:3000`](http://localhost:3000) to see the message:

```bash
No users have been added yet.
```

Stop the local server.

2.5. Clean up the standalone database [#25-clean-up-the-standalone-database]

Once testing is complete, remove the standalone PostgreSQL container:

```bash
docker compose -f docker-compose.postgres.yml down --remove-orphans
```

This command will:

* Stop running containers.
* Remove containers.
* Remove the default network created by Docker Compose.
* Remove associated volumes (if not named explicitly).

Now that we've tested the application locally, let's containerize it using Docker.

3. Run the app and database together with Docker Compose [#3-run-the-app-and-database-together-with-docker-compose]

We'll now containerize the application using Docker, ensuring it can run in any environment.

To do that create a `Dockerfile` in project root:

```bash
touch Dockerfile
```

For the next step, you'll need to choose between two options for the base image: `node:alpine` (lightweight) or `node:slim` (stable). Both options are fully supported by Prisma ORM, but may have to be configured differently.

3.1. Option 1: Use Linux Alpine (node:alpine) as a base image [#31-option-1-use-linux-alpine-nodealpine-as-a-base-image]

The `node:alpine` image is based on Alpine Linux, a lightweight Linux distribution that uses the `musl` C standard library. It's perfect if you want to keep your container small and efficient. Prisma supports Alpine on `amd64` out of the box, and supports it on `arm64` since `prisma@4.10.0`.

Add the following content to the `Dockerfile`:

```shell title="Dockerfile"
FROM node:lts-alpine3.17

WORKDIR /usr/src/app

COPY package.json package-lock.json ./

RUN npm ci

COPY . .

CMD ["sh", "-c", "npm run db:deploy && npm run dev"]
```

> [!INFO]
> When running on Linux Alpine, Prisma downloads engines that are compiled for the `musl` C standard library. Please don't install `glibc` on Alpine (e.g., via the `libc6-compat` package), as that would prevent Prisma from running successfully.

Related Docker images:

* `node:lts-alpine`
* `node:16-alpine`
* `node:14-alpine`

3.1. Option 2: Use Linux Debian (node:slim) as a base image [#31-option-2-use-linux-debian-nodeslim-as-a-base-image]

The `node:slim` image is based on Linux Debian, a stable and widely supported distribution that uses the `glibc` C standard library. It is mostly supported out of the box on `amd64` and `arm64`, making it a good choice if you're running into compatibility issues with Alpine or need a more production-ready environment. However, some older versions of this image may come without `libssl` installed, so it's sometimes necessary to install it manually.

Add the following content to the `Dockerfile`:

```shell title="Dockerfile"
FROM node:slim

RUN apt-get update -y \
&& apt-get install -y openssl

WORKDIR /usr/src/app

COPY package.json package-lock.json ./

RUN npm ci

COPY . .

CMD ["sh", "-c", "npm run db:deploy && npm run dev"]
```

Related Docker images:

* `node:lts-slim`
* `node:bullseye-slim`
* `node:buster-slim`
* `node:stretch-slim`

3.2. Create and configure a Docker Compose file [#32-create-and-configure-a-docker-compose-file]

Now that the `Dockerfile` is ready, we'll use Docker Compose to manage both the app and the database together. This makes it easy to start, stop, and manage the entire setup.

Create a `docker-compose.yml` file in your project folder:

```bash
touch docker-compose.yml
```

Add the following configuration to the file:

```yml title="docker-compose.yml"
version: '3.7' // [!code ++]
 // [!code ++]
services: // [!code ++]
  postgres_db: // [!code ++]
    image: postgres:15 // [!code ++]
    hostname: postgres_db // [!code ++]
    container_name: postgres_db // [!code ++]
    restart: always // [!code ++]
    environment: // [!code ++]
      POSTGRES_DB: postgres // [!code ++]
      POSTGRES_USER: postgres // [!code ++]
      POSTGRES_PASSWORD: prisma // [!code ++]
    ports: // [!code ++]
      - '5432:5432' // [!code ++]
    networks: // [!code ++]
      - prisma-network // [!code ++]
    healthcheck: // [!code ++]
      test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"] // [!code ++]
      interval: 5s // [!code ++]
      timeout: 2s // [!code ++]
      retries: 20 // [!code ++]
 // [!code ++]
  server: // [!code ++]
    build: // [!code ++]
      context: . // [!code ++]
      dockerfile: Dockerfile // [!code ++]
    ports: // [!code ++]
      - '3000:3000' // [!code ++]
    stdin_open: true // [!code ++]
    tty: true  # Keeps the container running for debugging // [!code ++]
    depends_on: // [!code ++]
      postgres_db: // [!code ++]
        condition: service_healthy // [!code ++]
    env_file: // [!code ++]
      - .env.prod // [!code ++]
    networks: // [!code ++]
      - prisma-network // [!code ++]
networks: // [!code ++]
  prisma-network: // [!code ++]
    name: prisma-network // [!code ++]
```

3.3. Configure environment variable for the container [#33-configure-environment-variable-for-the-container]

Before running the app, we need to configure the environment variables. Create a `.env.prod` file:

```
touch .env.prod
```

Add the following database connection url to the `.env.prod` file:

```bash title=".env.prod"
DATABASE_URL="postgresql://postgres:prisma@postgres_db:5432/postgres?schema=public" # [!code highlight]
```

3.4. Build and run the application [#34-build-and-run-the-application]

With everything set up, it's time to build and run the app using Docker Compose. Run the following command:

```bash
docker compose -f docker-compose.yml up --build -d
```

Visit `http://localhost:3000` to see your app running with the message:

```bash
No users have been added yet.
```

3.5. Bonus: Add Prisma Studio for database management [#35-bonus-add-prisma-studio-for-database-management]

[Prisma Studio](/studio) offers a graphical user interface (GUI) that allows you to view and manage your database directly in the browser. It's a great tool for debugging and managing your data during development.

To add Prisma Studio to your Docker setup, update the `docker-compose.yml` file:

```yml title="docker.compose.yml"
version: '3.7'

services:
  postgres_db:
    image: postgres:15
    hostname: postgres_db
    container_name: postgres_db
    restart: always
    environment:
      POSTGRES_DB: postgres
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: prisma
    ports:
      - '5432:5432'
    networks:
      - prisma-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
      interval: 5s
      timeout: 2s
      retries: 20

  server:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - '3000:3000'
    stdin_open: true
    tty: true  # Keeps the container running for debugging
    depends_on:
      postgres_db:
        condition: service_healthy
    env_file:
      - .env.prod
    networks:
      - prisma-network
  prisma-studio: // [!code ++]
    image: node:lts-alpine3.17 // [!code ++]
    working_dir: /usr/src/app // [!code ++]
    volumes: // [!code ++]
      - .:/usr/src/app // [!code ++]
    command: npx prisma studio --port 5555 --browser none // [!code ++]
    ports: // [!code ++]
      - "5555:5555" // [!code ++]
    env_file: // [!code ++]
      - .env.prod // [!code ++]
    networks: // [!code ++]
      - prisma-network // [!code ++]
    depends_on: // [!code ++]
      postgres_db: // [!code ++]
        condition: service_healthy // [!code ++]
      server: // [!code ++]
        condition: service_started // [!code ++]
networks:
  prisma-network:
    name: prisma-network
```

This will start Prisma Studio at [`http://localhost:5555`](http://localhost:5555) alongside the main app at [`http://localhost:3000`](http://localhost:3000). You can use Prisma Studio to manage your database with a GUI.

Run the following command to start everything:

```bash
docker compose -f docker-compose.yml up --build -d
```

By following this guide, you've successfully containerized your Prisma app and database using Docker Compose.

## Related pages

- [`Bun workspaces`](https://www.prisma.io/docs/guides/deployment/bun-workspaces): Learn step-by-step how to integrate Prisma ORM in a Bun workspaces monorepo to build scalable and modular applications efficiently
- [`Cloudflare D1`](https://www.prisma.io/docs/guides/deployment/cloudflare-d1): Learn how to use Prisma ORM with Cloudflare D1
- [`Cloudflare Workers`](https://www.prisma.io/docs/guides/deployment/cloudflare-workers): Learn how to use Prisma ORM in a Cloudflare Workers project
- [`pnpm workspaces`](https://www.prisma.io/docs/guides/deployment/pnpm-workspaces): Learn step-by-step how to integrate Prisma ORM in a pnpm workspaces monorepo to build scalable and modular applications efficiently
- [`Turborepo`](https://www.prisma.io/docs/guides/deployment/turborepo): Learn step-by-step how to integrate Prisma ORM with Turborepo to build modular, scalable monorepo architectures efficiently