diff --git a/install_daily_restart_cron.sh b/install_daily_restart_cron.sh new file mode 100755 index 0000000..f2f9e13 --- /dev/null +++ b/install_daily_restart_cron.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +# Install a daily cron job to restart the docker-compose stack. +# Non-interactive; idempotent update of user's crontab. +# Usage: +# INTERVAL="15 3 * * *" ./install_daily_restart_cron.sh +# Defaults to 03:15 daily if INTERVAL not provided. + +set -euo pipefail + +REPO_DIR="$(cd "$(dirname "$0")" && pwd)" +SCRIPT_PATH="$REPO_DIR/restart_containers.sh" +INTERVAL_CRON=${INTERVAL:-"15 3 * * *"} + +if [ ! -x "$SCRIPT_PATH" ]; then + echo "Making restart_containers.sh executable" + chmod +x "$SCRIPT_PATH" +fi + +if ! command -v crontab >/dev/null 2>&1; then + echo "Error: crontab not found on this system." + exit 1 +fi + +# Prefer docker compose; fallback to docker-compose is handled inside the script + +# Compose file to use (default docker-compose.yml). Override via COMPOSE_FILE env +COMPOSE_FILE_PATH=${COMPOSE_FILE:-docker-compose.yml} + +LOG_FILE="$REPO_DIR/logs/cron_restart.log" +mkdir -p "$(dirname "$LOG_FILE")" + +# Build the cron line; ensure PATH for docker is available +CRON_LINE="$INTERVAL_CRON PATH=/usr/local/bin:/usr/bin:/bin /bin/bash -lc 'COMPOSE_FILE=$COMPOSE_FILE_PATH "$SCRIPT_PATH" >> "$LOG_FILE" 2>&1'" + +# Install or update crontab entry +EXISTING_CRON="$(mktemp)" +trap 'rm -f "$EXISTING_CRON"' EXIT + +crontab -l > "$EXISTING_CRON" 2>/dev/null || true + +# Remove any previous lines referencing restart_containers.sh +grep -v "$SCRIPT_PATH" "$EXISTING_CRON" > "$EXISTING_CRON.cleaned" || true +mv "$EXISTING_CRON.cleaned" "$EXISTING_CRON" + +echo "$CRON_LINE" >> "$EXISTING_CRON" +crontab "$EXISTING_CRON" + +echo "Installed cron entry: $CRON_LINE" +echo "Logs will be written to: $LOG_FILE" + + diff --git a/restart_containers.sh b/restart_containers.sh new file mode 100755 index 0000000..4b0007f --- /dev/null +++ b/restart_containers.sh @@ -0,0 +1,67 @@ +#!/bin/bash + +# Restart docker-compose stack (or selected services) and log output. +# Usage: +# ./restart_containers.sh [service1 service2 ...] +# +# Env vars: +# COMPOSE_FILE: override compose file (default: docker-compose.yml) + +set -euo pipefail + +REPO_DIR="$(cd "$(dirname "$0")" && pwd)" +LOG_DIR="$REPO_DIR/logs" +mkdir -p "$LOG_DIR" + +timestamp() { + date +"%Y-%m-%d %H:%M:%S%z" +} + +echo "[$(timestamp)] Starting restart_containers.sh" | tee -a "$LOG_DIR/restart.log" + +# Detect compose command +detect_compose_cmd() { + if command -v docker >/dev/null 2>&1; then + if docker compose version >/dev/null 2>&1; then + echo "docker compose" + return 0 + fi + fi + if command -v docker-compose >/dev/null 2>&1; then + echo "docker-compose" + return 0 + fi + echo "[$(timestamp)] ERROR: Neither 'docker compose' nor 'docker-compose' found in PATH" | tee -a "$LOG_DIR/restart.log" + exit 1 +} + +COMPOSE_CMD=$(detect_compose_cmd) +COMPOSE_FILE_PATH=${COMPOSE_FILE:-docker-compose.yml} + +if [ ! -f "$REPO_DIR/$COMPOSE_FILE_PATH" ]; then + echo "[$(timestamp)] ERROR: Compose file not found: $REPO_DIR/$COMPOSE_FILE_PATH" | tee -a "$LOG_DIR/restart.log" + exit 1 +fi + +cd "$REPO_DIR" + +SERVICES=("$@") + +if [ ${#SERVICES[@]} -eq 0 ]; then + echo "[$(timestamp)] Restarting full stack using $COMPOSE_FILE_PATH" | tee -a "$LOG_DIR/restart.log" + set +e + $COMPOSE_CMD -f "$COMPOSE_FILE_PATH" down >>"$LOG_DIR/restart.log" 2>&1 + DOWN_STATUS=$? + set -e + echo "[$(timestamp)] docker compose down exit status: $DOWN_STATUS" | tee -a "$LOG_DIR/restart.log" + $COMPOSE_CMD -f "$COMPOSE_FILE_PATH" up -d >>"$LOG_DIR/restart.log" 2>&1 + echo "[$(timestamp)] Stack brought up" | tee -a "$LOG_DIR/restart.log" +else + echo "[$(timestamp)] Restarting services: ${SERVICES[*]} using $COMPOSE_FILE_PATH" | tee -a "$LOG_DIR/restart.log" + $COMPOSE_CMD -f "$COMPOSE_FILE_PATH" restart "${SERVICES[@]}" >>"$LOG_DIR/restart.log" 2>&1 + echo "[$(timestamp)] Services restarted" | tee -a "$LOG_DIR/restart.log" +fi + +echo "[$(timestamp)] Completed restart_containers.sh" | tee -a "$LOG_DIR/restart.log" + +