From d6fcb52941ff64976b73e436a1ef9b89fb923cca Mon Sep 17 00:00:00 2001 From: root Date: Wed, 29 Jul 2026 18:46:14 -0400 Subject: [PATCH] stripe build fix --- .env.docker.production.example | 2 ++ .gitea/workflows/build-and-deploy.yml | 9 ++++++--- docs/DOCKER.md | 2 ++ scripts/describe-env-values.sh | 4 ++++ scripts/docker-prod-common.sh | 21 ++++++++++----------- 5 files changed, 24 insertions(+), 14 deletions(-) diff --git a/.env.docker.production.example b/.env.docker.production.example index db7cb3d..168fcb1 100644 --- a/.env.docker.production.example +++ b/.env.docker.production.example @@ -90,6 +90,8 @@ MAIL_REPLY_TO_NAME=RentalDriveGo # STRIPE_API_KEY must be a live Stripe secret/restricted key (sk_live_ or rk_live_). # STRIPE_WEBHOOK_SECRET must be a Stripe webhook signing secret (whsec_). # Gitea deploys can override these from STRIPE_API_KEY and STRIPE_WEBHOOK_SECRET secrets. +# Set STRIPE_BILLING_REQUIRED=false only when deploying before Stripe billing is ready. +STRIPE_BILLING_REQUIRED=true STRIPE_API_KEY=placeholder STRIPE_WEBHOOK_SECRET=placeholder diff --git a/.gitea/workflows/build-and-deploy.yml b/.gitea/workflows/build-and-deploy.yml index e9b02aa..573393a 100644 --- a/.gitea/workflows/build-and-deploy.yml +++ b/.gitea/workflows/build-and-deploy.yml @@ -428,6 +428,7 @@ jobs: IMAGE_TAG: ${{ gitea.sha }} ENV_DOCKER_PRODUCTION: ${{ secrets.ENV_DOCKER_PRODUCTION }} ENV_DOCKER_PRODUCTION_B64: ${{ secrets.ENV_DOCKER_PRODUCTION_B64 }} + STRIPE_BILLING_REQUIRED: ${{ secrets.STRIPE_BILLING_REQUIRED }} STRIPE_API_KEY: ${{ secrets.STRIPE_API_KEY }} STRIPE_WEBHOOK_SECRET: ${{ secrets.STRIPE_WEBHOOK_SECRET }} REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }} @@ -445,6 +446,7 @@ jobs: SSH_OPTIONS="-i $HOME/.ssh/id_rsa -o BatchMode=yes -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=$HOME/.ssh/known_hosts" ENV_DOCKER_PRODUCTION_B64_CLEAN="$(printf '%s' "$ENV_DOCKER_PRODUCTION_B64" | tr -d '[:space:]')" ENV_DOCKER_PRODUCTION_RAW_B64="$(printf '%s' "$ENV_DOCKER_PRODUCTION" | base64 | tr -d '\n')" + STRIPE_BILLING_REQUIRED_B64="$(printf '%s' "$STRIPE_BILLING_REQUIRED" | base64 | tr -d '\n')" STRIPE_API_KEY_B64="$(printf '%s' "$STRIPE_API_KEY" | base64 | tr -d '\n')" STRIPE_WEBHOOK_SECRET_B64="$(printf '%s' "$STRIPE_WEBHOOK_SECRET" | base64 | tr -d '\n')" REGISTRY_USERNAME="${REGISTRY_USERNAME:-${REGISTRY_USER:-}}" @@ -475,12 +477,13 @@ jobs: chmod 600 '$REMOTE_BUILD_DIR/.env.docker.production' cd '$REMOTE_BUILD_DIR' if [ -n \"\$previous_env_file\" ]; then - bash scripts/preserve-env-values.sh \"\$previous_env_file\" .env.docker.production STRIPE_API_KEY STRIPE_WEBHOOK_SECRET + bash scripts/preserve-env-values.sh \"\$previous_env_file\" .env.docker.production STRIPE_BILLING_REQUIRED STRIPE_API_KEY STRIPE_WEBHOOK_SECRET fi + export STRIPE_BILLING_REQUIRED_B64='$STRIPE_BILLING_REQUIRED_B64' export STRIPE_API_KEY_B64='$STRIPE_API_KEY_B64' export STRIPE_WEBHOOK_SECRET_B64='$STRIPE_WEBHOOK_SECRET_B64' - bash scripts/apply-env-secret-overrides.sh .env.docker.production STRIPE_API_KEY STRIPE_WEBHOOK_SECRET - bash scripts/describe-env-values.sh .env.docker.production STRIPE_API_KEY STRIPE_WEBHOOK_SECRET + bash scripts/apply-env-secret-overrides.sh .env.docker.production STRIPE_BILLING_REQUIRED STRIPE_API_KEY STRIPE_WEBHOOK_SECRET + bash scripts/describe-env-values.sh .env.docker.production STRIPE_BILLING_REQUIRED STRIPE_API_KEY STRIPE_WEBHOOK_SECRET cp .env.docker.production '$DEPLOY_ROOT/.env.docker.production' chmod 600 '$DEPLOY_ROOT/.env.docker.production' export APP_IMAGE='$DEPLOY_REGISTRY_HOST/$IMAGE_REPOSITORY' diff --git a/docs/DOCKER.md b/docs/DOCKER.md index 5a2e49f..ea51e5a 100644 --- a/docs/DOCKER.md +++ b/docs/DOCKER.md @@ -164,6 +164,8 @@ Open `.env.docker.production` and fill in every value. The minimum required secr | `STRIPE_API_KEY` | Live Stripe secret key or restricted key for production billing (`sk_live_` or `rk_live_`) | | `STRIPE_WEBHOOK_SECRET` | Stripe webhook signing secret for `/api/v1/subscriptions/webhooks/stripe` (`whsec_`) | +Stripe billing is required by default. If you need to deploy production before Stripe is ready, set `STRIPE_BILLING_REQUIRED=false` in the production env file. The app will still start, but Stripe subscription checkout and Stripe webhooks will remain unavailable until live Stripe keys are configured. + For Gitea Actions deploys, either store the completed production env file as the raw `ENV_DOCKER_PRODUCTION` secret or as the base64-encoded `ENV_DOCKER_PRODUCTION_B64` secret: ```bash diff --git a/scripts/describe-env-values.sh b/scripts/describe-env-values.sh index bb04f49..ed4754d 100644 --- a/scripts/describe-env-values.sh +++ b/scripts/describe-env-values.sh @@ -68,6 +68,10 @@ describe_value() { printf '%s: missing\n' "${key}" elif [[ "${value}" == placeholder || "${value}" == replace-with-* || "${value}" == *changeme* || "${value}" == *change-me* ]]; then printf '%s: placeholder\n' "${key}" + elif [[ "${key}" == STRIPE_BILLING_REQUIRED && ( "${value}" == "true" || "${value}" == "1" || "${value}" == "yes" ) ]]; then + printf '%s: enabled\n' "${key}" + elif [[ "${key}" == STRIPE_BILLING_REQUIRED && ( "${value}" == "false" || "${value}" == "0" || "${value}" == "no" ) ]]; then + printf '%s: disabled\n' "${key}" elif [[ "${key}" == STRIPE_API_KEY && ( "${value}" == sk_live_* || "${value}" == rk_live_* ) ]]; then printf '%s: valid live prefix\n' "${key}" elif [[ "${key}" == STRIPE_WEBHOOK_SECRET && "${value}" == whsec_* ]]; then diff --git a/scripts/docker-prod-common.sh b/scripts/docker-prod-common.sh index bf6e407..54c8f29 100644 --- a/scripts/docker-prod-common.sh +++ b/scripts/docker-prod-common.sh @@ -181,7 +181,7 @@ EOF } validate_prod_env_file() { - local acme_email api_domain public_site_domain cors_origins portainer_domain postgres_password redis_password jwt_secret stripe_api_key stripe_webhook_secret + local acme_email api_domain public_site_domain cors_origins portainer_domain postgres_password redis_password jwt_secret stripe_api_key stripe_webhook_secret stripe_billing_required acme_email="$(read_env_value ACME_EMAIL)" api_domain="$(read_env_value API_DOMAIN)" @@ -193,6 +193,7 @@ validate_prod_env_file() { jwt_secret="$(read_env_value JWT_SECRET)" stripe_api_key="$(read_env_value STRIPE_API_KEY)" stripe_webhook_secret="$(read_env_value STRIPE_WEBHOOK_SECRET)" + stripe_billing_required="$(read_env_value STRIPE_BILLING_REQUIRED)" if [[ -z "${acme_email}" || "${acme_email}" != *@* || "${acme_email}" == *example.com* ]]; then echo "Invalid ACME_EMAIL in ${ENV_FILE}. Set it to a real contact email for Let's Encrypt, not example.com." >&2 @@ -223,25 +224,23 @@ validate_prod_env_file() { fi done - if [[ -z "${stripe_api_key}" || "${stripe_api_key}" == placeholder || "${stripe_api_key}" == replace-with-* || "${stripe_api_key}" == *changeme* || "${stripe_api_key}" == *change-me* ]]; then + if [[ "${stripe_billing_required}" == "false" || "${stripe_billing_required}" == "0" || "${stripe_billing_required}" == "no" ]]; then + echo "Stripe billing validation skipped because STRIPE_BILLING_REQUIRED=${stripe_billing_required}." >&2 + echo "Stripe checkout and Stripe webhooks will remain unavailable until STRIPE_API_KEY and STRIPE_WEBHOOK_SECRET are configured." >&2 + elif [[ -z "${stripe_api_key}" || "${stripe_api_key}" == placeholder || "${stripe_api_key}" == replace-with-* || "${stripe_api_key}" == *changeme* || "${stripe_api_key}" == *change-me* ]]; then echo "Invalid STRIPE_API_KEY in ${ENV_FILE}. Set a real Stripe secret or restricted API key for production billing." >&2 echo "Set STRIPE_API_KEY as a Gitea Actions secret, or include STRIPE_API_KEY=sk_live_.../rk_live_... in ENV_DOCKER_PRODUCTION_B64." >&2 + echo "If you need to deploy before Stripe is ready, set STRIPE_BILLING_REQUIRED=false in the production env file." >&2 exit 1 - fi - - if [[ "${stripe_api_key}" != sk_live_* && "${stripe_api_key}" != rk_live_* ]]; then + elif [[ "${stripe_api_key}" != sk_live_* && "${stripe_api_key}" != rk_live_* ]]; then echo "Invalid STRIPE_API_KEY in ${ENV_FILE}. It must start with sk_live_ or rk_live_ for production billing." >&2 echo "Use a live Stripe secret key or, preferably, a live restricted key with the required billing permissions." >&2 exit 1 - fi - - if [[ -z "${stripe_webhook_secret}" || "${stripe_webhook_secret}" == placeholder || "${stripe_webhook_secret}" == replace-with-* || "${stripe_webhook_secret}" == *changeme* || "${stripe_webhook_secret}" == *change-me* ]]; then + elif [[ -z "${stripe_webhook_secret}" || "${stripe_webhook_secret}" == placeholder || "${stripe_webhook_secret}" == replace-with-* || "${stripe_webhook_secret}" == *changeme* || "${stripe_webhook_secret}" == *change-me* ]]; then echo "Invalid STRIPE_WEBHOOK_SECRET in ${ENV_FILE}. Set the Stripe webhook signing secret for /api/v1/subscriptions/webhooks/stripe." >&2 echo "Set STRIPE_WEBHOOK_SECRET as a Gitea Actions secret, or include STRIPE_WEBHOOK_SECRET=whsec_... in ENV_DOCKER_PRODUCTION_B64." >&2 exit 1 - fi - - if [[ "${stripe_webhook_secret}" != whsec_* ]]; then + elif [[ "${stripe_webhook_secret}" != whsec_* ]]; then echo "Invalid STRIPE_WEBHOOK_SECRET in ${ENV_FILE}. It must start with whsec_." >&2 echo "Use the webhook signing secret from the Stripe webhook endpoint, not the Stripe API key." >&2 exit 1