diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 70595bb..8bc9a64 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -1,4 +1,4 @@ -name: Build and Deploy +name: Deploy on: push: @@ -9,63 +9,22 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v3 - - name: Install tools + - name: Setup SSH run: | - apt-get update && apt-get install -y docker.io curl jq + mkdir -p ~/.ssh + echo "${{ secrets.DEPLOY_SSH_KEY }}" > ~/.ssh/id_ed25519 + chmod 600 ~/.ssh/id_ed25519 + ssh-keyscan -H "${{ secrets.DEPLOY_HOST }}" >> ~/.ssh/known_hosts - - name: Build production image + - name: Install PHP & Deployer run: | - docker build --target frankenphp_prod -t mangarr:latest . + sudo apt-get install -y php-cli + curl -LO https://deployer.org/deployer.phar + chmod +x deployer.phar - - name: Redeploy via Portainer API + - name: Deploy env: - PORTAINER_USER: ${{ secrets.PORTAINER_USER }} - PORTAINER_PASSWORD: ${{ secrets.PORTAINER_PASSWORD }} - run: | - JWT=$(curl -s -X POST http://portainer:9000/api/auth \ - -H "Content-Type: application/json" \ - -d "{\"Username\":\"$PORTAINER_USER\",\"Password\":\"$PORTAINER_PASSWORD\"}" | jq -r '.jwt') - - if [ -z "$JWT" ] || [ "$JWT" = "null" ]; then - echo "Erreur: authentification Portainer echouee" - exit 1 - fi - - STACK_INFO=$(curl -s http://portainer:9000/api/stacks \ - -H "Authorization: Bearer $JWT") - STACK_ID=$(echo "$STACK_INFO" | jq '.[] | select(.Name=="mangarr") | .Id') - ENDPOINT_ID=$(echo "$STACK_INFO" | jq '.[] | select(.Name=="mangarr") | .EndpointId') - - if [ -z "$STACK_ID" ] || [ "$STACK_ID" = "null" ]; then - echo "Erreur: stack mangarr non trouvee" - exit 1 - fi - - echo "Stack ID: $STACK_ID, Endpoint ID: $ENDPOINT_ID" - - STACK_FILE=$(curl -s "http://portainer:9000/api/stacks/$STACK_ID/file" \ - -H "Authorization: Bearer $JWT" | jq -r '.StackFileContent') - STACK_ENV=$(curl -s "http://portainer:9000/api/stacks/$STACK_ID" \ - -H "Authorization: Bearer $JWT" | jq '.Env') - - HTTP_CODE=$(curl -s -o /tmp/deploy_result.json -w "%{http_code}" -X PUT \ - "http://portainer:9000/api/stacks/$STACK_ID?endpointId=$ENDPOINT_ID" \ - -H "Authorization: Bearer $JWT" \ - -H "Content-Type: application/json" \ - -d "{\"stackFileContent\":$(echo "$STACK_FILE" | jq -Rs .),\"env\":$STACK_ENV,\"prune\":true,\"pullImage\":false}") - - echo "Portainer redeploy: HTTP $HTTP_CODE" - if [ "$HTTP_CODE" -ge 300 ]; then - cat /tmp/deploy_result.json - exit 1 - fi - - - name: Run migrations - run: | - echo "Attente du demarrage de Mangarr..." - sleep 15 - docker exec mangarr php bin/console doctrine:migrations:migrate --no-interaction || echo "Rien a migrer" - docker exec mangarr php bin/console cache:clear --env=prod || true - echo "Deploy termine avec succes" + DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }} + run: php deployer.phar deploy production -vvv diff --git a/Dockerfile b/Dockerfile index 826a676..1ead9c3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -68,6 +68,19 @@ ENTRYPOINT ["docker-entrypoint"] HEALTHCHECK --start-period=60s CMD curl -f http://localhost:2019/metrics || exit 1 CMD [ "frankenphp", "run", "--config", "/etc/caddy/Caddyfile" ] +# Runtime FrankenPHP image (sans code baked-in) +# Le code vient du bind mount /srv/mangarr/current:/app (géré par Deployer) +# Builder une seule fois : docker build --target frankenphp_runtime -t mangarr:runtime . +FROM frankenphp_base AS frankenphp_runtime + +ENV APP_ENV=prod +ENV FRANKENPHP_CONFIG="import worker.Caddyfile" + +RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" + +COPY --link frankenphp/conf.d/app.prod.ini $PHP_INI_DIR/conf.d/ +COPY --link frankenphp/worker.Caddyfile /etc/caddy/worker.Caddyfile + # Dev FrankenPHP image FROM frankenphp_base AS frankenphp_dev diff --git a/deploy.php b/deploy.php index f6ceaa8..caa2f88 100644 --- a/deploy.php +++ b/deploy.php @@ -2,38 +2,42 @@ namespace Deployer; require 'recipe/symfony.php'; -// require 'contrib/webpack_encore.php'; -require 'contrib/npm.php'; -// Config -set('nodejs_version', 'node_22.x'); -set('keep_releases', '3'); -set('repository', 'gitea@git.test.nestor-server.fr:Colgora/Mangarr.git'); -set('webpack_encore/env', 'production'); -set('composer_options', '--verbose --prefer-dist --no-progress --no-interaction --optimize-autoloader'); +set('repository', 'https://git.homelab.nestor-server.fr/colgora/Mangarr.git'); +set('keep_releases', 3); +set('composer_options', '--no-dev --optimize-autoloader --no-interaction --prefer-dist'); -set('shared_files', ['.env.local','var/log/prod.log']); -set('shared_dirs', ['config/secrets','public/cbz','public/tmp','public/images']); -// add('writable_dirs', []); +// Pas de shared_files ni shared_dirs : tout est géré par les volumes Docker +set('shared_files', []); +set('shared_dirs', []); +set('writable_dirs', []); -desc('Runs webpack encore build'); -task('webpack_encore:build', function () { - run("cd {{release_path}} && npm run build"); -}); - -desc('Run messenger consume'); -task('messenger:consume', function () { - run("sudo supervisorctl restart messenger-consume:*"); -}); - -host('mangarr.test.nestor-server.fr') - ->set('remote_user', 'colgora') - ->set('deploy_path', '/var/www/mangarr') +host('production') + ->set('hostname', getenv('DEPLOY_HOST')) // Injecté depuis le secret Gitea + ->set('remote_user', 'deploy') // User avec accès docker group + ->set('deploy_path', '/srv/mangarr') ->set('branch', 'main'); +// composer install via container éphémère (pas de PHP sur l'hôte requis) +task('deploy:vendors', function () { + run('docker run --rm -v {{release_path}}:/app -w /app composer:2 install {{composer_options}}'); +}); + +// Build assets via container node éphémère +// mangarr_node_modules volume = cache npm entre les déploiements +desc('Build Webpack Encore assets'); +task('webpack_encore:build', function () { + run('docker run --rm -v {{release_path}}:/app -v mangarr_node_modules:/app/node_modules -w /app node:22-alpine sh -c "npm install && npm run build"'); +}); + +// Restart Docker containers (entrypoint gère les migrations automatiquement) +desc('Restart Docker containers'); +task('docker:restart', function () { + run('docker restart mangarr-worker-commands mangarr-worker-events mangarr-worker-scheduler'); + run('docker restart mangarr'); +}); + // Hooks -after('deploy:vendors', 'npm:install'); -after('npm:install', 'webpack_encore:build'); -after('deploy:vendors', 'database:migrate'); -after('deploy:symlink', 'messenger:consume'); +after('deploy:vendors', 'webpack_encore:build'); +after('deploy:symlink', 'docker:restart'); after('deploy:failed', 'deploy:unlock');