292 lines
11 KiB
YAML
292 lines
11 KiB
YAML
name: Build and Deploy LittleShop
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
- development
|
|
tags:
|
|
- 'v*'
|
|
workflow_dispatch:
|
|
|
|
env:
|
|
DOCKER_BUILDKIT: 1
|
|
COMPOSE_DOCKER_CLI_BUILD: 1
|
|
|
|
jobs:
|
|
deploy-production:
|
|
name: Deploy to Production VPS (Manual Only)
|
|
runs-on: ubuntu-latest
|
|
if: false # Disabled - Manual deployment only via workflow_dispatch
|
|
environment:
|
|
name: production
|
|
url: https://admin.dark.side
|
|
steps:
|
|
- name: Set up SSH
|
|
run: |
|
|
mkdir -p ~/.ssh
|
|
chmod 700 ~/.ssh
|
|
echo "${{ secrets.VPS_SSH_KEY }}" > ~/.ssh/deploy_key
|
|
chmod 600 ~/.ssh/deploy_key
|
|
ssh-keyscan -p ${{ secrets.VPS_PORT }} ${{ secrets.VPS_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
|
|
|
|
- name: Deploy to VPS
|
|
run: |
|
|
ssh -i ~/.ssh/deploy_key -p ${{ secrets.VPS_PORT }} ${{ secrets.VPS_USER }}@${{ secrets.VPS_HOST }} bash -s << 'ENDSSH'
|
|
set -e
|
|
export VERSION="${{ github.sha }}"
|
|
|
|
# Navigate to deployment directory
|
|
cd /opt/littleshop
|
|
|
|
# Clone or pull latest code
|
|
if [ ! -d .git ]; then
|
|
echo "Cloning repository..."
|
|
git clone https://git.silverlabs.uk/Jamie/littleshop.git .
|
|
fi
|
|
echo "Pulling latest code from git..."
|
|
git fetch origin
|
|
git checkout $VERSION || git checkout main
|
|
|
|
# Build images on VPS
|
|
echo "Building LittleShop image..."
|
|
docker build --no-cache -t littleshop:$VERSION .
|
|
docker tag littleshop:$VERSION littleshop:latest
|
|
docker tag littleshop:$VERSION localhost:5000/littleshop:$VERSION
|
|
docker tag littleshop:$VERSION localhost:5000/littleshop:latest
|
|
|
|
echo "Building TeleBot image..."
|
|
docker build --no-cache -t telebot:$VERSION -f Dockerfile.telebot .
|
|
docker tag telebot:$VERSION telebot:latest
|
|
docker tag telebot:$VERSION localhost:5000/telebot:$VERSION
|
|
docker tag telebot:$VERSION localhost:5000/telebot:latest
|
|
|
|
# Push to local registry
|
|
echo "Pushing images to local Docker registry..."
|
|
docker push localhost:5000/littleshop:$VERSION || true
|
|
docker push localhost:5000/littleshop:latest || true
|
|
docker push localhost:5000/telebot:$VERSION || true
|
|
docker push localhost:5000/telebot:latest || true
|
|
|
|
# Force stop all littleshop containers
|
|
echo "Stopping all littleshop containers..."
|
|
docker stop $(docker ps -q --filter "name=littleshop") 2>/dev/null || true
|
|
docker rm $(docker ps -aq --filter "name=littleshop") 2>/dev/null || true
|
|
|
|
# Stop TeleBot container
|
|
echo "Stopping TeleBot container..."
|
|
docker stop telebot-service 2>/dev/null || true
|
|
docker rm telebot-service 2>/dev/null || true
|
|
|
|
# Stop services with compose
|
|
echo "Stopping compose services..."
|
|
docker-compose down --remove-orphans || true
|
|
|
|
# Prune unused Docker networks
|
|
echo "Cleaning up Docker networks..."
|
|
docker network prune -f || true
|
|
|
|
# Apply database migrations if they exist
|
|
echo "Checking for database migrations..."
|
|
if [ -d "LittleShop/Migrations" ] && [ -n "$(ls -A LittleShop/Migrations/*.sql 2>/dev/null)" ]; then
|
|
echo "Found migration files, applying to database..."
|
|
for migration in LittleShop/Migrations/*.sql; do
|
|
migration_name=$(basename "$migration")
|
|
echo "Applying migration: $migration_name"
|
|
docker run --rm -v littleshop_littleshop_data:/data -v $(pwd)/LittleShop/Migrations:/migrations alpine:latest sh -c "
|
|
apk add --no-cache sqlite > /dev/null 2>&1
|
|
echo 'Creating backup before migration...'
|
|
cp /data/littleshop-production.db /data/littleshop-production.db.backup-\$(date +%Y%m%d-%H%M%S) 2>/dev/null || true
|
|
echo 'Applying migration: $migration_name'
|
|
sqlite3 /data/littleshop-production.db < /migrations/$migration_name
|
|
echo 'Migration applied successfully'
|
|
"
|
|
done
|
|
else
|
|
echo "No migration files found, skipping..."
|
|
fi
|
|
|
|
# Start services with new images
|
|
echo "Starting services with new images..."
|
|
docker-compose up -d
|
|
|
|
# Start TeleBot with new image
|
|
echo "Starting TeleBot with new image..."
|
|
docker run -d \
|
|
--name telebot-service \
|
|
--restart unless-stopped \
|
|
--network silverpay_silverpay-network \
|
|
-e ASPNETCORE_URLS=http://+:5010 \
|
|
-e LittleShop__ApiUrl=http://littleshop:5000 \
|
|
-e LittleShop__UseTor=false \
|
|
-e Privacy__EnableTor=true \
|
|
-e Privacy__TorSocksHost=tor-gateway \
|
|
-e Privacy__TorSocksPort=9050 \
|
|
localhost:5000/telebot:latest
|
|
|
|
# Connect TeleBot to LittleShop network
|
|
docker network connect littleshop_littleshop-network telebot-service
|
|
|
|
# Wait for startup
|
|
echo "Waiting for services to start..."
|
|
sleep 30
|
|
|
|
# Health check
|
|
echo "Running health checks..."
|
|
for i in 1 2 3 4 5 6; do
|
|
if curl -f -s http://localhost:5100/api/catalog/products > /dev/null 2>&1; then
|
|
echo "✅ Deployment successful - health check passed"
|
|
exit 0
|
|
fi
|
|
echo "Health check attempt $i/6 failed, waiting..."
|
|
sleep 10
|
|
done
|
|
|
|
echo "❌ Health check failed after deployment"
|
|
docker logs littleshop --tail 50
|
|
docker logs telebot-service --tail 30
|
|
exit 1
|
|
ENDSSH
|
|
|
|
- name: Cleanup
|
|
if: always()
|
|
run: |
|
|
rm -f ~/.ssh/deploy_key
|
|
|
|
deploy-preproduction:
|
|
name: Deploy to Pre-Production (CT109)
|
|
runs-on: ubuntu-latest
|
|
if: github.ref == 'refs/heads/development' || github.ref == 'refs/heads/main'
|
|
environment:
|
|
name: pre-production
|
|
url: http://ct109.local
|
|
steps:
|
|
- name: Set up SSH for CT109
|
|
run: |
|
|
echo "Setting up SSH connection..."
|
|
echo "Host: ${{ secrets.CT109_HOST }}"
|
|
echo "Port: ${{ secrets.CT109_SSH_PORT }}"
|
|
echo "User: ${{ secrets.CT109_USER }}"
|
|
|
|
mkdir -p ~/.ssh
|
|
chmod 700 ~/.ssh
|
|
|
|
echo "Writing SSH key..."
|
|
echo "${{ secrets.CT109_SSH_KEY }}" > ~/.ssh/deploy_key
|
|
chmod 600 ~/.ssh/deploy_key
|
|
|
|
echo "SSH key size: $(wc -c < ~/.ssh/deploy_key) bytes"
|
|
|
|
echo "Adding host to known_hosts..."
|
|
ssh-keyscan -p ${{ secrets.CT109_SSH_PORT }} ${{ secrets.CT109_HOST }} >> ~/.ssh/known_hosts 2>&1 || echo "Warning: ssh-keyscan failed"
|
|
|
|
echo "Testing SSH connection..."
|
|
ssh -i ~/.ssh/deploy_key -p ${{ secrets.CT109_SSH_PORT }} -o StrictHostKeyChecking=no ${{ secrets.CT109_USER }}@${{ secrets.CT109_HOST }} "echo 'SSH connection successful'" || echo "SSH test failed"
|
|
|
|
echo "SSH setup complete"
|
|
|
|
- name: Deploy to CT109
|
|
run: |
|
|
ssh -i ~/.ssh/deploy_key -p ${{ secrets.CT109_SSH_PORT }} ${{ secrets.CT109_USER }}@${{ secrets.CT109_HOST }} bash -s << 'ENDSSH'
|
|
set -e
|
|
export VERSION="${{ github.sha }}"
|
|
|
|
# Use home directory for deployment
|
|
DEPLOY_DIR=~/littleshop
|
|
echo "Using deployment directory: $DEPLOY_DIR"
|
|
|
|
# Create deployment directory if it doesn't exist
|
|
mkdir -p "$DEPLOY_DIR"
|
|
cd "$DEPLOY_DIR"
|
|
|
|
# Clone or pull latest code (public repository, no auth needed)
|
|
if [ ! -d .git ]; then
|
|
echo "Cloning repository from public HTTPS..."
|
|
rm -rf * # Clean any existing files
|
|
git clone https://git.silverlabs.uk/Jamie/littleshop.git .
|
|
else
|
|
echo "Repository already cloned, pulling latest..."
|
|
git fetch origin
|
|
fi
|
|
|
|
echo "Checking out version: $VERSION"
|
|
git checkout $VERSION || git checkout main
|
|
|
|
# Build images on CT109
|
|
echo "Building LittleShop image..."
|
|
docker build --no-cache -t littleshop:$VERSION .
|
|
docker tag littleshop:$VERSION littleshop:latest
|
|
|
|
echo "Building TeleBot image..."
|
|
docker build --no-cache -t telebot:$VERSION -f Dockerfile.telebot .
|
|
docker tag telebot:$VERSION telebot:latest
|
|
|
|
# Stop existing containers
|
|
echo "Stopping existing containers..."
|
|
docker stop littleshop telebot-service 2>/dev/null || true
|
|
docker rm littleshop telebot-service 2>/dev/null || true
|
|
|
|
# Prune unused Docker networks
|
|
echo "Cleaning up Docker networks..."
|
|
docker network prune -f || true
|
|
|
|
# Create networks if they don't exist
|
|
docker network create littleshop-network 2>/dev/null || true
|
|
docker network create silverpay-network 2>/dev/null || true
|
|
|
|
# Start LittleShop container
|
|
echo "Starting LittleShop container..."
|
|
docker run -d \
|
|
--name littleshop \
|
|
--restart unless-stopped \
|
|
--network littleshop-network \
|
|
-p 5100:5000 \
|
|
-v littleshop-data:/app/data \
|
|
-e ASPNETCORE_URLS=http://+:5000 \
|
|
-e ASPNETCORE_ENVIRONMENT=Development \
|
|
littleshop:latest
|
|
|
|
# Start TeleBot container
|
|
echo "Starting TeleBot container..."
|
|
docker run -d \
|
|
--name telebot-service \
|
|
--restart unless-stopped \
|
|
--network silverpay-network \
|
|
-e ASPNETCORE_URLS=http://+:5010 \
|
|
-e LittleShop__ApiUrl=http://littleshop:5000 \
|
|
-e LittleShop__UseTor=false \
|
|
telebot:latest
|
|
|
|
# Connect TeleBot to LittleShop network
|
|
docker network connect littleshop-network telebot-service
|
|
|
|
# Wait for startup
|
|
echo "Waiting for services to start..."
|
|
sleep 15
|
|
|
|
# Health check
|
|
echo "Running health checks..."
|
|
for i in 1 2 3 4 5; do
|
|
if curl -f -s http://localhost:5100/api/catalog/products > /dev/null 2>&1; then
|
|
echo "✅ Pre-production deployment successful - health check passed"
|
|
docker ps --filter "name=littleshop" --filter "name=telebot"
|
|
exit 0
|
|
fi
|
|
echo "Health check attempt $i/5 failed, waiting..."
|
|
sleep 10
|
|
done
|
|
|
|
echo "❌ Health check failed after deployment"
|
|
echo "LittleShop logs:"
|
|
docker logs littleshop --tail 50
|
|
echo ""
|
|
echo "TeleBot logs:"
|
|
docker logs telebot-service --tail 30
|
|
exit 1
|
|
ENDSSH
|
|
|
|
- name: Cleanup
|
|
if: always()
|
|
run: |
|
|
rm -f ~/.ssh/deploy_key
|