Wire Doctrine's default connection to the tenant database resolved from the subdomain for HTTP requests and tenant-scoped Messenger messages while keeping master-only services on the master connection. This removes the production inconsistency where demo data, migrations and tenant commands used the tenant database but the web runtime still read from master.
426 lines
9.8 KiB
Markdown
426 lines
9.8 KiB
Markdown
# Deploiement VPS-1
|
|
|
|
Cette procedure sert a mettre Classeo en ligne sur une petite machine Ubuntu 24.04 pour :
|
|
- valider le comportement en production
|
|
- faire une demo
|
|
- heberger un seul tenant
|
|
|
|
Elle est volontairement minimale :
|
|
- serveur unique
|
|
- Docker Compose
|
|
- pas de Mercure
|
|
- pas de Meilisearch
|
|
- pas de RabbitMQ
|
|
- Messenger stocke sa file async en base via Doctrine
|
|
|
|
Le dossier `deploy/vps/` contient deja les fichiers necessaires :
|
|
- `deploy/vps/.env.example`
|
|
- `deploy/vps/generate-env.sh`
|
|
- `deploy/vps/Caddyfile`
|
|
- `deploy/vps/generate-jwt.sh`
|
|
- `deploy/vps/postgres/01-create-tenant-db.sh`
|
|
- `deploy/vps/generate-demo-data.sh`
|
|
|
|
## 1. Prerequis
|
|
|
|
Il faut :
|
|
- un VPS Ubuntu 24.04
|
|
- un acces SSH
|
|
- un nom de domaine ou sous-domaine pointe vers le VPS
|
|
- les ports `80` et `443` accessibles depuis Internet
|
|
|
|
Exemple recommande :
|
|
- domaine final : `demo.example.com`
|
|
- tenant : `demo`
|
|
- domaine de base : `example.com`
|
|
|
|
Dans ce cas :
|
|
- `APP_DOMAIN=demo.example.com`
|
|
- `PUBLIC_BASE_DOMAIN=example.com`
|
|
- `TENANT_SUBDOMAIN=demo`
|
|
|
|
## 2. Connexion SSH
|
|
|
|
Chez OVH, l'utilisateur initial est generalement `ubuntu`.
|
|
|
|
```bash
|
|
ssh ubuntu@IP_DU_VPS
|
|
```
|
|
|
|
Si tu veux passer root pour l'installation :
|
|
|
|
```bash
|
|
sudo -i
|
|
```
|
|
|
|
## 3. Preparation du serveur
|
|
|
|
Les commandes suivantes installent Git, Docker Engine et le plugin Compose.
|
|
|
|
```bash
|
|
sudo apt update
|
|
sudo apt install -y ca-certificates curl git gnupg
|
|
|
|
sudo install -m 0755 -d /etc/apt/keyrings
|
|
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
|
sudo chmod a+r /etc/apt/keyrings/docker.gpg
|
|
|
|
echo \
|
|
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
|
|
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
|
|
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
|
|
|
sudo apt update
|
|
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
|
sudo usermod -aG docker "$USER"
|
|
```
|
|
|
|
Reconnecte ensuite ta session SSH, puis verifie :
|
|
|
|
```bash
|
|
docker --version
|
|
docker compose version
|
|
git --version
|
|
```
|
|
|
|
## 4. Ajouter du swap
|
|
|
|
Sur un `VPS-1`, le swap aide surtout pendant les builds Docker.
|
|
|
|
```bash
|
|
sudo fallocate -l 2G /swapfile
|
|
sudo chmod 600 /swapfile
|
|
sudo mkswap /swapfile
|
|
sudo swapon /swapfile
|
|
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
|
|
free -h
|
|
```
|
|
|
|
## 5. Configurer Git en SSH
|
|
|
|
Sur le VPS, genere une cle SSH dediee :
|
|
|
|
```bash
|
|
mkdir -p ~/.ssh
|
|
chmod 700 ~/.ssh
|
|
ssh-keygen -t ed25519 -C "vps-classeo" -f ~/.ssh/id_ed25519 -N ""
|
|
ssh-keyscan -H git.roukmoute.fr >> ~/.ssh/known_hosts
|
|
chmod 644 ~/.ssh/known_hosts
|
|
```
|
|
|
|
Le serveur Git ecoute en SSH sur le port `2222`, pas sur `22`.
|
|
Ajoute donc cette configuration :
|
|
|
|
```bash
|
|
cat >> ~/.ssh/config <<'EOF'
|
|
Host git.roukmoute.fr
|
|
HostName git.roukmoute.fr
|
|
User git
|
|
Port 2222
|
|
IdentityFile ~/.ssh/id_ed25519
|
|
EOF
|
|
chmod 600 ~/.ssh/config
|
|
```
|
|
|
|
Affiche ensuite la cle publique :
|
|
|
|
```bash
|
|
cat ~/.ssh/id_ed25519.pub
|
|
```
|
|
|
|
Ajoute cette cle dans ton compte Gitea :
|
|
- `https://git.roukmoute.fr`
|
|
- `Settings`
|
|
- `SSH / GPG Keys`
|
|
- `Add Key`
|
|
|
|
Teste ensuite la connexion :
|
|
|
|
```bash
|
|
ssh -T git@git.roukmoute.fr
|
|
```
|
|
|
|
## 6. Cloner le projet
|
|
|
|
```bash
|
|
sudo mkdir -p /srv/classeo
|
|
sudo chown -R "$USER":"$USER" /srv/classeo
|
|
git clone git@git.roukmoute.fr:Roukmoute/Classeo.git /srv/classeo
|
|
cd /srv/classeo
|
|
```
|
|
|
|
Sans fichier `~/.ssh/config`, la variante equivalente est :
|
|
|
|
```bash
|
|
git clone ssh://git@git.roukmoute.fr:2222/Roukmoute/Classeo.git /srv/classeo
|
|
```
|
|
|
|
Si tu veux juste depanner rapidement en HTTPS, le depot public repond aussi sur :
|
|
|
|
```bash
|
|
git clone https://git.roukmoute.fr/Roukmoute/Classeo.git /srv/classeo
|
|
```
|
|
|
|
## 7. Configurer le DNS
|
|
|
|
Avant de lancer la stack, cree un enregistrement DNS de type `A` :
|
|
- `demo.example.com` -> `IPV4_DU_VPS`
|
|
|
|
Attends que le domaine reponde correctement :
|
|
|
|
```bash
|
|
dig +short demo.example.com
|
|
```
|
|
|
|
Le resultat doit renvoyer l'IPv4 du VPS.
|
|
|
|
## 8. Preparer le fichier d'environnement
|
|
|
|
Le plus simple est d'utiliser le generateur interactif :
|
|
|
|
```bash
|
|
./deploy/vps/generate-env.sh
|
|
```
|
|
|
|
Il pose les questions utiles, genere les secrets, derive les regex et ecrit `deploy/vps/.env`.
|
|
|
|
Si tu preferes toujours partir du template a la main :
|
|
|
|
Depuis la racine du repo :
|
|
|
|
```bash
|
|
cp deploy/vps/.env.example deploy/vps/.env
|
|
```
|
|
|
|
Edite ensuite `deploy/vps/.env` :
|
|
|
|
```bash
|
|
nano deploy/vps/.env
|
|
```
|
|
|
|
Valeurs a adapter au minimum :
|
|
|
|
```env
|
|
APP_DOMAIN=demo.example.com
|
|
PUBLIC_BASE_DOMAIN=example.com
|
|
|
|
TENANT_ID=remplacer-par-un-uuid
|
|
TENANT_SUBDOMAIN=demo
|
|
|
|
POSTGRES_PASSWORD=mot-de-passe-base
|
|
APP_SECRET=secret-app
|
|
JWT_PASSPHRASE=passphrase-jwt
|
|
|
|
TRUSTED_HOSTS='^(.+\.)?example\.com$'
|
|
CORS_ALLOW_ORIGIN='^https://([\w-]+\.)?example\.com$'
|
|
ADMIN_ALERT_EMAIL=admin@example.com
|
|
```
|
|
|
|
Tu peux generer les secrets ainsi :
|
|
|
|
```bash
|
|
uuidgen
|
|
openssl rand -hex 32
|
|
openssl rand -base64 48
|
|
```
|
|
|
|
Pour une simple demo, les valeurs Turnstile de test peuvent rester telles quelles dans `.env`.
|
|
|
|
## 9. Charger les variables dans le shell
|
|
|
|
Certaines commandes plus bas utilisent les variables du fichier `.env`.
|
|
Charge-les une fois dans ton shell courant :
|
|
|
|
```bash
|
|
set -a
|
|
. deploy/vps/.env
|
|
set +a
|
|
```
|
|
|
|
## 10. Generer les cles JWT
|
|
|
|
Les cles JWT ne sont pas versionnees. Il faut donc les generer sur le serveur avant le premier build.
|
|
|
|
```bash
|
|
./deploy/vps/generate-jwt.sh
|
|
```
|
|
|
|
Verifie qu'elles existent :
|
|
|
|
```bash
|
|
ls -l backend/config/jwt
|
|
```
|
|
|
|
## 11. Lancer la stack
|
|
|
|
```bash
|
|
docker compose --env-file deploy/vps/.env -f compose.prod.yaml up -d --build
|
|
```
|
|
|
|
Services demarres :
|
|
- `caddy`
|
|
- `php`
|
|
- `frontend`
|
|
- `worker`
|
|
- `db`
|
|
- `redis`
|
|
|
|
Suivre les logs au premier demarrage :
|
|
|
|
```bash
|
|
docker compose --env-file deploy/vps/.env -f compose.prod.yaml logs -f caddy php frontend worker
|
|
```
|
|
|
|
## 12. Executer les migrations
|
|
|
|
Migrations de la base master :
|
|
|
|
```bash
|
|
docker compose --env-file deploy/vps/.env -f compose.prod.yaml exec php \
|
|
php bin/console doctrine:migrations:migrate --no-interaction
|
|
```
|
|
|
|
Migrations de la base tenant :
|
|
|
|
```bash
|
|
docker compose --env-file deploy/vps/.env -f compose.prod.yaml exec php \
|
|
php bin/console tenant:migrate "${TENANT_SUBDOMAIN}"
|
|
```
|
|
|
|
Le tenant PostgreSQL est cree automatiquement au premier demarrage via `deploy/vps/postgres/01-create-tenant-db.sh`.
|
|
|
|
## 13. Generer un jeu de donnees de demo
|
|
|
|
Pour peupler rapidement l'application avec des comptes et des donnees realistes :
|
|
- direction
|
|
- vie scolaire
|
|
- secretariat
|
|
- professeurs
|
|
- eleves
|
|
- parents
|
|
- matieres
|
|
- classes
|
|
- affectations
|
|
- emploi du temps
|
|
|
|
Le plus simple est d'utiliser le wrapper VPS :
|
|
|
|
```bash
|
|
./deploy/vps/generate-demo-data.sh
|
|
```
|
|
|
|
Le script lit `deploy/vps/.env`, reprend `TENANT_SUBDOMAIN` par defaut, puis execute la commande Symfony dans le conteneur `php`.
|
|
|
|
Exemples :
|
|
|
|
```bash
|
|
./deploy/vps/generate-demo-data.sh --password 'Demo2026!'
|
|
./deploy/vps/generate-demo-data.sh --school 'College de demo'
|
|
./deploy/vps/generate-demo-data.sh --tenant demo --zone B --period-type trimester
|
|
./deploy/vps/generate-demo-data.sh --target master
|
|
```
|
|
|
|
La commande utilise un mot de passe commun pour tous les comptes, avec une valeur par defaut si tu n'en fournis pas, et affiche tous les comptes crees.
|
|
Elle est relancable sans dupliquer les donnees.
|
|
|
|
Alternative sans wrapper :
|
|
|
|
```bash
|
|
docker compose --env-file deploy/vps/.env -f compose.prod.yaml exec php \
|
|
php bin/console app:dev:generate-demo-data --tenant="${TENANT_SUBDOMAIN}"
|
|
```
|
|
|
|
Si tu veux juste creer un compte unique de verification, la commande unitaire existe toujours :
|
|
|
|
```bash
|
|
docker compose --env-file deploy/vps/.env -f compose.prod.yaml exec php \
|
|
php bin/console app:dev:create-test-user \
|
|
--tenant="${TENANT_SUBDOMAIN}" \
|
|
--role=ADMIN \
|
|
--email=demo-admin@example.com \
|
|
--password='ChangeMe123!'
|
|
```
|
|
|
|
## 14. Verifications
|
|
|
|
Verifier les conteneurs :
|
|
|
|
```bash
|
|
docker compose --env-file deploy/vps/.env -f compose.prod.yaml ps
|
|
```
|
|
|
|
Verifier l'application :
|
|
|
|
```bash
|
|
curl -I "https://${APP_DOMAIN}"
|
|
curl -I "https://${APP_DOMAIN}/api/docs"
|
|
```
|
|
|
|
A ouvrir dans le navigateur :
|
|
- `https://demo.example.com`
|
|
- `https://demo.example.com/api/docs`
|
|
|
|
## 15. Mise a jour ulterieure
|
|
|
|
Pour redeployer sur la meme machine :
|
|
|
|
```bash
|
|
cd /srv/classeo
|
|
git pull
|
|
|
|
set -a
|
|
. deploy/vps/.env
|
|
set +a
|
|
|
|
docker compose --env-file deploy/vps/.env -f compose.prod.yaml up -d --build
|
|
|
|
docker compose --env-file deploy/vps/.env -f compose.prod.yaml exec php \
|
|
php bin/console doctrine:migrations:migrate --no-interaction
|
|
|
|
docker compose --env-file deploy/vps/.env -f compose.prod.yaml exec php \
|
|
php bin/console tenant:migrate "${TENANT_SUBDOMAIN}"
|
|
|
|
# Optionnel: remettre un jeu de demo complet a jour
|
|
./deploy/vps/generate-demo-data.sh
|
|
```
|
|
|
|
## 16. Reinstallation sur une nouvelle machine
|
|
|
|
Si tu veux remettre la meme instance sur un autre VPS, conserve au minimum :
|
|
- `deploy/vps/.env`
|
|
- `backend/config/jwt/private.pem`
|
|
- `backend/config/jwt/public.pem`
|
|
|
|
Si tu veux aussi conserver les donnees, il faut en plus sauvegarder PostgreSQL et les volumes Docker.
|
|
|
|
## 17. Depannage rapide
|
|
|
|
Si `docker compose up` se fait tuer pendant le build :
|
|
- verifie le swap avec `free -h`
|
|
- relance le build apres activation du swap
|
|
|
|
Si le domaine ne repond pas en HTTPS :
|
|
- verifie que le DNS pointe bien vers le VPS
|
|
- verifie que les ports `80` et `443` sont ouverts
|
|
- regarde les logs `caddy`
|
|
|
|
Si le frontend repond mais pas l'API :
|
|
- verifie `https://TON_DOMAINE/api/docs`
|
|
- regarde les logs `php`
|
|
- regarde les logs `worker`
|
|
|
|
## Resume ultra-court
|
|
|
|
```bash
|
|
ssh ubuntu@IP_DU_VPS
|
|
sudo apt update && sudo apt install -y ca-certificates curl git gnupg
|
|
# installer Docker
|
|
# cloner le repo
|
|
cp deploy/vps/.env.example deploy/vps/.env
|
|
set -a && . deploy/vps/.env && set +a
|
|
./deploy/vps/generate-jwt.sh
|
|
docker compose --env-file deploy/vps/.env -f compose.prod.yaml up -d --build
|
|
docker compose --env-file deploy/vps/.env -f compose.prod.yaml exec php php bin/console doctrine:migrations:migrate --no-interaction
|
|
docker compose --env-file deploy/vps/.env -f compose.prod.yaml exec php php bin/console tenant:migrate "${TENANT_SUBDOMAIN}"
|
|
```
|