尝试在 Strapi 上上传文件时显示“ACCES:权限被拒绝”

Bra*_*tor 3 docker dockerfile docker-compose strapi

我对 Strapi 和 Docker 有点陌生,在尝试在 Strapi 的管理面板上上传文件时遇到问题

我可以使用内容管理器添加像用户这样的行,但是当我想在媒体库中上传文件时,Strapi 容器崩溃并抛出错误:

[2023-08-16 22:39:14.438] http: GET /upload/files?sort=createdAt:DESC&page=1&pageSize=10&filters[$and][0][folderPath][$eq]=/ (203 ms) 200
[2023-08-16 22:39:14.694] http: GET /upload/folders?sort=createdAt:DESC&page=1&pageSize=10&pagination[pageSize]=-1&filters[$and][0][parent][id][$null]=true (171 ms) 200
node:internal/process/promises:288
            triggerUncaughtException(err, true /* fromPromise */);
            ^
[Error: EACCES: permission denied, open '/opt/app/public/uploads/image_GIF_15e7099416.gif'] {
  errno: -13,
  code: 'EACCES',
  syscall: 'open',
  path: '/opt/app/public/uploads/image_GIF_15e7099416.gif'
}
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,我使用的是 Ubuntu 22.04.3 LTS,并且 Strapi 在端口 1337 上运行,MySQL 数据库在端口 3306 上运行(均在 Docker 上)

这是我的 docker compose 和 Strapi 的 Dockerfile :

version: "3"
services:
  strapi:
    container_name: strapi
    build: .
    image: strapi:latest
    restart: unless-stopped
    env_file: .env
    environment:
      DATABASE_CLIENT: ${DATABASE_CLIENT}
      DATABASE_HOST: strapi-mysql-db
      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:
      - strapi-mysql-db

  strapi-mysql-db:
    container_name: strapi-mysql-db
    platform: linux/amd64 #for platform error on Apple M1 chips
    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 # if you want to use a bind folder
    ports:
      - "3306:3306"
    networks:
      - strapi

volumes:
  strapi-data:

networks:
  strapi:
    name: Strapi
    driver: bridge
Run Code Online (Sandbox Code Playgroud)
FROM node:18-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
ARG NODE_ENV=development
ENV NODE_ENV=${NODE_ENV}

WORKDIR /opt/
COPY package.json yarn.lock ./
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", "dev"]
Run Code Online (Sandbox Code Playgroud)

我尝试使用不同的配置构建图像,但没有成功

Mar*_*che 6

我无法真正复制这个问题,但作为 Strapi 和 Docker 爱好者,我可以想到一些原因。

在 Strapi 中,您必须生成一个令牌,用于向端点运行请求。您可以拥有公共令牌(仅适用于公众的 GET 请求)和私有令牌(用于上传、修改或删除内容)。因此,您可能使用了错误的令牌。

或者,您尝试上传文件的 FTP 系统在输出文件夹上存在一些权限问题。也许 FTP 位于 Docker 容器本身内部?在这种情况下,修复起来可能很容易。使用命令进入容器docker exec -it <container_id> /bin/bash,您可以授予777 -R输出文件夹的权限(正如/opt/app/public/uploads日志中打印的那样)。

问题可能出在 Dockerfile 中的这行代码:

RUN chown -R node:node /opt/app
Run Code Online (Sandbox Code Playgroud)

也许这node不是上传文件的用户/opt/app?或者您必须使用 来启动此命令sudo?(我知道这在 Dockerfile 中几乎是不可能的)

另外,正如我在这篇文章中看到的,这可能是您如何安装依赖项的问题npm。尝试跑步sudo npm install -g --unsafe-perm=true --allow-root在 Dockerfile 中运行。

希望它足够有用!