All checks were successful
Deploy Plane Project Tracker / Deploy to cisystem (push) Successful in 6m47s
121 lines
4.5 KiB
Bash
Executable file
121 lines
4.5 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
set -e
|
|
|
|
# ==============================================================================
|
|
# Plane Installation & Deployment Script for cisystem
|
|
# Target Directory: /home/ubuntu/plane
|
|
# Port: 127.0.0.1:8090 (Routed by Nginx to jira.tradhox.com)
|
|
# ==============================================================================
|
|
|
|
INSTALL_DIR="/home/ubuntu/plane"
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
echo "==> [1/6] Initializing Plane directory structure at ${INSTALL_DIR}..."
|
|
mkdir -p "${INSTALL_DIR}/patches"
|
|
mkdir -p "${INSTALL_DIR}/logs" "${INSTALL_DIR}/logs/api" "${INSTALL_DIR}/logs/worker" "${INSTALL_DIR}/logs/beat-worker" "${INSTALL_DIR}/logs/migrator" "${INSTALL_DIR}/logs/web" "${INSTALL_DIR}/logs/proxy"
|
|
chmod -R 777 "${INSTALL_DIR}/logs" 2>/dev/null || true "${INSTALL_DIR}/logs"
|
|
|
|
# Verify .env exists and sync database credentials
|
|
if [ -f "${INSTALL_DIR}/.env" ]; then
|
|
echo "==> Updating database settings in existing ${INSTALL_DIR}/.env..."
|
|
python3 -c '
|
|
import re, os
|
|
env_file = "'"${INSTALL_DIR}/.env"'"
|
|
updates = {
|
|
"PGHOST": "host.docker.internal",
|
|
"POSTGRES_HOST": "host.docker.internal",
|
|
"POSTGRES_USER": "vignesh",
|
|
"POSTGRES_PASSWORD": "vignesh_secret_pass_2026",
|
|
"DATABASE_URL": "postgresql://vignesh:vignesh_secret_pass_2026@host.docker.internal:5432/plane"
|
|
}
|
|
if os.path.exists(env_file):
|
|
with open(env_file, "r") as f:
|
|
content = f.read()
|
|
for k, v in updates.items():
|
|
pattern = re.compile(rf"^{k}=.*$", re.MULTILINE)
|
|
if pattern.search(content):
|
|
content = pattern.sub(f"{k}={v}", content)
|
|
else:
|
|
content += f"\n{k}={v}\n"
|
|
with open(env_file, "w") as f:
|
|
f.write(content)
|
|
'
|
|
elif [ -f "${SCRIPT_DIR}/.env.example" ]; then
|
|
echo "Notice: Creating initial .env from .env.example..."
|
|
cp "${SCRIPT_DIR}/.env.example" "${INSTALL_DIR}/.env"
|
|
fi
|
|
|
|
echo "==> [2/6] Syncing docker-compose, scripts and runtime patches..."
|
|
if [ "${SCRIPT_DIR}" != "${INSTALL_DIR}" ]; then
|
|
cp "${SCRIPT_DIR}/docker-compose.yml" "${INSTALL_DIR}/docker-compose.yml"
|
|
if [ -f "${SCRIPT_DIR}/logs.sh" ]; then
|
|
cp "${SCRIPT_DIR}/logs.sh" "${INSTALL_DIR}/logs.sh"
|
|
fi
|
|
if [ -d "${SCRIPT_DIR}/patches" ]; then
|
|
cp -r "${SCRIPT_DIR}/patches/"* "${INSTALL_DIR}/patches/"
|
|
fi
|
|
else
|
|
echo "Already inside target directory ${INSTALL_DIR}."
|
|
fi
|
|
chmod +x "${INSTALL_DIR}/logs.sh" 2>/dev/null || true
|
|
|
|
cd "${INSTALL_DIR}"
|
|
|
|
echo "==> [3/6] Loading or Pulling Docker images..."
|
|
if [ -f "source.tar.gz" ]; then
|
|
echo "==> Extracting source code..."
|
|
mkdir -p source-build
|
|
tar -xzf source.tar.gz -C source-build
|
|
rm source.tar.gz
|
|
echo "==> Building custom Docker images from source on EC2..."
|
|
cd source-build
|
|
docker build -t makeplane/plane-frontend:stable -f apps/web/Dockerfile.web .
|
|
docker build -t makeplane/plane-backend:stable -f apps/api/Dockerfile.api apps/api/
|
|
cd ..
|
|
rm -rf source-build
|
|
echo "==> Pulling remaining images (stable)..."
|
|
docker compose pull space admin live plane-redis plane-mq proxy
|
|
else
|
|
echo "==> Pulling all Docker images..."
|
|
docker compose pull web space admin live api worker beat-worker migrator plane-redis plane-mq proxy
|
|
fi
|
|
|
|
echo "==> [4/6] Executing database migrations..."
|
|
docker compose run --rm migrator
|
|
|
|
echo "==> Generating frontend Enterprise patches..."
|
|
if [ -f "${INSTALL_DIR}/patches/patch_frontend.py" ]; then
|
|
python3 "${INSTALL_DIR}/patches/patch_frontend.py" "${INSTALL_DIR}/patches" || true
|
|
fi
|
|
|
|
echo "==> [5/6] Starting Plane containers without touching other host services..."
|
|
docker compose up -d --remove-orphans
|
|
|
|
echo "==> [6/6] Verifying service health..."
|
|
HEALTHY=false
|
|
for i in $(seq 1 45); do
|
|
STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8090/ || true)
|
|
if [ "$STATUS" = "200" ] || [ "$STATUS" = "302" ]; then
|
|
echo "✓ Plane is healthy! HTTP Status: $STATUS (http://127.0.0.1:8090/)"
|
|
HEALTHY=true
|
|
break
|
|
fi
|
|
echo "Waiting for Plane to be ready (attempt $i/45, status: $STATUS)..."
|
|
sleep 2
|
|
done
|
|
|
|
if [ "$HEALTHY" != "true" ]; then
|
|
echo "ERROR: Plane did not respond with 200/302 within 90 seconds. Checking logs:"
|
|
docker compose logs --tail=50 proxy api web
|
|
exit 1
|
|
fi
|
|
|
|
echo "==> Verifying existing cisystem services are undisturbed..."
|
|
for s in "3000:Forgejo" "3001:Docmost" "8084:OnlyOffice Portal" "8083:OnlyOffice Engine"; do
|
|
PORT="${s%%:*}"
|
|
NAME="${s##*:}"
|
|
CODE=$(curl -s -o /dev/null -w "%{http_code}" "http://127.0.0.1:${PORT}/" || true)
|
|
echo " - ${NAME} (Port ${PORT}): HTTP ${CODE}"
|
|
done
|
|
|
|
echo "✓ Plane installation / deployment completed successfully!"
|