Reputation: 45
probably a noob question but please do enlighten me.
Let's say I create a clean new project mkdir nextjs_app && cd nextjs_app
, then install three packages to start basic nextjs project npm install react react-dom next
followed by npm init -y
. Then add scripts:
"dev": "next",
"build": "next build",
"start": "next start"
and add empty public
folder.
Now if app started in dev mode npm run dev
and I add some image.jpg
inside public
and navigate to http://localhost:3000/image.jpg
I can access it just fine.
But if I run npm run build
and npm run start
, again I add manually image.jpg
to public
and then try to access it at http://localhost:3000/image.jpg
I get a 404 Not Found
. I have to stop the app ctrl + c
and just start it again npm run start
(no need to build) to be able to access it. Is that expected behavior? Why is like that?
I have an app where I upload files to public/uploads and in dev mode everything works fine and then in production just saved images cannot be accessed. Am I not supposed to save images like I am doing? Please advise!
Upvotes: 4
Views: 2713
Reputation: 141
I have the same problem when I dockerize the app.
The phrase :
I would suggest to upload files to a cloud storage like Amazon S3.
from Nikolai gave me the idea: Run a node server to read the folder.
const express = require("express");
app = express();
app.use(express.static("/path/where/images/are"));
in docker-compose.yml in the volumes section I added:
volumes:
- /path/where/images/are:/app/public
to read the shared folder
and then the images in my next.js app uses :
<img src={"https://www.server2.com/products/" + id } alt='product'/>
The second server ( or docker in my case ) just serves the folder, and the other one ( the backend that works with next.js) uploads my images.
The other way was to restart my docker container ( that was very trashy -> hate to do that)
hope it helps !
Upvotes: 0
Reputation: 884
Might be coming late to the party here, but here's my 2cents on it
create a custom server and serve the uploads folder via express static
app.prepare().then(() => {
const expressApp = express();
const handle = app.getRequestHandler();
expressApp.use(compression({ filter: shouldCompress }));
expressApp.use(
'/uploads',
express.static('/root/projects/uploads', { caseSensitive: true })
);
expressApp.all('*', (req, res) => {
return handle(req, res);
});
createServer(expressApp)
.listen(port, (error) => {
if(error) throw error;
console.log(`Listening @:${port}`);
});
});
Upvotes: 0
Reputation: 6603
When you start Next.js server with npm run start
it reads all files in the /public
directory and adds every present file to the router. If you add files after it's done the server doesn't know that something has changed there. Restarting the server without build reads the /public
directory again and you can see newly added images.
In the development
mode public files are not added to the router but handled as a fallback instead.
Saving uploaded files to /public
might be not reliable approach in production. What if the /public
will be overwritten with next deploy?
What if you want to scale the app and launch additional instances?
I would suggest to upload files to a cloud storage like Amazon S3.
Upvotes: 2