Jason
Jason

Reputation: 268

Heroku nodejs pathing issue... Error: ENOENT: no such file or directory

I have a nodejs application using hapi.js and I'm trying to download an image from a url. Heroku is giving me errors with the pathing.

My code:

Request(uri).pipe(fs.createWriteStream(__dirname+'/../public/images/'+filename)).on('close', callback);

My errors:

 Error: ENOENT: no such file or directory, open '/app/../public/images/1430540759757341747_4232065786.jpg'

My file structure is simple:

app.js
-public
 -images
  -sampleimage.jpg
 -videos
  -samplevideo.mp4
 -audio
  -sampleaudio.wav

As you can see the __dirname for heroku application is /app. I've tried using __dirname+'all sorts of pathing ../ ./ etc' and I've also tried it without __dirname.

I will be creating a lot of these files using ffmpeg and a speech tool. So could anyone explain to me what kind of problem I am having? Is it something that can be solved by using the correct path name or is it my hapijs server configurations that I need to configure?

Upvotes: 2

Views: 3372

Answers (2)

The folder you hosted on heroku is considered as "app" which you can see from the error you got. I m commenting this after 5 years just to let future viewers know. If any folder is empty, it is not pushed to github or heroku when you pushed the entire project as the folder is empty.

When we try to access a folder which is empty initially, we get the above error as the folder is not pushed in the first place. So, if you want to get rid of the error, place a temp file of any type ( I used a txt file) and push the code. Now the error won't be there anymore as this time the folder is pushed and it can access it.

Upvotes: 0

rdegges
rdegges

Reputation: 33824

You just have the wrong path in your project.

On Heroku, you can't write to the folder BELOW the root of your project.

In your case, your code is running in app.js, which is in the 'root' folder of your project.

So, on Heroku's filesystem, this means your project looks like this:

/app
/app/app.js
/app/public
/app/public/images
...

Heroku puts all your code into a folder called app.

Now, in your code pasted above, you show:

Request(uri).pipe(fs.createWriteStream(__dirname+'/../public/images/'+filename)).on('close', callback);

If this code is running in your app.js, it means that by going BACK a folder (eg: ..), you're trying to write to a non-writable part of Heroku's filesystem.

Instead, you want to write to:

Request(uri).pipe(fs.createWriteStream(__dirname+'/public/images/'+filename)).on('close', callback);

This will correctly write your file into the images folder like you want.

HOWEVER

Here's where things are going to get complicated for a moment.

On Heroku, you can indeed write files to the filesystem, but they will DISAPPEAR after a short period of time.

Heroku's filesystem is EPHEMERAL, this means that you should treat it like it doesn't exist.

The reason Heroku does this is because they try to force you to write scalable software.

If your application writes files to your webserver disk, it won't scale very much. The reason why is that disk space is limited. Each web server has its own disk. This can lead to confusing / odd behavior where each webserver has a copy of the same file(s), etc. It just isn't a good practice.

Instead: what you should do is use a file storage service (usually Amazon S3) to store your files in a central location.

This service lets you store all of your files in a central location. This means:

  • You can easily access your files from ALL of your web servers.
  • You can have 'reliable' storage that is managed by a company.
  • You can scale your web applications better.

Upvotes: 4

Related Questions