在 Docker 容器中运行 Strapi
Strapi 不构建任何官方容器镜像。以下说明是为社区提供的。如果您有任何疑问,请联系 Discord。
Strapi 应用程序不应连接到预先存在的数据库,不应由 Strapi 应用程序创建,也不应连接到 Strapi v3 数据库。Strapi 团队不支持此类尝试。尝试连接到不受支持的数据库可能会导致数据丢失,例如表被丢弃。
以下文档将指导您使用现有 Strapi 项目构建自定义 Docker 容器。
Docker 是一个开放平台,允许使用容器(即包含应用程序运行所需的所有部分的包,例如库和依赖项)开发、运送和运行应用程序。容器彼此隔离,并捆绑自己的软件、库和配置文件;它们可以通过明确定义的渠道相互通信。
- 您的机器上已安装 Docker
- 支持的 Node.js 版本
- 现有的 Strapi v4 项目,或使用 快速入门指南 创建的新项目
- 您的机器上已安装 Yarn (可选)
- 您的机器上已安装 Docker Compose (可选)
开发和/或暂存环境
若要在主机上本地使用 Strapi,您可以使用 Dockerfile,如果需要,还可以使用 docker-compose.yml 启动数据库容器。
这两种方法都需要现有的 Strapi 项目或新建一个项目(请参阅 快速入门指南)。
开发 Dockerfile
以下 Dockerfile
可用于为 Strapi 项目构建非生产 Docker 映像。
如果您使用的是 docker-compose
,则可以跳过手动设置环境变量,因为它们将在 docker-compose.yml
文件或 .env
文件中设置。
要在 Docker 容器中运行 Strapi,需要以下环境变量:
变量名称 | 描述 |
---|---|
NODE_ENV | 应用程序运行的环境。 |
DATABASE_CLIENT | 要使用的数据库客户端。 |
DATABASE_HOST | 数据库主机。 |
DATABASE_PORT | 数据库端口。 |
DATABASE_NAME | 数据库名称。 |
DATABASE_USERNAME | 数据库用户名。 |
DATABASE_PASSWORD | 数据库密码。 |
JWT_SECRET | 用于为用户权限插件签署 JWT 的密钥。 |
ADMIN_JWT_SECRET | 用于为管理面板签署 JWT 的密钥。 |
APP_KEYS | 用于签署会话 cookie 的密钥。 |
您还可以设置一些可选环境变量。
有关 Dockerfile
及其命令的更多信息,请参阅 官方 Docker 文档。
示例 Dockerfile
:
# ./Dockerfile
FROM node:18-alpine3.18
# 安装 libvips-dev 以实现 sharp 兼容性
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
ENV PATH /opt/node_modules/.bin:$PATH
WORKDIR /opt/app
COPY . .
RUN chown -R node:node /opt/app
USER node
RUN ["yarn", "build"]
EXPOSE 1337
CMD ["yarn", "develop"]
Docker Compose (可选)
以下 docker-compose.yml
可用于启动数据库容器和 Strapi 容器以及用于两者之间通信的共享网络。
有关运行 Docker Compose 及其命令的更多信息,请参阅 Docker Compose 文档。
Sample docker-compose.yml
:
# ./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}
volumes:
- ./config:/opt/app/config
- ./src:/opt/app/src
- ./package.json:/opt/package.json
- ./yarn.lock:/opt/yarn.lock
- ./.env:/opt/app/.env
- ./public/uploads:/opt/app/public/uploads
ports:
- '1337:1337'
networks:
- strapi
depends_on:
- strapiDB
strapiDB:
container_name: strapiDB
platform: linux/amd64 # 针对 Apple M1 芯片上的平台错误
restart: unless-stopped
env_file: .env
image: mysql:5.7
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_USER: ${DATABASE_USERNAME}
MYSQL_ROOT_PASSWORD: ${DATABASE_PASSWORD}
MYSQL_PASSWORD: ${DATABASE_PASSWORD}
MYSQL_DATABASE: ${DATABASE_NAME}
volumes:
- strapi-data:/var/lib/mysql
# - ./data:/var/lib/mysql # 如果您想使用绑定文件夹
ports:
- '3306:3306'
networks:
- strapi
volumes:
strapi-data:
networks:
strapi:
name: Strapi
driver: bridge
.dockerignore(可选)
构建 Docker 镜像时,必须仅包含运行容器内应用程序所需的文件。这就是 .dockerignore
文件发挥作用的地方。与 .gitignore
对 Git 的工作方式类似,指定不应跟踪或上传的文件和目录,.dockerignore
告诉 Docker 在构建镜像时要忽略哪些文件和目录。
Sample .dockerignore
:
.tmp/
.cache/
.git/
.env
build/
node_modules/
# 忽略可能在入门模板中使用的文件夹
data/
backup/
为何使用 .dockerignore?
在 Docker 构建上下文中包含不必要的文件会显著减慢构建过程。通过 .dockerignore 排除 .tmp、.cache、.git、build、node_modules 和 .env 等文件和目录,发送到 Docker 守护进程的数据量会减少。这可以缩短构建时间,因为 Docker 需要处理和包含在镜像中的文件更少。
安全性
排除文件和目录还可以增强 Docker 镜像的安全性。敏感文件(例如 .env
)可能包含特定于环境的机密或凭据,不应包含在 Docker 镜像中。这可以防止意外泄露敏感信息。
更干净的镜像
Docker 镜像中充斥着不必要的文件可能会导致潜在的混乱和问题,尤其是在跨团队共享镜像或用于生产时。通过保持镜像干净并仅关注基本要素,可以更轻松地进行维护和故障排除。
减小镜像大小
较小的 Docker 镜像更易于存储、传输和启动。通过排除非必要文件,可以显著减小最终镜像大小,从而缩短拉取和启动时间,尤其是在分布式和云环境中。
生产环境
生产中的 Docker 镜像与开发/暂存环境中使用的 Docker 镜像不同,因为除了用于运行应用程序的命令之外,管理员构建过程也有所不同。典型的生产环境将使用反向代理来为应用程序和管理面板提供服务。Docker 镜像是使用管理面板的生产版本构建的,用于运行应用程序的命令是 strapi start
。
创建 Dockerfile 后,可以构建 生产容器。或者,可以将容器发布到 注册表,以使其可供社区使用。 社区工具 可以帮助您 构建生产 Docker 映像并将其部署到生产环境。
生产 Dockerfile
以下 Dockerfile
可用于为 Strapi 项目构建生产 Docker 映像。
# ./Dockerfile.prod
# 为生产创建多阶段构建
FROM node:18-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
ENV NODE_ENV=production
WORKDIR /opt/
COPY package.json yarn.lock ./
RUN yarn global add node-gyp
RUN yarn config set network-timeout 600000 -g && yarn install --production
ENV PATH /opt/node_modules/.bin:$PATH
WORKDIR /opt/app
COPY . .
RUN yarn build
# 创建最终生产镜像
FROM node:18-alpine
RUN apk add --no-cache vips-dev
ENV NODE_ENV=production
WORKDIR /opt/
COPY --from=build /opt/node_modules ./node_modules
WORKDIR /opt/app
COPY --from=build /opt/app ./
ENV PATH /opt/node_modules/.bin:$PATH
RUN chown -R node:node /opt/app
USER node
EXPOSE 1337
CMD ["yarn", "start"]
构建生产容器
构建生产 Docker 映像可以有多种选择。以下示例使用 docker build
命令为 Strapi 项目构建生产 Docker 映像。但是,建议您查看 Docker 文档 以获取有关使用更高级选项构建 Docker 映像的更多信息。
要为 Strapi 项目构建生产 Docker 映像,请运行以下命令:
docker build \
--build-arg NODE_ENV=production \
# --build-arg STRAPI_URL=https://api.example.com \ # 取消注释以设置 Strapi 服务器 URL
-t mystrapiapp:latest \ # Replace with your image name
-f Dockerfile.prod .
将容器发布到注册表(可选)
为 Strapi 项目构建生产 Docker 映像后,您可以将映像发布到 Docker 注册表。理想情况下,对于生产用途,这应该是私有注册表,因为您的 Docker 映像将包含敏感信息。
根据您的托管服务提供商,您可能需要使用不同的命令来发布您的映像。建议您查看 Docker 文档 以获取有关使用更高级选项发布 Docker 映像的更多信息。
一些流行的托管服务提供商是:
- AWS ECR
- Azure Container Registry
- GCP Container Registry
- Digital Ocean Container Registry
- IBM Cloud Container Registry
- GitHub Container Registry
- Gitlab Container Registry
社区工具
有几种社区工具可帮助您将 Strapi 部署到各种云提供商并在开发或生产环境中设置 Docker。
我们大力支持我们的社区工作,并鼓励您查看以下工具,请通过为其开发做出贡献来帮助支持它们。
如果您想将您的工具添加到此列表中,请在 Strapi 文档存储库 上打开拉取请求。
@strapi-community/dockerize
@strapi-community/dockerize
包是一个 CLI 工具,可用于为 Strapi 项目生成 Dockerfile
和 docker-compose.yml
文件。
要开始使用,请在现有 Strapi 项目文件夹中运行 npx @strapi-community/dockerize@latest
并按照 CLI 提示进行操作。
有关更多信息,请参阅官方 GitHub 存储库 或 npm 包。
@strapi-community/deployify
@strapi-community/deployify
包是一个 CLI 工具,可用于将您的应用程序部署到各种云提供商和托管服务。其中一些还支持使用 Docker 容器部署 Strapi 项目,并将调用 @strapi-community/dockerize
包来生成所需文件(如果它们尚不存在)。
要开始使用,请在现有 Strapi 项目文件夹中运行 npx @strapi-community/deployify@latest
并按照 CLI 提示进行操作。
有关更多信息,请参阅官方 GitHub 存储库 或 npm 包。
Docker 常见问题解答
为什么 Strapi 不提供官方 Docker 镜像?
Strapi 是一个可用于构建多种不同类型应用程序的框架。因此,不可能提供可用于所有用例的单个 Docker 镜像。
为什么我们为开发和生产使用不同的 Dockerfile?
各种 Docker 镜像的主要原因在于我们的管理面板的构建方式。管理面板使用 React 构建,并在构建过程中捆绑到 Strapi 应用程序中。这意味着 Strapi 后端充当 Web 服务器来为管理面板提供服务,因此某些环境变量被静态编译到构建的管理面板中。
使用 Strapi 的最佳实践是为开发和生产环境构建不同的 Docker 镜像。这是因为开发环境并未针对性能进行优化,并且不打算暴露在公共互联网上。