mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-06 11:09:18 +02:00
ops: simplify justfile, guard deploy-db, extract scripts, fix .gitignore
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -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
|
||||
|
||||
111
README.md
111
README.md
@@ -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
15
TODO.md
@@ -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)
|
||||
|
||||
@@ -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
233
justfile
@@ -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
|
||||
|
||||
@@ -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
105
scripts/deploy-server.sh
Executable 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)"
|
||||
0
scripts/manage-admin-user.sh → scripts/manage-admin-users.sh
Normal file → Executable file
0
scripts/manage-admin-user.sh → scripts/manage-admin-users.sh
Normal file → Executable file
@@ -1 +1 @@
|
||||
[1771972436,1771972448]
|
||||
[1772461679,1772461686]
|
||||
Reference in New Issue
Block a user