Files
gitea-infrastructure/deploy-to-bigbox.sh
Alex Mikhalev 961e54a902 security: redact credentials and remove corporate hostname/vault references
- README: replace zesticai-non-prod vault name and bigbox hostname with
  generic placeholders; replace hardcoded Tailscale IP with descriptive text
- deploy-to-bigbox.sh: make BIGBOX and TAILSCALE_IP configurable via env
  vars (auto-detect via tailscale ip -4); replace op_zesticai_non_prod.sh
  with op_credentials.sh
- Caddyfile: remove bigbox hostname from comment
- RESEARCH doc: remove hardcoded S3 access key and secret key values from
  the secrets table; replace with generic op:// reference format
- docker-compose_kitchen_sink.yml: replace hardcoded S3 credentials with
  CHANGE_ME placeholders

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-18 19:56:32 +01:00

274 lines
7.6 KiB
Bash
Executable File

#!/bin/bash
#
# Deploy Gitea Stack with 1Password Secrets Management
#
# Prerequisites:
# - SSH access to target server configured (BIGBOX env var or "your-server" alias)
# - 1Password CLI installed locally and on the server
# - op_credentials.sh exists on the server (sets OP_SERVICE_ACCOUNT_TOKEN)
# - 1Password vault items created (gitea-postgres, gitea-s3)
# - Caddy already running on the server
#
# Network Configuration:
# - Gitea: Public via Caddy (git.terraphim.cloud) -> localhost:3000
# - Prometheus: Tailscale only (TAILSCALE_IP:9000)
# - S3: Tailscale only (TAILSCALE_IP:8333)
#
# Usage:
# BIGBOX=your-server TAILSCALE_IP=$(tailscale ip -4) ./deploy-to-bigbox.sh
#
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Configuration
BIGBOX="${BIGBOX:-your-server}"
REMOTE_DIR="~/gitea-stack"
TAILSCALE_IP="${TAILSCALE_IP:-$(tailscale ip -4 2>/dev/null || echo 'SET_TAILSCALE_IP')}"
echo -e "${GREEN}=== Gitea Stack Deployment to ${BIGBOX} ===${NC}"
echo ""
# Step 1: Verify local prerequisites
echo -e "${YELLOW}Step 1: Verifying local prerequisites...${NC}"
if ! command -v rsync &> /dev/null; then
echo -e "${RED}Error: rsync is not installed${NC}"
exit 1
fi
if ! ssh -o ConnectTimeout=5 "$BIGBOX" "echo 'SSH OK'" &> /dev/null; then
echo -e "${RED}Error: Cannot connect to $BIGBOX via SSH${NC}"
exit 1
fi
echo -e "${GREEN}✓ Local prerequisites verified${NC}"
echo ""
# Step 2: Verify server prerequisites
echo -e "${YELLOW}Step 2: Verifying server prerequisites...${NC}"
ssh "$BIGBOX" << 'CHECKSCRIPT'
set -e
# Check Docker
if ! command -v docker &> /dev/null; then
echo "Error: Docker not installed"
exit 1
fi
# Check Docker Compose
if ! docker compose version &> /dev/null; then
echo "Error: Docker Compose not installed"
exit 1
fi
# Check 1Password CLI
if ! command -v op &> /dev/null; then
echo "Error: 1Password CLI not installed"
exit 1
fi
# Check service account script
if [ ! -f "$HOME/op_credentials.sh" ]; then
echo "Error: op_credentials.sh not found in home directory"
exit 1
fi
# Test 1Password authentication
source "$HOME/op_credentials.sh"
if ! op vault list &> /dev/null; then
echo "Error: 1Password authentication failed"
exit 1
fi
# Check Caddy is running
if ! pgrep -x caddy > /dev/null; then
echo "Error: Caddy is not running"
exit 1
fi
# Check Caddy admin API is accessible
if ! curl -s http://localhost:2019/config/ > /dev/null; then
echo "Error: Caddy admin API is not accessible"
exit 1
fi
echo "All prerequisites verified"
CHECKSCRIPT
echo -e "${GREEN}✓ Server prerequisites verified${NC}"
echo ""
# Step 3: Transfer files
echo -e "${YELLOW}Step 3: Transferring files to ${BIGBOX}...${NC}"
ssh "$BIGBOX" "mkdir -p $REMOTE_DIR"
rsync -avz --progress \
--exclude='.git' \
--exclude='gitea' \
--exclude='postgres' \
--exclude='seaweedfs' \
--exclude='seaweedfs_filter' \
--exclude='docker-compose.yml' \
--exclude='s3_config.json' \
--exclude='.env' \
--exclude='*.log' \
--exclude='.docs/' \
. "$BIGBOX:$REMOTE_DIR/"
echo -e "${GREEN}✓ Files transferred${NC}"
echo ""
# Step 4: Inject secrets and start services
echo -e "${YELLOW}Step 4: Injecting secrets and starting services...${NC}"
ssh "$BIGBOX" << DEPLOYSCRIPT
set -e
cd $REMOTE_DIR
echo "Loading 1Password credentials..."
source ~/op_credentials.sh
echo "Injecting secrets into docker-compose.yml..."
op inject --in-file docker-compose.yml.template --out-file docker-compose.yml
echo "Injecting secrets into s3_config.json..."
op inject --in-file s3_config.json.template --out-file s3_config.json
echo "Creating data directories..."
mkdir -p gitea postgres seaweedfs seaweedfs_filter prometheus
echo "Setting permissions..."
chmod -R 1000:1000 gitea 2>/dev/null || sudo chown -R 1000:1000 gitea 2>/dev/null || true
echo "Starting services with Docker Compose..."
docker compose up -d
echo "Waiting for services to start..."
sleep 30
echo "Service status:"
docker compose ps
DEPLOYSCRIPT
echo -e "${GREEN}✓ Services started${NC}"
echo ""
# Step 5: Add Gitea route to Caddy
echo -e "${YELLOW}Step 5: Adding Gitea route to Caddy...${NC}"
ssh "$BIGBOX" << CADDYSCRIPT
set -e
echo "Creating log directory..."
sudo mkdir -p /var/log/caddy
echo "Adding Gitea route to Caddy via Admin API..."
curl -s -X POST http://localhost:2019/config/apps/http/servers/srv0/routes \
-H "Content-Type: application/json" \
-d '{
"@id": "gitea_route",
"match": [{"host": ["git.terraphim.cloud"]}],
"handle": [{
"handler": "subroute",
"routes": [{
"handle": [{
"handler": "reverse_proxy",
"upstreams": [{"dial": "localhost:3000"}]
}]
}]
}],
"terminal": true
}'
# Verify route was added
if curl -s http://localhost:2019/config/apps/http/servers/srv0/routes | grep -q "git.terraphim.cloud"; then
echo "✓ Gitea route added successfully to Caddy"
else
echo "✗ Warning: Could not verify Gitea route was added"
fi
CADDYSCRIPT
echo -e "${GREEN}✓ Caddy configured${NC}"
echo ""
# Step 6: Verify deployment
echo -e "${YELLOW}Step 6: Verifying deployment...${NC}"
ssh "$BIGBOX" << VERIFYSCRIPT
set -e
cd $REMOTE_DIR
echo ""
echo "=== Service Health Checks ==="
# Check Gitea (direct)
if curl -s -o /dev/null -w '%{http_code}' http://localhost:3000/api/healthz | grep -q "200"; then
echo "✓ Gitea is healthy (localhost:3000)"
else
echo "✗ Gitea is not responding"
fi
# Check S3 (Tailscale)
if curl -s http://${TAILSCALE_IP}:8333 > /dev/null 2>&1; then
echo "✓ SeaweedFS S3 is responding (${TAILSCALE_IP}:8333)"
else
echo "✗ SeaweedFS S3 is not responding"
fi
# Check Prometheus (Tailscale)
if curl -s http://${TAILSCALE_IP}:9000/-/healthy > /dev/null 2>&1; then
echo "✓ Prometheus is healthy (${TAILSCALE_IP}:9000)"
else
echo "✗ Prometheus is not responding"
fi
# Check SSH port
if nc -zv localhost 222 2>&1 | grep -q succeeded; then
echo "✓ SSH port is open (port 222)"
else
echo "✗ SSH port is not responding"
fi
# Check Caddy
if pgrep -x caddy > /dev/null; then
echo "✓ Caddy is running"
else
echo "✗ Caddy is not running"
fi
echo ""
echo "=== Container Status ==="
docker compose ps
echo ""
echo "=== Recent Logs ==="
docker compose logs --tail=10
VERIFYSCRIPT
echo ""
echo -e "${GREEN}=== Deployment Complete ===${NC}"
echo ""
echo "Access your services:"
echo ""
echo "Public (via HTTPS):"
echo " - Gitea Web: https://git.terraphim.cloud"
echo ""
echo "Tailscale Network Only (${TAILSCALE_IP}):"
echo " - Prometheus: http://${TAILSCALE_IP}:9000"
echo " - S3 API: http://${TAILSCALE_IP}:8333"
echo ""
echo "SSH Access:"
echo " - Gitea SSH: ssh://${BIGBOX}:222"
echo ""
echo "Note: Prometheus and S3 are NOT accessible from the public internet."
echo " Connect via Tailscale first: tailscale up"
echo ""
echo "Next steps:"
echo " 1. Ensure DNS points git.terraphim.cloud to ${BIGBOX}"
echo " 2. Access Gitea at https://git.terraphim.cloud to complete setup"
echo " 3. Change default admin password after first login"
echo " 4. Review Caddy logs: ssh ${BIGBOX} 'sudo tail -f /var/log/caddy/gitea-access.log'"
echo ""