first question + junior dev here !
So my problem is : I'm developping an API whith nodejs/express + Docker and Multer where I want to upload files. I tried to configure Docker as good as I can, same for Multer and persist uploaded files in a volume but it keeps throwing me this error :
{
"errno": -13,
"code": "EACCES",
"syscall": "open",
"path": "public/media/pictures/picture-1642414319690.jpg",
"storageErrors": []
}
Here is my Multer upload middleware config :
const multer = require('multer');
const path = require('path');
// PICTURES
// Picture storage path
const storage = multer.diskStorage({
destination(req, file, cb) {
cb(null, '/public/media/pictures');
},
filename: (req, file, cb) => {
cb(
null,
`${file.fieldname}-${Date.now()}${path.extname(file.originalname)}`
);
},
});
// Check pictures type
const checkPicType = (file, cb) => {
// Allowed ext
const pictypes = /jpeg|jpg|png/;
// Check ext
const extname = pictypes.test(path.extname(file.originalname).toLowerCase());
// Check mime
const mimetype = pictypes.test(file.mimetype);
if (mimetype && extname) {
return cb(null, true);
}
return cb('Error: Images only!');
};
// Picture upload options
const picUpload = multer({
storage,
limits: {
fields: 5,
fieldNameSize: 10,
fieldSize: 2000,
fileSize: 25000000,
},
fileFilter(req, file, cb) {
checkPicType(file, cb);
},
}).single('picture');
module.exports = {
picUpload,
};
My Upload method in api/picture.js :
router.post('/upload', (req, res) => {
picUpload(req, res, (err) => {
if (err) {
return res.status(403).json(err);
}
return res.status(201).json({
path: `${req.protocol}://${req.hostname}:${PORT}/${req.file.path}`,
});
});
});
and finally my docker-compose :
services:
web:
build:
context: ./
target: dev
volumes:
- .:/src
- uploaded-files:/src/public/media/files
- uploaded-pictures:/src/public/media/pictures
command: npm run start:dev
ports:
- "5000:5000"
environment:
NODE_ENV: development
DEBUG: nodejs-docker-express:*
postgres:
image: postgres
restart: always
environment:
- POSTGRES_USER=${DB_USER}
- POSTGRES_PASSWORD=${DB_PASS}
volumes:
- postgres:/var/lib/postgresql/data
ports:
- '5432:5432'
volumes:
postgres:
uploaded-files:
uploaded-pictures:
As I said I'm pretty to docker and multer so if I missed a file or some lines to help you understand better, tell me.
Thanks!
I figured it out, it was just a simple path arror in the middleware (picUpload.js)
cb(null, '/src/public/media/pictures');
// Picture storage path
const storage = multer.diskStorage({
destination(req, file, cb) {
cb(null, '/src/public/media/pictures');
},
filename: (req, file, cb) => {
cb(
null,
`${file.fieldname}-${Date.now()}${path.extname(file.originalname)}`
);
},
});