title: Error EACCES permission denied mkdir multer node.js
body: <p>I have a Node.js application server on production running on an Ubuntu 14.04 LTS machine, but when I try to connect via browser, the following error shows up on PM2 logs:</p>
  
  <pre><code>www-0 (err): Error: EACCES: permission denied, mkdir '/var/www/myapp/MyApp/MyApp/uploads'
  www-0 (err):     at Error (native)
  www-0 (err):     at Object.fs.mkdirSync (fs.js:794:18)
  www-0 (err):     at Function.sync (/var/www/myapp/MyApp/MyApp/node_modules/multer/node_modules/mkdirp/index.js:71:13)
  www-0 (err):     at new DiskStorage (/var/www/myapp/MyApp/MyApp/node_modules/multer/storage/disk.js:21:12)
  www-0 (err):     at module.exports (/var/www/myapp/MyApp/MyApp/node_modules/multer/storage/disk.js:65:10)
  www-0 (err):     at new Multer (/var/www/myapp/MyApp/MyApp/node_modules/multer/index.js:15:20)
  www-0 (err):     at multer (/var/www/myapp/MyApp/MyApp/node_modules/multer/index.js:88:12)
  www-0 (err):     at Object.&lt;anonymous&gt; (/var/www/myapp/MyApp/MyApp/app.js:45:9)
  www-0 (err):     at Module._compile (module.js:410:26)
  www-0 (err):     at Object.Module._extensions..js (module.js:417:10)
  www-0 (err):     at Module.load (module.js:344:32)
  www-0 (err):     at Function.Module._load (module.js:301:12)
  www-0 (err):     at Function._load (/usr/local/lib/node_modules/pm2/node_modules/pmx/lib/transaction.js:62:21)
  www-0 (err):     at Module.require (module.js:354:17)
  www-0 (err):     at require (internal/module.js:12:17)
  www-0 (err):     at Object.&lt;anonymous&gt; (/var/www/myapp/MyApp/MyApp/bin/www:7:11)
  </code></pre>
  
  <p>As you can see, the error comes from multer package. I am currently using multer version 1.1.0, and this is my <code>app.js</code> file:</p>
  
  <pre><code>// app.js
  
  // set up ======================================================================
  // get all the tools we need
  
  var express = require('express');
  var path = require('path');
  var favicon = require('serve-favicon');
  var logger = require('morgan');
  var cookieParser = require('cookie-parser');
  var bodyParser = require('body-parser');
  var session = require('express-session');
  var mongoose = require('mongoose');
  var passport = require('passport');
  var flash = require('connect-flash');
  var multer = require('multer');
  
  var configDB = require('./config/database');
  
  var app = express();
  
  // configuration ===============================================================
  mongoose.connect(configDB.url); // connect to our database
  require('./config/passport')(passport); // pass passport for configuration
  
  // view engine setup
  app.set('views', path.join(__dirname, 'views'));
  app.set('view engine', 'ejs');
  
  // uncomment after placing your favicon in /public
  //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
  //app.use(logger('dev'));
  app.use(bodyParser.json());
  app.use(bodyParser.urlencoded({ extended: false }));
  app.use(cookieParser());
  app.use(express.static(path.join(__dirname, 'public')));
  app.use(session({
      secret: 'secret',
      resave: false,
      saveUninitialized: false
  })); // session secret
  app.use(passport.initialize());
  app.use(passport.session()); // persistent login session
  app.use(flash()); // use connect-flash for flash messages stored in session
  app.use(multer({ // use multer for processing of multipart/form-data
      dest: 'uploads/',
      rename: function (fieldname, filename){
          return filename.replace(/\W+/g, '-').toLowerCase() + Date.now();
      },
      onFileUploadStart: function (file){
          console.log(file.fieldname + ' upload starting...');
      },
      onFileUploadData: function (file, data){
          console.log(data.length + ' of ' + file.fieldname + ' arrived');
      },
      onFileUploadComplete: function (file){
          console.log(file.fieldname + ' uploaded to ' + file.path);
      }
  }).single('avatar'));
  
  // routes ======================================================================
  require('./routes/routes')(app, passport); // load our routes and pass in our app and fully configured passport
  
  // catch 404 and forward to error handler
  app.use(function(req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
  });
  
  // set production environment
  app.set('env', 'production');
  
  // set development environment
  //app.set('env', 'development');
  
  // error handlers
  
  // development error handler
  // will print stacktrace
  if (app.get('env') === 'development') {
    app.use(function(err, req, res, next) {
      res.status(err.status || 500);
      res.render('pages/error', {
        message: err.message,
        error: err
      });
    });
  }
  
  // production error handler
  // no stacktraces leaked to user
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('pages/error', {
      message: err.message,
      error: {}
    });
  });
  
  
  module.exports = app;
  </code></pre>
  
  <p>Also, these are the permissions and rights the directories currently have (myuser has sudo privileges)</p>
  
  <pre><code>myuser@myhost:~$ ls -dl /var/www
  drwxr-xr-x 3 root root 4096 Feb  4 01:17 /var/www
  
  myuser@myhost:~$ ls -dl /var/www/myapp
  drwxr-xr-x 3 myuser myuser 4096 Feb  4 01:18 /var/www/myapp
  
  myuser@myhost:~$ ls -dl /var/www/myapp/MyApp
  drwxrwxr-x 4 myuser myuser 4096 Feb  4 16:49 /var/www/myapp/MyApp
  
  myuser@myhost:~$ ls -dl /var/www/myapp/MyApp/MyApp
  drwxrwxr-x 12 myuser myuser 4096 Feb  4 16:57 /var/www/myapp/MyApp/MyApp
  
  myuser@myhost:~$ ls -dl /var/www/myapp/MyApp/MyApp/uploads
  drwxrwxr-x 2 myuser myuser 4096 Feb  4 02:04 /var/www/myapp/MyApp/MyApp/uploads
  </code></pre>
  
  <p>By the way, changing to <code>{ dest: './uploads/'}</code> gives the same error.</p>