Skip to main content

使用docker-compose部署

使用了 pm2 还需要 docker 吗?

还是要的

  1. pm2 主要用于服务的进程管理,比如启动服务,自动重启,日志输出等。

  2. 使用 docker-compose 主要用于服务编排,比如 mysql 和 strapi 服务一起部署。

创建.dockerignore文件

.tmp/
.cache/
.git/
build/
node_modules/
data/
logs/
db/
public/

这里记得要把db,logs,public这三个文件夹都加入到.dockerignore中。因为后续我们会把这三个文件夹挂载出来(挂载到app/目录下)。如果不 ignore 的话,被复制到 docker 中会导致资源挂载冲突。

warning

由于忽略了public目录,所以需要在本地创建文件夹app/public/uploads,否则 docker 中 strapi 会运行错误,提示 uploads 目录不存在。后续可以考虑启动前检查该目录是否存在并自动创建。

创建 Dockerfile

Dockerfile
# FROM alpine:3.14
FROM node:16-alpine3.14 AS BUILD_IMAGE
# couchbase sdk requirements
RUN apk add --no-cache curl bash python3 make g++

# install node-prune (https://github.com/tj/node-prune)
RUN curl -sfL https://gobinaries.com/tj/node-prune | bash -s -- -b /usr/local/bin

WORKDIR /usr/app

COPY package.json package-lock.json .npmrc ./

# install dependencies
RUN npm install --only=production

COPY . .

# build application
RUN npm run build

# remove development dependencies
RUN npm prune --production

# run node prune
RUN /usr/local/bin/node-prune

FROM node:16-alpine3.14

WORKDIR /usr/app

# copy from build image
COPY --from=BUILD_IMAGE /usr/app/ ./
EXPOSE 1337
CMD ["npm", "run", "deploy:container"]

安装 npm 包,剔除多余包资源,编译项目,启动服务。

编写 docker-compose 文件

docker-compose.yml
version: '3'

services:
strapi:
container_name: strapi
build: .
environment:
- TZ=Asia/Shanghai
- DATABASE_CLIENT=mysql
- DATABASE_HOST=db
- DATABASE_PORT=3306
- DATABASE_NAME=${MYSQL_DATABASE}
- DATABASE_USERNAME=${MYSQL_USER}
- DATABASE_PASSWORD=${MYSQL_PASSWORD}
ports:
- 1337:1337
volumes:
- ./app/public:/usr/app/public
- ./app/logs:/usr/app/logs
depends_on:
- db

db:
container_name: mysql
image: mysql:5.7
restart: always
command: --default-authentication-plugin=mysql_native_password
environment:
TZ: Asia/Shanghai
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
volumes:
- ./db:/var/lib/mysql

启动服务编排:

package.json
{
"scripts": {
"restart": "docker-compose --env-file .env.prod up -d --build"
}
}

这样在服务器上,只需要执行npm run restart就可以启动或重启服务了。

其中:

  1. -d是进程守护模式启动
  2. --build启动前 build 下 Dockerfile,这样保证服务是最新的,否则启动的还是旧的镜像
env-file

注意 docker-compose 的--env-file 命令行参数需要版本 1.25.0 及以上。如果低于这个版本运行 docker-compose 可以使用:

env $(cat .env.prod) docker-compose up -d --build

社区讨论:https://github.com/docker/compose/issues/6170

备份与恢复

备份 mysql:

scripts/backup_mysql.sh
docker exec mysql /usr/bin/mysqldump -u strapi --no-tablespaces --password=strapi strapi > backup.sql

恢复 mysql:

scripts/restore_mysql.sh
cat backup.sql | docker exec -i mysql /usr/bin/mysql -u strapi --password=strapi strapi