Align prod PHP container UID with bot user (1001) and harden restore.sh
Some checks failed
CI / sonarqube (push) Failing after 52s
Some checks failed
CI / sonarqube (push) Failing after 52s
Sur le serveur prod, l'utilisateur 'bot' (cree par Ansible) a UID 1001 alors que l'utilisateur 'appuser' du conteneur PHP etait hardcode a UID 1000, ce qui causait des erreurs 'Unable to write in var/cache/prod' apres restore ou deploiement: les fichiers du host appartenaient a bot:bot (1001) et appuser (1000) ne pouvait pas y ecrire. docker/php/prod/Dockerfile: - appuser UID/GID passe de 1000 a 1001 pour matcher bot - dev/Dockerfile reste a 1000 (les users dev sont generalement 1000) ansible/deploy.yml: - chown des dossiers public/uploads/* et var/payouts passe de 1000 a 1001 restore.sh: - Nouvelle option --owner USER:GRP (defaut: bot:bot, override via RESTORE_OWNER) - Chown automatique en fin de restore sur var/, public/uploads/, config/cert/, .env.local - Purge automatique de var/cache (sera reconstruit par PHP) - Verification root au demarrage (sudo requis pour chown) - Verification de l'existence du user et group cibles - Option --skip-chown pour bypass (deconseille) - Etapes post-migration mises a jour (ajout de make build_prod en premier) Procedure de migration sur le serveur apres ce commit: cd /var/www/e-ticket git pull origin master make build_prod # rebuild image PHP avec UID 1001 make stop_prod sudo chown -R bot:bot var public/uploads config/cert .env.local sudo rm -rf var/cache make start_prod make clear_prod Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -157,8 +157,8 @@
|
||||
file:
|
||||
path: "/var/www/e-ticket/public/uploads/{{ item }}"
|
||||
state: directory
|
||||
owner: "1000"
|
||||
group: "1000"
|
||||
owner: "1001"
|
||||
group: "1001"
|
||||
mode: "0755"
|
||||
recurse: true
|
||||
loop:
|
||||
@@ -168,8 +168,8 @@
|
||||
file:
|
||||
path: /var/www/e-ticket/var/payouts
|
||||
state: directory
|
||||
owner: "1000"
|
||||
group: "1000"
|
||||
owner: "1001"
|
||||
group: "1001"
|
||||
mode: "0755"
|
||||
|
||||
- name: Ensure Caddy sites directory exists
|
||||
|
||||
@@ -24,7 +24,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
opcache \
|
||||
&& pecl install redis imagick \
|
||||
&& docker-php-ext-enable redis imagick \
|
||||
&& groupadd -g 1000 appuser && useradd -u 1000 -g appuser -m appuser
|
||||
&& groupadd -g 1001 appuser && useradd -u 1001 -g appuser -m appuser
|
||||
|
||||
COPY php.ini /usr/local/etc/php/conf.d/app.ini
|
||||
COPY opcache.ini /usr/local/etc/php/conf.d/opcache.ini
|
||||
|
||||
93
restore.sh
93
restore.sh
@@ -5,14 +5,19 @@
|
||||
# Le bundle est attendu au format e_ticket_migration_<DATE>.tar.gz et contient:
|
||||
# db.sql.gz, public_uploads.tar.gz, var_state.tar.gz, env.local, cert/, manifest.txt
|
||||
#
|
||||
# A la fin, le script chown automatiquement les fichiers restaures vers RESTORE_OWNER
|
||||
# (defaut: bot) afin que l'utilisateur PHP du conteneur puisse y ecrire, et purge
|
||||
# var/cache pour eviter les fichiers obsoletes appartenant a un autre utilisateur.
|
||||
#
|
||||
# Usage:
|
||||
# ./restore.sh <bundle.tar.gz> [--yes] [--skip-db] [--skip-uploads] [--skip-var] [--skip-secrets]
|
||||
# ./restore.sh <bundle.tar.gz> [options]
|
||||
#
|
||||
# Variables d'environnement supportees:
|
||||
# COMPOSE_FILE : fichier docker-compose a utiliser (defaut: docker-compose-prod.yml)
|
||||
# DB_SERVICE : service Docker de la base (defaut: db-master)
|
||||
# DB_USER : utilisateur PostgreSQL (defaut: e-ticket)
|
||||
# DB_NAME : base de donnees a restaurer (defaut: e-ticket)
|
||||
# COMPOSE_FILE : fichier docker-compose a utiliser (defaut: docker-compose-prod.yml)
|
||||
# DB_SERVICE : service Docker de la base (defaut: db-master)
|
||||
# DB_USER : utilisateur PostgreSQL (defaut: e-ticket)
|
||||
# DB_NAME : base de donnees a restaurer (defaut: e-ticket)
|
||||
# RESTORE_OWNER : user:group pour le chown final (defaut: bot:bot)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
@@ -21,6 +26,7 @@ COMPOSE_FILE="${COMPOSE_FILE:-${SCRIPT_DIR}/docker-compose-prod.yml}"
|
||||
DB_SERVICE="${DB_SERVICE:-db-master}"
|
||||
DB_USER="${DB_USER:-e-ticket}"
|
||||
DB_NAME="${DB_NAME:-e-ticket}"
|
||||
RESTORE_OWNER="${RESTORE_OWNER:-bot:bot}"
|
||||
|
||||
BUNDLE=""
|
||||
ASSUME_YES="false"
|
||||
@@ -28,6 +34,7 @@ SKIP_DB="false"
|
||||
SKIP_UPLOADS="false"
|
||||
SKIP_VAR="false"
|
||||
SKIP_SECRETS="false"
|
||||
SKIP_CHOWN="false"
|
||||
|
||||
log() {
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
|
||||
@@ -40,7 +47,7 @@ err() {
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
./restore.sh <bundle.tar.gz> [options]
|
||||
sudo ./restore.sh <bundle.tar.gz> [options]
|
||||
|
||||
Options:
|
||||
--yes, -y Mode non interactif (pas de confirmation)
|
||||
@@ -48,9 +55,15 @@ Options:
|
||||
--skip-uploads Ne pas restaurer public/uploads
|
||||
--skip-var Ne pas restaurer var/ (payouts, billets, invoices, unsubscribed.json)
|
||||
--skip-secrets Ne pas restaurer .env.local et config/cert/
|
||||
--skip-chown Ne pas faire le chown final (deconseille)
|
||||
--owner USER:GRP Utilisateur:groupe pour le chown final (defaut: bot:bot)
|
||||
-h, --help Affiche cette aide
|
||||
|
||||
Variables d'environnement (alternatives aux flags):
|
||||
RESTORE_OWNER Equivalent de --owner
|
||||
|
||||
ATTENTION: La restauration ECRASE les donnees existantes !
|
||||
ATTENTION: Le chown final necessite root (sudo).
|
||||
EOF
|
||||
}
|
||||
|
||||
@@ -62,6 +75,15 @@ while [ $# -gt 0 ]; do
|
||||
--skip-uploads) SKIP_UPLOADS="true"; shift ;;
|
||||
--skip-var) SKIP_VAR="true"; shift ;;
|
||||
--skip-secrets) SKIP_SECRETS="true"; shift ;;
|
||||
--skip-chown) SKIP_CHOWN="true"; shift ;;
|
||||
--owner)
|
||||
if [ $# -lt 2 ]; then
|
||||
err "--owner requiert une valeur (ex: --owner bot:bot)"
|
||||
exit 1
|
||||
fi
|
||||
RESTORE_OWNER="$2"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
--*) err "Option inconnue: $1"; usage; exit 1 ;;
|
||||
*)
|
||||
@@ -77,6 +99,27 @@ while [ $# -gt 0 ]; do
|
||||
esac
|
||||
done
|
||||
|
||||
# --- Verification root pour le chown final ---
|
||||
if [ "${SKIP_CHOWN}" = "false" ] && [ "$(id -u)" != "0" ]; then
|
||||
err "Ce script doit etre execute en root (sudo) pour le chown final vers ${RESTORE_OWNER}"
|
||||
err "Soit relancer avec sudo, soit ajouter --skip-chown (deconseille)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Verification que le user/group cible existe ---
|
||||
if [ "${SKIP_CHOWN}" = "false" ]; then
|
||||
OWNER_USER="${RESTORE_OWNER%%:*}"
|
||||
OWNER_GROUP="${RESTORE_OWNER##*:}"
|
||||
if ! id -u "${OWNER_USER}" >/dev/null 2>&1; then
|
||||
err "Utilisateur '${OWNER_USER}' introuvable sur le systeme"
|
||||
exit 1
|
||||
fi
|
||||
if ! getent group "${OWNER_GROUP}" >/dev/null 2>&1; then
|
||||
err "Groupe '${OWNER_GROUP}' introuvable sur le systeme"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "${BUNDLE}" ]; then
|
||||
err "Aucun bundle specifie"
|
||||
usage
|
||||
@@ -245,10 +288,40 @@ if [ "${HAS_VAR}" = "true" ] && [ "${SKIP_VAR}" = "false" ]; then
|
||||
log " OK"
|
||||
fi
|
||||
|
||||
# --- 5. Purge du cache Symfony ---
|
||||
# Indispensable: var/cache contient des fichiers compiles avec les anciens
|
||||
# uid/gid et peut empecher PHP d'ecrire au demarrage suivant.
|
||||
if [ -d "${SCRIPT_DIR}/var/cache" ]; then
|
||||
log "[cache] Purge de var/cache (sera reconstruit par PHP au demarrage)..."
|
||||
rm -rf "${SCRIPT_DIR}/var/cache"
|
||||
log " OK"
|
||||
fi
|
||||
|
||||
# --- 6. Chown final pour matcher l'utilisateur PHP du conteneur ---
|
||||
if [ "${SKIP_CHOWN}" = "false" ]; then
|
||||
log "[chown] Application de '${RESTORE_OWNER}' sur les fichiers restaures..."
|
||||
CHOWN_TARGETS=()
|
||||
[ -d "${SCRIPT_DIR}/var" ] && CHOWN_TARGETS+=("${SCRIPT_DIR}/var")
|
||||
[ -d "${SCRIPT_DIR}/public/uploads" ] && CHOWN_TARGETS+=("${SCRIPT_DIR}/public/uploads")
|
||||
[ -d "${SCRIPT_DIR}/config/cert" ] && CHOWN_TARGETS+=("${SCRIPT_DIR}/config/cert")
|
||||
[ -f "${SCRIPT_DIR}/.env.local" ] && CHOWN_TARGETS+=("${SCRIPT_DIR}/.env.local")
|
||||
|
||||
if [ ${#CHOWN_TARGETS[@]} -gt 0 ]; then
|
||||
chown -R "${RESTORE_OWNER}" "${CHOWN_TARGETS[@]}"
|
||||
log " OK - cibles: ${CHOWN_TARGETS[*]}"
|
||||
else
|
||||
log " Aucune cible a chown"
|
||||
fi
|
||||
else
|
||||
log "[chown] Saut du chown final (--skip-chown)"
|
||||
log " ATTENTION: PHP pourrait ne pas avoir les droits d'ecriture sur var/, public/uploads/..."
|
||||
fi
|
||||
|
||||
log "=== Migration terminee avec succes ==="
|
||||
log
|
||||
log "Etapes recommandees post-migration:"
|
||||
log " 1. make start_prod (si pas deja fait)"
|
||||
log " 2. make migrate_prod (appliquer les migrations Doctrine eventuelles)"
|
||||
log " 3. make clear_prod (vider le cache)"
|
||||
log " 4. Verifier le bon fonctionnement de l'application"
|
||||
log " 1. make build_prod (si l'image PHP n'a pas ete reconstruite avec le bon UID)"
|
||||
log " 2. make start_prod (si pas deja fait)"
|
||||
log " 3. make migrate_prod (appliquer les migrations Doctrine eventuelles)"
|
||||
log " 4. make clear_prod (vider le cache)"
|
||||
log " 5. Verifier le bon fonctionnement de l'application"
|
||||
|
||||
Reference in New Issue
Block a user