semblance/deploy.sh
Vadym Samoilenko 4a6b4d6fe0 Dockerize backend — replace systemd service with docker-compose
- Add backend/Dockerfile (python:3.12-slim)
- Add docker-compose.yml (backend :5137 + mongo:7)
- Add backend/.dockerignore
- Rewrite deploy.sh: build frontend locally, rsync dist/, docker compose up --build
- Remove semblance.service (no longer needed)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 13:21:34 +00:00

102 lines
5.6 KiB
Bash
Executable file

#!/bin/bash
set -e
# ─────────────────────────────────────────────────────────────────────────────
# Semblance — deploy script
# Builds frontend locally, rsyncs dist/ to server, restarts Docker services.
#
# Server: optical-dev.oliver.solution (Ubuntu 24.04, Apache2, Docker)
# SSH alias: optical-dev (see ~/.ssh/config)
#
# First-time setup on server (run once manually):
# ssh optical-dev
# sudo mkdir -p /opt/semblance && sudo chown vadym.samoilenko:vadym.samoilenko /opt/semblance
# git clone git@bitbucket.org:zlalani/semblance-dev.git /opt/semblance
# cp /opt/semblance/backend/.env.example /opt/semblance/backend/.env
# nano /opt/semblance/backend/.env # fill in real values
# cd /opt/semblance && docker compose up -d --build
# ─────────────────────────────────────────────────────────────────────────────
SSH_HOST="optical-dev"
DEPLOY_DIR="/opt/semblance"
FRONTEND_DEST="/var/www/html/semblance"
echo "======================================"
echo "Semblance — starting deployment"
echo "======================================"
# ── Pre-flight: backend/.env must exist on server ────────────────────────────
echo ""
echo "[pre-flight] Checking backend/.env on server..."
if ! ssh "$SSH_HOST" "test -f $DEPLOY_DIR/backend/.env"; then
echo ""
echo "ERROR: $DEPLOY_DIR/backend/.env not found on server."
echo "Run on server:"
echo " cp $DEPLOY_DIR/backend/.env.example $DEPLOY_DIR/backend/.env"
echo " nano $DEPLOY_DIR/backend/.env"
exit 1
fi
for VAR in SECRET_KEY JWT_SECRET_KEY OPENAI_API_KEY GEMINI_API_KEY; do
if ! ssh "$SSH_HOST" "grep -q '^${VAR}=.\+' $DEPLOY_DIR/backend/.env 2>/dev/null"; then
echo "ERROR: $VAR is not set in backend/.env on server"
exit 1
fi
done
echo "✓ backend/.env present and required vars set"
# ── Step 1: Pull latest code on server ───────────────────────────────────────
echo ""
echo "[1/5] Pulling latest code on server..."
ssh "$SSH_HOST" "cd $DEPLOY_DIR && git pull"
# ── Step 2: Build frontend locally ───────────────────────────────────────────
echo ""
echo "[2/5] Building frontend locally..."
cp .env.production .env
npm install --silent
npm run build
echo "✓ Frontend built (dist/)"
# ── Step 3: Deploy frontend to server ────────────────────────────────────────
echo ""
echo "[3/5] Deploying frontend to server..."
ssh "$SSH_HOST" "sudo mkdir -p $FRONTEND_DEST"
rsync -az --delete dist/ "$SSH_HOST:$FRONTEND_DEST/"
ssh "$SSH_HOST" "sudo chown -R www-data:www-data $FRONTEND_DEST"
echo "✓ Frontend deployed to $FRONTEND_DEST"
# ── Step 4: Ensure Apache proxy config for semblance ─────────────────────────
echo ""
echo "[4/5] Ensuring Apache proxy config..."
ssh "$SSH_HOST" "
CONF='/etc/apache2/sites-enabled/optical-dev.oliver.solutions.conf'
if grep -q 'semblance_back' \"\$CONF\" 2>/dev/null; then
echo '✓ Apache semblance config already present'
else
echo 'Adding semblance blocks to Apache config...'
sudo sed -i 's|</VirtualHost>| # ----------------------------------------------------------------\n # Semblance — Quart/Hypercorn backend at :5137\n # ----------------------------------------------------------------\n\n # WebSocket (Socket.IO)\n RewriteCond %{HTTP:Upgrade} websocket [NC]\n RewriteCond %{HTTP:Connection} upgrade [NC]\n RewriteRule ^/semblance_back/socket.io/(.*) ws://127.0.0.1:5137/socket.io/\$1 [P,L]\n\n # REST API\n ProxyPass /semblance_back/api/ http://127.0.0.1:5137/api/\n ProxyPassReverse /semblance_back/api/ http://127.0.0.1:5137/api/\n\n # Socket.IO HTTP polling fallback\n ProxyPass /semblance_back/socket.io/ http://127.0.0.1:5137/socket.io/\n ProxyPassReverse /semblance_back/socket.io/ http://127.0.0.1:5137/socket.io/\n\n # Semblance SPA — served at /semblance/\n Alias /semblance $FRONTEND_DEST\n <Directory $FRONTEND_DEST>\n Options -Indexes +FollowSymLinks\n AllowOverride None\n Require all granted\n RewriteEngine On\n RewriteBase /semblance/\n RewriteCond %{REQUEST_FILENAME} !-f\n RewriteCond %{REQUEST_FILENAME} !-d\n RewriteRule ^ index.html [L]\n </Directory>\n\n</VirtualHost>|' \"\$CONF\"
sudo apache2ctl configtest && sudo systemctl reload apache2
echo '✓ Apache config updated and reloaded'
fi
"
# ── Step 5: Rebuild and restart Docker services ───────────────────────────────
echo ""
echo "[5/5] Rebuilding and restarting Docker services..."
ssh "$SSH_HOST" "
cd $DEPLOY_DIR
docker compose pull mongo 2>/dev/null || true
docker compose up -d --build
echo ''
echo 'Container status:'
docker compose ps
"
echo ""
echo "======================================"
echo "Deployment complete!"
echo " Frontend: https://optical-dev.oliver.solution/semblance/"
echo " API: https://optical-dev.oliver.solution/semblance_back/api/"
echo "======================================"