Webapp-starter/sh/prod.sh
2025-05-07 14:17:54 +08:00

164 lines
5.6 KiB
Bash
Executable File

#!/bin/bash
# Configuration - Replace these with your actual values
TARGET_USER="fmc"
TARGET_HOST="macmini"
TARGET_PATH="/Users/fmc/docker/starter" # Use absolute path instead of ~ to avoid expansion issues
# Colors for output
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
# Error handling function
handle_error() {
echo -e "${RED}ERROR: $1${NC}"
exit 1
}
echo -e "${GREEN}Starting deployment process for FMC Writer...${NC}"
# Create a temporary directory for the deployment package
TEMP_DIR=$(mktemp -d) || handle_error "Failed to create temporary directory"
PACKAGE_NAME="starter-deploy.tar.gz"
echo -e "${GREEN}Creating deployment package...${NC}"
# Create the tar.gz package excluding common files that should not be deployed
tar --exclude='.git' \
--exclude='frontend/node_modules' \
--exclude='frontend/.next' \
--exclude='backend/tmp' \
--exclude='backend/vendor' \
--exclude='.DS_Store' \
--exclude='**/.DS_Store' \
--exclude='*.log' \
--exclude='.env.local' \
--exclude='.env.development' \
--exclude='.env.test' \
--exclude='.cursor' \
-czf "${TEMP_DIR}/${PACKAGE_NAME}" . || handle_error "Failed to create deployment package"
echo -e "${GREEN}Uploading package to ${TARGET_HOST}...${NC}"
# Check if the target directory exists on the remote server
ssh "${TARGET_USER}@${TARGET_HOST}" "mkdir -p ${TARGET_PATH}" || handle_error "Failed to create target directory on remote server"
# Upload the package to the target server
scp "${TEMP_DIR}/${PACKAGE_NAME}" "${TARGET_USER}@${TARGET_HOST}:${TARGET_PATH}/" || handle_error "Failed to upload package to remote server"
# Upload the .env file separately to the remote server (if it exists locally)
if [ -f ".env" ]; then
echo -e "${YELLOW}Uploading .env file to remote server...${NC}"
scp ".env" "${TARGET_USER}@${TARGET_HOST}:${TARGET_PATH}/.env" || handle_error "Failed to upload .env file"
else
echo -e "${YELLOW}Warning: No .env file found locally. Make sure it exists on the remote server.${NC}"
fi
echo -e "${GREEN}Deploying on remote server...${NC}"
# Connect to the remote server and perform deployment steps
ssh -T "${TARGET_USER}@${TARGET_HOST}" << EOF || handle_error "Remote deployment failed"
set -e # Exit immediately if a command exits with a non-zero status
echo "Changing to target directory: ${TARGET_PATH}"
cd "${TARGET_PATH}" || { echo "Failed to change to target directory"; exit 1; }
# Verify the package exists
if [ ! -f "${PACKAGE_NAME}" ]; then
echo "Package ${PACKAGE_NAME} not found in ${TARGET_PATH}"
exit 1
fi
# Verify .env file exists
if [ ! -f ".env" ]; then
echo "Warning: .env file not found in ${TARGET_PATH}"
echo "Deployment will continue, but may fail if environment variables are required"
fi
# Remove frontend and backend directories to ensure deleted files don't persist
echo "Removing existing frontend and backend directories..."
rm -rf frontend backend
# Extract the package
echo "Extracting package..."
tar -xzf "${PACKAGE_NAME}" || { echo "Failed to extract package"; exit 1; }
# Ensure frontend/public directory exists on the remote server
echo "Ensuring frontend/public directory exists..."
mkdir -p frontend/public
touch frontend/public/.keep
# Check if docker-compose.yml exists
if [ ! -f "docker-compose.yml" ]; then
echo "docker-compose.yml not found in the extracted package"
exit 1
fi
# Stop any running containers
echo "Stopping any running containers..."
docker-compose down || echo "Warning: docker-compose down failed, continuing anyway"
# # Clean any previous Docker build cache
# echo "Cleaning Docker build cache..."
# docker builder prune -f || echo "Warning: Failed to clean Docker build cache, continuing anyway"
# Build images with debug output
echo "Building images..."
docker-compose build --progress=plain || {
echo "Failed to build images"
echo "Checking Docker logs for errors:"
docker-compose logs
exit 1
}
echo "Starting containers..."
docker-compose up -d --build || {
echo "Failed to start containers"
echo "Checking Docker logs for errors:"
docker-compose logs
exit 1
}
# Verify containers are running
echo "Verifying containers are running..."
sleep 5
if [ \$(docker-compose ps -q | wc -l) -lt 2 ]; then
echo "Not all containers are running. Checking logs:"
docker-compose logs
exit 1
fi
# Clean up
echo "Cleaning up..."
rm "${PACKAGE_NAME}" || { echo "Failed to remove package file"; exit 1; }
echo "Deployment completed successfully!"
echo "Container status:"
docker-compose ps
EOF
# Check if the SSH command was successful
if [ $? -ne 0 ]; then
handle_error "Deployment on remote server failed"
fi
# Clean up local temporary files
echo -e "${GREEN}Cleaning up local temporary files...${NC}"
rm -rf "${TEMP_DIR}" || handle_error "Failed to clean up local temporary files"
echo -e "${GREEN}Deployment process completed!${NC}"
# Automatically tail logs after deployment
echo -e "${GREEN}Tailing logs...${NC}"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
REPO_ROOT="$SCRIPT_DIR/.."
sh "$SCRIPT_DIR/log.sh" -f
LOG_EXIT_CODE=$?
if [ $LOG_EXIT_CODE -eq 130 ]; then
echo -e "${YELLOW}Log viewing interrupted by user.${NC}"
else
if [ $LOG_EXIT_CODE -ne 0 ]; then
handle_error "Log viewing failed with exit code $LOG_EXIT_CODE"
fi
fi