109 lines
3.6 KiB
Bash
Executable File
109 lines
3.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -Eeuo pipefail
|
|
|
|
APP_NAME="corp-address-book"
|
|
CONTAINER_NAME="corporate-address-book"
|
|
INSTALL_DIR="/opt/corp-address-book"
|
|
IMAGE_NAME="corp-address-book:latest"
|
|
HOST_PORT="8180"
|
|
CONTAINER_PORT="3000"
|
|
|
|
log() {
|
|
printf '\n[%s] %s\n' "$(date +'%H:%M:%S')" "$*"
|
|
}
|
|
|
|
die() {
|
|
printf '\nERROR: %s\n' "$*" >&2
|
|
exit 1
|
|
}
|
|
|
|
# 1. Require root
|
|
if [ "${EUID:-$(id -u)}" -ne 0 ]; then
|
|
die "Run this update script as root, for example: curl -fsSL ... | sudo bash"
|
|
fi
|
|
|
|
# 2. Go to installation directory
|
|
log "Navigating to ${INSTALL_DIR}"
|
|
cd "$INSTALL_DIR" || die "Directory ${INSTALL_DIR} does not exist. Run install.sh first."
|
|
|
|
# 2.1. Backup existing database
|
|
if [ -f "${INSTALL_DIR}/data/database.db" ]; then
|
|
log "Backing up existing database"
|
|
cp "${INSTALL_DIR}/data/database.db" "${INSTALL_DIR}/data/database.db.bak"
|
|
log "Database backup created at ${INSTALL_DIR}/data/database.db.bak"
|
|
fi
|
|
|
|
# 3. Configure git safe directory
|
|
log "Configuring git safe directory"
|
|
git config --global --add safe.directory "$INSTALL_DIR" || true
|
|
|
|
# 4. Pull changes using the deploy key
|
|
log "Pulling latest changes from Gitea"
|
|
SSH_KEY="/home/fabritsky/.ssh/gitea_corp_address_book_ed25519"
|
|
if [ ! -f "$SSH_KEY" ]; then
|
|
# Fallback: search for any deploy/private key in fabritsky's .ssh directory
|
|
SSH_KEY_FOUND=$(find /home/fabritsky/.ssh/ -type f \( -name "*gitea*" -o -name "*ed25519*" -o -name "*rsa*" \) ! -name "*.pub" | head -n 1)
|
|
if [ -n "$SSH_KEY_FOUND" ]; then
|
|
SSH_KEY="$SSH_KEY_FOUND"
|
|
fi
|
|
fi
|
|
|
|
log "Using SSH key: ${SSH_KEY}"
|
|
GIT_SSH_COMMAND="ssh -i ${SSH_KEY} -o StrictHostKeyChecking=no -o BatchMode=yes" git pull
|
|
|
|
# 5. Build Docker Image (Re-compile frontend and backend inside container)
|
|
log "Building updated Docker image ${IMAGE_NAME}"
|
|
docker build -t "$IMAGE_NAME" "$INSTALL_DIR"
|
|
|
|
# 6. Safely replace container
|
|
log "Replacing container ${CONTAINER_NAME}"
|
|
old_name=""
|
|
if docker container inspect "$CONTAINER_NAME" >/dev/null 2>&1; then
|
|
old_name="${CONTAINER_NAME}-old-$(date +%Y%m%d-%H%M%S)"
|
|
docker stop "$CONTAINER_NAME" >/dev/null
|
|
docker rename "$CONTAINER_NAME" "$old_name"
|
|
log "Previous container renamed to ${old_name}"
|
|
fi
|
|
|
|
log "Starting new container on port ${HOST_PORT}"
|
|
if ! docker run -d \
|
|
--name "$CONTAINER_NAME" \
|
|
--restart unless-stopped \
|
|
--env-file "${INSTALL_DIR}/.env" \
|
|
-p "${HOST_PORT}:${CONTAINER_PORT}" \
|
|
-v "${INSTALL_DIR}/data:/app/data" \
|
|
"$IMAGE_NAME" >/dev/null; then
|
|
if [ -n "$old_name" ]; then
|
|
log "New container failed to start; rolling back to ${old_name}"
|
|
docker rename "$old_name" "$CONTAINER_NAME" || true
|
|
docker start "$CONTAINER_NAME" || true
|
|
fi
|
|
die "Failed to start new container."
|
|
fi
|
|
|
|
# 7. Health Check / Status
|
|
log "Running health check..."
|
|
sleep 5
|
|
if curl -fsSI "http://127.0.0.1:${HOST_PORT}/" >/dev/null; then
|
|
log "Update completed successfully!"
|
|
log "Service HTTP Status: $(curl -o /dev/null -s -w "%{http_code}" http://127.0.0.1:${HOST_PORT}/)"
|
|
log "Container Status:"
|
|
docker ps --filter "name=${CONTAINER_NAME}"
|
|
|
|
# Remove the backup old container since deployment succeeded
|
|
if [ -n "$old_name" ]; then
|
|
log "Cleaning up old backup container ${old_name}"
|
|
docker rm "$old_name" >/dev/null || true
|
|
fi
|
|
else
|
|
docker logs --tail=80 "$CONTAINER_NAME" || true
|
|
if [ -n "$old_name" ]; then
|
|
log "Health check failed; rolling back to ${old_name}"
|
|
docker stop "$CONTAINER_NAME" >/dev/null || true
|
|
docker rm "$CONTAINER_NAME" || true
|
|
docker rename "$old_name" "$CONTAINER_NAME" || true
|
|
docker start "$CONTAINER_NAME" || true
|
|
fi
|
|
die "Health check failed. Rolled back to the previous container version."
|
|
fi
|