diff --git a/.forgejo/workflows/deploy.yml b/.forgejo/workflows/deploy.yml index 3015ab4..8ff68af 100644 --- a/.forgejo/workflows/deploy.yml +++ b/.forgejo/workflows/deploy.yml @@ -28,19 +28,33 @@ jobs: git push origin ${{ github.event.inputs.version }} - name: Write production .env + env: + POSTGRES_DB: ${{ secrets.POSTGRES_DB }} + POSTGRES_USER: ${{ secrets.POSTGRES_USER }} + POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }} + JWT_SECRET: ${{ secrets.JWT_SECRET }} + STRIPE_SECRET_KEY: ${{ secrets.STRIPE_SECRET_KEY }} + STRIPE_WEBHOOK_SECRET: ${{ secrets.STRIPE_WEBHOOK_SECRET }} + STRIPE_PRICE_ID: ${{ secrets.STRIPE_PRICE_ID }} + SWISH_NUMBER: ${{ secrets.SWISH_NUMBER }} + ADMIN_EMAIL: ${{ secrets.ADMIN_EMAIL }} + ADMIN_PASSWORD: ${{ secrets.ADMIN_PASSWORD }} run: | - cat > .env << 'EOF' - POSTGRES_DB=${{ secrets.POSTGRES_DB }} - POSTGRES_USER=${{ secrets.POSTGRES_USER }} - POSTGRES_PASSWORD=${{ secrets.POSTGRES_PASSWORD }} - JWT_SECRET=${{ secrets.JWT_SECRET }} - STRIPE_SECRET_KEY=${{ secrets.STRIPE_SECRET_KEY }} - STRIPE_WEBHOOK_SECRET=${{ secrets.STRIPE_WEBHOOK_SECRET }} - STRIPE_PRICE_ID=${{ secrets.STRIPE_PRICE_ID }} - SWISH_NUMBER=${{ secrets.SWISH_NUMBER }} - ADMIN_EMAIL=${{ secrets.ADMIN_EMAIL }} - ADMIN_PASSWORD=${{ secrets.ADMIN_PASSWORD }} - EOF + # Docker Compose treats $ as variable interpolation in .env files. + # Escape literal dollar signs (e.g. in passwords) as $$. + escape() { printf '%s' "$1" | sed 's/\$/$$/g'; } + { + printf 'POSTGRES_DB=%s\n' "$(escape "$POSTGRES_DB")" + printf 'POSTGRES_USER=%s\n' "$(escape "$POSTGRES_USER")" + printf 'POSTGRES_PASSWORD=%s\n' "$(escape "$POSTGRES_PASSWORD")" + printf 'JWT_SECRET=%s\n' "$(escape "$JWT_SECRET")" + printf 'STRIPE_SECRET_KEY=%s\n' "$(escape "$STRIPE_SECRET_KEY")" + printf 'STRIPE_WEBHOOK_SECRET=%s\n' "$(escape "$STRIPE_WEBHOOK_SECRET")" + printf 'STRIPE_PRICE_ID=%s\n' "$(escape "$STRIPE_PRICE_ID")" + printf 'SWISH_NUMBER=%s\n' "$(escape "$SWISH_NUMBER")" + printf 'ADMIN_EMAIL=%s\n' "$(escape "$ADMIN_EMAIL")" + printf 'ADMIN_PASSWORD=%s\n' "$(escape "$ADMIN_PASSWORD")" + } > .env - name: Build and start production stack run: | diff --git a/README.md b/README.md index 0a40cc7..c3fb243 100644 --- a/README.md +++ b/README.md @@ -273,6 +273,7 @@ Before the first deploy, complete these steps on the production server (`srvr.nu | `ADMIN_EMAIL` | Production admin email (e.g. `admin@bilhej.se`) | | `ADMIN_PASSWORD` | Strong unique admin password (password manager) | + Passwords may contain `$` — the deploy workflow escapes these for Docker Compose. Production does **not** seed `test@bilhej.se` or demo orders. On first start, the backend creates one admin from `ADMIN_EMAIL` / `ADMIN_PASSWORD` if no admin exists.