ops: simplify justfile, guard deploy-db, extract scripts, fix .gitignore

This commit is contained in:
Pontoporeia
2026-03-02 15:24:00 +01:00
parent 2110d2b916
commit 52978aa658
10 changed files with 289 additions and 562 deletions

6
.gitignore vendored
View File

@@ -6,11 +6,11 @@ vendor/
compose.lock
### Test databases ###
database/test.db
storage/test.db
### Logs ###
formulaire/error.log
lib/cache/rate_limit/
error.log
src/cache/rate_limit/
# OS files
.DS_Store

View File

@@ -1,2 +1,3 @@
docs
nginx
src/cache/rate_limit

111
README.md
View File

@@ -1,59 +1,96 @@
# PostERG - Monorepo
# posterg
PostERG est un projet de l'ERG (École de Recherche Graphique) permettant aux étudiant.e.s sortant en cursus de Master de mettre à disposition leurs mémoires et travaux de fin d'études.
Répertoire des travaux de fin d'études de l'[ERG](https://erg.be) (École de Recherche Graphique).
## Structure du projet
## Requirements
Ce monorepo contient deux applications :
- PHP 8.4
- SQLite3 (`php8.4-sqlite3`)
- nginx (production)
- **[formulaire/](./formulaire/)** - Formulaire d'ajout de mémoires pour les étudiant.e.s
- **[front-backend/](./front-backend/)** - Site web public affichant les mémoires soumis
## Project structure
## Prérequis
- PHP 7.4 ou supérieur
- Composer (gestionnaire de dépendances PHP)
### Installation de Composer
```shell
curl -sS https://getcomposer.org/installer | php
```
posterg/
├── public/ # DocumentRoot — web-accessible only
│ ├── admin/ # Admin panel (session-authenticated)
│ ├── assets/ # CSS, fonts, icons
│ ├── media.php # Controlled file serving (covers, PDFs)
│ └── *.php # Public pages (index, search, tfe, apropos)
├── src/ # PHP classes (not web-accessible)
│ ├── AdminAuth.php
│ ├── Database.php
│ ├── RateLimit.php
│ └── config.php
├── templates/ # Shared PHP template partials
├── config/ # Bootstrap and credentials (not web-accessible)
├── storage/ # Database and uploaded files (not web-accessible)
│ ├── schema.sql
│ ├── test.db
│ └── fixtures/
├── tests/
├── scripts/ # Dev and server management scripts
│ ├── setup-dev.sh
│ ├── deploy-server.sh # Run on server with sudo to apply nginx config
│ └── manage-admin-users.sh # Run on server with sudo to manage htpasswd
└── nginx/ # nginx config and reference files
└── posterg.conf
```
ou
Uploaded files (PDFs, covers) live in `storage/` — outside the webroot — and are
served exclusively through `public/media.php`, which validates paths and MIME types.
```shell
php -r "readfile('https://getcomposer.org/installer');" | php
## Development
```bash
just setup # first-time: installs dev dependencies
just serve # http://localhost:8000 (public) and /admin/
just test # run test suite
```
ou installer le paquet `composer` de votre distribution.
Admin credentials in development are set via `config/admin_credentials.php`
(see `config/admin_credentials.example.php`).
## Installation
## Deployment
Chaque sous-projet a ses propres dépendances. Installez-les séparément :
Files are pushed to the server with rsync — there is no repo on the remote.
```shell
cd formulaire && composer install
cd ../front-backend && composer install
```bash
just deploy # rsync app files → posterg:/var/www/posterg/
just deploy-db # push local test.db → remote (only if remote DB is absent)
```
## Lancement en local
`deploy-db` refuses to run if a database already exists on the server, to avoid
accidental overwrites of production data.
Pour chaque application, lancez un serveur PHP :
### First-time server setup
```shell
# Pour le formulaire (port 3000)
cd formulaire && php -S 127.0.0.1:3000
# Pour le site web (port 3001)
cd front-backend && php -S 127.0.0.1:3001
```bash
ssh posterg
sudo mkdir -p /var/www/posterg
sudo chown www-data:posterg /var/www/posterg
sudo chmod 775 /var/www/posterg
exit
```
## Documentation
Then deploy once, copy nginx config, and apply:
- [Documentation du formulaire](./formulaire/README.md)
- [Documentation du site web](./front-backend/README.md)
```bash
just deploy
rsync -v nginx/posterg.conf posterg:/tmp/posterg.conf
ssh posterg "sudo bash /var/www/posterg/scripts/deploy-server.sh"
ssh posterg "sudo systemctl reload nginx"
```
## Liens
### Admin users (htpasswd)
- [Site web PostERG](https://codeberg.org/PostERG/posterg-website)
```bash
ssh posterg "sudo bash /var/www/posterg/scripts/manage-admin-users.sh"
```
## Security notes
- Admin panel protected by nginx `auth_basic` + PHP session (`AdminAuth`)
- Uploads stored outside webroot, served via controlled `media.php`
- Rate limiting on public search (`src/RateLimit.php`)
- See `docs/TODO.SECURITY.md` for outstanding items

15
TODO.md
View File

@@ -25,7 +25,22 @@
- [x] Rewrite `public/admin/thanks.php` (dark info cards)
- [x] Rewrite `public/admin/import.php` (clean dark form)
## Justfile / Ops
- [x] Simplify `serve` and `deploy` to one recipe each
- [x] Remove sysadmin recipes (server-logs, server-status, deploy-nginx, deploy-admin-tools)
- [x] Extract server scripts to `scripts/` (deploy-server.sh, manage-admin-users.sh)
- [x] Guard `deploy-db` against overwriting existing remote database
- [x] Update README.md and docs/SERVER_SETUP.md to reflect current structure
## Pending
- [ ] Add pagination to répertoire student index (currently capped at 100)
- [ ] Thumbnail generation / cover image support for home grid cards
## Admin / Server
- [ ] Add server status view in admin panel (nginx + php-fpm health, site HTTP check)
- [ ] Add server log viewer in admin panel (tail nginx error/access logs via SSH or log endpoint)
- [ ] Add nginx config deploy flow to admin panel (upload `scripts/deploy-server.sh`, run remotely)
- [ ] Add admin user management UI (wraps `scripts/manage-admin-users.sh` on server)

View File

@@ -1,116 +1,62 @@
# Server Setup (Manual)
# Server Setup
Since sudo prompts don't work over SSH in justfile, do the initial setup manually.
## One-Time Setup on Server
## One-time setup on server
```bash
# 1. SSH to server
ssh posterg
# 2. Backup current site (recommended)
sudo cp -r /var/www/html /var/www/html.backup
# 3. Create new directory structure
sudo mkdir -p /var/www/posterg
# 4. Set ownership (www-data is the web server user)
sudo chown www-data:posterg /var/www/posterg
# 5. Set permissions (775 = rwxrwxr-x)
sudo chmod 775 /var/www/posterg
# 6. Verify
ls -ld /var/www/posterg
# Should show: drwxrwxr-x 2 www-data posterg 4096 ... /var/www/posterg
# 7. Exit server
exit
```
## Deploy from Local Machine
## Deploying the application
Files are pushed via rsync — there is no repo on the server.
```bash
# Push all app files
just deploy
# Push initial database (aborts if remote DB already exists)
just deploy-db
```
## Complete Deployment Process
## Applying the nginx config
The config is in `nginx/posterg.conf`. Upload it and run the deploy script on the server:
```bash
# On server (one time)
ssh posterg
sudo mkdir -p /var/www/posterg
sudo chown www-data:posterg /var/www/posterg
sudo chmod 775 /var/www/posterg
exit
# From local machine
just deploy # Deploy files
just deploy-nginx # Update nginx config
# On server - apply nginx config
ssh posterg
sudo bash /tmp/deploy-production.sh
sudo systemctl reload nginx
exit
# Verify from local
just server-status
rsync -v nginx/posterg.conf posterg:/tmp/posterg.conf
ssh posterg "sudo bash /var/www/posterg/scripts/deploy-server.sh"
ssh posterg "sudo systemctl reload nginx"
```
## Important Notes
`scripts/deploy-server.sh` fixes ownership/permissions and installs the nginx config
from `/tmp/posterg.conf`. It must be run as root.
- **Don't delete `/var/www/html/` yet!** Keep it as backup until you confirm the new structure works
- The new structure uses `/var/www/posterg/public/` as DocumentRoot
- Nginx must be updated to point to the new location
## After Confirming Everything Works
Once you've verified the new deployment works:
## Managing admin users
```bash
ssh posterg
sudo rm -rf /var/www/html.backup # Remove backup if no longer needed
sudo rm -rf /var/www/html # Remove old directory
ssh posterg "sudo bash /var/www/posterg/scripts/manage-admin-users.sh"
```
## Directory Structure on Server
```
/var/www/
├── html/ ← OLD (keep as backup for now)
├── html.backup/ ← BACKUP (can delete later)
└── posterg/ ← NEW
├── public/ ← DocumentRoot (nginx serves from here)
├── includes/
├── config/
├── database/
├── lib/
└── vendor/
```
This is an interactive menu for adding, changing, and deleting htpasswd entries
at `/etc/nginx/.htpasswd-posterg`.
## Troubleshooting
### Permission denied during deploy
**Cause:** Directory doesn't exist or has wrong ownership
**Fix:** Run the setup commands above
### Nginx 403 Forbidden
**Cause:** Wrong permissions on files
**Fix:**
```bash
ssh posterg
cd /var/www/posterg
sudo chown -R www-data:posterg .
sudo find . -type d -exec chmod 755 {} \;
sudo find . -type f -exec chmod 644 {} \;
sudo chmod 775 database/
sudo chmod 660 database/*.db
sudo chown -R www-data:posterg /var/www/posterg
sudo find /var/www/posterg -type d -exec chmod 755 {} \;
sudo find /var/www/posterg -type f -exec chmod 644 {} \;
sudo chmod 775 /var/www/posterg/storage
sudo chmod 660 /var/www/posterg/storage/*.db
```
### Database connection errors
**Cause:** Database file permissions
**Fix:**
### Database permission error
```bash
ssh posterg
sudo chown www-data:posterg /var/www/posterg/storage/test.db

233
justfile
View File

@@ -1,72 +1,34 @@
# Post-ERG Justfile
# Unified recipes for the complete site (public + admin)
# Default recipe - show available commands
default:
@just --list
# ============================================================================
# Development Setup
# Development
# ============================================================================
[group('dev')]
setup:
@echo "🛠️ Setting up development environment..."
@bash setup-dev.sh
# ============================================================================
# Development Server
# ============================================================================
@bash scripts/setup-dev.sh
[group('dev')]
serve:
@echo "🚀 Starting Post-ERG development server"
@echo "========================================"
@echo ""
@echo "📍 Public site: http://localhost:8000"
@echo "📍 Admin panel: http://localhost:8000/admin/"
@echo "🔒 Serving from public/ directory (matches production)"
@echo ""
@echo "✨ Live reload enabled - browser auto-refreshes on file save!"
@echo ""
@echo "Press Ctrl+C to stop"
@echo ""
@php -S 127.0.0.1:8000 -t public/
[group('dev')]
stop:
@echo "🛑 Stopping development server..."
@pkill -f "php -S 127.0.0.1:8000" 2>/dev/null && echo "✓ Server stopped" || echo "No server running"
@pkill -f "php -S 127.0.0.1:8000" 2>/dev/null && echo "stopped" || echo "no server running"
[group('dev')]
logs:
@echo "📋 Development logs"
@echo "==================="
@echo ""
@if [ -f error.log ]; then \
echo "Application errors:"; \
echo "------------------"; \
tail -n 20 error.log; \
else \
echo "No error log found"; \
fi
@tail -n 20 error.log 2>/dev/null || echo "no error log"
# ============================================================================
# Deploy Group
# Deploy
# ============================================================================
[group('deploy')]
deploy:
@echo "📤 Deploying Post-ERG complete site"
@echo "===================================="
@echo ""
@echo "⚠️ First time? Ensure /var/www/posterg/ exists on server with:"
@echo " ssh posterg"
@echo " sudo mkdir -p /var/www/posterg"
@echo " sudo chown www-data:posterg /var/www/posterg"
@echo " sudo chmod 775 /var/www/posterg"
@echo ""
@echo "Step 1: Deploying application to /var/www/posterg/..."
rsync -vur --progress \
--chown="www-data:posterg" \
--exclude 'vendor' \
@@ -82,132 +44,64 @@ deploy:
--exclude 'nginx' \
--exclude 'docs' \
--exclude 'justfile*' \
--exclude 'migrate-structure.sh' \
--exclude 'setup-dev.sh' \
--exclude 'scripts' \
--exclude 'var/cache/*' \
--exclude 'var/logs/*' \
./ posterg:/var/www/posterg/
@echo ""
@echo "Step 2: Setting up directories and permissions..."
ssh posterg "cd /var/www/posterg && \
mkdir -p var/{cache,logs,tmp} && \
chown -R www-data:posterg . && \
chmod -R 755 . && \
chmod -R 775 var/ storage/ && \
chmod 660 storage/*.db 2>/dev/null || true"
@echo ""
@echo "✅ Deployment complete!"
@echo ""
@echo "📁 Server structure:"
@echo " • App root: /var/www/posterg/"
@echo " • DocumentRoot: /var/www/posterg/public/"
@echo ""
@echo "🔍 Verify deployment:"
@echo " • Public: https://posterg.erg.be/"
@echo " • Admin: https://posterg.erg.be/admin/"
@echo ""
@echo "⚠️ IMPORTANT: Update nginx config to point to /var/www/posterg/public/"
@echo " Run: just deploy-nginx"
[group('deploy')]
deploy-database:
@echo "⚠️ Deploying test database (will overwrite remote test.db)"
@echo "Creating database directory if needed..."
ssh posterg "mkdir -p /var/www/posterg/storage"
rsync -vur --progress ./storage/test.db posterg:/var/www/posterg/storage/test.db
@echo "Setting correct permissions..."
ssh posterg "chown www-data:posterg /var/www/posterg/storage /var/www/posterg/storage/test.db && chmod 775 /var/www/posterg/storage && chmod 660 /var/www/posterg/storage/test.db"
@echo "✅ Test database deployed and configured"
deploy-db:
@ssh posterg '[ ! -f /var/www/posterg/storage/test.db ]' || (echo "ERROR: remote database already exists. Remove it manually if you intend to overwrite." && exit 1)
rsync -v --progress ./storage/test.db posterg:/var/www/posterg/storage/test.db
ssh posterg "chown www-data:posterg /var/www/posterg/storage/test.db && chmod 660 /var/www/posterg/storage/test.db"
# Legacy alias
[group('deploy')]
test-deploy:
@just deploy-database
# ============================================================================
# Testing
# ============================================================================
[group('test')]
test:
@echo "🧪 Running Post-ERG Test Suite"
@echo "==============================="
@echo ""
@php tests/run-tests.php
[group('test')]
test-unit:
@echo "🧪 Unit Tests"
@echo "============="
@php tests/Unit/DatabaseTest.php
@echo ""
@php tests/Unit/RateLimitTest.php
[group('test')]
test-integration:
@echo "🧪 Integration Tests"
@echo "===================="
@php tests/Integration/SearchTest.php
[group('test')]
test-security:
@echo "🧪 Security Tests"
@echo "================="
@php tests/Security/SecurityTest.php
[group('test')]
syntax:
@echo "🔍 Checking PHP Syntax"
@echo "======================"
@find . -maxdepth 1 -name "*.php" -not -path "./vendor/*" -exec php -l {} \; | grep -v "No syntax errors"
@find admin/ -name "*.php" -exec php -l {} \; 2>/dev/null | grep -v "No syntax errors" || true
@find src/ -name "*.php" -exec php -l {} \; | grep -v "No syntax errors"
@echo "✅ All PHP files have valid syntax"
@echo "✅ Syntax OK"
# ============================================================================
# Database Management
# ============================================================================
# ============================================================================
# Database Statistics
# ============================================================================
[group('stats')]
stats:
@echo "📊 Database Statistics"
@echo "======================"
@echo ""
@sqlite3 storage/test.db "SELECT COUNT(*) || ' total theses' FROM theses;"
@sqlite3 storage/test.db "SELECT COUNT(*) || ' published theses' FROM theses WHERE is_published = 1;"
@sqlite3 storage/test.db "SELECT COUNT(*) || ' authors' FROM authors;"
@sqlite3 storage/test.db "SELECT COUNT(*) || ' supervisors' FROM supervisors;"
@sqlite3 storage/test.db "SELECT COUNT(*) || ' keywords' FROM keywords;"
@sqlite3 storage/test.db "SELECT COUNT(*) || ' files uploaded' FROM thesis_files;"
[group('stats')]
recent:
@echo "📅 Recent Theses"
@echo "================"
@sqlite3 -column -header storage/test.db "SELECT id, title, year, authors FROM v_theses_public ORDER BY year DESC, title LIMIT 10;"
# ============================================================================
# Database Management
# Database
# ============================================================================
[group('database')]
init-db:
@echo "📊 Creating test database from schema..."
@sqlite3 storage/test.db < storage/schema.sql
@echo "✓ Test database created"
@sqlite3 storage/test.db "SELECT COUNT(*) || ' tables created' FROM sqlite_master WHERE type='table';"
@sqlite3 storage/test.db "SELECT COUNT(*) || ' orientations loaded' FROM orientations;"
@sqlite3 storage/test.db "SELECT COUNT(*) || ' AP programs loaded' FROM ap_programs;"
@sqlite3 storage/test.db "SELECT COUNT(*) || ' tables' FROM sqlite_master WHERE type='table';"
[group('database')]
reset-db:
@echo "⚠️ Resetting database (will delete all data)..."
@rm -f storage/test.db
@just init-db
@echo "✓ Database reset complete"
[group('database')]
query:
@@ -215,118 +109,27 @@ query:
[group('database')]
show id:
@echo "Thesis #{{id}}"
@echo "=============="
@sqlite3 -column -header storage/test.db "SELECT * FROM v_theses_full WHERE id = {{id}};"
[group('database')]
backup:
@echo "💾 Backing up database..."
@sqlite3 storage/test.db .dump > storage/backup_$(date +%Y%m%d_%H%M%S).sql
@echo "✓ Database dumped to storage/backup_$(date +%Y%m%d_%H%M%S).sql"
[group('database')]
fixtures:
@echo "🎭 Creating test database with fixtures..."
@php storage/fixtures/CreateTestDatabase.php
[group('database')]
deploy-test-db:
@echo "⚠️ Deploying test database to server (will overwrite remote test.db)"
@echo "Creating database directory if needed..."
ssh posterg "mkdir -p /var/www/html/database"
rsync -vur --progress ./storage/test.db posterg:/var/www/html/storage/test.db
@echo "Setting correct permissions..."
ssh posterg "chgrp posterg /var/www/html/database /var/www/html/storage/test.db && \
chmod 775 /var/www/html/database && \
chmod 660 /var/www/html/storage/test.db"
@echo "✅ Test database deployed"
# ============================================================================
# Server Tools
# ============================================================================
[group('server')]
deploy-nginx:
@echo "🔧 Deploying nginx configuration..."
@echo ""
@echo "⚠️ IMPORTANT: Checking nginx config has correct DocumentRoot..."
@if ! grep -q "/var/www/posterg/public" nginx/posterg.conf 2>/dev/null; then \
echo "❌ ERROR: nginx/posterg.conf must contain '/var/www/posterg/public'"; \
echo " Current DocumentRoot needs updating!"; \
echo ""; \
echo " Edit nginx/posterg.conf and change:"; \
echo " root /var/www/html;"; \
echo " To:"; \
echo " root /var/www/posterg/public;"; \
exit 1; \
fi
@echo "✅ nginx config looks correct"
@echo ""
rsync -vur --progress ./nginx/posterg.conf posterg:/tmp/posterg.conf
rsync -vur --progress ./nginx/deploy-production-new.sh posterg:/tmp/deploy-production.sh
@echo "✅ Files uploaded to /tmp/ on server"
@echo ""
@echo "Next steps on the server:"
@echo " ssh posterg"
@echo " sudo bash /tmp/deploy-production.sh"
@echo " (This will apply config and show reload command)"
[group('server')]
deploy-admin-tools:
@echo "🔑 Uploading admin user management tools..."
rsync -vur --progress ./nginx/manage-admin-users.sh posterg:/tmp/manage-admin-users.sh
@echo "✅ Script uploaded"
@echo ""
@echo "To manage admin users:"
@echo " ssh posterg"
@echo " sudo bash /tmp/manage-admin-users.sh"
[group('server')]
server-logs:
@echo "📋 Server logs (last 50 lines)"
@echo "=============================="
@echo ""
@echo "Nginx error log:"
@echo "----------------"
ssh posterg "sudo tail -50 /var/log/nginx/posterg_error.log" || echo "Cannot read logs (permission denied)"
@echo ""
@echo "Nginx access log:"
@echo "-----------------"
ssh posterg "sudo tail -20 /var/log/nginx/posterg_access.log" || echo "Cannot read logs (permission denied)"
[group('server')]
server-status:
@echo "🔍 Server Status"
@echo "================"
@ssh posterg "systemctl is-active nginx && echo '✓ Nginx running' || echo '✗ Nginx stopped'"
@ssh posterg "systemctl is-active php8.4-fpm && echo '✓ PHP-FPM running' || echo '✗ PHP-FPM stopped'"
@echo ""
@echo "Site check:"
@curl -s -o /dev/null -w " • Public: %{http_code}\n" https://posterg.erg.be/ || echo " • Public: offline"
@curl -s -o /dev/null -w " • Admin: %{http_code}\n" https://posterg.erg.be/admin/ || echo " • Admin: offline"
# ============================================================================
# Utility Commands
# Utils
# ============================================================================
[group('utils')]
clean:
@echo "🧹 Cleaning up development files..."
@rm -f error.log
@rm -f admin/error.log
@rm -f error.log admin/error.log
@rm -rf src/cache/rate_limit/*
@rm -f /tmp/posterg-*.log
@rm -f /tmp/posterg-*.pid
@echo "✓ Cleanup complete"
@rm -f /tmp/posterg-*.log /tmp/posterg-*.pid
[group('utils')]
setup-dirs:
@echo "📁 Creating data directories..."
@mkdir -p admin/data/theses
@mkdir -p admin/data/covers
@mkdir -p admin/data/yaml
@mkdir -p src/cache/rate_limit
@touch admin/data/theses/.gitkeep
@touch admin/data/covers/.gitkeep
@echo "✓ Directories created"
@mkdir -p admin/data/{theses,covers,yaml} src/cache/rate_limit
@touch admin/data/theses/.gitkeep admin/data/covers/.gitkeep

View File

@@ -1,180 +0,0 @@
#!/bin/bash
# Deploy production nginx configuration and fix permissions for Post-ERG
set -e
echo "🚀 Post-ERG Production Deployment"
echo "=================================="
echo ""
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Check if running as root
if [ "$EUID" -ne 0 ]; then
echo -e "${RED}Error: This script must be run as root (use sudo)${NC}"
exit 1
fi
echo "📋 Step 1: Fixing file permissions..."
echo "--------------------------------------"
# Change group to posterg (www-data is member of this group)
chown -R theophile:posterg /var/www/html/
echo "✓ Changed group to posterg"
# Set directory permissions (755 - readable/executable by everyone)
find /var/www/html -type d -exec chmod 755 {} \;
echo "✓ Set directory permissions to 755"
# Set file permissions (640 - owner read/write, group read)
find /var/www/html -type f -exec chmod 640 {} \;
echo "✓ Set file permissions to 640"
# Make upload directories writable by group (for www-data to write)
if [ -d "/var/www/html/formulaire/data/theses" ]; then
chmod 775 /var/www/html/formulaire/data/theses
chmod 775 /var/www/html/formulaire/data/covers
echo "✓ Set upload directories to 775"
fi
# Protect database if it exists
if [ -f "/var/www/html/storage/posterg.db" ]; then
chmod 660 /var/www/html/storage/posterg.db
chown www-data:posterg /var/www/html/storage/posterg.db
echo "✓ Protected database file"
fi
echo ""
echo "📋 Step 2: Checking prerequisites..."
echo "--------------------------------------"
# Check if htpasswd is available
if ! command -v htpasswd &>/dev/null; then
echo -e "${YELLOW}⚠️ htpasswd not found, installing apache2-utils...${NC}"
apt-get update -qq
apt-get install -y apache2-utils
echo -e "${GREEN}✓ apache2-utils installed${NC}"
fi
# Check if htpasswd file exists
if [ ! -f "/etc/nginx/.htpasswd-posterg" ]; then
echo -e "${YELLOW}⚠️ Warning: /etc/nginx/.htpasswd-posterg not found${NC}"
echo " Creating it now..."
echo ""
echo "Please enter admin username:"
read -r ADMIN_USER
htpasswd -c /etc/nginx/.htpasswd-posterg "$ADMIN_USER"
echo -e "${GREEN}✓ Password file created${NC}"
echo ""
else
echo "✓ Password file exists"
fi
# Check if config file was uploaded
if [ ! -f "/tmp/posterg.conf" ]; then
echo -e "${RED}✗ Error: /tmp/posterg.conf not found${NC}"
echo "Please upload it first: rsync -vur ./nginx/posterg-production.conf posterg:/tmp/posterg.conf"
exit 1
fi
echo ""
echo "📋 Step 3: Installing nginx configuration..."
echo "--------------------------------------"
# Backup existing config if it exists
if [ -f "/etc/nginx/sites-available/posterg" ]; then
cp /etc/nginx/sites-available/posterg /etc/nginx/sites-available/posterg.backup.$(date +%Y%m%d_%H%M%S)
echo "✓ Backed up existing config"
fi
# Copy new configuration
cp /tmp/posterg.conf /etc/nginx/sites-available/posterg
echo "✓ Installed configuration to /etc/nginx/sites-available/posterg"
# Create symlink
if [ ! -L "/etc/nginx/sites-enabled/posterg" ]; then
ln -s /etc/nginx/sites-available/posterg /etc/nginx/sites-enabled/posterg
echo "✓ Created symlink in sites-enabled"
else
echo "✓ Symlink already exists"
fi
# Remove default site
if [ -L "/etc/nginx/sites-enabled/default" ]; then
rm /etc/nginx/sites-enabled/default
echo "✓ Disabled default site"
fi
echo ""
echo "📋 Step 4: Testing nginx configuration..."
echo "--------------------------------------"
if nginx -t; then
echo -e "${GREEN}✓ Nginx configuration is valid${NC}"
else
echo -e "${RED}✗ Nginx configuration has errors!${NC}"
echo "Restoring backup..."
if ls /etc/nginx/sites-available/posterg.backup* 1>/dev/null 2>&1; then
BACKUP=$(ls -t /etc/nginx/sites-available/posterg.backup* | head -1)
cp "$BACKUP" /etc/nginx/sites-available/posterg
echo "Configuration restored from backup"
fi
exit 1
fi
echo ""
echo "📋 Step 5: Reloading nginx..."
echo "--------------------------------------"
if systemctl reload nginx; then
echo -e "${GREEN}✓ Nginx reloaded successfully${NC}"
else
echo -e "${RED}✗ Failed to reload nginx${NC}"
exit 1
fi
echo ""
echo "📋 Step 6: Verifying services..."
echo "--------------------------------------"
# Check PHP-FPM
if systemctl is-active --quiet php8.4-fpm; then
echo -e "${GREEN}✓ PHP 8.4-FPM is running${NC}"
else
echo -e "${YELLOW}⚠️ PHP-FPM is not running, starting it...${NC}"
systemctl start php8.4-fpm
systemctl enable php8.4-fpm
echo -e "${GREEN}✓ PHP-FPM started${NC}"
fi
# Check nginx
if systemctl is-active --quiet nginx; then
echo -e "${GREEN}✓ Nginx is running${NC}"
else
echo -e "${RED}✗ Nginx is not running!${NC}"
exit 1
fi
echo ""
echo "═══════════════════════════════════════"
echo -e "${GREEN}✅ Deployment Complete!${NC}"
echo "═══════════════════════════════════════"
echo ""
echo "🧪 Quick Tests:"
echo " • Test public site: curl -I http://localhost/"
echo " • Test admin panel: curl -I http://localhost/formulaire/"
echo " • Test PHP: curl http://localhost/index.php"
echo ""
echo "📊 View logs:"
echo " • Access log: tail -f /var/log/nginx/posterg_access.log"
echo " • Error log: tail -f /var/log/nginx/posterg_error.log"
echo ""
echo "🔒 Security Checks:"
echo " • Database blocked: curl -I http://localhost/storage/posterg.db"
echo " • MD files blocked: curl -I http://localhost/README.md"
echo " • Shared blocked: curl -I http://localhost/shared/Database.php"
echo ""

105
scripts/deploy-server.sh Executable file
View File

@@ -0,0 +1,105 @@
#!/bin/bash
# Deploy production nginx configuration for Post-ERG (NEW STRUCTURE)
# This script applies the nginx config for /var/www/posterg/public/ structure
set -e
echo "🚀 Post-ERG Production Deployment (NEW STRUCTURE)"
echo "=================================================="
echo ""
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Check if running as root
if [ "$EUID" -ne 0 ]; then
echo -e "${RED}Error: This script must be run as root (use sudo)${NC}"
exit 1
fi
echo "📋 Step 1: Fixing file permissions..."
echo "--------------------------------------"
# Change ownership to www-data:posterg
chown -R www-data:posterg /var/www/posterg/
echo "✓ Changed ownership to www-data:posterg"
# Set directory permissions (755)
find /var/www/posterg -type d -exec chmod 755 {} \;
echo "✓ Set directory permissions to 755"
# Set file permissions (644)
find /var/www/posterg -type f -exec chmod 644 {} \;
echo "✓ Set file permissions to 644"
# Make storage directory writable by group
if [ -d "/var/www/posterg/storage" ]; then
chmod 775 /var/www/posterg/storage
echo "✓ Made storage directory group-writable (775)"
fi
# Fix database file permissions
if [ -f "/var/www/posterg/storage/test.db" ]; then
chmod 660 /var/www/posterg/storage/test.db
chown www-data:posterg /var/www/posterg/storage/test.db
echo "✓ Fixed database file permissions (660)"
fi
# Make admin upload directories writable by group
if [ -d "/var/www/posterg/public/admin/data" ]; then
find /var/www/posterg/public/admin/data -type d -exec chmod 775 {} \;
echo "✓ Made admin upload directories group-writable"
fi
echo ""
echo "📋 Step 2: Deploying nginx configuration..."
echo "--------------------------------------"
# Backup existing config
if [ -f "/etc/nginx/sites-available/posterg" ]; then
cp /etc/nginx/sites-available/posterg /etc/nginx/sites-available/posterg.backup.$(date +%Y%m%d_%H%M%S)
echo "✓ Backed up existing config"
fi
# Copy new config
if [ -f "/tmp/posterg.conf" ]; then
cp /tmp/posterg.conf /etc/nginx/sites-available/posterg
echo "✓ Installed new nginx config"
else
echo -e "${RED}Error: /tmp/posterg.conf not found${NC}"
echo "Run 'just deploy-nginx' first"
exit 1
fi
# Test nginx configuration
echo ""
echo "📋 Step 3: Testing nginx configuration..."
echo "--------------------------------------"
if nginx -t; then
echo -e "${GREEN}✓ Nginx configuration is valid${NC}"
else
echo -e "${RED}✗ Nginx configuration has errors!${NC}"
echo "Restoring backup..."
cp /etc/nginx/sites-available/posterg.backup.$(date +%Y%m%d_%H%M%S | tail -1) /etc/nginx/sites-available/posterg
exit 1
fi
echo ""
echo "📋 Step 4: Summary..."
echo "--------------------------------------"
echo -e "${GREEN}✓ Permissions fixed${NC}"
echo -e "${GREEN}✓ Nginx config installed${NC}"
echo -e "${GREEN}✓ Configuration validated${NC}"
echo ""
echo -e "${YELLOW}Ready to reload nginx!${NC}"
echo ""
echo "Run: ${GREEN}sudo systemctl reload nginx${NC}"
echo ""
echo "After reload, verify:"
echo " • https://posterg.erg.be/"
echo " • https://posterg.erg.be/admin/"
echo " • https://posterg.erg.be/storage/test.db (should 404)"

View File

@@ -19,7 +19,7 @@ if [ "$EUID" -ne 0 ]; then
fi
# Check if htpasswd is available
if ! command -v htpasswd &>/dev/null; then
if ! command -v htpasswd &> /dev/null; then
echo -e "${YELLOW}Installing apache2-utils...${NC}"
apt-get update -qq
apt-get install -y apache2-utils
@@ -172,28 +172,28 @@ while true; do
read -r CHOICE
case $CHOICE in
1)
list_users
;;
2)
add_user
;;
3)
change_password
;;
4)
delete_user
;;
5)
reset_all
;;
6)
echo ""
echo "Goodbye!"
exit 0
;;
*)
echo -e "${RED}Invalid option${NC}"
;;
1)
list_users
;;
2)
add_user
;;
3)
change_password
;;
4)
delete_user
;;
5)
reset_all
;;
6)
echo ""
echo "Goodbye!"
exit 0
;;
*)
echo -e "${RED}Invalid option${NC}"
;;
esac
done

View File

@@ -1 +1 @@
[1771972436,1771972448]
[1772461679,1772461686]