From cd48f85a47878de80ecc59321fa7d97ae46c1722 Mon Sep 17 00:00:00 2001 From: Twooey Date: Thu, 27 Aug 2026 11:23:35 -0400 Subject: [PATCH] =?UTF-8?q?Remove=20staging=20basic-auth=20wall=20?= =?UTF-8?q?=E2=80=94=20box=20is=20LAN-only?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Staging runs on a private-network VM, not reachable from outside, so the HTTP basic-auth layer was unnecessary defense-in-depth. Removing it also lets the Caddyfile drop the render-around-Compose workaround entirely (that workaround existed specifically because Compose's interpolation mangles a bcrypt hash) — the noindex header and blog_public=0 stay, since those guard against search-engine indexing, a separate concern from network-level access. Co-Authored-By: Claude Sonnet 5 --- .env.example | 10 +--------- .gitignore | 1 - README.md | 14 +++++++------- deploy/deploy.sh | 13 ------------- docker-compose.staging.yml | 6 +----- docker/caddy/Caddyfile.staging | 14 ++------------ 6 files changed, 11 insertions(+), 47 deletions(-) diff --git a/.env.example b/.env.example index 2811820..308e96e 100644 --- a/.env.example +++ b/.env.example @@ -7,9 +7,7 @@ # compose passes these into containers via ${VAR} interpolation, which will # silently mangle a value containing `$` followed by a letter (it tries to # resolve it as another variable and blanks it out if unset). Avoid `$` in -# these specific values, or double it ($$) if you must use one. This does -# NOT apply to STAGING_BASIC_AUTH_HASH below — that one's wired through -# env_file instead specifically so a bcrypt hash's `$` signs are safe. +# these specific values, or double it ($$) if you must use one. # --- Site --- # (WP_ENVIRONMENT_TYPE is NOT set here — it's hardcoded per environment in @@ -30,12 +28,6 @@ DB_PASSWORD=changeme DB_ROOT_PASSWORD=changeme WP_TABLE_PREFIX=wp_ -# --- Staging only: basic-auth wall + noindex --- -# Generate the hash with: -# docker run --rm caddy:2-alpine caddy hash-password --plaintext 'your-password' -STAGING_BASIC_AUTH_USER=staging -STAGING_BASIC_AUTH_HASH= - # --- Backups (deploy/backup.sh) --- BACKUP_DIR=./backups BACKUP_REMOTE= diff --git a/.gitignore b/.gitignore index 9fe5cc0..4c4fc3a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ !/.env.example /backups/ -/docker/caddy/.generated/ vendor/ node_modules/ *.log diff --git a/README.md b/README.md index 74732cc..b4a864b 100644 --- a/README.md +++ b/README.md @@ -44,17 +44,17 @@ drops into the app container. ``` cp .env.example .env.staging -# fill in SITE_DOMAIN, SITE_URL, DB_*, and: -docker run --rm caddy:2-alpine caddy hash-password --plaintext 'pick-a-password' -# -> paste result into STAGING_BASIC_AUTH_HASH +# fill in SITE_DOMAIN, SITE_URL, DB_* make deploy ENV=staging ``` -Staging is `noindex`'d and sits behind HTTP basic auth (Caddyfile.staging) -in addition to `blog_public=0` — two independent reasons search engines and -random visitors won't see it, per the launch gate. Mail never leaves the -box: it's caught by MailHog, viewable at `:8025`. +Staging is `noindex`'d (`blog_public=0` plus the `X-Robots-Tag` header in +Caddyfile.staging) so search engines won't index it — there's no basic-auth +wall on top of that, since this box is LAN-only and not reachable from +outside. If that ever changes (a public domain, port-forwarding, etc.), +basic-auth is worth adding back before that happens, not after. Mail never +leaves the box: it's caught by MailHog, viewable at `:8025`. ### Theme: Blocksy + the Book Store starter site diff --git a/deploy/deploy.sh b/deploy/deploy.sh index 191edbe..aa11427 100755 --- a/deploy/deploy.sh +++ b/deploy/deploy.sh @@ -32,19 +32,6 @@ WP_ADMIN_EMAIL="$(env_get "$ENV_FILE" WP_ADMIN_EMAIL)" # reuse dev's db_data volume/credentials the first time this ran). COMPOSE="docker compose -p bookstore-${ENVIRONMENT} -f docker-compose.yml -f docker-compose.${ENVIRONMENT}.yml --env-file ${ENV_FILE}" -if [[ "$ENVIRONMENT" == "staging" ]]; then - echo "==> rendering Caddyfile.staging (basic-auth hash bypasses compose entirely)" - mkdir -p docker/caddy/.generated - AUTH_USER="$(env_get "$ENV_FILE" STAGING_BASIC_AUTH_USER)" - AUTH_HASH="$(env_get "$ENV_FILE" STAGING_BASIC_AUTH_HASH)" - : "${AUTH_USER:?set STAGING_BASIC_AUTH_USER in ${ENV_FILE}}" - : "${AUTH_HASH:?set STAGING_BASIC_AUTH_HASH in ${ENV_FILE} — see .env.example for how to generate it}" - TEMPLATE="$(cat docker/caddy/Caddyfile.staging)" - TEMPLATE="${TEMPLATE//__STAGING_BASIC_AUTH_USER__/$AUTH_USER}" - TEMPLATE="${TEMPLATE//__STAGING_BASIC_AUTH_HASH__/$AUTH_HASH}" - printf '%s\n' "$TEMPLATE" > docker/caddy/.generated/Caddyfile.staging -fi - echo "==> building and starting ${ENVIRONMENT}" $COMPOSE up -d --build diff --git a/docker-compose.staging.yml b/docker-compose.staging.yml index 111117c..2ae91fa 100644 --- a/docker-compose.staging.yml +++ b/docker-compose.staging.yml @@ -16,14 +16,10 @@ services: ports: - "80:80" - "443:443" - # SITE_DOMAIN is safe to pass through normally (no `$` in a domain name). - # STAGING_BASIC_AUTH_USER/HASH are NOT passed via compose at all — see - # the comment in docker/caddy/Caddyfile.staging for why; deploy.sh - # renders them directly into the mounted file below instead. env_file: - .env.staging volumes: - - ./docker/caddy/.generated/Caddyfile.staging:/etc/caddy/Caddyfile:ro + - ./docker/caddy/Caddyfile.staging:/etc/caddy/Caddyfile:ro - wp_core:/var/www/html:ro - wp_uploads:/var/www/html/wp-content/uploads:ro - wp_themes:/var/www/html/wp-content/themes:ro diff --git a/docker/caddy/Caddyfile.staging b/docker/caddy/Caddyfile.staging index 9bfd741..b50a21e 100644 --- a/docker/caddy/Caddyfile.staging +++ b/docker/caddy/Caddyfile.staging @@ -2,18 +2,8 @@ encode gzip # Launch gate: "No staging URLs are publicly indexed." Belt-and-suspenders - # with wp_option blog_public=0, which deploy.sh sets on staging. - # - # The two tokens below are substituted by deploy.sh directly (bash string - # replacement), not by Caddy's {$VAR} or docker compose's ${VAR} — a - # bcrypt hash contains `$identifier`-looking substrings that Compose's - # own interpolation will silently corrupt if this value ever passes - # through it (confirmed: both `environment:` and `env_file:` are - # affected). This file is a tracked template; deploy.sh renders it into - # docker/caddy/.generated/Caddyfile.staging, which is what's mounted. - basic_auth { - __STAGING_BASIC_AUTH_USER__ __STAGING_BASIC_AUTH_HASH__ - } + # with wp_option blog_public=0, which deploy.sh sets on staging. No + # basic-auth wall — this box is LAN-only, not reachable from outside. header X-Robots-Tag "noindex, nofollow, noarchive" root * /var/www/html