Upload files from Express.js and Multer to persistent Docker Volume

Viewed 883

I am running my frontend and backend using node.js and express.js. For image upload i am using Multer and i would like to store the images in the docker volume i call media.

Expectation: Upload an image from my node.js application and then it will be stored in the docker volume, and then it can be accessed in the browser by typing /media/image_name.jpg.

Problem: If i create a folder called media in the root of my project, multer is uploading images directly to that, but that folder is not persistent when i delete the project image (Not the volume). If i don't create the media folder in the docker container, i simply get file or folder does not exist.

I have successfully created the volume and i can see in portainer that they are connected / mounted as /media. If i try to upload to media, it still won't upload to the volume.

Question: How do i make multer upload files to the docker volume called media, and how do i then access it in the browser as /media/image_name.jpg.

Here is my docker-compose:

version: '3'

services:
  nodejs:
    build:
      context: .
      dockerfile: Dockerfile
    image: nodejs
    container_name: nodejs
    ports:
      - 8081:8081
    volumes:
      - media:/media
    restart: unless-stopped
    networks:
      - app-network

  webservertest:
    image: nginx:stable-perl
    container_name: webservertest
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - web-root:/var/www/html
      - ./server/nginx-conf:/etc/nginx/conf.d
    depends_on:
      - nodejs
    networks:
      - app-network

  db:
    container_name: mongo
    image: arm7/mongo
    volumes:
      - dbdata:/data/db
    restart: unless-stopped
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

volumes:
  dbdata:
  node_modules:
  media:
  web-root:
    driver: local
    driver_opts:
      type: none
      device: /
      o: bind

Here is my multer configation:

const storage = multer.diskStorage({
    destination: function(req, file, cb) {
        cb(null, '/media');
    },
    filename: function(req, file, cb) {
        cb(null, file.originalname + '-' + Date.now() + path.extname(file.origi$
    }
});

I have tried to rewrite the multer path as the direct route to the docker volume, but that doesn't work either.

I hope someone will be able to help me solve this problem, so that multer can upload directly to the docker volume and the files will be persistent.

1 Answers

I solved it!

I figured out that the volume was mounted correctly. It happened because I in my Dockerfile was using “node” as a user and apparently no matter if I gave permissions the docker container wouldn’t allow that user to write files to the folder. Instead I changed the user to root, and now it is working perfectly.

I also changed the multer file path to “./media/“. And I changed the volume declaration in the docker-compose to - media:/home/node/app/media, since that’s the path I was having the project in according to the Dockerfile.

Related