Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"ACCES: permission denied" while trying to upload a file on Strapi

I'm a bit new with Strapi and Docker and I have a problem while trying to upload file on the admin panel of strapi

I'm able to add row like User with the Content-Manager, but when I want to upload a file in the Media Library, the Strapi Container crash and throw an error :

[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'
}

For more details, I'm using Ubuntu 22.04.3 LTS and I have Strapi running on port 1337 and a MySQL database on port 3306 (both on Docker)

That's my docker compose and the Dockerfile of Strapi :

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
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"]

I tried to build my images with different configs but it didn't worked

like image 303
Branligator Avatar asked Sep 08 '25 17:09

Branligator


1 Answers

I cannot really replicate this problem, but as a Strapi and Docker enthusiast I can think of some of the causes.

In Strapi you have to generate a token which you'll use to run requests towards the endpoints. You can have either a public token (only GET requests, meant for the public) and a private token (meant to upload, modify or delete stuff). So, probably, you are using a bad token.

Or, the FTP system where you are trying to upload the file has some permission problems on the output folder. Maybe the FTP is inside the Docker Container itself? In this case, it could be easy to fix. Entering the container with the docker exec -it <container_id> /bin/bash command, you can give -R 777 permissions on the output folder (which is /opt/app/public/uploads as it's printed in logs).

Probably the problem is this line of code in your Dockerfile:

RUN chown -R node:node /opt/app

Maybe this node is not the user who is uploading files to /opt/app? Or you have to launch this command with sudo? (I know it's nearly impossible inside a Dockerfile)

Also, as I saw in this post, it could be a problem of how you installed npm dependencies. Try running sudo npm install -g --unsafe-perm=true --allow-root in the Dockerfile.

Hope it was useful enough!

like image 115
Marco Frag Delle Monache Avatar answered Sep 10 '25 06:09

Marco Frag Delle Monache