diff --git a/.env.example b/.env.example index 5cf910a..789188b 100644 --- a/.env.example +++ b/.env.example @@ -9,9 +9,9 @@ PGHOST=postgres DATABASE_URL=postgresql://socialflow:changeme@postgres:5432/socialflow # Configuration de l'application -PORT=5000 +PORT=4523 NODE_ENV=production -APP_URL=http://localhost:5000 +APP_URL=http://localhost:4523 # Clé secrète pour les sessions (CHANGEZ CETTE VALEUR) SESSION_SECRET=your-secret-key-change-me-to-random-string diff --git a/DOCKER.md b/DOCKER.md new file mode 100644 index 0000000..bcb3291 --- /dev/null +++ b/DOCKER.md @@ -0,0 +1,194 @@ +# Déploiement Docker - Social Flow + +## 📋 Configuration + +L'application utilise Docker Compose pour orchestrer : +- **PostgreSQL 16** : Base de données sur réseau interne +- **Social Flow App** : Application Node.js exposée sur le port **4523** + +## 🚀 Démarrage rapide + +### 1. Copier le fichier d'environnement + +```bash +cp .env.example .env +``` + +### 2. Éditer les variables d'environnement + +Modifiez `.env` avec vos valeurs : + +```bash +# Base de données +PGDATABASE=socialflow +PGUSER=socialflow +PGPASSWORD=votre_mot_de_passe_securise + +# Application +PORT=4523 +SESSION_SECRET=votre_cle_secrete_aleatoire + +# API OpenRouter (pour la génération IA) +OPENROUTER_API_KEY=votre_cle_openrouter +``` + +### 3. Lancer les conteneurs + +```bash +# Démarrer en arrière-plan +docker-compose up -d + +# Voir les logs +docker-compose logs -f + +# Arrêter +docker-compose down +``` + +## 🌐 Accès à l'application + +- **Accès direct** : http://localhost:4523 +- **Avec Nginx** (reverse proxy) : Voir section ci-dessous + +## 🔧 Architecture réseau + +### Réseau interne (`internal`) +- PostgreSQL et l'application communiquent sur ce réseau privé + +### Réseau nginx (`nginx_default`) +- Réseau externe pour le reverse proxy Nginx +- PostgreSQL et l'application sont sur ce réseau +- Permet l'accès via Nginx et un domaine personnalisé + +## 📝 Configuration Nginx + +### Prérequis : Créer le réseau nginx + +**Avant de lancer docker-compose**, créez le réseau nginx (une seule fois) : + +```bash +docker network create nginx_default +``` + +### Configuration Nginx + +Mettez à jour votre configuration Nginx pour cibler le port **4523** : + +```nginx +upstream socialflow { + server socialflow-app:4523; # ← Utiliser le port 4523 +} + +server { + listen 80; + server_name votre-domaine.com; + + location / { + proxy_pass http://socialflow; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + 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; + } +} +``` + +**Important** : Si vous n'utilisez pas Nginx, vous pouvez retirer le réseau `nginx_default` du `docker-compose.yml`. + +## 🛠️ Commandes utiles + +### Reconstruire les images + +```bash +docker-compose build --no-cache +docker-compose up -d +``` + +### Voir les logs d'un service spécifique + +```bash +docker-compose logs -f app # Application +docker-compose logs -f postgres # Base de données +``` + +### Accéder au conteneur + +```bash +docker-compose exec app sh # Shell de l'application +docker-compose exec postgres psql -U socialflow # PostgreSQL CLI +``` + +### Nettoyer complètement + +```bash +# Arrêter et supprimer les conteneurs, réseaux +docker-compose down + +# Supprimer aussi les volumes (⚠️ PERTE DE DONNÉES) +docker-compose down -v +``` + +## 🔒 Sécurité en production + +1. **Variables d'environnement** : Ne commitez JAMAIS le fichier `.env` +2. **Mots de passe** : Utilisez des mots de passe forts et aléatoires +3. **SESSION_SECRET** : Générez une clé aléatoire de 32+ caractères +4. **Firewall** : Limitez l'accès au port 4523 ou utilisez Nginx +5. **HTTPS** : Configurez un certificat SSL (Let's Encrypt + Nginx) + +## 📊 Healthchecks + +- **PostgreSQL** : Vérifie que la base est prête avant de démarrer l'app +- **Migrations** : Exécutées automatiquement au démarrage (`drizzle-kit push --force`) + +## 🐛 Dépannage + +### L'application ne démarre pas + +```bash +# Vérifier les logs +docker-compose logs app + +# Vérifier que PostgreSQL est prêt +docker-compose exec postgres pg_isready -U socialflow +``` + +### Port 4523 déjà utilisé + +```bash +# Trouver le processus +sudo lsof -i :4523 + +# Ou changer le port dans .env et docker-compose.yml +``` + +### Erreur de connexion à la base de données + +Vérifiez que `DATABASE_URL` dans `.env` correspond aux variables `PGUSER`, `PGPASSWORD`, etc. + +## 📦 Volumes Docker + +- `postgres_data` : Données persistantes de PostgreSQL +- Mappages locaux : + - `./attached_assets` → `/app/attached_assets` (médias uploadés) + - `./migrations` → `/app/migrations` (migrations DB) + +## 🔄 Mise à jour de l'application + +```bash +# 1. Pull les dernières modifications +git pull + +# 2. Reconstruire l'image +docker-compose build + +# 3. Redémarrer +docker-compose up -d + +# 4. Vérifier les logs +docker-compose logs -f app +``` diff --git a/Dockerfile b/Dockerfile index f4e5b4e..cb4ef01 100644 --- a/Dockerfile +++ b/Dockerfile @@ -34,12 +34,12 @@ RUN npm run build # Nettoyer les fichiers inutiles pour réduire la taille RUN rm -rf client node_modules/.cache -# Exposer le port 5555 -EXPOSE 5555 +# Exposer le port de l'application (défini par ENV PORT) +EXPOSE 4523 # Variables d'environnement par défaut ENV NODE_ENV=production -ENV PORT=5555 +ENV PORT=4523 # Démarrer l'application CMD ["npm", "run", "start"] diff --git a/docker-compose.yml b/docker-compose.yml index b7b9a0b..88ecb63 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -14,6 +14,7 @@ services: - postgres_data:/var/lib/postgresql/data networks: - internal + - nginx_default # Port non exposé sur l'hôte pour plus de sécurité en production # Décommentez la ligne suivante si vous avez besoin d'accéder à la DB localement # ports: @@ -31,17 +32,15 @@ services: dockerfile: Dockerfile container_name: socialflow-app restart: unless-stopped - # Port non exposé publiquement car nginx reverse proxy accède via le réseau Docker - # Décommentez si vous avez besoin d'accéder directement sans nginx : - # ports: - # - "${PORT:-5555}:5555" + ports: + - "4523:4523" environment: NODE_ENV: production - PORT: 5555 + PORT: 4523 DATABASE_URL: postgresql://${PGUSER:-socialflow}:${PGPASSWORD:-changeme}@postgres:5432/${PGDATABASE:-socialflow} OPENROUTER_API_KEY: ${OPENROUTER_API_KEY} SESSION_SECRET: ${SESSION_SECRET:-your-secret-key-change-me} - APP_URL: ${APP_URL:-http://localhost:5555} + APP_URL: ${APP_URL:-http://localhost:4523} networks: - internal - nginx_default diff --git a/replit.md b/replit.md index bd2dd79..82f03e3 100644 --- a/replit.md +++ b/replit.md @@ -10,6 +10,9 @@ Preferred communication style: Simple, everyday language. ## Recent Changes +### October 17, 2025 +- **Docker Deployment Configuration**: Configured Docker Compose for private server deployment with PostgreSQL and application on same network. Application exposed on port 4523:4523 as requested. PostgreSQL and app communicate via internal Docker network and are both on nginx_default external network for reverse proxy access. Updated Dockerfile to use port 4523. Created comprehensive DOCKER.md documentation with setup instructions, network architecture explanation, and troubleshooting guide. + ### October 14, 2025 - **Publication History Error Display Fix**: Fixed bug where publication history incorrectly displayed persistent errors for posts that failed initially but succeeded on retry. Problem: When a post failed, the `error` field was populated, but when the post was successfully republished, only `publishedAt` and `externalPostId` were updated without clearing the `error` field. Solution: Modified `schedulerService.publishPost()` to set `error: null` when publication succeeds, ensuring error messages are cleared from the history view after successful republication. - **Publishing Permissions Security Fix**: Fixed critical security vulnerability in POST `/api/posts` endpoint where standard users could publish to ANY page without verification. Added permission check that validates non-admin users can only publish to pages in their `user_page_permissions` list via `getUserAccessiblePages()`. Admins bypass this check and retain full access. Returns 403 Forbidden if user attempts to publish to unauthorized pages. This prevents privilege escalation and ensures proper page-level access control.