Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1487c54d3 | ||
|
|
778a0a16e8 | ||
|
|
8fce19e3d4 | ||
|
|
74d87126ea | ||
|
|
4effafe3a1 | ||
|
|
cbe6326284 | ||
|
|
3a792c1a56 | ||
|
|
a14da5113f | ||
|
|
12e9326ccd | ||
|
|
39b462e274 | ||
|
|
cd51f3f945 | ||
|
|
2649e02f7b | ||
|
|
d33928b5f0 | ||
|
|
582339ca99 | ||
|
|
20e8382ae0 | ||
|
|
224df3a4b7 | ||
|
|
0282a21298 | ||
|
|
adf007b379 | ||
|
|
65c680da5b | ||
|
|
85a6c0d795 | ||
|
|
a119950806 | ||
|
|
2fe1062106 | ||
|
|
bf6f98d83b | ||
|
|
5ef90c3676 | ||
|
|
dce22c0ced | ||
|
|
ce95ae33b6 | ||
|
|
5e446df042 | ||
|
|
826ee83ca5 | ||
|
|
fef8a941b3 |
@@ -13,7 +13,7 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
token: ${{ secrets.REGISTRY_TOKEN }}
|
||||
persist-credentials: true
|
||||
|
||||
- name: Create next tag from config/version.yaml
|
||||
|
||||
116
CLAUDE.md
116
CLAUDE.md
@@ -1,6 +1,69 @@
|
||||
# Coltura
|
||||
|
||||
CRM/ERP. Monorepo Symfony 8 (API Platform 4) + Nuxt 4.
|
||||
CRM/ERP. Monorepo Symfony 8 (API Platform 4) + Nuxt 4. **Architecture DDD (Domain-Driven Design).**
|
||||
|
||||
## Architecture DDD
|
||||
|
||||
Le projet suit une architecture DDD cote backend ET frontend. Le code est organise par **domaine metier** (Bounded Context), pas par type technique.
|
||||
|
||||
### Backend — Organisation par domaine
|
||||
|
||||
```
|
||||
src/
|
||||
Domain/ # Couche domaine (logique metier pure, aucune dependance framework)
|
||||
{BoundedContext}/ # Ex: Customer, Sales, Catalog, Invoice...
|
||||
Entity/ # Entites et Aggregates du domaine
|
||||
ValueObject/ # Value Objects (Money, Address, Email...)
|
||||
Repository/ # Interfaces des repositories (ports)
|
||||
Service/ # Services domaine (logique metier)
|
||||
Event/ # Domain Events
|
||||
Exception/ # Exceptions metier
|
||||
Application/ # Couche application (cas d'usage, orchestration)
|
||||
{BoundedContext}/
|
||||
Command/ # Commands (write) + Handlers
|
||||
Query/ # Queries (read) + Handlers
|
||||
DTO/ # Data Transfer Objects
|
||||
Infrastructure/ # Couche infrastructure (implementations techniques)
|
||||
{BoundedContext}/
|
||||
Repository/ # Implementations Doctrine des repositories
|
||||
Persistence/ # Mapping Doctrine (si XML/YAML)
|
||||
Shared/ # Services techniques partages (mail, storage, etc.)
|
||||
Api/ # Couche API (exposition HTTP)
|
||||
{BoundedContext}/
|
||||
Resource/ # ApiResource API Platform
|
||||
State/ # Providers & Processors API Platform
|
||||
```
|
||||
|
||||
**Regles DDD backend :**
|
||||
- Le domaine (`Domain/`) ne depend de RIEN (pas de Doctrine, pas de Symfony, pas d'API Platform)
|
||||
- Les repositories dans `Domain/` sont des **interfaces** ; les implementations Doctrine sont dans `Infrastructure/`
|
||||
- Les entites API Platform (`Api/Resource/`) sont decouples des entites domaine si necessaire
|
||||
- Chaque Bounded Context est autonome — pas d'import croise entre contextes (communiquer via events ou services application)
|
||||
- `User` et `Auth` restent dans `src/` (hors DDD) car c'est du framework pur (Security Bundle)
|
||||
|
||||
### Frontend — Organisation par domaine
|
||||
|
||||
```
|
||||
frontend/
|
||||
domains/ # Modules metier
|
||||
{bounded-context}/ # Ex: customer, sales, catalog, invoice...
|
||||
components/ # Composants Vue specifiques au domaine
|
||||
composables/ # Composables specifiques au domaine
|
||||
services/ # Services API du domaine
|
||||
dto/ # Types TypeScript du domaine
|
||||
pages/ # Pages du domaine (optionnel, ou dans pages/)
|
||||
stores/ # Store Pinia du domaine (si necessaire)
|
||||
components/ # Composants UI partages (non lies a un domaine)
|
||||
composables/ # Composables partages (useApi, useAppVersion)
|
||||
stores/ # Stores globaux (auth, ui)
|
||||
services/ # Services partages
|
||||
```
|
||||
|
||||
**Regles DDD frontend :**
|
||||
- Chaque domaine est un dossier autonome dans `frontend/domains/`
|
||||
- Un domaine ne doit pas importer depuis un autre domaine — utiliser les composables/stores partages
|
||||
- Les composants, services et types partages restent a la racine (`components/`, `composables/`, etc.)
|
||||
- Les pages peuvent etre dans `frontend/pages/` (routing Nuxt) et importer les composants du domaine
|
||||
|
||||
## Stack
|
||||
|
||||
@@ -12,26 +75,37 @@ CRM/ERP. Monorepo Symfony 8 (API Platform 4) + Nuxt 4.
|
||||
## Structure
|
||||
|
||||
```
|
||||
src/Entity/ # Entites Doctrine (User)
|
||||
src/ApiResource/ # Ressources API Platform decouples (AppVersion)
|
||||
src/State/ # Providers et Processors API Platform (MeProvider, AppVersionProvider, UserPasswordHasherProcessor)
|
||||
src/Service/ # Services metier
|
||||
src/Repository/ # Repositories Doctrine
|
||||
src/DataFixtures/ # Fixtures
|
||||
config/ # Config Symfony (security, api_platform, lexik_jwt, nelmio_cors, doctrine)
|
||||
config/jwt/ # Cles JWT (private.pem, public.pem)
|
||||
migrations/ # Migrations Doctrine
|
||||
infra/dev/ # Config Docker dev (Dockerfile, nginx, php.ini, xdebug)
|
||||
infra/prod/ # Config Docker prod (Dockerfile multi-stage, nginx, php-prod.ini)
|
||||
frontend/ # App Nuxt 4
|
||||
frontend/pages/ # Pages (index, login)
|
||||
frontend/layouts/ # Layouts (default)
|
||||
frontend/components/ # Composants Vue
|
||||
frontend/composables/# Composables (useApi, useAppVersion)
|
||||
frontend/stores/ # Stores Pinia (auth, ui)
|
||||
frontend/services/ # Services API (auth)
|
||||
frontend/services/dto/ # Types TypeScript
|
||||
frontend/i18n/locales/ # Fichiers de traduction
|
||||
src/
|
||||
Domain/{Context}/Entity/ # Entites domaine
|
||||
Domain/{Context}/ValueObject/ # Value Objects
|
||||
Domain/{Context}/Repository/ # Interfaces repositories
|
||||
Domain/{Context}/Service/ # Services domaine
|
||||
Domain/{Context}/Event/ # Domain Events
|
||||
Application/{Context}/Command/ # Commands + Handlers
|
||||
Application/{Context}/Query/ # Queries + Handlers
|
||||
Application/{Context}/DTO/ # Data Transfer Objects
|
||||
Infrastructure/{Context}/Repository/ # Implementations Doctrine
|
||||
Api/{Context}/Resource/ # ApiResource API Platform
|
||||
Api/{Context}/State/ # Providers & Processors
|
||||
Entity/ # Entites framework (User)
|
||||
DataFixtures/ # Fixtures
|
||||
config/ # Config Symfony
|
||||
config/jwt/ # Cles JWT
|
||||
migrations/ # Migrations Doctrine
|
||||
infra/dev/ # Docker dev
|
||||
infra/prod/ # Docker prod (multi-stage)
|
||||
frontend/
|
||||
domains/{context}/components/ # Composants du domaine
|
||||
domains/{context}/composables/ # Composables du domaine
|
||||
domains/{context}/services/ # Services API du domaine
|
||||
domains/{context}/dto/ # Types TS du domaine
|
||||
domains/{context}/stores/ # Store Pinia du domaine
|
||||
components/ # Composants UI partages
|
||||
composables/ # Composables partages (useApi, useAppVersion)
|
||||
stores/ # Stores globaux (auth, ui)
|
||||
pages/ # Pages (routing Nuxt)
|
||||
layouts/ # Layouts
|
||||
i18n/locales/ # Traductions
|
||||
```
|
||||
|
||||
## Commandes
|
||||
|
||||
99
README.md
99
README.md
@@ -1,26 +1,103 @@
|
||||
# Coltura
|
||||
|
||||
CRM/ERP - Symfony 8 + API Platform 4 + Nuxt 4
|
||||
CRM/ERP — Symfony 8 (API Platform 4) + Nuxt 4
|
||||
|
||||
## Stack
|
||||
|
||||
- **Backend** : PHP 8.4, Symfony 8, API Platform 4, Doctrine ORM, PostgreSQL 16
|
||||
- **Frontend** : Nuxt 4 (SPA), Vue 3, Pinia, Tailwind CSS, @malio/layer-ui
|
||||
- **Auth** : JWT HTTP-only cookie (Lexik)
|
||||
- **Infra** : Docker Compose (dev + prod multi-stage)
|
||||
- **CI/CD** : Gitea Actions (auto-tag + build Docker)
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
make start # Start Docker containers
|
||||
make install # Install dependencies, run migrations, build frontend
|
||||
make start # Demarrer les containers Docker
|
||||
make install # Composer, migrations, fixtures, build Nuxt
|
||||
```
|
||||
|
||||
Dev frontend: `make dev-nuxt` (hot reload on port 3003)
|
||||
Dev frontend (hot reload) :
|
||||
|
||||
```bash
|
||||
make dev-nuxt # Port 3003
|
||||
```
|
||||
|
||||
## Ports
|
||||
|
||||
| Service | Port |
|
||||
|----------|------|
|
||||
| API | 8083 |
|
||||
| Frontend | 3003 |
|
||||
| Service | Port |
|
||||
|------------|------|
|
||||
| API (Nginx)| 8083 |
|
||||
| Frontend | 3003 |
|
||||
| PostgreSQL | 5436 |
|
||||
|
||||
## Commandes
|
||||
|
||||
| Commande | Description |
|
||||
|----------|-------------|
|
||||
| `make start` | Demarrer les containers |
|
||||
| `make stop` | Arreter les containers |
|
||||
| `make restart` | Redemarrer les containers |
|
||||
| `make install` | Install complet |
|
||||
| `make reset` | Tout supprimer et reinstaller |
|
||||
| `make dev-nuxt` | Serveur dev Nuxt (hot reload) |
|
||||
| `make shell` | Shell dans le container PHP |
|
||||
| `make cache-clear` | Vider le cache Symfony |
|
||||
| `make migration-migrate` | Lancer les migrations |
|
||||
| `make fixtures` | Charger les fixtures |
|
||||
| `make db-reset` | Reset BDD + migrations + fixtures |
|
||||
| `make test` | PHPUnit |
|
||||
| `make php-cs-fixer-allow-risky` | Fix code style PHP |
|
||||
| `make logs-dev` | Tail logs Symfony |
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
src/ # Backend Symfony
|
||||
Entity/ # Entites Doctrine
|
||||
ApiResource/ # Ressources API Platform
|
||||
State/ # Providers & Processors
|
||||
Repository/ # Repositories Doctrine
|
||||
DataFixtures/ # Fixtures
|
||||
config/ # Config Symfony
|
||||
migrations/ # Migrations Doctrine
|
||||
frontend/ # App Nuxt 4
|
||||
pages/ # Pages Vue
|
||||
layouts/ # Layouts
|
||||
components/ # Composants
|
||||
composables/ # Composables (useApi, useAppVersion)
|
||||
stores/ # Stores Pinia (auth, ui)
|
||||
services/ # Services API + DTOs
|
||||
i18n/ # Traductions
|
||||
infra/
|
||||
dev/ # Docker dev (Dockerfile, nginx, php.ini, xdebug)
|
||||
prod/ # Docker prod (multi-stage, nginx, php-prod.ini)
|
||||
.gitea/workflows/ # CI Gitea (auto-tag, build Docker)
|
||||
```
|
||||
|
||||
## CI/CD
|
||||
|
||||
- **Auto Tag** : push sur `develop` → bump `config/version.yaml` → tag `vX.Y.Z`
|
||||
- **Build Docker** : push tag `v*` → build image multi-stage → push Gitea Registry
|
||||
|
||||
Secrets requis dans Gitea :
|
||||
- `RELEASE_TOKEN` — PAT avec droits `write:repository`
|
||||
- `REGISTRY_TOKEN` — token pour le registry Docker
|
||||
|
||||
## Credentials (dev)
|
||||
|
||||
- admin / admin (ROLE_ADMIN)
|
||||
- alice / alice (ROLE_USER)
|
||||
- bob / bob (ROLE_USER)
|
||||
| Username | Password | Role |
|
||||
|----------|----------|------|
|
||||
| admin | admin | ROLE_ADMIN |
|
||||
| alice | alice | ROLE_USER |
|
||||
| bob | bob | ROLE_USER |
|
||||
|
||||
## Conventions
|
||||
|
||||
### Commits
|
||||
|
||||
```
|
||||
<type>(<scope optionnel>) : <message>
|
||||
```
|
||||
|
||||
Types : `build`, `chore`, `ci`, `docs`, `feat`, `fix`, `perf`, `refactor`, `revert`, `style`, `test`
|
||||
|
||||
11149
composer.lock
generated
Normal file
11149
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
1911
config/reference.php
Normal file
1911
config/reference.php
Normal file
File diff suppressed because it is too large
Load Diff
@@ -2,3 +2,9 @@
|
||||
|
||||
controllers:
|
||||
resource: routing.controllers
|
||||
|
||||
login_check:
|
||||
path: /login_check
|
||||
|
||||
api_logout:
|
||||
path: /api/logout
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
parameters:
|
||||
app.version: '0.1.0'
|
||||
app.version: '0.1.15'
|
||||
|
||||
314
doc/deployment-docker.md
Normal file
314
doc/deployment-docker.md
Normal file
@@ -0,0 +1,314 @@
|
||||
# Deploiement Docker — Coltura
|
||||
|
||||
## Pre-requis
|
||||
|
||||
### Docker
|
||||
|
||||
```bash
|
||||
# Ubuntu
|
||||
sudo apt update
|
||||
sudo apt install -y ca-certificates curl 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
|
||||
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-compose-plugin
|
||||
sudo usermod -aG docker $USER
|
||||
```
|
||||
|
||||
Se deconnecter/reconnecter pour que le groupe `docker` prenne effet.
|
||||
|
||||
### Nginx
|
||||
|
||||
```bash
|
||||
sudo apt install -y nginx
|
||||
sudo systemctl enable nginx
|
||||
sudo systemctl start nginx
|
||||
```
|
||||
|
||||
### PostgreSQL
|
||||
|
||||
PostgreSQL tourne dans un conteneur Docker separe (voir le repo `infra-postgres`).
|
||||
Il doit etre installe et accessible avant de deployer Coltura.
|
||||
|
||||
Creer la base de donnees pour Coltura :
|
||||
|
||||
```bash
|
||||
cd /var/www/postgres
|
||||
docker compose exec postgres psql -U admin
|
||||
```
|
||||
|
||||
```sql
|
||||
-- Si le user n'existe pas encore
|
||||
CREATE USER malio WITH PASSWORD 'motdepasse';
|
||||
|
||||
-- Creer la base
|
||||
CREATE DATABASE coltura_prod OWNER malio;
|
||||
\q
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Premiere installation (nouvelle machine)
|
||||
|
||||
Guide complet pour mettre en ligne Coltura sur une machine vierge. Inclut les pre-requis, la BDD et l'app.
|
||||
|
||||
### 1. Installer les pre-requis
|
||||
|
||||
Installer Docker, Nginx et PostgreSQL (voir section Pre-requis ci-dessus).
|
||||
|
||||
### 2. Creer le dossier de deploiement
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /var/www/coltura
|
||||
sudo chown -R $(whoami):$(whoami) /var/www/coltura
|
||||
cd /var/www/coltura
|
||||
```
|
||||
|
||||
### 3. Se connecter au registry Docker de Gitea
|
||||
|
||||
```bash
|
||||
docker login gitea.malio.fr
|
||||
```
|
||||
|
||||
- **Username** : le nom d'utilisateur du compte organisation Gitea `MALIO`
|
||||
- **Password** : le token REGISTRY_TOKEN dispo dans le bitwarden
|
||||
|
||||
Le login est sauvegarde dans `~/.docker/config.json`, pas besoin de le refaire a chaque deploiement.
|
||||
|
||||
### 4. Creer les fichiers de deploiement
|
||||
|
||||
Creer `docker-compose.yml` :
|
||||
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
image: gitea.malio.fr/malio-dev/coltura:${COLTURA_IMAGE_TAG:-latest}
|
||||
container_name: coltura-app
|
||||
env_file: .env
|
||||
ports:
|
||||
- "8083:80"
|
||||
volumes:
|
||||
- ./config/jwt:/var/www/html/config/jwt:ro
|
||||
- ./uploads:/var/www/html/var/uploads
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
Creer `deploy.sh` :
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
TAG="${1:-latest}"
|
||||
export COLTURA_IMAGE_TAG="$TAG"
|
||||
|
||||
echo "==> Deploying coltura:${TAG}..."
|
||||
|
||||
echo "==> Pulling image..."
|
||||
docker compose pull
|
||||
|
||||
echo "==> Starting container..."
|
||||
docker compose up -d
|
||||
|
||||
echo "==> Waiting for container to be ready..."
|
||||
sleep 3
|
||||
|
||||
echo "==> Running migrations..."
|
||||
docker compose exec -T -u www-data app php bin/console doctrine:migrations:migrate --no-interaction
|
||||
|
||||
echo "==> Clearing cache..."
|
||||
docker compose exec -T -u www-data app php bin/console cache:clear --env=prod
|
||||
docker compose exec -T -u www-data app php bin/console cache:warmup --env=prod
|
||||
|
||||
VERSION=$(docker compose exec -T app cat config/version.yaml | grep 'app.version' | awk -F"'" '{print $2}')
|
||||
echo "==> Deployed v${VERSION}"
|
||||
```
|
||||
|
||||
Rendre executable :
|
||||
|
||||
```bash
|
||||
chmod +x deploy.sh
|
||||
```
|
||||
|
||||
### 5. Configurer l'environnement
|
||||
|
||||
Creer `.env` avec les variables suivantes :
|
||||
|
||||
```env
|
||||
# Symfony
|
||||
APP_ENV=prod
|
||||
APP_DEBUG=0
|
||||
APP_SECRET=<generer avec: openssl rand -hex 32>
|
||||
|
||||
# Database (host.docker.internal = la machine hote, ou le PG tourne en Docker)
|
||||
DATABASE_URL="postgresql://malio:password@host.docker.internal:5432/coltura_prod?serverVersion=16&charset=utf8"
|
||||
|
||||
# JWT
|
||||
JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem
|
||||
JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem
|
||||
JWT_PASSPHRASE=<generer avec: openssl rand -hex 32>
|
||||
JWT_COOKIE_SECURE=1
|
||||
JWT_COOKIE_SAMESITE=lax
|
||||
JWT_TOKEN_TTL=86400
|
||||
JWT_COOKIE_TTL=86400
|
||||
|
||||
# CORS
|
||||
CORS_ALLOW_ORIGIN='^https?://coltura\.malio-dev\.fr$'
|
||||
|
||||
# App
|
||||
DEFAULT_URI=https://coltura.malio-dev.fr
|
||||
```
|
||||
|
||||
### 6. Generer les cles JWT
|
||||
|
||||
```bash
|
||||
mkdir -p config/jwt
|
||||
openssl genpkey -algorithm RSA -out config/jwt/private.pem -pkeyopt rsa_keygen_bits:4096
|
||||
openssl rsa -pubout -in config/jwt/private.pem -out config/jwt/public.pem
|
||||
```
|
||||
|
||||
Rendre les cles lisibles par le conteneur (www-data = uid 33) :
|
||||
|
||||
```bash
|
||||
sudo chown 33:33 config/jwt/private.pem config/jwt/public.pem
|
||||
sudo chmod 644 config/jwt/private.pem config/jwt/public.pem
|
||||
```
|
||||
|
||||
### 7. Creer le dossier uploads
|
||||
|
||||
```bash
|
||||
mkdir -p uploads
|
||||
```
|
||||
|
||||
### 8. Configurer Nginx systeme (reverse proxy + maintenance)
|
||||
|
||||
Copier la config reverse proxy depuis le repo :
|
||||
|
||||
```bash
|
||||
sudo cp infra/prod/nginx-proxy.conf /etc/nginx/sites-available/coltura.conf
|
||||
```
|
||||
|
||||
Ou creer `/etc/nginx/sites-available/coltura.conf` manuellement (voir `infra/prod/nginx-proxy.conf`).
|
||||
|
||||
La config inclut le **mode maintenance** : si le fichier `/var/www/coltura/maintenance.on` existe, Nginx renvoie une 503 avec `maintenance.html`.
|
||||
|
||||
Activer le site :
|
||||
|
||||
```bash
|
||||
sudo ln -sf /etc/nginx/sites-available/coltura.conf /etc/nginx/sites-enabled/coltura.conf
|
||||
sudo nginx -t && sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
### Mode maintenance
|
||||
|
||||
```bash
|
||||
# Activer la maintenance
|
||||
touch /var/www/coltura/maintenance.on
|
||||
|
||||
# Desactiver la maintenance
|
||||
rm /var/www/coltura/maintenance.on
|
||||
```
|
||||
|
||||
Optionnel : creer une page `/var/www/coltura/public/maintenance.html` personnalisee.
|
||||
|
||||
### 9. Deployer
|
||||
|
||||
```bash
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
### 10. Creer le premier user admin
|
||||
|
||||
```bash
|
||||
docker compose exec -T -u www-data app php bin/console security:hash-password --env=prod
|
||||
```
|
||||
|
||||
Choisir `App\Entity\User`, taper le mdp, copier le hash. Puis :
|
||||
|
||||
```bash
|
||||
cd /var/www/postgres
|
||||
docker compose exec -T postgres psql -U malio coltura_prod -c "INSERT INTO \"user\" (username, roles, password, created_at) VALUES ('admin', '[\"ROLE_ADMIN\"]', '<le-hash>', NOW());"
|
||||
```
|
||||
|
||||
Ou charger les fixtures (dev uniquement) :
|
||||
|
||||
```bash
|
||||
docker compose exec -T -u www-data app php bin/console doctrine:fixtures:load --no-interaction --env=prod
|
||||
```
|
||||
|
||||
### Structure finale du dossier
|
||||
|
||||
```
|
||||
/var/www/coltura/
|
||||
├── docker-compose.yml
|
||||
├── deploy.sh
|
||||
├── .env
|
||||
├── config/jwt/
|
||||
│ ├── private.pem
|
||||
│ └── public.pem
|
||||
└── uploads/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Deployer une nouvelle version
|
||||
|
||||
Quand l'app est deja installee, deployer une mise a jour :
|
||||
|
||||
```bash
|
||||
cd /var/www/coltura
|
||||
./deploy.sh # deploie la derniere version (latest)
|
||||
./deploy.sh v0.2.0 # deploie une version specifique
|
||||
```
|
||||
|
||||
C'est tout. Le script pull l'image, redemarre le conteneur, lance les migrations et vide le cache.
|
||||
|
||||
---
|
||||
|
||||
## Rollback
|
||||
|
||||
### Image seule (pas de changement de schema BDD)
|
||||
|
||||
```bash
|
||||
./deploy.sh v0.1.9
|
||||
```
|
||||
|
||||
### Avec rollback de migration
|
||||
|
||||
```bash
|
||||
# 1. Rollback schema (pendant que la version actuelle tourne encore)
|
||||
docker compose exec -T -u www-data app php bin/console doctrine:migrations:migrate prev --no-interaction
|
||||
# 2. Deployer l'ancienne version
|
||||
./deploy.sh v0.1.9
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## CI/CD
|
||||
|
||||
Le workflow `.gitea/workflows/build-docker.yml` se declenche automatiquement sur push de tag `v*` :
|
||||
1. Build l'image multi-stage
|
||||
2. Push vers `gitea.malio.fr/malio-dev/coltura:<tag>` et `:latest`
|
||||
|
||||
Combine avec `auto-tag-develop.yml`, chaque push sur `develop` cree automatiquement un tag → build → image disponible.
|
||||
|
||||
---
|
||||
|
||||
## Voir les logs
|
||||
|
||||
```bash
|
||||
cd /var/www/coltura
|
||||
docker compose logs -f # tous les logs
|
||||
docker compose logs -f --tail=100 # 100 dernieres lignes
|
||||
```
|
||||
|
||||
Logs Symfony :
|
||||
|
||||
```bash
|
||||
docker compose exec app cat var/log/prod.log
|
||||
```
|
||||
1
frontend/.npmrc
Normal file
1
frontend/.npmrc
Normal file
@@ -0,0 +1 @@
|
||||
@malio:registry=https://gitea.malio.fr/api/packages/MALIO-DEV/npm/
|
||||
0
frontend/domains/.gitkeep
Normal file
0
frontend/domains/.gitkeep
Normal file
7
frontend/layouts/auth.vue
Normal file
7
frontend/layouts/auth.vue
Normal file
@@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<div class="min-h-screen bg-tertiary-500 from-tertiary-500 via-white to-neutral-100 text-neutral-900">
|
||||
<main class="mx-auto flex min-h-screen w-full max-w-[720px] items-center px-6 py-12">
|
||||
<slot />
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
14874
frontend/package-lock.json
generated
Normal file
14874
frontend/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
BIN
frontend/public/coltura.png
Normal file
BIN
frontend/public/coltura.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.9 KiB |
BIN
frontend/public/favicon.ico
Normal file
BIN
frontend/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
2
frontend/public/robots.txt
Normal file
2
frontend/public/robots.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
User-Agent: *
|
||||
Disallow:
|
||||
@@ -74,13 +74,13 @@ RUN cd frontend && npm ci && npm run build:dist && rm -rf node_modules
|
||||
RUN chown -R www-data:www-data /var/www/html/var /var/www/html/frontend/dist
|
||||
|
||||
# PHP prod config
|
||||
COPY infra/deploy/php-prod.ini /usr/local/etc/php/php.ini
|
||||
COPY infra/prod/php-prod.ini /usr/local/etc/php/php.ini
|
||||
|
||||
EXPOSE 9000
|
||||
|
||||
# ── Nginx stage ──
|
||||
FROM nginx:1.27-alpine AS nginx
|
||||
|
||||
COPY infra/deploy/nginx.conf /etc/nginx/conf.d/default.conf
|
||||
COPY infra/prod/nginx.conf /etc/nginx/conf.d/default.conf
|
||||
COPY --from=php-base /var/www/html/public /var/www/html/public
|
||||
COPY --from=php-base /var/www/html/frontend/dist /var/www/html/frontend/dist
|
||||
|
||||
31
infra/prod/nginx-proxy.conf
Normal file
31
infra/prod/nginx-proxy.conf
Normal file
@@ -0,0 +1,31 @@
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name coltura.malio-dev.fr;
|
||||
|
||||
root /var/www/coltura/public;
|
||||
|
||||
# Maintenance mode
|
||||
if (-f /var/www/coltura/maintenance.on) {
|
||||
return 503;
|
||||
}
|
||||
|
||||
error_page 503 @maintenance;
|
||||
|
||||
location @maintenance {
|
||||
rewrite ^(.*)$ /maintenance.html break;
|
||||
}
|
||||
|
||||
location = /maintenance.html {
|
||||
internal;
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8083;
|
||||
proxy_set_header Host $host;
|
||||
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;
|
||||
client_max_body_size 55m;
|
||||
}
|
||||
}
|
||||
32
migrations/Version20260407095546.php
Normal file
32
migrations/Version20260407095546.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20260407095546 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE TABLE "user" (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, username VARCHAR(180) NOT NULL, roles JSON NOT NULL, password VARCHAR(255) NOT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY (id))');
|
||||
$this->addSql('CREATE UNIQUE INDEX UNIQ_8D93D649F85E0677 ON "user" (username)');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('DROP TABLE "user"');
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\State;
|
||||
namespace App\Api\Auth\State;
|
||||
|
||||
use ApiPlatform\Metadata\Operation;
|
||||
use ApiPlatform\State\ProviderInterface;
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\State;
|
||||
namespace App\Api\Auth\State;
|
||||
|
||||
use ApiPlatform\Metadata\Operation;
|
||||
use ApiPlatform\State\ProcessorInterface;
|
||||
use App\Entity\User;
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
|
||||
|
||||
/**
|
||||
@@ -15,7 +16,7 @@ use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
|
||||
class UserPasswordHasherProcessor implements ProcessorInterface
|
||||
{
|
||||
public function __construct(
|
||||
/** @var ProcessorInterface<User, User> */
|
||||
#[Autowire(service: 'api_platform.doctrine.orm.state.persist_processor')]
|
||||
private readonly ProcessorInterface $persistProcessor,
|
||||
private readonly UserPasswordHasherInterface $passwordHasher,
|
||||
) {}
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\ApiResource;
|
||||
namespace App\Api\Shared\Resource;
|
||||
|
||||
use ApiPlatform\Metadata\ApiResource;
|
||||
use ApiPlatform\Metadata\Get;
|
||||
use App\State\AppVersionProvider;
|
||||
use App\Api\Shared\State\AppVersionProvider;
|
||||
|
||||
#[ApiResource(
|
||||
operations: [
|
||||
@@ -2,10 +2,11 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\State;
|
||||
namespace App\Api\Shared\State;
|
||||
|
||||
use ApiPlatform\Metadata\Operation;
|
||||
use ApiPlatform\State\ProviderInterface;
|
||||
use App\Api\Shared\Resource\AppVersion;
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||
|
||||
/**
|
||||
@@ -20,6 +21,6 @@ class AppVersionProvider implements ProviderInterface
|
||||
|
||||
public function provide(Operation $operation, array $uriVariables = [], array $context = []): object
|
||||
{
|
||||
return new \App\ApiResource\AppVersion($this->appVersion);
|
||||
return new AppVersion($this->appVersion);
|
||||
}
|
||||
}
|
||||
0
src/Application/.gitkeep
Normal file
0
src/Application/.gitkeep
Normal file
0
src/Domain/.gitkeep
Normal file
0
src/Domain/.gitkeep
Normal file
@@ -10,9 +10,9 @@ use ApiPlatform\Metadata\Get;
|
||||
use ApiPlatform\Metadata\GetCollection;
|
||||
use ApiPlatform\Metadata\Patch;
|
||||
use ApiPlatform\Metadata\Post;
|
||||
use App\Api\Auth\State\MeProvider;
|
||||
use App\Api\Auth\State\UserPasswordHasherProcessor;
|
||||
use App\Repository\UserRepository;
|
||||
use App\State\MeProvider;
|
||||
use App\State\UserPasswordHasherProcessor;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
||||
|
||||
0
src/Infrastructure/Shared/.gitkeep
Normal file
0
src/Infrastructure/Shared/.gitkeep
Normal file
Reference in New Issue
Block a user