diff --git a/.gitea/workflows/webhosting.yaml b/.gitea/workflows/webhosting.yaml new file mode 100644 index 0000000..2ad20a0 --- /dev/null +++ b/.gitea/workflows/webhosting.yaml @@ -0,0 +1,49 @@ +name: WebHosting + +on: + pull_request: + branches: [main] + push: + branches: [main] + + workflow_dispatch: + +jobs: + validate: + runs-on: webhosting + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + - name: Lint and check Compose syntax + run: | + set -e + yamllint -d '{extends: relaxed, rules: {line-length: disable}}' docker-compose.yaml stacks .gitea + docker compose config --quiet + + deploy: + needs: validate + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + runs-on: webhosting + steps: + - name: Deploy + run: | + set -eo pipefail + cd /opt/WebHosting + git pull --ff-only origin main + domains=$(awk '$1 == "ssl_certificate" && $2 ~ /^\/etc\/nginx\/certs\/[^\/]+\.crt;$/ {sub(/^\/etc\/nginx\/certs\//, "", $2); sub(/\.crt;$/, "", $2); print $2}' conf.d/*.conf | sort -u) + for domain in $domains; do + if [ ! -s "/etc/letsencrypt/live/$domain/fullchain.pem" ] || [ ! -s "/etc/letsencrypt/live/$domain/privkey.pem" ]; then + certbot certonly \ + -d "$domain" \ + --cert-name "$domain" \ + --config /etc/letsencrypt/cli.ini \ + --keep-until-expiring \ + --no-directory-hooks + fi + ln -sf "/etc/letsencrypt/live/$domain/fullchain.pem" "/etc/pki/tls/certs/$domain.crt" + ln -sf "/etc/letsencrypt/live/$domain/privkey.pem" "/etc/pki/tls/private/$domain.key" + done + docker compose up -d + docker compose exec -T nginx nginx -t + docker compose exec -T nginx nginx -s reload diff --git a/README.md b/README.md index 6438d43..017bf78 100644 --- a/README.md +++ b/README.md @@ -15,3 +15,14 @@ Shared web applications behind Nginx/Apache, deployed in `/opt/WebHosting`. Puppet must provision all required env files before Compose validation or deployment. Use `config --quiet` to avoid printing secrets. After an update, check the application; if its container IP changed, validate and reload Nginx using the host's deployment procedure. + +Gitea Actions runs linting and Compose syntax checks for PRs. After a merge to +`main`, it pulls the repo, obtains missing certificates, runs Compose, and +tests/reloads Nginx. Failed commands stop the job; there is no automatic rollback. + +For new sites, use `/etc/nginx/certs/.crt` and +`/etc/nginx/private/.key` in the Nginx config. CI checks the host's +`/etc/letsencrypt/live//` for `fullchain.pem` and `privkey.pem`, requesting +a certificate if either is missing. It uses the existing host ACME config and +ensures symlinks under `/etc/pki/tls/`, mounted at those Nginx paths in the container. +It reloads Nginx at the end. Existing certificates keep their normal renewal schedule.