fix(docker): inicializar permissoes do storage com seguranca
This commit is contained in:
1 parent
e142a44c01
commit
2be97ea969
8 files changed
+421
-3
No files matched your search
+80
-2
@@ -9,6 +9,81 @@ set -eu
|
||||
|
||||
TSX="--import=tsx"
|
||||
|
||||
# Armazenamento local (development): o volume `app-storage` montado em /app/.data.
|
||||
# Homologação e produção usam o bucket do Supabase e não montam este volume.
|
||||
DATA_DIR=/app/.data
|
||||
STORAGE_DIR="$DATA_DIR/storage"
|
||||
|
||||
# Mesma regra de src/infra/storage/index.ts: sem as três variáveis do Supabase,
|
||||
# o processo grava no disco local.
|
||||
local_storage_in_use() {
|
||||
[ -z "${NEXT_PUBLIC_SUPABASE_URL:-}" ] || [ -z "${SUPABASE_SERVICE_ROLE_KEY:-}" ] || [ -z "${SUPABASE_STORAGE_BUCKET:-}" ]
|
||||
}
|
||||
|
||||
# Web e worker recusam subir com armazenamento local que não aceita escrita.
|
||||
# Sem isto o processo fica no ar e o primeiro upload responde "Erro interno".
|
||||
assert_storage_writable() {
|
||||
local_storage_in_use || return 0
|
||||
probe="$STORAGE_DIR/.write-probe-$$"
|
||||
if mkdir -p "$STORAGE_DIR" 2>/dev/null && touch "$probe" 2>/dev/null; then
|
||||
rm -f "$probe"
|
||||
return 0
|
||||
fi
|
||||
echo "STORAGE_NOT_WRITABLE: $STORAGE_DIR não aceita escrita pelo uid $(id -u)." >&2
|
||||
echo "Rode o serviço storage-init do compose (docs/spreadsheet-adapter/23-storage-permissions.md)." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Roda como root, uma vez, antes de web e worker (serviço storage-init).
|
||||
# Ajusta só os dois diretórios do armazenamento, sem recursão: arquivos que já
|
||||
# existem não são tocados, a não ser com --fix-existing, que é passo manual.
|
||||
prepare_storage() {
|
||||
if [ "$(id -u)" != "0" ]; then
|
||||
echo "prepare-storage precisa rodar como root (user: \"0:0\" no serviço storage-init)." >&2
|
||||
exit 1
|
||||
fi
|
||||
app_uid=$(id -u adaptador)
|
||||
app_gid=$(id -g adaptador)
|
||||
|
||||
for dir in "$DATA_DIR" "$STORAGE_DIR"; do
|
||||
if [ -L "$dir" ]; then
|
||||
echo "[storage-init] recusado: $dir é link simbólico." >&2
|
||||
exit 1
|
||||
fi
|
||||
mkdir -p "$dir"
|
||||
owner=$(stat -c '%u:%g' "$dir")
|
||||
if [ "$owner" != "$app_uid:$app_gid" ]; then
|
||||
chown "$app_uid:$app_gid" "$dir"
|
||||
echo "[storage-init] $dir: dono $owner -> $app_uid:$app_gid"
|
||||
fi
|
||||
mode=$(stat -c '%a' "$dir")
|
||||
if [ "$mode" != "750" ]; then
|
||||
chmod 750 "$dir"
|
||||
echo "[storage-init] $dir: modo $mode -> 750"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "${1:-}" = "--fix-existing" ]; then
|
||||
# -xdev não atravessa outro sistema de arquivos; -h não segue link simbólico.
|
||||
find "$DATA_DIR" -xdev ! -user "$app_uid" -exec chown -h "$app_uid:$app_gid" {} +
|
||||
echo "[storage-init] dono de itens existentes ajustado para $app_uid:$app_gid"
|
||||
fi
|
||||
|
||||
foreign=$(find "$DATA_DIR" -xdev ! -user "$app_uid" | wc -l)
|
||||
if [ "$foreign" -gt 0 ]; then
|
||||
echo "[storage-init] AVISO: $foreign item(ns) em $DATA_DIR com outro dono; nada foi alterado neles." >&2
|
||||
echo "[storage-init] Para ajustar, rode com --fix-existing (procedimento de recuperação no doc 23)." >&2
|
||||
fi
|
||||
|
||||
# Prova com o usuário da aplicação, não com root.
|
||||
if ! setpriv --reuid="$app_uid" --regid="$app_gid" --clear-groups \
|
||||
sh -c 'p="$1/.write-probe-$$"; touch "$p" && rm -f "$p"' _ "$STORAGE_DIR"; then
|
||||
echo "STORAGE_NOT_WRITABLE: o uid $app_uid não escreve em $STORAGE_DIR mesmo após a preparação." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "[storage-init] STORAGE_WRITABLE: $STORAGE_DIR, dono $app_uid:$app_gid, modo 750"
|
||||
}
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
uso: entrypoint.sh <comando> [args]
|
||||
@@ -23,6 +98,8 @@ uso: entrypoint.sh <comando> [args]
|
||||
check-bucket
|
||||
smoke
|
||||
worker-health confere o heartbeat do worker (healthcheck do contêiner)
|
||||
prepare-storage [--fix-existing]
|
||||
prepara /app/.data como root (serviço storage-init)
|
||||
exec <cmd...> qualquer outro comando
|
||||
EOF
|
||||
}
|
||||
@@ -31,8 +108,9 @@ cmd="${1:-web}"
|
||||
[ $# -gt 0 ] && shift || true
|
||||
|
||||
case "$cmd" in
|
||||
web) exec node server.js ;;
|
||||
worker) exec node $TSX scripts/worker.ts ;;
|
||||
web) assert_storage_writable; exec node server.js ;;
|
||||
worker) assert_storage_writable; exec node $TSX scripts/worker.ts ;;
|
||||
prepare-storage) prepare_storage "$@" ;;
|
||||
migrate) exec node $TSX scripts/migrate.ts "$@" ;;
|
||||
seed-staging) exec node $TSX scripts/seed-staging.ts "$@" ;;
|
||||
flag) exec node $TSX scripts/set-flag.ts "$@" ;;
|
||||
|
||||
Reference in new issue
Block a user