There is something preventing image upload to mongo. Try uploading a picture .
Marcus
1
urgent
important
apps
Gotcha — let’s get your image uploads working end-to-end with Node.js + MongoDB. Below are the fastest fixes and 3 proven approaches (save file path, S3, or GridFS), plus the common “it doesn’t upload” pitfalls I see a lot. Quick diagnostic checklist (fix these first) • Your HTML/JS form uses enctype="multipart/form-data" and the field name matches your server middleware (e.g. single('image')). • You are using a multipart parser like multer (uploads won’t arrive via express.json()). • Body/size limits aren’t blocking you: • Express: limits: { fileSize: 5 * 1024 * 1024 } (example) • Nginx (you use it): client_max_body_size 20M; in the server block, then sudo nginx -t && sudo systemctl reload nginx • Disk/permissions: your upload folder exists and Node can write to it. • Mongoose schema matches what you store (URL/string vs Buffer, etc.). • Field names are consistent everywhere (front end, multer, DB). Option A (simple & fast): save file to disk, store URL in MongoDB Best for: small/medium apps, easiest to debug debug // app.js const path = require('path'); const express = require('express'); const mongoose = require('mongoose'); const multer = require('multer'); const Photo = require('./models/Photo'); mongoose.connect(process.env.MONGO_URI); // ensure this succeeds const app = express(); // static hosting for uploaded files app.use('/uploads', express.static(path.join(__dirname, 'uploads'))); // configure multer (disk) const storage = multer.diskStorage({ destination: (req, file, cb) => cb(null, path.join(__dirname, 'uploads')), filename: (req, file, cb) => { const unique = Date.now() + '-' + Math.round(Math.random() * 1e9); const ext = path.extname(file.originalname || ''); cb(null, unique + ext); } }); const upload = multer({ storage }); // add { limits: { fileSize: ... } } if needed // upload route app.post('/upload', upload.single('image'), async (req, res, next) => { try { if (!req.file) return res.status(400).json({ error: 'No file uploaded' }); const fileUrl = `/uploads/${req.file.filename}`; // served statically above const photo = await Photo.create({ title: req.body.title || '', imageUrl: fileUrl }); res.json({ ok: true, photo }); } catch (e) { next(e); } }); app.listen(3000); <form action="/upload" method="POST" enctype="multipart/form-data"> <input type="text" name="title" /> <input type="file" name="image" accept="image/*" /> <button>Upload</button> </form> Option B (scalable): store in S3, save the S3 URL in MongoDB Best for: production/CDN needs, multiple servers. // s3-upload.js const multer = require('multer'); const multerS3 = require('multer-s3'); const { S3Client } = require('@aws-sdk/client-s3'); const s3 = new S3Client({ region: process.env.AWS_REGION }); const upload = multer({ storage: multerS3({ s3, bucket: process.env.S3_BUCKET, contentType: multerS3.AUTO_CONTENT_TYPE, acl: 'public-read', key: (req, file, cb) => { const unique = Date.now() + '-' + Math.round(Math.random() * 1e9); cb(null, `uploads/${unique}-${file.originalname}`); } }) }); module.exports = upload; // route const upload = require('./s3-upload'); app.post('/upload', upload.single('image'), async (req, res, next) => { try { const imageUrl = req.file.location; // S3 public URL const photo = await Photo.create({ title: req.body.title || '', imageUrl }); res.json({ ok: true, photo }); } catch (e) { next(e); } }); Option C (DB-only): GridFS (store the binary in MongoDB) Best for: when you must keep binaries in MongoDB (large files). Note: more moving parts vs A/B. const express = require('express'); const multer = require('multer'); const { MongoClient, ObjectId, GridFSBucket } = require('mongodb'); const upload = multer({ storage: multer.memoryStorage() }); // buffer (async () => { const client = new MongoClient(process.env.MONGO_URI); await client.connect(); const db = client.db(); // default DB const bucket = new GridFSBucket(db, { bucketName: 'images' }); const app = express(); app.post('/upload', upload.single('image'), (req, res, next) => { try { if (!req.file) return res.status(400).json({ error: 'No file' }); const uploadStream = bucket.openUploadStream(req.file.originalname, { contentType: req.file.mimetype }); uploadStream.end(req.file.buffer); uploadStream.on('finish', file => { res.json({ ok: true, fileId: file._id.toString() }); }); uploadStream.on('error', next); } catch (e) { next(e); } }); app.get('/image/:id', (req, res, next) => { try { const _id = new ObjectId(req.params.id); const dl = bucket.openDownloadStream(_id); dl.on('error', next); dl.pipe(res); } catch (e) { next(e); } }); app.listen(3000); })(); ⸻ Common “why isn’t it uploading?” pitfalls & fixes • req.file is undefined → You forgot multer, field name mismatch (single('image') vs <input name="photo">), or no multipart/form-data. • 413 Request Entity Too Large → Increase Nginx client_max_body_size, and (if proxying) ensure proxy_max_temp_file_size/upstream limits are OK. • Saved DB value is empty → You’re storing a Buffer in schema but sending only a path, or vice versa; fix the schema or what you save. • Static file not loading → Forgot app.use('/uploads', express.static(...)), or path is wrong (relative vs absolute). • Docker/Nginx path issues → The folder in the container exists, but the volume isn’t mapped to the host; map the volume or use S3. • Multer storage not configured → If you set only multer() with no storage, it defaults to memory (fine), but you must persist req.file.buffer yourself. ⸻ Minimal curl test (bypass the front end) curl -F "image=@/path/to/pic.jpg" -F "title=Test" http://localhost:3000/upload If this works, the server path is good—then fix your front-end form. ⸻ If you paste your current route + middleware + form (or fetch/XHR) snippet, I’ll point to the exact bug, but the templates above are “known-good” and should work as-is.
I was able to upload pictures to a server directory /playgrounds/picture_upload/upload/ and save the path to mongo. I can delete the path in mongo, but it didn’t delete the file in the server directory.
Find a place to store pictures. Research s3 or other options. Delete the picture from the server
successful deleted picture from server and database.
important to test the upload with a curl command before trying to complicate things and upload pictures. #!/bin/bash echo "starting my script" # Health is GET curl -v http://localhost/healthz # expect: ok echo " start upload testing" # Upload is POST multipart; NOTE the @ curl -F "image=@coffee.jpg" -F "title=Test" http://localhost/upload # expect JSON: { "ok": true, ... }