Files
xamxam/docs/MIGRATION_CHECKLIST.md
Théophile Gervreau-Mercier 4bbbc58e24 Fix admin CSS not loading and quirks mode issues
Fixed multiple issues in admin panel:

1. CSS path: modern-normalize.css → modern-normalize.min.css
   (File is actually named .min.css)

2. Icon path: assets/icon.svg → /assets/admin_favicon.svg
   (Was relative, now absolute; correct filename)

3. Navigation: /admin/list.php → /admin/
   (list.php was renamed to index.php)

4. Short PHP tags: <? → <?php
   (Better compatibility, some servers don't enable short_open_tag)

5. Quirks mode warning was due to CSS not loading, not DOCTYPE
   (DOCTYPE was already present)

Files modified:
- public/admin/inc/head.php (main fixes)
- public/admin/index.php (short tags)
- public/admin/add.php (short tags)
- public/admin/import.php (short tags)

Need to redeploy for production: just deploy
2026-02-06 13:26:24 +01:00

382 lines
9.3 KiB
Markdown

# Migration Checklist - Public Directory Structure
Quick reference for migrating from current flat structure to secure public/ structure.
## 📋 Summary of Required Changes
### 1. Dev Server (justfile) ⚡
**Line 51** - Change from:
```just
@php -S 127.0.0.1:8000
```
To:
```just
@php -S 127.0.0.1:8000 -t public/
```
### 2. Deployment (justfile) 📤
**Lines 56-75** - Replace entire `deploy` recipe with two-step deployment:
- Deploy app to `/var/www/posterg/` (not `/var/www/html/`)
- Nginx serves from `/var/www/posterg/public/`
See `DEPLOYMENT_MIGRATION.md` for complete updated recipe.
### 3. Nginx Configuration 🔧
**nginx/posterg.conf line 14** - Change from:
```nginx
root /var/www/html;
```
To:
```nginx
root /var/www/posterg/public;
```
**Also update admin location** (line 58) - Change from:
```nginx
location ^~ /formulaire/ {
```
To:
```nginx
location ^~ /admin/ {
```
(Since you're moving admin/ to public/admin/)
---
## 🚀 Quick Migration (Local Dev)
```bash
# 1. Update justfile serve command
sed -i 's/@php -S 127.0.0.1:8000/@php -S 127.0.0.1:8000 -t public\//' justfile
# 2. Test new dev server
just serve
# Visit http://localhost:8000
# Verify http://localhost:8000/database/test.db returns 404
# 3. If it works, you're ready for production migration
```
---
## 📁 File Movements (Do This After Testing)
```bash
# Create new structure
mkdir -p public/{admin,assets}
mkdir -p src config var/{cache,logs,tmp}
# Move public files
mv index.php search.php memoire.php public/
mv admin/* public/admin/ && rmdir admin
mv assets/* public/assets/ && rmdir assets
# Move private files
mv inc/* config/ && rmdir inc
# OR if inc/ contains classes:
# mv inc/* src/ && rmdir inc
# Keep these as-is
# database/ (already private)
# vendor/ (already private)
# tests/ (already private)
# lib/ (decide if it goes to src/lib or stays)
```
---
## ⚠️ Critical Changes Required
### In nginx/posterg.conf:
1. **Line 14** - DocumentRoot
```nginx
# BEFORE
root /var/www/html;
# AFTER
root /var/www/posterg/public;
```
2. **Line 58-76** - Admin location (already at `/formulaire/`, might want `/admin/`)
```nginx
# BEFORE
location ^~ /formulaire/ {
auth_basic "Admin Access - Post-ERG";
auth_basic_user_file /etc/nginx/.htpasswd-posterg;
# ... rest of config
}
# AFTER (if renaming to /admin/)
location ^~ /admin/ {
auth_basic "Admin Access - Post-ERG";
auth_basic_user_file /etc/nginx/.htpasswd-posterg;
# ... rest of config
}
```
3. **Remove/update deny rules** (lines 48-60) - These become redundant!
```nginx
# BEFORE - needed because everything in DocumentRoot
location ^~ /database/ { deny all; }
location ^~ /shared/ { deny all; }
location ^~ /data/ { deny all; }
# AFTER - can remove! They're already outside public/
# But keep as defense-in-depth:
location ^~ /database/ { deny all; } # Will never match, but safe
```
### In justfile:
**Complete replacement for lines 40-76:**
```just
[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 ""
@echo "🔒 Serving from public/ directory (matches production)"
@if [ -d "vendor/php-live-reload" ]; then \
echo "✨ Live reload enabled"; \
else \
echo "💡 Tip: Run 'just setup' to enable live reload"; \
fi
@echo ""
@echo "Press Ctrl+C to stop"
@echo ""
@php -S 127.0.0.1:8000 -t public/
[group('deploy')]
deploy:
@echo "📤 Deploying Post-ERG complete site"
@echo "===================================="
@echo ""
@echo "Deploying to /var/www/posterg/..."
rsync -vur --progress \
--chown="www-data:posterg" \
--exclude 'vendor' \
--exclude 'tests' \
--exclude 'test.db' \
--exclude '*.md' \
--exclude '.git*' \
--exclude '.jj' \
--exclude '.DS_Store' \
--exclude 'justfile*' \
--exclude 'setup-dev.sh' \
--exclude 'database/backup_*' \
--exclude 'database/fixtures' \
--exclude 'var/cache/*' \
--exclude 'var/logs/*' \
./ posterg:/var/www/posterg/
@echo ""
@echo "Setting up directories and permissions..."
ssh posterg "cd /var/www/posterg && \
mkdir -p var/{cache,logs,tmp} && \
chown -R www-data:posterg var/ database/ && \
chmod -R 775 var/ database/ && \
chmod 660 database/*.db"
@echo ""
@echo "✅ Deployment complete!"
@echo ""
@echo "🔍 Verify:"
@echo " • Public: https://posterg.erg.be/"
@echo " • Admin: https://posterg.erg.be/admin/"
[group('deploy')]
test-deploy:
@echo "⚠️ Deploying test database"
ssh posterg "mkdir -p /var/www/posterg/database"
rsync -vur --progress ./database/test.db posterg:/var/www/posterg/database/
ssh posterg "chown www-data:posterg /var/www/posterg/database/test.db && \
chmod 660 /var/www/posterg/database/test.db"
@echo "✅ Test database deployed"
```
---
## 🧪 Testing Steps
### 1. Test Local Dev Server
```bash
# Start server with new -t public/ flag
just serve
# In another terminal:
curl http://localhost:8000/ # ✅ Should work
curl http://localhost:8000/admin/ # ✅ Should work (after moving)
curl http://localhost:8000/database/test.db # ❌ Should 404
curl http://localhost:8000/config/ # ❌ Should 404
curl http://localhost:8000/vendor/ # ❌ Should 404
```
### 2. Test After File Migration
```bash
# After moving files to public/
just serve
# Test again
curl http://localhost:8000/ # ✅ index.php serves
curl http://localhost:8000/search.php # ✅ works
curl http://localhost:8000/admin/ # ✅ works
curl http://localhost:8000/assets/css/style.css # ✅ works
# Verify old paths don't work
curl http://localhost:8000/../database/test.db # ❌ 404
curl http://localhost:8000/../config/ # ❌ 404
```
### 3. Test Production Deployment
```bash
# After deploying to server
just server-status
# Manual checks
curl -I https://posterg.erg.be/
curl -I https://posterg.erg.be/admin/
curl -I https://posterg.erg.be/database/test.db # Must be 404!
```
---
## 📝 PHP Path Updates Needed
After moving to public/, update PHP includes:
**Before (from root):**
```php
<?php
require_once 'inc/config.php';
require_once 'lib/Database.php';
require_once 'database/test.db';
```
**After (from public/):**
```php
<?php
require_once __DIR__ . '/../config/config.php';
require_once __DIR__ . '/../src/lib/Database.php';
$db = new PDO('sqlite:' . __DIR__ . '/../database/test.db');
```
**Or use a bootstrap:**
```php
<?php
// public/index.php
require_once __DIR__ . '/../config/bootstrap.php';
// config/bootstrap.php
define('APP_ROOT', dirname(__DIR__));
define('PUBLIC_ROOT', APP_ROOT . '/public');
define('DATABASE_PATH', APP_ROOT . '/database/test.db');
require_once APP_ROOT . '/vendor/autoload.php';
```
---
## 🔍 What to Check in Your Code
Run these searches to find hardcoded paths:
```bash
# Find absolute paths
grep -r "/var/www/html" ./*.php
grep -r "/var/www/html" ./admin/*.php
# Find relative paths that need updating
grep -r "require.*inc/" ./*.php
grep -r "require.*lib/" ./*.php
grep -r "require.*database/" ./*.php
# Find database connections
grep -r "\.db" ./*.php
# Find asset references
grep -r "src=\"assets/" ./*.php
grep -r "href=\"assets/" ./*.php
```
---
## ⚡ Quick Start (Minimal Changes First)
If you want to test with minimal changes:
**1. Only change dev server:**
```bash
# Edit justfile line 51
@php -S 127.0.0.1:8000 -t public/
# Create public/ with symlinks (temporary test)
mkdir public
ln -s ../index.php public/index.php
ln -s ../search.php public/search.php
ln -s ../admin public/admin
ln -s ../assets public/assets
# Test
just serve
```
**2. If it works, do full migration**
---
## 🆘 Rollback Plan
If production deployment fails:
```bash
# On server
sudo systemctl stop nginx
# Restore old config
sudo cp /etc/nginx/sites-available/posterg.backup /etc/nginx/sites-available/posterg
sudo nginx -t
sudo systemctl start nginx
# Or restore files
sudo rm -rf /var/www/posterg
sudo mv /var/www/html.backup /var/www/html
```
**Always backup before deploying:**
```bash
# Before migration
ssh posterg "sudo cp -r /var/www/html /var/www/html.backup"
ssh posterg "sudo cp /etc/nginx/sites-available/posterg /etc/nginx/sites-available/posterg.backup"
```
---
## 📊 Benefits After Migration
| Before | After |
|--------|-------|
| ❌ All files in DocumentRoot | ✅ Only public/ in DocumentRoot |
| ❌ Database accessible if nginx misconfigured | ✅ Database physically unreachable |
| ❌ Config files one deny rule away | ✅ Config files outside web root |
| ❌ 20+ deny/exclude rules needed | ✅ Physical separation, minimal rules |
| ❌ Dev server exposes everything | ✅ Dev matches production security |
---
## Next: Check Your Current Paths
Run this to see what paths need updating:
```bash
# Find all require/include statements
find . -name "*.php" -not -path "./vendor/*" -not -path "./tests/*" \
-exec grep -H "require\|include" {} \; > paths-audit.txt
# Review paths-audit.txt and update paths
cat paths-audit.txt
```
See **DEPLOYMENT_MIGRATION.md** for complete implementation details.