diff --git a/docusaurus/docs/cms/faq.md b/docusaurus/docs/cms/faq.md
index 1fd9509c5c..08f9ac0787 100644
--- a/docusaurus/docs/cms/faq.md
+++ b/docusaurus/docs/cms/faq.md
@@ -18,6 +18,7 @@ tags:
- typescript
- database
- foreign keys
+- docker
---
@@ -140,6 +141,23 @@ By default, most package managers enable hoisting, however, if it's not function
You can see the to see which feature requests are currently being worked on and which have not been started yet, and to add new feature requests.
+## Why doesn't Strapi provide official Docker images?
+
+Strapi is a framework used to build many different types of applications. A single Docker image cannot cover all use cases, so Strapi provides Dockerfile examples instead. See the [Docker installation guide](/cms/installation/docker) for details.
+
+## Why use different Dockerfiles for development and production with Docker?
+
+Strapi builds the admin panel with React and bundles it into the application during the build process. The Strapi backend serves the admin panel as a web server, and the following environment variables are statically compiled into the built admin panel:
+
+- `STRAPI_ADMIN_BACKEND_URL`
+- `ADMIN_PATH` (if using a custom admin path)
+
+Because these values are baked in at build time, you must either pass them as `ARG` in your Dockerfile or rebuild the image when they change. Without this, the admin panel may point to `localhost:1337` instead of your production URL.
+
+Additionally, development images are not optimized for performance and should not be exposed to the public internet. Building separate Docker images for each environment ensures correct configuration and better security.
+
+See the [Docker installation guide](/cms/installation/docker) for full Dockerfile examples.
+
## Is there an MCP server for Strapi?
There’s currently no MCP () server available, but it’s in the works!
diff --git a/docusaurus/docs/cms/installation.md b/docusaurus/docs/cms/installation.md
index 9b01dff1b6..c1b6b0a5a5 100644
--- a/docusaurus/docs/cms/installation.md
+++ b/docusaurus/docs/cms/installation.md
@@ -14,6 +14,6 @@ Strapi projects can be installed either locally on a computer or on a remote ser
-If you already have an existing Strapi project on your local machine, the following guide provides step-by-step instructions on creating a custom Docker image for your project:
+If you already have an existing Strapi project on your local machine, the following guide covers running it in Docker containers for development and production:
-
+
diff --git a/docusaurus/docs/cms/installation/docker.md b/docusaurus/docs/cms/installation/docker.md
index 70c4eaba91..623f927524 100644
--- a/docusaurus/docs/cms/installation/docker.md
+++ b/docusaurus/docs/cms/installation/docker.md
@@ -3,95 +3,65 @@ title: Docker
displayed_sidebar: cmsSidebar
pagination_prev: cms/installation/cli
pagination_next: cms/features/admin-panel
-description: Quickly create a Docker container from a local project.
+description: Build and run a Strapi project in a Docker container for development and production environments.
tags:
-- installation
-- environment
-- MySQL
+ - installation
+ - docker
+ - deployment
+ - production
---
import DockerEnvTable from '/docs/snippets/docker-env-table.md'
# Running Strapi in a Docker container
+
+This page guides you through running Strapi in Docker containers for development and production environments, including Dockerfile examples, Docker Compose configurations, and troubleshooting common issues.
+
+
:::caution
Strapi does not build any official container images. The following instructions are provided as a courtesy to the community. If you have any questions please reach out on .
:::
-:::danger
- Strapi applications are not meant to be connected to a pre-existing database, not created by a Strapi application, nor connected to a Strapi v3 database. The Strapi team will not support such attempts. Attempting to connect to an unsupported database may, and most likely will, result in lost data such as dropped tables.
-:::
-
-The following documentation will guide you through building a custom container with an existing Strapi project.
-
-Docker is an open platform that allows developing, shipping, and running applications by using containers (i.e. packages containing all the parts an application needs to function, such as libraries and dependencies). Containers are isolated from each other and bundle their own software, libraries, and configuration files; they can communicate with each other through well-defined channels.
+Containerizing Strapi makes the runtime environment reproducible across machines and simplifies dependency management for deployment. This page covers building custom Docker images for an existing Strapi 5 project, with separate instructions for [development](#development-environment) and [production](#production-environment) environments, a [troubleshooting](#troubleshooting) section, and a list of [community tools](#community-tools-and-images). If you would rather not write your own Dockerfile, see [Community tools and images](#community-tools-and-images) for packaged alternatives.
:::prerequisites
- installed on your machine
+- v2 or later
- A [supported version of Node.js](/cms/installation/cli#preparing-the-installation)
-- An **existing Strapi 5 project**, or a new one created with the [Quick Start guide](/cms/quick-start.md)
-- (_optional_) installed on your machine
-- (_optional_) installed on your machine
+- An **existing Strapi 5 project**, or a new one created with the [Quick Start guide](/cms/quick-start)
+- npm as your package manager (the examples on this page use npm, but you can adapt the commands for yarn or pnpm)
:::
-## Development and/or Staging environments
-
-For working with Strapi locally on your host machine you can use the , and if needed the can also be used to start up a database container.
+## Development environment
-Both methods require an existing Strapi project or a new one created (see [Quick Start guide](/cms/quick-start.md)).
+Development images use `npm run develop` and mount your local source code for hot-reload. Before creating the Dockerfile, set up 2 required files: `.dockerignore` and `.env`.
-### Development Dockerfile
+### Create a .dockerignore file
-The following `Dockerfile` can be used to build a non-production Docker image for a Strapi project.
+A `.dockerignore` file prevents local files from being copied into the Docker image. Without it, your local `node_modules` directory gets included in the build context, which causes architecture mismatches (e.g., x64 binaries on ARM) and increases the image size.
-:::note
-
-If you are using `docker-compose`, you can skip setting the environment variables manually, as they will be set in the `docker-compose.yml` file or a `.env` file.
-
-:::
-
-
-
-For more information on the `Dockerfile` and its commands, please refer to the .
-
-Sample `Dockerfile`:
-
-
-
-
-
-```dockerfile title="./Dockerfile"
-FROM node:22-alpine
-# Installing libvips-dev for sharp Compatibility
-RUN apk update && apk add --no-cache build-base gcc autoconf automake zlib-dev libpng-dev nasm bash vips-dev git
-ARG NODE_ENV=development
-ENV NODE_ENV=${NODE_ENV}
-
-WORKDIR /opt/
-COPY package.json yarn.lock ./
-RUN yarn global add node-gyp
-RUN yarn config set network-timeout 600000 -g && yarn install --frozen-lockfile
-ENV PATH=/opt/node_modules/.bin:$PATH
+Create a `.dockerignore` file at the root of your Strapi project:
-WORKDIR /opt/app
-COPY . .
-RUN chown -R node:node /opt/app
-USER node
-RUN ["yarn", "build"]
-EXPOSE 1337
-CMD ["yarn", "develop"]
+```txt title="./.dockerignore"
+node_modules/
+.tmp/
+.cache/
+.git/
+build/
+.env
```
-
+### Create the Dockerfile
-
+The following `Dockerfile` can be used to build a non-production Docker image for a Strapi project.
```dockerfile title="./Dockerfile"
FROM node:22-alpine
-# Installing libvips-dev for sharp Compatibility
-RUN apk update && apk add --no-cache build-base gcc autoconf automake zlib-dev libpng-dev nasm bash vips-dev git
+# Installing libvips-dev for sharp compatibility
+RUN apk update && apk add --no-cache build-base gcc autoconf automake zlib-dev libpng-dev bash vips-dev git
ARG NODE_ENV=development
ENV NODE_ENV=${NODE_ENV}
@@ -105,17 +75,28 @@ WORKDIR /opt/app
COPY . .
RUN chown -R node:node /opt/app
USER node
-RUN ["npm", "run", "build"]
EXPOSE 1337
CMD ["npm", "run", "develop"]
-
```
-
+:::tip Optional: pre-build the admin panel
+You can add `RUN ["npm", "run", "build"]` before the `EXPOSE` line to pre-build the admin panel and speed up the first start. This is not required since `npm run develop` rebuilds it in watch mode.
+:::
-
+:::tip Optional: reduce image size with virtual packages
+For single-stage Dockerfiles like this dev image, you can use the `--virtual` flag to clean up build dependencies after `npm ci`, producing a leaner image:
-:::tip Alternative base image for restricted networks
+```dockerfile
+RUN apk add --no-cache --virtual .build-deps \
+ build-base gcc autoconf automake zlib-dev libpng-dev bash vips-dev git \
+ && npm ci \
+ && apk del .build-deps
+```
+
+This is not needed in the production Dockerfile, which already discards build dependencies through its multi-stage build.
+:::
+
+:::note Alternative base image for restricted networks
If your CI environment has limited network access (e.g., DNS restrictions that prevent downloading Sharp prebuilt binaries from GitHub), consider using `node:22-slim` instead of `node:22-alpine`. The Debian-based slim image avoids the need to compile native dependencies like `libvips` from source, and Sharp's prebuilt binaries work out of the box:
```dockerfile
@@ -123,22 +104,55 @@ FROM node:22-slim
RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*
```
-This trades a slightly larger image for simpler builds and fewer network dependencies.
+
+This trades a slightly larger image for fewer build dependencies and fewer network requirements.
:::
-### (Optional) Docker Compose
+### Set up environment variables
+
+Create a `.env` file at the root of your Strapi project. Docker Compose reads this file automatically when starting containers, so there is no need to `export` them in your shell.
+
+
+
+The following example contains placeholder values. Replace them with your own values before starting the containers:
+
+```bash title="./.env"
+# Server
+HOST=0.0.0.0
+PORT=1337
+
+# Database
+# Use 'mysql' for MySQL or MariaDB, and change DATABASE_PORT to 3306
+DATABASE_CLIENT=postgres
+DATABASE_HOST=strapiDB
+DATABASE_PORT=5432
+DATABASE_NAME=strapi
+DATABASE_USERNAME=strapi
+DATABASE_PASSWORD=strapi
+
+# Secrets
+APP_KEYS=toBeModified1,toBeModified2
+API_TOKEN_SALT=tobemodified
+ADMIN_JWT_SECRET=tobemodified
+TRANSFER_TOKEN_SALT=tobemodified
+JWT_SECRET=tobemodified
+ENCRYPTION_KEY=tobemodified
+
+# Environment
+NODE_ENV=development
+```
+
+### Add Docker Compose for the database
-The following `docker-compose.yml` can be used to start up a database container and a Strapi container along with a shared network for communication between the two.
+The following `docker-compose.yml` starts a database container and a Strapi container on a shared network.
:::note
-For more information about running Docker compose and its commands, please refer to the .
+For more information about Docker Compose and its commands, see the .
:::
-Sample `docker-compose.yml`:
-
-
+
```yml title="./docker-compose.yml"
services:
@@ -147,51 +161,43 @@ services:
build: .
image: strapi:latest
restart: unless-stopped
- env_file: .env
- environment:
- DATABASE_CLIENT: ${DATABASE_CLIENT}
- DATABASE_HOST: strapiDB
- DATABASE_PORT: ${DATABASE_PORT}
- DATABASE_NAME: ${DATABASE_NAME}
- DATABASE_USERNAME: ${DATABASE_USERNAME}
- DATABASE_PASSWORD: ${DATABASE_PASSWORD}
- JWT_SECRET: ${JWT_SECRET}
- ADMIN_JWT_SECRET: ${ADMIN_JWT_SECRET}
- APP_KEYS: ${APP_KEYS}
- NODE_ENV: ${NODE_ENV}
+ env_file: .env # All variables from .env are injected into the container
volumes:
- ./config:/opt/app/config
- ./src:/opt/app/src
- ./package.json:/opt/package.json
- - ./yarn.lock:/opt/yarn.lock
- - ./.env:/opt/app/.env
+ - ./package-lock.json:/opt/package-lock.json
+ - ./.env:/opt/app/.env # Needed because Strapi uses dotenv to read .env in development
- ./public/uploads:/opt/app/public/uploads
ports:
- "1337:1337"
networks:
- strapi
depends_on:
- - strapiDB
+ strapiDB:
+ condition: service_healthy
strapiDB:
container_name: strapiDB
- platform: linux/amd64 #for platform error on Apple M1 chips
+ # platform: linux/amd64 # Uncomment if you encounter platform errors on Apple Silicon
restart: unless-stopped
- env_file: .env
- image: mysql:8.0
- command: --default-authentication-plugin=mysql_native_password
+ image: postgres:16-alpine
environment:
- MYSQL_USER: ${DATABASE_USERNAME}
- MYSQL_ROOT_PASSWORD: ${DATABASE_PASSWORD}
- MYSQL_PASSWORD: ${DATABASE_PASSWORD}
- MYSQL_DATABASE: ${DATABASE_NAME}
+ POSTGRES_USER: ${DATABASE_USERNAME}
+ POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
+ POSTGRES_DB: ${DATABASE_NAME}
volumes:
- - strapi-data:/var/lib/mysql
- #- ./data:/var/lib/mysql # if you want to use a bind folder
+ - strapi-data:/var/lib/postgresql/data/
+ #- ./data:/var/lib/postgresql/data/ # if you want to use a bind folder
ports:
- - "3306:3306"
+ - "5432:5432" # Exposed for local debugging tools; remove if not needed
networks:
- strapi
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U ${DATABASE_USERNAME} -d ${DATABASE_NAME}"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
volumes:
strapi-data:
@@ -204,48 +210,36 @@ networks:
-
+
```yml title="./docker-compose.yml"
-version: "3"
services:
strapi:
container_name: strapi
build: .
image: strapi:latest
restart: unless-stopped
- env_file: .env
- environment:
- DATABASE_CLIENT: ${DATABASE_CLIENT}
- DATABASE_HOST: strapiDB
- DATABASE_PORT: ${DATABASE_PORT}
- DATABASE_NAME: ${DATABASE_NAME}
- DATABASE_USERNAME: ${DATABASE_USERNAME}
- DATABASE_PASSWORD: ${DATABASE_PASSWORD}
- JWT_SECRET: ${JWT_SECRET}
- ADMIN_JWT_SECRET: ${ADMIN_JWT_SECRET}
- APP_KEYS: ${APP_KEYS}
- NODE_ENV: ${NODE_ENV}
+ env_file: .env # All variables from .env are injected into the container
volumes:
- ./config:/opt/app/config
- ./src:/opt/app/src
- ./package.json:/opt/package.json
- - ./yarn.lock:/opt/yarn.lock
- - ./.env:/opt/app/.env
+ - ./package-lock.json:/opt/package-lock.json
+ - ./.env:/opt/app/.env # Needed because Strapi uses dotenv to read .env in development
- ./public/uploads:/opt/app/public/uploads
ports:
- "1337:1337"
networks:
- strapi
depends_on:
- - strapiDB
+ strapiDB:
+ condition: service_healthy
strapiDB:
container_name: strapiDB
- platform: linux/amd64 #for platform error on Apple M1 chips
+ # platform: linux/amd64 # Uncomment if you encounter platform errors on Apple Silicon
restart: unless-stopped
- env_file: .env
- image: mariadb:latest
+ image: mysql:8.4
environment:
MYSQL_USER: ${DATABASE_USERNAME}
MYSQL_ROOT_PASSWORD: ${DATABASE_PASSWORD}
@@ -255,9 +249,14 @@ services:
- strapi-data:/var/lib/mysql
#- ./data:/var/lib/mysql # if you want to use a bind folder
ports:
- - "3306:3306"
+ - "3306:3306" # Exposed for local debugging tools; remove if not needed
networks:
- strapi
+ healthcheck:
+ test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
volumes:
strapi-data:
@@ -270,60 +269,53 @@ networks:
-
+
```yml title="./docker-compose.yml"
-version: "3"
services:
strapi:
container_name: strapi
build: .
image: strapi:latest
restart: unless-stopped
- env_file: .env
- environment:
- DATABASE_CLIENT: ${DATABASE_CLIENT}
- DATABASE_HOST: strapiDB
- DATABASE_PORT: ${DATABASE_PORT}
- DATABASE_NAME: ${DATABASE_NAME}
- DATABASE_USERNAME: ${DATABASE_USERNAME}
- DATABASE_PASSWORD: ${DATABASE_PASSWORD}
- JWT_SECRET: ${JWT_SECRET}
- ADMIN_JWT_SECRET: ${ADMIN_JWT_SECRET}
- APP_KEYS: ${APP_KEYS}
- NODE_ENV: ${NODE_ENV}
+ env_file: .env # All variables from .env are injected into the container
volumes:
- ./config:/opt/app/config
- ./src:/opt/app/src
- ./package.json:/opt/package.json
- - ./yarn.lock:/opt/yarn.lock
- - ./.env:/opt/app/.env
+ - ./package-lock.json:/opt/package-lock.json
+ - ./.env:/opt/app/.env # Needed because Strapi uses dotenv to read .env in development
- ./public/uploads:/opt/app/public/uploads
ports:
- "1337:1337"
networks:
- strapi
depends_on:
- - strapiDB
+ strapiDB:
+ condition: service_healthy
strapiDB:
container_name: strapiDB
- platform: linux/amd64 #for platform error on Apple M1 chips
+ # platform: linux/amd64 # Uncomment if you encounter platform errors on Apple Silicon
restart: unless-stopped
- env_file: .env
- image: postgres:16.0-alpine
+ image: mariadb:11.4
environment:
- POSTGRES_USER: ${DATABASE_USERNAME}
- POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
- POSTGRES_DB: ${DATABASE_NAME}
+ MYSQL_USER: ${DATABASE_USERNAME}
+ MYSQL_ROOT_PASSWORD: ${DATABASE_PASSWORD}
+ MYSQL_PASSWORD: ${DATABASE_PASSWORD}
+ MYSQL_DATABASE: ${DATABASE_NAME}
volumes:
- - strapi-data:/var/lib/postgresql/data/ #using a volume
- #- ./data:/var/lib/postgresql/data/ # if you want to use a bind folder
-
+ - strapi-data:/var/lib/mysql
+ #- ./data:/var/lib/mysql # if you want to use a bind folder
ports:
- - "5432:5432"
+ - "3306:3306" # Exposed for local debugging tools; remove if not needed
networks:
- strapi
+ healthcheck:
+ test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
volumes:
strapi-data:
@@ -338,156 +330,301 @@ networks:
-## Production Environments
+### Build and run
-The Docker image in production is different from the one used in development/staging environments because of the differences in the admin build process in addition to the command used to run the application. Typical production environments will use a reverse proxy to serve the application and the admin panel. The Docker image is built with the production build of the admin panel and the command used to run the application is `strapi start`.
+1. Build and start all containers:
-Once the [Dockerfile](#production-dockerfile) is created, the [production container](#building-the-production-container) can be built. Optionally, the container can be published to a [registry](#optional-publishing-the-container-to-a-registry) to make it available to the community. [Community tools](#community-tools) can help you
-in the process of building a production Docker image and deploying it to a production environment.
+ ```bash
+ docker compose up --build
+ ```
-### Production Dockerfile
+2. Open `http://localhost:1337/admin` in your browser to access the Strapi admin panel.
-The following `Dockerfile` can be used to build a production Docker image for a Strapi project.
+To stop the containers, run `docker compose down`. Add the `-v` flag to also remove the database volume.
-
+## Production environment
-
-
-```dockerfile title="./Dockerfile.prod"
-# Creating multi-stage build for production
-FROM node:22-alpine AS build
-RUN apk update && apk add --no-cache build-base gcc autoconf automake zlib-dev libpng-dev vips-dev git > /dev/null 2>&1
-ARG NODE_ENV=production
-ENV NODE_ENV=${NODE_ENV}
+Production images differ from development images in 3 key ways: they use multi-stage builds to reduce image size, they install only production dependencies in the final stage, and they run `npm run start` instead of the develop command. This ensures the image contains only what is needed to serve the application, without development tooling or source maps. A reverse proxy should sit in front of the Strapi container in production (see [deployment documentation](/cms/deployment)).
-WORKDIR /opt/
-COPY package.json yarn.lock ./
-RUN yarn global add node-gyp
-RUN yarn config set network-timeout 600000 -g && yarn install --frozen-lockfile --production
-ENV PATH=/opt/node_modules/.bin:$PATH
-WORKDIR /opt/app
-COPY . .
-RUN yarn build
+### Create the production Dockerfile
-# Creating final production image
-FROM node:22-alpine
-RUN apk add --no-cache vips-dev
-ENV NODE_ENV=production
-ENV NODE_ENV=${NODE_ENV}
-WORKDIR /opt/app
-COPY --from=build /opt/node_modules ./node_modules
-COPY --from=build /opt/app ./
-ENV PATH=/opt/node_modules/.bin:$PATH
+The following `Dockerfile.prod` uses a multi-stage build. The first stage installs all dependencies, including devDependencies needed for the build step, and builds the admin panel. The second stage copies only production assets into the final image.
-RUN chown -R node:node /opt/app
-USER node
-EXPOSE 1337
-CMD ["yarn", "start"]
-```
-
-
-
-
+:::caution
+Do not set `NODE_ENV=production` before `npm ci`. Doing so causes npm to skip `devDependencies`, which Strapi needs to compile the admin panel. The build may appear to succeed but produce a broken or incomplete admin bundle.
+:::
```dockerfile title="./Dockerfile.prod"
-# Creating multi-stage build for production
+# Build stage
FROM node:22-alpine AS build
-RUN apk update && apk add --no-cache build-base gcc autoconf automake zlib-dev libpng-dev vips-dev git > /dev/null 2>&1
-ARG NODE_ENV=production
-ENV NODE_ENV=${NODE_ENV}
+RUN apk update && apk add --no-cache build-base gcc autoconf automake zlib-dev libpng-dev bash vips-dev git > /dev/null 2>&1
WORKDIR /opt/
COPY package.json package-lock.json ./
RUN npm install -g node-gyp
-RUN npm config set fetch-retry-maxtimeout 600000 -g && npm ci --only=production
+RUN npm config set fetch-retry-maxtimeout 600000 -g && npm ci
ENV PATH=/opt/node_modules/.bin:$PATH
+
WORKDIR /opt/app
COPY . .
+# Uncomment the following lines to set the admin panel URL at build time.
+# Without this, the admin panel defaults to localhost:1337.
+# ARG STRAPI_ADMIN_BACKEND_URL
+# ENV STRAPI_ADMIN_BACKEND_URL=${STRAPI_ADMIN_BACKEND_URL}
+ENV NODE_ENV=production
RUN npm run build
-# Creating final production image
+# Production stage
FROM node:22-alpine
RUN apk add --no-cache vips-dev
-ARG NODE_ENV=production
-ENV NODE_ENV=${NODE_ENV}
+ENV NODE_ENV=production
+
+WORKDIR /opt/
+COPY --from=build /opt/package.json /opt/package-lock.json ./
+RUN npm ci --omit=dev && npm cache clean --force # --omit=dev replaces the deprecated --only=production
+ENV PATH=/opt/node_modules/.bin:$PATH
+
WORKDIR /opt/app
-COPY --from=build /opt/node_modules ./node_modules
COPY --from=build /opt/app ./
-ENV PATH=/opt/node_modules/.bin:$PATH
RUN chown -R node:node /opt/app
USER node
EXPOSE 1337
+HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
+ CMD wget --quiet --tries=1 --spider http://localhost:1337/_health || exit 1
CMD ["npm", "run", "start"]
-
```
-
+:::tip Optimize image size
+The `COPY --from=build /opt/app ./` line copies the entire application directory, including source files. For a leaner image, you can replace it with selective copies (e.g., `dist/build/`, `config/`, `public/`, `src/`). The Strapi 5 admin bundle lands in `dist/build/`, so make sure that path is included. This is optional since Strapi needs most of these files at runtime.
+:::
-
+:::info Key difference from the development Dockerfile
+The build stage installs all dependencies (including devDependencies) because the `npm run build` step needs them to compile the admin panel. The production stage then installs only production dependencies, keeping the final image lean.
+:::
+
+### Add Docker Compose for production
+
+The following `docker-compose.prod.yml` is suitable for production deployments. It uses PostgreSQL and includes healthchecks. The Strapi port binds to `127.0.0.1` so that only a local reverse proxy can reach it.
+
+```yml title="./docker-compose.prod.yml"
+services:
+ strapi:
+ container_name: strapi
+ build:
+ context: .
+ dockerfile: Dockerfile.prod
+ image: strapi:latest
+ restart: always
+ env_file: .env
+ environment:
+ NODE_ENV: production # Overrides the development value from .env
+ ports:
+ - "127.0.0.1:1337:1337"
+ networks:
+ - strapi
+ depends_on:
+ strapiDB:
+ condition: service_healthy
+
+ strapiDB:
+ container_name: strapiDB
+ restart: always
+ image: postgres:16-alpine
+ environment:
+ POSTGRES_USER: ${DATABASE_USERNAME}
+ POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
+ POSTGRES_DB: ${DATABASE_NAME}
+ volumes:
+ - strapi-data:/var/lib/postgresql/data/
+ networks:
+ - strapi
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U ${DATABASE_USERNAME} -d ${DATABASE_NAME}"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+
+volumes:
+ strapi-data:
-### Building the production container
+networks:
+ strapi:
+ name: strapi
+ driver: bridge
+```
-Building production Docker images can have several options. The following example uses the `docker build` command to build a production Docker image for a Strapi project. However, it is recommended you review the for more information on building Docker images with more advanced options.
+
+ Do not expose database ports to the host. The strapiDB service above has no ports mapping, making it accessible only to other containers on the strapi network.
+ Persist uploads. The production docker-compose does not mount a volume for /opt/app/public/uploads. If you use the default local upload provider, add a named volume (e.g., strapi-uploads:/opt/app/public/uploads) or configure an external provider such as AWS S3 or Cloudinary.
+ Secure your secrets. The production docker-compose uses env_file: .env, which is acceptable for single-host deployments. For orchestrated environments, prefer Docker secrets, environment variables injected by your orchestrator (Kubernetes, ECS), or a dedicated secret manager (HashiCorp Vault, AWS Secrets Manager).
+
-To build a production Docker image for a Strapi project, run the following command:
+### Build and publish
+
+To build a production Docker image, run the following command:
```bash
docker build \
- --build-arg NODE_ENV=production \
- # --build-arg STRAPI_URL=https://api.example.com \ # Uncomment to set the Strapi Server URL
- -t mystrapiapp:latest \ # Replace with your image name
+ -t mystrapiapp:latest \
-f Dockerfile.prod .
```
-### (Optional) Publishing the container to a registry
-
-After you have built a production Docker image for a Strapi project, you can publish the image to a Docker registry. Ideally for production usage this should be a private registry as your Docker image will contain sensitive information.
-
-Depending on your hosting provider you may need to use a different command to publish your image. It is recommended you review the for more information on publishing Docker images with more advanced options.
+After building, you can publish the image to a Docker registry. For production usage, use a private registry since your Docker image may contain sensitive configuration.
-Some popular hosting providers are:
+Popular container registries include:
-
-
--
+-
-
-
-
-
-## Community tools
+## Community tools and images
-Several community tools are available to assist you in deploying Strapi to various cloud providers and setting up Docker in a development or production environment.
-
-We strongly support our community efforts and encourage you to check out the following tools, please help support them by contributing to their development.
+Strapi does not provide official Docker images (see [FAQ](/cms/faq)). The following community-maintained tools and images can help you get started.
If you would like to add your tool to this list, please open a pull request on the .
-### @strapi-community/dockerize
+### The `@strapi-community/dockerize` CLI
+
+The `@strapi-community/dockerize` package is a CLI tool that generates a `Dockerfile` and `docker-compose.yml` file for a Strapi project.
+
+To get started, run `npx @strapi-community/dockerize@latest` within an existing Strapi project folder and follow the CLI prompts.
+
+For more information, see the official or the .
+
+### Community-maintained Docker images
+
+Pre-built Docker images maintained by community members are available for Strapi 5. These images let you run Strapi without writing your own Dockerfile.
+
+:::caution
+These images are community-maintained and not officially supported by Strapi. Review their documentation and source code before using them in production.
+:::
+
+- : Actively maintained image that tracks Strapi 5 releases. Available on .
+- : Supports both AMD64 and ARM64 architectures. Tracks Strapi 5 releases.
+
+## Troubleshooting
+
+The following section details some common issues with Sharp and ARM builds on Apple Silicon-powered machines.
+
+:::info
+The Dockerfiles on this page do not include `nasm` in the Alpine package list. It was previously included in older versions of this guide but is not required for Sharp or libvips compilation.
+:::
+
+### Sharp and libvips errors
+
+Sharp is the image processing library used by Strapi. It depends on `libvips`, which requires native compilation on Alpine-based images. Common error messages include `Cannot find module 'sharp'` or `Error: sharp: Installation error`.
+
+To resolve Sharp issues:
+
+1. Run `docker exec node -e "require('sharp')"`. If it errors with a missing library, the runtime stage is missing the Alpine packages above. If it errors with a glibc/musl mismatch, switch to `node:22-slim` (see step 2).
+
+2. Verify that your Dockerfile installs the required Alpine packages:
+
+ ```dockerfile
+ RUN apk update && apk add --no-cache build-base gcc autoconf automake zlib-dev libpng-dev bash vips-dev git
+ ```
+
+3. If the issue persists, switch to `node:22-slim` (Debian-based) to avoid native library **compatibility problems** Alpine Linux uses a lightweight C library called **musl** instead of the standard **glibc** used by Debian and Ubuntu. Some npm packages ship pre-compiled binaries built for glibc that do not work on Alpine. Switching to a Debian-based image like `node:22-slim` avoids this issue entirely.:
+
+ ```dockerfile
+ FROM node:22-slim
+ RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*
+ ```
+
+4. For ARM builds (see [below](#apple-silicon-and-arm-builds)), add the following environment variable before installing dependencies:
+
+ ```dockerfile
+ ENV SHARP_IGNORE_GLOBAL_LIBVIPS=1
+ ```
+
+### Apple Silicon and ARM builds
+
+The `platform: linux/amd64` flag in docker-compose files forces containers to run under x86 emulation on ARM-based machines (Apple M1/M2/M3). This works but is slower than native ARM builds.
+
+For native ARM performance:
+
+- Remove the `platform: linux/amd64` line from your docker-compose file.
+- Use `node:22-alpine` or `node:22-slim` as your base image. Both support ARM64 natively.
+- Ensure Sharp dependencies are installed correctly (see [Sharp and libvips errors](#sharp-and-libvips-errors)).
+
+:::note
+The `platform: linux/amd64` flag is commented out in the [docker-compose examples](#add-docker-compose-for-the-database) above. Uncomment it if your database image does not provide an ARM64 variant.
+:::
+
+### Database connection issues
+
+:::danger
+Strapi applications must use a database created by a Strapi application. Connecting to a pre-existing non-Strapi database, or to a Strapi v3 database, is not supported and may result in lost data such as dropped tables.
+:::
+
+If Strapi cannot connect to the database in Docker, check the following:
+
+1. Verify that `DATABASE_HOST` matches the service name in your docker-compose file (e.g., `strapiDB`), not `localhost` or `127.0.0.1`. Containers communicate over the Docker network using service names.
+
+2. Check for port conflicts with local database instances. If a database is already running locally on the same port:
+ - Stop the local database,
+ - or change the host-side port mapping in your docker-compose file (e.g., `"5433:5432"`).
+
+3. Set the connection pool `min` value to `0` in your [database configuration](/cms/configurations/database), as Docker may kill idle connections:
-The `@strapi-community/dockerize` package is a CLI tool that can be used to generate a `Dockerfile` and `docker-compose.yml` file for a Strapi project.
+
-To get started run `npx @strapi-community/dockerize@latest` within an existing Strapi project folder and follow the CLI prompts.
+
-For more information please see the official or the .
+ ```js title="./config/database.js"
+ module.exports = ({ env }) => ({
+ connection: {
+ client: env('DATABASE_CLIENT'),
+ // ...
+ pool: {
+ min: 0,
+ max: 10,
+ },
+ },
+ });
+ ```
-### @strapi-community/deployify
+
-The `@strapi-community/deployify` package is a CLI tool that can be used to deploy your application to various cloud providers and hosting services. Several of these also support deploying a Strapi project with a Docker container and will call on the `@strapi-community/dockerize` package to generate the required files if they don't already exist.
+
-To get started run `npx @strapi-community/deployify@latest` within an existing Strapi project folder and follow the CLI prompts.
+ ```ts title="./config/database.ts"
+ export default ({ env }) => ({
+ connection: {
+ client: env('DATABASE_CLIENT'),
+ // ...
+ pool: {
+ min: 0,
+ max: 10,
+ },
+ },
+ });
+ ```
-For more information please see the official or the .
+
-## Docker FAQ
+
-### Why doesn't Strapi provide official Docker images?
+4. If the database container becomes unreachable after periods of inactivity, add timeout settings to the pool configuration in your [database configuration](/cms/configurations/database):
-Strapi is a framework that can be used to build many different types of applications. As such, it is not possible to provide a single Docker image that can be used for all use cases.
+ ```js
+ pool: {
+ min: 0,
+ max: 10,
+ acquireTimeoutMillis: 60000,
+ idleTimeoutMillis: 30000,
+ },
+ ```
-### Why do we have different Dockerfiles for development and production?
+## What to do next?
-The primary reason for various Docker images is due to the way our Admin panel is built. The Admin panel is built using React and is bundled into the Strapi application during the build process. This means that the Strapi backend is acting as a web server to serve the Admin panel and thus certain environment variables are statically compiled into the built Admin panel.
+Now that Strapi is running in a Docker container, you can:
-It is generally considered a best practice with Strapi to build different Docker images for development and production environments. This is because the development environment is not optimized for performance and is not intended to be exposed to the public internet.
+ Set up the [admin panel](/cms/features/admin-panel) and create your first content types with the [Content-Type Builder](/cms/features/content-type-builder).
+ Configure a reverse proxy and deploy to production (see [deployment documentation](/cms/deployment)).
+ Explore [environment configuration](/cms/configurations/environment) for fine-tuning your Strapi instance.
diff --git a/docusaurus/docs/snippets/docker-env-table.md b/docusaurus/docs/snippets/docker-env-table.md
index 29f1f90e59..eae23805e3 100644
--- a/docusaurus/docs/snippets/docker-env-table.md
+++ b/docusaurus/docs/snippets/docker-env-table.md
@@ -12,5 +12,8 @@ The following environment variables are required in order to run Strapi in a Doc
| `JWT_SECRET` | The secret used to sign the JWT for the Users-Permissions plugin. |
| `ADMIN_JWT_SECRET` | The secret used to sign the JWT for the Admin panel. |
| `APP_KEYS` | The secret keys used to sign the session cookies. |
+| `API_TOKEN_SALT` | The salt used to generate API tokens. |
+| `TRANSFER_TOKEN_SALT` | The salt used to generate transfer tokens. |
+| `ENCRYPTION_KEY` | The key used to encrypt secrets stored in the database (e.g., provider credentials configured through the admin panel). |
You can also set some [optional environment variables](/cms/configurations/environment#strapi).
diff --git a/docusaurus/static/llms-code.txt b/docusaurus/static/llms-code.txt
index a2f60b04ad..4fc25cf427 100644
--- a/docusaurus/static/llms-code.txt
+++ b/docusaurus/static/llms-code.txt
@@ -23879,16 +23879,33 @@ npm run develop
# Docker
Source: https://docs.strapi.io/cms/installation/docker
-## Development Dockerfile
-Description: Sample Dockerfile:
-(Source: https://docs.strapi.io/cms/installation/docker#development-dockerfile)
+## Create a .dockerignore file
+Description: Create a .dockerignore file at the root of your Strapi project:
+(Source: https://docs.strapi.io/cms/installation/docker#create-a-dockerignore-file)
+
+Language: TXT
+File path: ./.dockerignore
+
+```txt
+node_modules/
+.tmp/
+.cache/
+.git/
+build/
+.env
+```
+
+
+## Create the Dockerfile
+Description: :::tip Alternative base image for restricted networks If your CI environment has limited network access (e.g., DNS restrictions that prevent downloading Sharp prebuilt binaries from GitHub), consider using node:22-slim instead of node:22-alpine.
+(Source: https://docs.strapi.io/cms/installation/docker#create-the-dockerfile)
Language: DOCKERFILE
File path: ./Dockerfile
```dockerfile
FROM node:22-alpine
-# Installing libvips-dev for sharp Compatibility
+# Installing libvips-dev for sharp compatibility
RUN apk update && apk add --no-cache build-base gcc autoconf automake zlib-dev libpng-dev nasm bash vips-dev git
ARG NODE_ENV=development
ENV NODE_ENV=${NODE_ENV}
@@ -23914,7 +23931,7 @@ File path: ./Dockerfile
```dockerfile
FROM node:22-alpine
-# Installing libvips-dev for sharp Compatibility
+# Installing libvips-dev for sharp compatibility
RUN apk update && apk add --no-cache build-base gcc autoconf automake zlib-dev libpng-dev nasm bash vips-dev git
ARG NODE_ENV=development
ENV NODE_ENV=${NODE_ENV}
@@ -23943,9 +23960,41 @@ RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*
```
-## (Optional) Docker Compose
-Description: Sample docker-compose.yml:
-(Source: https://docs.strapi.io/cms/installation/docker#optional-docker-compose)
+## Set up environment variables
+Description: Code example from "Set up environment variables"
+(Source: https://docs.strapi.io/cms/installation/docker#set-up-environment-variables)
+
+Language: DOTENV
+File path: ./.env
+
+```dotenv
+# Server
+HOST=0.0.0.0
+PORT=1337
+
+# Database
+DATABASE_CLIENT=postgres
+DATABASE_HOST=strapiDB
+DATABASE_PORT=5432
+DATABASE_NAME=strapi
+DATABASE_USERNAME=strapi
+DATABASE_PASSWORD=strapi
+
+# Secrets
+APP_KEYS=toBeModified1,toBeModified2
+API_TOKEN_SALT=tobemodified
+ADMIN_JWT_SECRET=tobemodified
+TRANSFER_TOKEN_SALT=tobemodified
+JWT_SECRET=tobemodified
+
+# Environment
+NODE_ENV=development
+```
+
+
+## Add Docker Compose for the database
+Description: Code example from "Add Docker Compose for the database"
+(Source: https://docs.strapi.io/cms/installation/docker#add-docker-compose-for-the-database)
Language: YAML
File path: ./docker-compose.yml
@@ -23981,15 +24030,15 @@ services:
networks:
- strapi
depends_on:
- - strapiDB
+ strapiDB:
+ condition: service_healthy
strapiDB:
container_name: strapiDB
platform: linux/amd64 #for platform error on Apple M1 chips
restart: unless-stopped
env_file: .env
- image: mysql:8.0
- command: --default-authentication-plugin=mysql_native_password
+ image: mysql:8.4
environment:
MYSQL_USER: ${DATABASE_USERNAME}
MYSQL_ROOT_PASSWORD: ${DATABASE_PASSWORD}
@@ -24002,6 +24051,11 @@ services:
- "3306:3306"
networks:
- strapi
+ healthcheck:
+ test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
volumes:
strapi-data:
@@ -24017,7 +24071,6 @@ Language: YAML
File path: ./docker-compose.yml
```yaml
-version: "3"
services:
strapi:
container_name: strapi
@@ -24048,14 +24101,15 @@ services:
networks:
- strapi
depends_on:
- - strapiDB
+ strapiDB:
+ condition: service_healthy
strapiDB:
container_name: strapiDB
platform: linux/amd64 #for platform error on Apple M1 chips
restart: unless-stopped
env_file: .env
- image: mariadb:latest
+ image: mariadb:11.4
environment:
MYSQL_USER: ${DATABASE_USERNAME}
MYSQL_ROOT_PASSWORD: ${DATABASE_PASSWORD}
@@ -24068,6 +24122,11 @@ services:
- "3306:3306"
networks:
- strapi
+ healthcheck:
+ test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
volumes:
strapi-data:
@@ -24083,7 +24142,6 @@ Language: YAML
File path: ./docker-compose.yml
```yaml
-version: "3"
services:
strapi:
container_name: strapi
@@ -24114,26 +24172,31 @@ services:
networks:
- strapi
depends_on:
- - strapiDB
+ strapiDB:
+ condition: service_healthy
strapiDB:
container_name: strapiDB
platform: linux/amd64 #for platform error on Apple M1 chips
restart: unless-stopped
env_file: .env
- image: postgres:16.0-alpine
+ image: postgres:16-alpine
environment:
POSTGRES_USER: ${DATABASE_USERNAME}
POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
POSTGRES_DB: ${DATABASE_NAME}
volumes:
- - strapi-data:/var/lib/postgresql/data/ #using a volume
+ - strapi-data:/var/lib/postgresql/data/
#- ./data:/var/lib/postgresql/data/ # if you want to use a bind folder
-
ports:
- "5432:5432"
networks:
- strapi
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U ${DATABASE_USERNAME} -d ${DATABASE_NAME}"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
volumes:
strapi-data:
@@ -24145,42 +24208,61 @@ networks:
```
-## Production Dockerfile
-Description: The following Dockerfile can be used to build a production Docker image for a Strapi project.
-(Source: https://docs.strapi.io/cms/installation/docker#production-dockerfile)
+## Build and run
+Description: Build and start all containers:
+(Source: https://docs.strapi.io/cms/installation/docker#build-and-run)
+
+Language: Bash
+File path: N/A
+
+```bash
+ docker compose up --build
+```
+
+
+## Create the production Dockerfile
+Description: Code example from "Create the production Dockerfile"
+(Source: https://docs.strapi.io/cms/installation/docker#create-the-production-dockerfile)
Language: DOCKERFILE
File path: ./Dockerfile.prod
```dockerfile
-# Creating multi-stage build for production
+# Build stage
FROM node:22-alpine AS build
RUN apk update && apk add --no-cache build-base gcc autoconf automake zlib-dev libpng-dev vips-dev git > /dev/null 2>&1
-ARG NODE_ENV=production
-ENV NODE_ENV=${NODE_ENV}
WORKDIR /opt/
COPY package.json yarn.lock ./
RUN yarn global add node-gyp
-RUN yarn config set network-timeout 600000 -g && yarn install --frozen-lockfile --production
+RUN yarn config set network-timeout 600000 -g && yarn install --frozen-lockfile
ENV PATH=/opt/node_modules/.bin:$PATH
+
WORKDIR /opt/app
COPY . .
+ENV NODE_ENV=production
RUN yarn build
-# Creating final production image
+# Production stage
FROM node:22-alpine
RUN apk add --no-cache vips-dev
ENV NODE_ENV=production
-ENV NODE_ENV=${NODE_ENV}
+
+WORKDIR /opt/
+COPY --from=build /opt/package.json /opt/yarn.lock ./
+RUN yarn install --frozen-lockfile --production && yarn cache clean
+ENV PATH=/opt/node_modules/.bin:$PATH
+
WORKDIR /opt/app
-COPY --from=build /opt/node_modules ./node_modules
COPY --from=build /opt/app ./
-ENV PATH=/opt/node_modules/.bin:$PATH
RUN chown -R node:node /opt/app
USER node
EXPOSE 1337
+# highlight-start
+HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
+ CMD wget --quiet --tries=1 --spider http://localhost:1337/_health || exit 1
+# highlight-end
CMD ["yarn", "start"]
```
@@ -24189,54 +24271,171 @@ Language: DOCKERFILE
File path: ./Dockerfile.prod
```dockerfile
-# Creating multi-stage build for production
+# Build stage
FROM node:22-alpine AS build
RUN apk update && apk add --no-cache build-base gcc autoconf automake zlib-dev libpng-dev vips-dev git > /dev/null 2>&1
-ARG NODE_ENV=production
-ENV NODE_ENV=${NODE_ENV}
WORKDIR /opt/
COPY package.json package-lock.json ./
RUN npm install -g node-gyp
-RUN npm config set fetch-retry-maxtimeout 600000 -g && npm ci --only=production
+RUN npm config set fetch-retry-maxtimeout 600000 -g && npm ci
ENV PATH=/opt/node_modules/.bin:$PATH
+
WORKDIR /opt/app
COPY . .
+ENV NODE_ENV=production
RUN npm run build
-# Creating final production image
+# Production stage
FROM node:22-alpine
RUN apk add --no-cache vips-dev
-ARG NODE_ENV=production
-ENV NODE_ENV=${NODE_ENV}
+ENV NODE_ENV=production
+
+WORKDIR /opt/
+COPY --from=build /opt/package.json /opt/package-lock.json ./
+RUN npm ci --only=production && npm cache clean --force
+ENV PATH=/opt/node_modules/.bin:$PATH
+
WORKDIR /opt/app
-COPY --from=build /opt/node_modules ./node_modules
COPY --from=build /opt/app ./
-ENV PATH=/opt/node_modules/.bin:$PATH
RUN chown -R node:node /opt/app
USER node
EXPOSE 1337
+# highlight-start
+HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
+ CMD wget --quiet --tries=1 --spider http://localhost:1337/_health || exit 1
+# highlight-end
CMD ["npm", "run", "start"]
```
-## Building the production container
-Description: To build a production Docker image for a Strapi project, run the following command:
-(Source: https://docs.strapi.io/cms/installation/docker#building-the-production-container)
+## Add Docker Compose for production
+Description: Code example from "Add Docker Compose for production"
+(Source: https://docs.strapi.io/cms/installation/docker#add-docker-compose-for-production)
-Language: Bash
-File path: N/A
+Language: YAML
+File path: ./docker-compose.prod.yml
-```bash
+```yaml
+services:
+ strapi:
+ container_name: strapi
+ build:
+ context: .
+ dockerfile: Dockerfile.prod
+ image: strapi:latest
+ restart: always
+ env_file: .env
+ environment:
+ DATABASE_CLIENT: ${DATABASE_CLIENT}
+ DATABASE_HOST: strapiDB
+ DATABASE_PORT: ${DATABASE_PORT}
+ DATABASE_NAME: ${DATABASE_NAME}
+ DATABASE_USERNAME: ${DATABASE_USERNAME}
+ DATABASE_PASSWORD: ${DATABASE_PASSWORD}
+ JWT_SECRET: ${JWT_SECRET}
+ ADMIN_JWT_SECRET: ${ADMIN_JWT_SECRET}
+ APP_KEYS: ${APP_KEYS}
+ NODE_ENV: production
+ ports:
+ - "127.0.0.1:1337:1337"
+ networks:
+ - strapi
+ depends_on:
+ strapiDB:
+ condition: service_healthy
+
+ strapiDB:
+ container_name: strapiDB
+ restart: always
+ image: postgres:16-alpine
+ environment:
+ POSTGRES_USER: ${DATABASE_USERNAME}
+ POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
+ POSTGRES_DB: ${DATABASE_NAME}
+ volumes:
+ - strapi-data:/var/lib/postgresql/data/
+ networks:
+ - strapi
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U ${DATABASE_USERNAME} -d ${DATABASE_NAME}"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+
+volumes:
+ strapi-data:
+
+networks:
+ strapi:
+ name: strapi
+ driver: bridge
+```
+
+
+## Build and publish
+Description: To build a production Docker image, run the following command:
+(Source: https://docs.strapi.io/cms/installation/docker#build-and-publish)
+
+Language: YAML
+File path: .prod.yml
+
+```yaml
docker build \
- --build-arg NODE_ENV=production \
- # --build-arg STRAPI_URL=https://api.example.com \ # Uncomment to set the Strapi Server URL
- -t mystrapiapp:latest \ # Replace with your image name
+ -t mystrapiapp:latest \
-f Dockerfile.prod .
```
+## Sharp and libvips errors
+Description: Verify that your Dockerfile installs the required Alpine packages:
+(Source: https://docs.strapi.io/cms/installation/docker#sharp-and-libvips-errors)
+
+Language: DOCKERFILE
+File path: .prod.yml
+
+```dockerfile
+ RUN apk update && apk add --no-cache build-base gcc autoconf automake zlib-dev libpng-dev nasm bash vips-dev git
+```
+
+Language: DOCKERFILE
+File path: .prod.yml
+
+```dockerfile
+ FROM node:22-slim
+ RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*
+```
+
+Language: DOCKERFILE
+File path: .prod.yml
+
+```dockerfile
+ ENV SHARP_IGNORE_GLOBAL_LIBVIPS=1
+```
+
+
+## Database connection issues
+Description: Code example from "Database connection issues"
+(Source: https://docs.strapi.io/cms/installation/docker#database-connection-issues)
+
+Language: JavaScript
+File path: ./config/database.js
+
+```js
+ module.exports = ({ env }) => ({
+ connection: {
+ client: env('DATABASE_CLIENT'),
+ // ...
+ pool: {
+ min: 0,
+ max: 10,
+ },
+ },
+ });
+```
+
+
# From Entity Service API to Document Service API
Source: https://docs.strapi.io/cms/migration/v4-to-v5/additional-resources/from-entity-service-to-document-service