Service d'images personnalisé pour la gestion des photos de plats. Similaire à Cloudinary mais open-source et économique.
- ✅ Upload d'images (JPG, PNG, WebP)
- ✅ Conversion automatique en WebP
- ✅ Redimensionnement dynamique (resize=200, resize=500, full)
- ✅ Cache intelligent
- ✅ CORS pour multi-domaines
- ✅ API REST simple
- Node.js v18+
- npm
git clone https://github.com/your-repo/image-service.git
cd image-service
npm installcp .env.example .env
# Éditer .env selon tes besoinsnpm run dev
# ou
npm startServer lancé sur http://localhost:3000
POST /upload
Content-Type: multipart/form-data
curl -X POST http://localhost:3000/upload \
-F "image=@photo.jpg"Réponse :
{
"id": "uuid-1234-5678",
"urls": {
"full": "/img/full/uuid-1234-5678.webp",
"medium": "/img/resize=500/uuid-1234-5678.webp",
"thumb": "/img/resize=200/uuid-1234-5678.webp"
}
}GET /img/:params/:filename
# Exemple:
GET /img/full/uuid-1234-5678.webp # Full resolution
GET /img/resize=500/uuid-1234-5678.webp # Resized to 500px
GET /img/resize=200/uuid-1234-5678.webp # Resized to 200px (thumbnail)image-service/
├── src/
│ ├── server.js # Point d'entrée
│ ├── controllers/
│ │ └── imageController.js # Logique upload/serve
│ ├── routes/
│ │ └── upload.js # Route upload
│ └── utils/
│ ├── storage.js # Sauvegarde images
│ ├── processor.js # Traitement/redimensionnement
│ └── cache.js # Gestion du cache
├── images/ # ⚠️ Généré (git ignored)
├── cache/ # ⚠️ Généré (git ignored)
├── temp/ # ⚠️ Généré (git ignored)
├── package.json
└── README.md
- Modification dans
src/ - Tester localement
- Commit et push vers GitHub
- Déployer sur VPS
# Test d'upload simple
curl -X POST http://localhost:3000/upload \
-F "image=@test.jpg"
# Vérifier les fichiers générés
ls -la images/
ls -la cache/# SSH sur le VPS
ssh root@your-vps.com
# Cloner le repo
git clone https://github.com/your-repo/image-service.git
cd image-service
# Installer
npm install
# Lancer avec PM2
npm install -g pm2
pm2 start src/server.js --name "image-service"
pm2 startup
pm2 save
# Configurer Nginx (reverse proxy)
# Voir section "Configuration Nginx" plus bas# /etc/nginx/sites-available/images
server {
server_name images.ton-domaine.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 50M;
}
}
server {
listen 80;
server_name images.ton-domaine.com;
return 301 https://$server_name$request_uri;
}sudo certbot certonly --nginx -d images.ton-domaine.com- express - Framework web
- multer - Upload de fichiers
- sharp - Traitement d'images
- uuid - Génération d'IDs uniques
- cors - CORS cross-origin
- ✅ CORS configuré pour domaines spécifiques
- ✅ Validation des types d'images (MIME)
- ✅ Limite de taille d'upload (50MB par défaut)
- ✅ Nettoyage des fichiers temporaires
- ✅ Noms de fichiers sécurisés (UUIDs)
# Trouver le process
lsof -i :3000
# Tuer le process
kill -9 <PID>- Vérifier que les fichiers sont dans
/images/et/cache/ - Vérifier les permissions des dossiers
- Vérifier
ALLOWED_ORIGINSdans.env - Ajouter le domaine Vercel
- WebP compression: 80% plus petit que JPEG
- Cache: Images resizées mises en cache
- Lazy loading possible via thumbnails 200px
Voir restaurant-app pour un exemple d'intégration NextJS complète.
MIT
Pour les problèmes, crée une issue sur GitHub.
- Support WebP input
- Formats multiples (PNG, GIF, AVIF)
- API clé d'authentification
- Analytics (uploads/traffic)
- CDN intégration
- Watermark support
- Crop/rotation API