830 lines
19 KiB
Markdown
830 lines
19 KiB
Markdown
# HarborSmith Gitea Docker Workflow
|
|
## Automated Build & Deployment Pipeline
|
|
|
|
**Version:** 1.0
|
|
**Date:** September 2025
|
|
**Purpose:** Gitea repository setup with automated Docker image building and deployment
|
|
|
|
---
|
|
|
|
## 📋 Overview
|
|
|
|
This guide configures HarborSmith to work with your Gitea instance for:
|
|
- Source control management
|
|
- Automated Docker image building
|
|
- Container registry management
|
|
- Automated deployment to production
|
|
|
|
---
|
|
|
|
## 🏗️ Repository Structure
|
|
|
|
```bash
|
|
harborsmith/ # Main repository in Gitea
|
|
├── .gitea/ # Gitea-specific configuration
|
|
│ └── workflows/ # Gitea Actions (CI/CD)
|
|
│ ├── build.yaml # Build Docker images on push
|
|
│ ├── test.yaml # Run tests
|
|
│ └── deploy.yaml # Deploy to production
|
|
├── .dockerignore # Files to exclude from Docker builds
|
|
├── docker-compose.yml # Production orchestration
|
|
├── docker-compose.dev.yml # Development overrides
|
|
├── docker-compose.build.yml # Build configuration
|
|
├── Makefile # Build and deploy commands
|
|
└── [rest of project structure as defined]
|
|
```
|
|
|
|
---
|
|
|
|
## 🔧 Gitea Actions Workflow
|
|
|
|
### Build Workflow (.gitea/workflows/build.yaml)
|
|
```yaml
|
|
name: Build and Push Docker Images
|
|
on:
|
|
push:
|
|
branches: [main, develop]
|
|
tags:
|
|
- 'v*'
|
|
pull_request:
|
|
branches: [main]
|
|
|
|
jobs:
|
|
build-web:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@v2
|
|
|
|
- name: Login to Gitea Registry
|
|
uses: docker/login-action@v2
|
|
with:
|
|
registry: gitea.yourdomain.com
|
|
username: ${{ secrets.REGISTRY_USERNAME }}
|
|
password: ${{ secrets.REGISTRY_PASSWORD }}
|
|
|
|
- name: Extract metadata
|
|
id: meta
|
|
uses: docker/metadata-action@v4
|
|
with:
|
|
images: gitea.yourdomain.com/harborsmith/web
|
|
tags: |
|
|
type=ref,event=branch
|
|
type=ref,event=pr
|
|
type=semver,pattern={{version}}
|
|
type=semver,pattern={{major}}.{{minor}}
|
|
type=sha,prefix={{branch}}-
|
|
type=raw,value=latest,enable={{is_default_branch}}
|
|
|
|
- name: Build and push Web
|
|
uses: docker/build-push-action@v4
|
|
with:
|
|
context: ./apps/web
|
|
file: ./apps/web/Dockerfile
|
|
push: true
|
|
tags: ${{ steps.meta.outputs.tags }}
|
|
labels: ${{ steps.meta.outputs.labels }}
|
|
cache-from: type=registry,ref=gitea.yourdomain.com/harborsmith/web:buildcache
|
|
cache-to: type=registry,ref=gitea.yourdomain.com/harborsmith/web:buildcache,mode=max
|
|
build-args: |
|
|
BUILDKIT_INLINE_CACHE=1
|
|
NODE_ENV=production
|
|
|
|
build-api:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@v2
|
|
|
|
- name: Login to Gitea Registry
|
|
uses: docker/login-action@v2
|
|
with:
|
|
registry: gitea.yourdomain.com
|
|
username: ${{ secrets.REGISTRY_USERNAME }}
|
|
password: ${{ secrets.REGISTRY_PASSWORD }}
|
|
|
|
- name: Extract metadata
|
|
id: meta
|
|
uses: docker/metadata-action@v4
|
|
with:
|
|
images: gitea.yourdomain.com/harborsmith/api
|
|
|
|
- name: Build and push API
|
|
uses: docker/build-push-action@v4
|
|
with:
|
|
context: ./apps/api
|
|
file: ./apps/api/Dockerfile
|
|
push: true
|
|
tags: ${{ steps.meta.outputs.tags }}
|
|
labels: ${{ steps.meta.outputs.labels }}
|
|
cache-from: type=registry,ref=gitea.yourdomain.com/harborsmith/api:buildcache
|
|
cache-to: type=registry,ref=gitea.yourdomain.com/harborsmith/api:buildcache,mode=max
|
|
|
|
build-services:
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
matrix:
|
|
service: [charter, maintenance, payments, notifications]
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@v2
|
|
|
|
- name: Login to Gitea Registry
|
|
uses: docker/login-action@v2
|
|
with:
|
|
registry: gitea.yourdomain.com
|
|
username: ${{ secrets.REGISTRY_USERNAME }}
|
|
password: ${{ secrets.REGISTRY_PASSWORD }}
|
|
|
|
- name: Extract metadata
|
|
id: meta
|
|
uses: docker/metadata-action@v4
|
|
with:
|
|
images: gitea.yourdomain.com/harborsmith/${{ matrix.service }}
|
|
|
|
- name: Build and push ${{ matrix.service }}
|
|
uses: docker/build-push-action@v4
|
|
with:
|
|
context: ./services/${{ matrix.service }}
|
|
file: ./services/${{ matrix.service }}/Dockerfile
|
|
push: true
|
|
tags: ${{ steps.meta.outputs.tags }}
|
|
labels: ${{ steps.meta.outputs.labels }}
|
|
```
|
|
|
|
---
|
|
|
|
## 🐳 Optimized Dockerfiles
|
|
|
|
### Multi-stage Dockerfile for Next.js (apps/web/Dockerfile)
|
|
```dockerfile
|
|
# Dependencies stage
|
|
FROM node:20-alpine AS deps
|
|
RUN apk add --no-cache libc6-compat
|
|
WORKDIR /app
|
|
|
|
# Copy package files
|
|
COPY package.json pnpm-lock.yaml* ./
|
|
RUN corepack enable pnpm && pnpm i --frozen-lockfile
|
|
|
|
# Builder stage
|
|
FROM node:20-alpine AS builder
|
|
WORKDIR /app
|
|
COPY --from=deps /app/node_modules ./node_modules
|
|
COPY . .
|
|
|
|
# Build arguments for environment variables
|
|
ARG NEXT_PUBLIC_API_URL
|
|
ARG NEXT_PUBLIC_SUPABASE_URL
|
|
ARG NEXT_PUBLIC_SUPABASE_ANON_KEY
|
|
ARG NEXT_PUBLIC_STRIPE_PUBLIC_KEY
|
|
ARG NEXT_PUBLIC_KEYCLOAK_URL
|
|
ARG NEXT_PUBLIC_KEYCLOAK_REALM
|
|
ARG NEXT_PUBLIC_KEYCLOAK_CLIENT_ID
|
|
|
|
ENV NEXT_TELEMETRY_DISABLED 1
|
|
RUN corepack enable pnpm && pnpm build
|
|
|
|
# Runner stage
|
|
FROM node:20-alpine AS runner
|
|
WORKDIR /app
|
|
|
|
ENV NODE_ENV production
|
|
ENV NEXT_TELEMETRY_DISABLED 1
|
|
|
|
RUN addgroup --system --gid 1001 nodejs
|
|
RUN adduser --system --uid 1001 nextjs
|
|
|
|
# Copy built application
|
|
COPY --from=builder /app/public ./public
|
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
|
|
|
USER nextjs
|
|
|
|
EXPOSE 3000
|
|
ENV PORT 3000
|
|
ENV HOSTNAME "0.0.0.0"
|
|
|
|
CMD ["node", "server.js"]
|
|
```
|
|
|
|
### Optimized API Dockerfile (apps/api/Dockerfile)
|
|
```dockerfile
|
|
# Build stage
|
|
FROM node:20-alpine AS builder
|
|
RUN apk add --no-cache libc6-compat
|
|
WORKDIR /app
|
|
|
|
COPY package.json pnpm-lock.yaml* ./
|
|
RUN corepack enable pnpm && pnpm i --frozen-lockfile
|
|
|
|
COPY . .
|
|
RUN pnpm build
|
|
|
|
# Production stage
|
|
FROM node:20-alpine AS runner
|
|
RUN apk add --no-cache libc6-compat
|
|
WORKDIR /app
|
|
|
|
ENV NODE_ENV production
|
|
|
|
RUN addgroup --system --gid 1001 nodejs
|
|
RUN adduser --system --uid 1001 apiuser
|
|
|
|
COPY --from=builder /app/dist ./dist
|
|
COPY --from=builder /app/node_modules ./node_modules
|
|
COPY --from=builder /app/package.json ./package.json
|
|
|
|
USER apiuser
|
|
|
|
EXPOSE 4000
|
|
|
|
CMD ["node", "dist/server.js"]
|
|
```
|
|
|
|
### Microservice Dockerfile Template (services/*/Dockerfile)
|
|
```dockerfile
|
|
FROM node:20-alpine AS builder
|
|
WORKDIR /app
|
|
|
|
COPY package*.json ./
|
|
COPY pnpm-lock.yaml* ./
|
|
RUN corepack enable pnpm && pnpm i --frozen-lockfile
|
|
|
|
COPY . .
|
|
RUN pnpm build
|
|
|
|
FROM node:20-alpine
|
|
WORKDIR /app
|
|
|
|
RUN addgroup -g 1001 -S nodejs
|
|
RUN adduser -S nodejs -u 1001
|
|
|
|
COPY --from=builder /app/dist ./dist
|
|
COPY --from=builder /app/node_modules ./node_modules
|
|
|
|
USER nodejs
|
|
|
|
EXPOSE 5001
|
|
|
|
CMD ["node", "dist/index.js"]
|
|
```
|
|
|
|
---
|
|
|
|
## 📦 Production docker-compose.yml (Using Gitea Registry)
|
|
|
|
```yaml
|
|
version: '3.9'
|
|
|
|
networks:
|
|
harborsmith:
|
|
driver: bridge
|
|
|
|
volumes:
|
|
postgres_data:
|
|
minio_data:
|
|
keycloak_data:
|
|
redis_data:
|
|
|
|
services:
|
|
# ===== FRONTEND =====
|
|
web:
|
|
image: gitea.yourdomain.com/harborsmith/web:latest
|
|
container_name: harborsmith-web
|
|
restart: unless-stopped
|
|
ports:
|
|
- "3000:3000"
|
|
env_file:
|
|
- .env.production
|
|
depends_on:
|
|
- api
|
|
- keycloak
|
|
networks:
|
|
- harborsmith
|
|
|
|
# ===== API GATEWAY =====
|
|
api:
|
|
image: gitea.yourdomain.com/harborsmith/api:latest
|
|
container_name: harborsmith-api
|
|
restart: unless-stopped
|
|
ports:
|
|
- "4000:4000"
|
|
env_file:
|
|
- .env.production
|
|
depends_on:
|
|
- postgres
|
|
- redis
|
|
- keycloak
|
|
networks:
|
|
- harborsmith
|
|
|
|
# ===== MICROSERVICES =====
|
|
charter-service:
|
|
image: gitea.yourdomain.com/harborsmith/charter:latest
|
|
container_name: harborsmith-charter
|
|
restart: unless-stopped
|
|
env_file:
|
|
- .env.production
|
|
depends_on:
|
|
- postgres
|
|
- redis
|
|
networks:
|
|
- harborsmith
|
|
|
|
maintenance-service:
|
|
image: gitea.yourdomain.com/harborsmith/maintenance:latest
|
|
container_name: harborsmith-maintenance
|
|
restart: unless-stopped
|
|
env_file:
|
|
- .env.production
|
|
depends_on:
|
|
- postgres
|
|
- redis
|
|
networks:
|
|
- harborsmith
|
|
|
|
payment-service:
|
|
image: gitea.yourdomain.com/harborsmith/payments:latest
|
|
container_name: harborsmith-payments
|
|
restart: unless-stopped
|
|
env_file:
|
|
- .env.production
|
|
depends_on:
|
|
- postgres
|
|
networks:
|
|
- harborsmith
|
|
|
|
notification-service:
|
|
image: gitea.yourdomain.com/harborsmith/notifications:latest
|
|
container_name: harborsmith-notifications
|
|
restart: unless-stopped
|
|
env_file:
|
|
- .env.production
|
|
networks:
|
|
- harborsmith
|
|
|
|
# ===== INFRASTRUCTURE SERVICES =====
|
|
# (These use public images, not built from source)
|
|
postgres:
|
|
image: supabase/postgres:15.1.0.117
|
|
container_name: harborsmith-db
|
|
restart: unless-stopped
|
|
ports:
|
|
- "5432:5432"
|
|
env_file:
|
|
- .env.production
|
|
volumes:
|
|
- postgres_data:/var/lib/postgresql/data
|
|
- ./migrations:/docker-entrypoint-initdb.d:ro
|
|
networks:
|
|
- harborsmith
|
|
|
|
redis:
|
|
image: redis:7-alpine
|
|
container_name: harborsmith-redis
|
|
restart: unless-stopped
|
|
ports:
|
|
- "6379:6379"
|
|
volumes:
|
|
- redis_data:/data
|
|
networks:
|
|
- harborsmith
|
|
|
|
keycloak:
|
|
image: quay.io/keycloak/keycloak:23.0
|
|
container_name: harborsmith-keycloak
|
|
restart: unless-stopped
|
|
ports:
|
|
- "8080:8080"
|
|
env_file:
|
|
- .env.production
|
|
volumes:
|
|
- keycloak_data:/opt/keycloak/data
|
|
depends_on:
|
|
- postgres
|
|
networks:
|
|
- harborsmith
|
|
|
|
minio:
|
|
image: minio/minio:latest
|
|
container_name: harborsmith-minio
|
|
restart: unless-stopped
|
|
ports:
|
|
- "9000:9000"
|
|
- "9001:9001"
|
|
env_file:
|
|
- .env.production
|
|
volumes:
|
|
- minio_data:/data
|
|
command: server /data --console-address ":9001"
|
|
networks:
|
|
- harborsmith
|
|
|
|
# Additional services as defined in main implementation plan...
|
|
```
|
|
|
|
---
|
|
|
|
## 🔄 Deployment Workflow
|
|
|
|
### 1. Initial Setup on Production Server
|
|
```bash
|
|
# On your production server
|
|
# 1. Install Docker and Docker Compose
|
|
curl -fsSL https://get.docker.com -o get-docker.sh
|
|
sh get-docker.sh
|
|
apt-get install docker-compose-plugin
|
|
|
|
# 2. Create project directory
|
|
mkdir -p /opt/harborsmith
|
|
cd /opt/harborsmith
|
|
|
|
# 3. Login to Gitea Registry
|
|
docker login gitea.yourdomain.com
|
|
|
|
# 4. Clone deployment files (not full source)
|
|
git clone https://gitea.yourdomain.com/harborsmith/deployment.git .
|
|
```
|
|
|
|
### 2. Deployment Script (deploy.sh)
|
|
```bash
|
|
#!/bin/bash
|
|
# HarborSmith Deployment Script
|
|
|
|
set -e
|
|
|
|
echo "🚀 Starting HarborSmith deployment..."
|
|
|
|
# Configuration
|
|
GITEA_REGISTRY="gitea.yourdomain.com"
|
|
PROJECT="harborsmith"
|
|
ENVIRONMENT=${1:-production}
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Function to print colored output
|
|
print_status() {
|
|
echo -e "${GREEN}✓${NC} $1"
|
|
}
|
|
|
|
print_error() {
|
|
echo -e "${RED}✗${NC} $1"
|
|
}
|
|
|
|
print_warning() {
|
|
echo -e "${YELLOW}⚠${NC} $1"
|
|
}
|
|
|
|
# 1. Login to Gitea Registry
|
|
print_status "Logging into Gitea Registry..."
|
|
docker login ${GITEA_REGISTRY}
|
|
|
|
# 2. Pull latest images
|
|
print_status "Pulling latest images..."
|
|
SERVICES="web api charter maintenance payments notifications"
|
|
for SERVICE in $SERVICES; do
|
|
print_status "Pulling ${SERVICE}..."
|
|
docker pull ${GITEA_REGISTRY}/${PROJECT}/${SERVICE}:latest
|
|
done
|
|
|
|
# 3. Backup database (optional but recommended)
|
|
if [ "$ENVIRONMENT" = "production" ]; then
|
|
print_warning "Backing up database..."
|
|
docker exec harborsmith-db pg_dump -U postgres harborsmith > backup-$(date +%Y%m%d-%H%M%S).sql
|
|
fi
|
|
|
|
# 4. Stop running containers
|
|
print_status "Stopping current containers..."
|
|
docker-compose down
|
|
|
|
# 5. Start new containers
|
|
print_status "Starting new containers..."
|
|
docker-compose up -d
|
|
|
|
# 6. Run migrations
|
|
print_status "Running database migrations..."
|
|
docker exec harborsmith-db psql -U postgres -d harborsmith -f /docker-entrypoint-initdb.d/migrate.sql
|
|
|
|
# 7. Health checks
|
|
print_status "Performing health checks..."
|
|
sleep 10
|
|
|
|
# Check if services are running
|
|
HEALTH_CHECK_FAILED=0
|
|
for SERVICE in $SERVICES; do
|
|
if docker ps | grep -q "harborsmith-${SERVICE}"; then
|
|
print_status "${SERVICE} is running"
|
|
else
|
|
print_error "${SERVICE} is not running"
|
|
HEALTH_CHECK_FAILED=1
|
|
fi
|
|
done
|
|
|
|
# 8. Cleanup old images
|
|
print_status "Cleaning up old images..."
|
|
docker image prune -f
|
|
|
|
if [ $HEALTH_CHECK_FAILED -eq 0 ]; then
|
|
print_status "Deployment completed successfully! 🎉"
|
|
echo ""
|
|
echo "Services available at:"
|
|
echo " - Web: http://localhost:3000"
|
|
echo " - API: http://localhost:4000"
|
|
echo " - Keycloak: http://localhost:8080"
|
|
echo " - MinIO: http://localhost:9001"
|
|
else
|
|
print_error "Deployment completed with errors. Please check the logs."
|
|
exit 1
|
|
fi
|
|
```
|
|
|
|
---
|
|
|
|
## 🛠️ Makefile for Common Operations
|
|
|
|
```makefile
|
|
# HarborSmith Makefile
|
|
.PHONY: help build push deploy logs restart clean
|
|
|
|
# Variables
|
|
GITEA_REGISTRY := gitea.yourdomain.com
|
|
PROJECT := harborsmith
|
|
VERSION := $(shell git describe --tags --always --dirty)
|
|
BRANCH := $(shell git rev-parse --abbrev-ref HEAD)
|
|
|
|
help: ## Show this help
|
|
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'
|
|
|
|
build: ## Build all Docker images locally
|
|
docker-compose -f docker-compose.build.yml build
|
|
|
|
build-web: ## Build web service
|
|
docker build -t $(GITEA_REGISTRY)/$(PROJECT)/web:$(VERSION) ./apps/web
|
|
|
|
build-api: ## Build API service
|
|
docker build -t $(GITEA_REGISTRY)/$(PROJECT)/api:$(VERSION) ./apps/api
|
|
|
|
push: ## Push all images to Gitea registry
|
|
docker push $(GITEA_REGISTRY)/$(PROJECT)/web:$(VERSION)
|
|
docker push $(GITEA_REGISTRY)/$(PROJECT)/api:$(VERSION)
|
|
docker push $(GITEA_REGISTRY)/$(PROJECT)/charter:$(VERSION)
|
|
docker push $(GITEA_REGISTRY)/$(PROJECT)/maintenance:$(VERSION)
|
|
docker push $(GITEA_REGISTRY)/$(PROJECT)/payments:$(VERSION)
|
|
docker push $(GITEA_REGISTRY)/$(PROJECT)/notifications:$(VERSION)
|
|
|
|
deploy: ## Deploy to production
|
|
ssh production-server 'cd /opt/harborsmith && ./deploy.sh'
|
|
|
|
deploy-staging: ## Deploy to staging
|
|
ssh staging-server 'cd /opt/harborsmith && ./deploy.sh staging'
|
|
|
|
logs: ## Show logs from all services
|
|
docker-compose logs -f
|
|
|
|
logs-web: ## Show logs from web service
|
|
docker-compose logs -f web
|
|
|
|
restart: ## Restart all services
|
|
docker-compose restart
|
|
|
|
restart-web: ## Restart web service
|
|
docker-compose restart web
|
|
|
|
clean: ## Clean up Docker resources
|
|
docker system prune -f
|
|
docker volume prune -f
|
|
|
|
backup: ## Backup database
|
|
docker exec harborsmith-db pg_dump -U postgres harborsmith > backups/backup-$(shell date +%Y%m%d-%H%M%S).sql
|
|
|
|
restore: ## Restore database from latest backup
|
|
docker exec -i harborsmith-db psql -U postgres harborsmith < $(shell ls -t backups/*.sql | head -1)
|
|
|
|
dev: ## Start development environment
|
|
docker-compose -f docker-compose.dev.yml up
|
|
|
|
test: ## Run tests in containers
|
|
docker-compose -f docker-compose.test.yml up --abort-on-container-exit
|
|
|
|
migrate: ## Run database migrations
|
|
docker exec harborsmith-db psql -U postgres -d harborsmith -f /docker-entrypoint-initdb.d/migrate.sql
|
|
```
|
|
|
|
---
|
|
|
|
## 🔐 Gitea Repository Secrets
|
|
|
|
Configure these secrets in your Gitea repository settings:
|
|
|
|
```yaml
|
|
REGISTRY_USERNAME: harborsmith-bot
|
|
REGISTRY_PASSWORD: [secure-token]
|
|
PRODUCTION_HOST: production.harborsmith.com
|
|
STAGING_HOST: staging.harborsmith.com
|
|
SSH_PRIVATE_KEY: [deployment-key]
|
|
```
|
|
|
|
---
|
|
|
|
## 📝 .dockerignore
|
|
|
|
```dockerignore
|
|
# Dependencies
|
|
node_modules
|
|
npm-debug.log
|
|
yarn-error.log
|
|
.pnpm-store
|
|
|
|
# Next.js
|
|
.next
|
|
out
|
|
build
|
|
dist
|
|
|
|
# Testing
|
|
coverage
|
|
.nyc_output
|
|
|
|
# Environment
|
|
.env
|
|
.env.*
|
|
!.env.example
|
|
|
|
# Git
|
|
.git
|
|
.gitignore
|
|
.gitea
|
|
|
|
# Documentation
|
|
*.md
|
|
docs
|
|
|
|
# IDE
|
|
.vscode
|
|
.idea
|
|
*.swp
|
|
*.swo
|
|
|
|
# OS
|
|
.DS_Store
|
|
Thumbs.db
|
|
|
|
# Development
|
|
.docker
|
|
docker-compose.dev.yml
|
|
docker-compose.test.yml
|
|
|
|
# Temporary files
|
|
tmp
|
|
temp
|
|
*.tmp
|
|
```
|
|
|
|
---
|
|
|
|
## 🚀 Complete Workflow Example
|
|
|
|
### 1. Developer pushes code to Gitea
|
|
```bash
|
|
git add .
|
|
git commit -m "feat: add vessel booking feature"
|
|
git push origin develop
|
|
```
|
|
|
|
### 2. Gitea Actions automatically:
|
|
- Runs tests
|
|
- Builds Docker images
|
|
- Tags with branch name and commit SHA
|
|
- Pushes to Gitea container registry
|
|
|
|
### 3. Deploy to staging
|
|
```bash
|
|
make deploy-staging
|
|
# OR manually:
|
|
ssh staging-server
|
|
cd /opt/harborsmith
|
|
docker-compose pull
|
|
docker-compose up -d
|
|
```
|
|
|
|
### 4. Deploy to production (after testing)
|
|
```bash
|
|
git checkout main
|
|
git merge develop
|
|
git tag v1.2.0
|
|
git push origin main --tags
|
|
|
|
# Gitea Actions builds production images
|
|
make deploy
|
|
```
|
|
|
|
---
|
|
|
|
## 📊 Monitoring Container Health
|
|
|
|
### Health Check Script (healthcheck.sh)
|
|
```bash
|
|
#!/bin/bash
|
|
# Container health monitoring
|
|
|
|
SERVICES=("web" "api" "charter" "maintenance" "payments" "notifications")
|
|
WEBHOOK_URL="https://your-monitoring-webhook.com"
|
|
|
|
for service in "${SERVICES[@]}"; do
|
|
if ! docker exec harborsmith-${service} curl -f http://localhost:${PORT}/health > /dev/null 2>&1; then
|
|
curl -X POST ${WEBHOOK_URL} \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"service\": \"${service}\", \"status\": \"unhealthy\", \"timestamp\": \"$(date -Iseconds)\"}"
|
|
|
|
# Attempt restart
|
|
docker-compose restart ${service}
|
|
fi
|
|
done
|
|
```
|
|
|
|
---
|
|
|
|
## 🔄 Rolling Updates
|
|
|
|
For zero-downtime deployments:
|
|
|
|
```yaml
|
|
# docker-compose.production.yml
|
|
services:
|
|
web:
|
|
image: gitea.yourdomain.com/harborsmith/web:latest
|
|
deploy:
|
|
replicas: 2
|
|
update_config:
|
|
parallelism: 1
|
|
delay: 10s
|
|
order: start-first
|
|
restart_policy:
|
|
condition: any
|
|
delay: 5s
|
|
max_attempts: 3
|
|
```
|
|
|
|
---
|
|
|
|
## ✅ Deployment Checklist
|
|
|
|
- [ ] Gitea repository created
|
|
- [ ] Container registry enabled in Gitea
|
|
- [ ] Gitea Actions configured
|
|
- [ ] Secrets added to repository
|
|
- [ ] Production server has Docker installed
|
|
- [ ] Registry credentials configured on server
|
|
- [ ] Environment files prepared
|
|
- [ ] SSL certificates ready
|
|
- [ ] Database backups scheduled
|
|
- [ ] Monitoring configured
|
|
- [ ] Rollback plan documented
|
|
|
|
---
|
|
|
|
## 🆘 Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
1. **Image pull authentication failed**
|
|
```bash
|
|
docker logout gitea.yourdomain.com
|
|
docker login gitea.yourdomain.com
|
|
```
|
|
|
|
2. **Container fails to start**
|
|
```bash
|
|
docker logs harborsmith-web
|
|
docker-compose down
|
|
docker-compose up -d
|
|
```
|
|
|
|
3. **Database connection issues**
|
|
```bash
|
|
docker exec harborsmith-db pg_isready
|
|
docker-compose restart postgres
|
|
```
|
|
|
|
4. **Build cache issues**
|
|
```bash
|
|
docker builder prune -a
|
|
docker-compose build --no-cache
|
|
```
|
|
|
|
---
|
|
|
|
*This workflow ensures automated, reliable deployments from your Gitea repository to production Docker containers.*
|