1

I have a Meteor application deployed with nginx. I try to upload images from the application to save the images on the server. When I'm in localhost, I save my images in the myapp/public/uploads folder. But, when I deploy, this folder become myapp/bundle/programs/web.browser/app/uploads. So, when I upload an image, it saved in a new folder in myapp/public/uploads. But so, I can't access to it. When I'm in localhost I access to my images like that : localhost:3000/uploads/myImage.png but when I do myAdress/uploads/myImage.png I access to the myapp/bundle/programs/web.browser/app/uploads folder and not the one where the images are saved (myapp/public/uploads).

This is my code to save images :

Meteor.startup(function () {
  UploadServer.init({
    tmpDir: process.env.PWD + '/app/uploads',
    uploadDir: process.env.PWD + '/app/uploads',
    checkCreateDirectories: true,
    uploadUrl: '/upload',
    // *** For renaming files on server
    getFileName: function(file, formData) {
      //CurrentUserId is a variable passed from publications.js
      var name = file.name;
      name = name.replace(/\s/g, '');
      return currentTileId + "_"  + name;
    },
    finished: function(fileInfo, formFields) {
      var name = fileInfo.name;
      name = name.replace(/\s/g, '');
      insertionImages(name, currentTileId, docId);
    },
  });
});

So, do you know how can I do to save and access to my images when the application is deployed ? Maybe save the image in the myapp/bundle/programs/web.browser/app/uploads folder or access to the myapp/public/uploads folder with an url.

Adrien
  • 2,866
  • 4
  • 23
  • 46
  • for this and other reasons, my team quickly switched to Cloudinary for uploading user images. lots of advantages to using a provider rather than your own server, and Cloudinary (though a PITA at times) does provide a pretty handy service. we use a Meteor package to help manage image operations: https://github.com/Lepozepo/cloudinary – zim Jun 18 '17 at 20:33
  • Thanks for your comment, but I prefer to keep my own server. – Adrien Jun 18 '17 at 20:49
  • Understood. I'm curious to see the solution. – zim Jun 18 '17 at 21:35

1 Answers1

0

This is what we do.

Use an external dir for uploads, say, /var/uploads. Keeping the uploads in public folder makes the meteor app to reload in the dev environment, on any file upload.

Now, at local, use Meteor to serve these files at a certain url. In production, use nginx to serve the same at the same url.

For Development

1) Symlink your upload dir to a hidden folder in public.

eg:

ln -s /var/uploads /path/to/public/.#static

2) Serve the public hidden folder via Meteor by using:

The url /static will server the folder public/.#static by using the following code on the server. Ref: How to prevent Meteor from watching files?

var fs = require('fs'), mime = require('mime');

WebApp.rawConnectHandlers.use(function(req, res, next) {

    var data, filePath, re, type;
    re = /^\/static\/(.*)$/.exec(req.url);
    if (re !== null) {
        filePath = process.env.PWD + '/public/.#static/' + re[1];
        try {
            stats = fs.lstatSync(filePath);
            if (stats.isFile()) {
                type = mime.lookup(filePath);
                data = fs.readFileSync(filePath, data);
                res.writeHead(200, {
                    'Content-Type': type
                });
                res.write(data);
                res.end();
            }
        }
        catch (e) {
            // console.error(filePath, "not found", e); // eslint-disable-line no-console
            next();
        }
    }
    else {
        next();
    }
});

For production

1) Use nginx for serving the upload dir

server {
   ...
   location /static/ {
      root /var/uploads;
   }
   ...
}

That's it. /static will server the content of your uploads dir i.e. /var/uploads

Sudhanshu
  • 457
  • 5
  • 18