A member followed his invitation link, chose a password, typed it twice, pressed save, and was shown the name of an environment variable. The server knew from the first byte of that request that it could not save anything: without GITEA_ADMIN_TOKEN it cannot set a password in Gitea. It asked him to do the work anyway. Three places had the same shape, all now checked up front through a new gitea.admin_configured(), mirroring mail.configured(): - the invitation page answers 503 with an explanation and no password field, identically for a real and an invented token so it cannot be used to probe for live ones - /recuperar refuses instead of mailing a link to a page that could only apologise — and its deliberately identical answer would have hidden that from the admin as well as the member - the sign-in page stops offering recovery it cannot complete Also: a 404 from admin_set_password now names the real cause. A member added without "crear también su cuenta" has no Gitea account, so the password change is aimed at nothing, and "Gitea rechazó el cambio de contraseña (404)" blames Gitea for an account that was never made. deploy-board.sh warns about settings that are present but empty. The previous check looked for missing names, and GITEA_ADMIN_TOKEN= has a name — which is why the deploy that led to this said nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NizVpJ2dwzCbjCrTLCjeHn
88 lines
3.3 KiB
Bash
Executable File
88 lines
3.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Put the current checkout of the members area onto the server.
|
|
#
|
|
# The app's code is baked into the image by docker/board/Dockerfile (`COPY apps
|
|
# /srv/apps`), so pulling new commits changes nothing on its own — the container
|
|
# keeps running the code that was in the image when it was built. `docker
|
|
# compose up -d --force-recreate` does not help either: same tag, same layers,
|
|
# same old code. That is a quiet failure, because everything reports success and
|
|
# the site behaves exactly as it did before.
|
|
#
|
|
# This script is the whole update, in the order that matters:
|
|
#
|
|
# git pull # done by you, first
|
|
# sudo bash scripts/deploy-board.sh
|
|
#
|
|
# It never touches /srv/board/.env. That file holds the secrets and exists only
|
|
# on the server; the repository has .env.example instead, and the two drifting
|
|
# apart is expected — new settings appear in the example and have to be copied
|
|
# across by hand.
|
|
|
|
set -euo pipefail
|
|
|
|
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
TARGET="${BOARD_DIR:-/srv/board}"
|
|
IMAGE="vienalatina/board:1"
|
|
|
|
cd "$REPO"
|
|
|
|
echo "==> Building $IMAGE from $(git rev-parse --short HEAD)"
|
|
docker build -t "$IMAGE" -f docker/board/Dockerfile .
|
|
|
|
echo "==> Syncing compose files into $TARGET (never .env)"
|
|
mkdir -p "$TARGET"
|
|
cp "$REPO/infra/board/docker-compose.yml" "$TARGET/docker-compose.yml"
|
|
cp "$REPO/infra/board/.env.example" "$TARGET/.env.example"
|
|
|
|
if [ ! -f "$TARGET/.env" ]; then
|
|
echo "No $TARGET/.env — copy .env.example to .env and fill it in first." >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Settings that appear in the example and not in the live file. Nothing is
|
|
# copied automatically: some of them are secrets, and a blank line silently
|
|
# added to .env is worse than a line missing loudly.
|
|
missing="$(comm -23 \
|
|
<(grep -oE '^[A-Z][A-Z0-9_]*=' "$TARGET/.env.example" | sort -u) \
|
|
<(grep -oE '^[A-Z][A-Z0-9_]*=' "$TARGET/.env" | sort -u) || true)"
|
|
if [ -n "$missing" ]; then
|
|
echo
|
|
echo "!! These settings exist in .env.example but not in your .env:"
|
|
echo "$missing" | sed 's/^/ /'
|
|
echo " Add them to $TARGET/.env and run this again if the feature needs them."
|
|
echo
|
|
fi
|
|
|
|
# Present but empty, which the check above cannot see: `NAME=` has the name.
|
|
# Worth its own warning, because an empty value is how a feature ends up
|
|
# switched off while looking configured — GITEA_ADMIN_TOKEN= reads as a settled
|
|
# decision and behaves as a missing one. Each of these disables something whole.
|
|
blank="$(grep -oE '^[A-Z][A-Z0-9_]*=[[:space:]]*$' "$TARGET/.env" | sed 's/=.*//' || true)"
|
|
if [ -n "$blank" ]; then
|
|
echo
|
|
echo "!! These are set to nothing in your .env, so their feature is off:"
|
|
while read -r name; do
|
|
case "$name" in
|
|
GITEA_ADMIN_TOKEN) note="no se pueden crear cuentas ni cambiar contraseñas" ;;
|
|
MAIL_HOST|MAIL_PASSWORD) note="no se envían invitaciones ni recuperaciones" ;;
|
|
BOARD_SECRET_KEY) note="LA APP NO ARRANCA" ;;
|
|
*) note="" ;;
|
|
esac
|
|
printf ' %-20s %s\n' "$name" "$note"
|
|
done <<< "$blank"
|
|
echo
|
|
fi
|
|
|
|
echo "==> Restarting"
|
|
cd "$TARGET"
|
|
docker compose up -d --force-recreate
|
|
|
|
# The schema is applied at start-up with CREATE TABLE IF NOT EXISTS, so a new
|
|
# table arrives with the new code. If the container is not up a few seconds
|
|
# later it died during that, and the log says why.
|
|
sleep 3
|
|
docker compose ps
|
|
echo
|
|
echo "Recent log:"
|
|
docker compose logs --tail 20 board
|