diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..51c2c10 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,43 @@ +name: OpenClimb Docker Deploy +on: + push: + branches: [main] + paths: + - "sync/**" + - ".github/workflows/deploy.yml" + pull_request: + branches: [main] + paths: + - "sync/**" + - ".github/workflows/deploy.yml" + +jobs: + build-and-push: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Login to Container Registry + uses: docker/login-action@v2 + with: + registry: ${{ secrets.REPO_HOST }} + username: ${{ github.repository_owner }} + password: ${{ secrets.DEPLOY_TOKEN }} + + - name: Build and push sync-server + uses: docker/build-push-action@v4 + with: + context: ./sync + file: ./sync/Dockerfile + platforms: linux/amd64 + push: true + tags: | + ${{ secrets.REPO_HOST }}/${{ github.repository_owner }}/openclimb-sync-server:${{ github.sha }} + ${{ secrets.REPO_HOST }}/${{ github.repository_owner }}/openclimb-sync-server:latest diff --git a/ios/OpenClimb.xcodeproj/project.xcworkspace/xcuserdata/atridad.xcuserdatad/UserInterfaceState.xcuserstate b/ios/OpenClimb.xcodeproj/project.xcworkspace/xcuserdata/atridad.xcuserdatad/UserInterfaceState.xcuserstate index de72ced..63a5df0 100644 Binary files a/ios/OpenClimb.xcodeproj/project.xcworkspace/xcuserdata/atridad.xcuserdatad/UserInterfaceState.xcuserstate and b/ios/OpenClimb.xcodeproj/project.xcworkspace/xcuserdata/atridad.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/sync-server/DEPLOY.md b/sync-server/DEPLOY.md new file mode 100644 index 0000000..b34440d --- /dev/null +++ b/sync-server/DEPLOY.md @@ -0,0 +1,303 @@ +# OpenClimb Sync Server Deployment Guide + +This guide covers deploying the OpenClimb Sync Server using the automated Docker build and deployment system. + +## Overview + +The sync server is automatically built into a Docker container via GitHub Actions and can be deployed to any Docker-compatible environment. + +## Prerequisites + +- Docker and Docker Compose installed +- Access to the container registry (configured in GitHub secrets) +- Basic understanding of Docker deployments + +## Quick Start + +### 1. Automated Deployment (Recommended) + +```bash +# Clone the repository +git clone +cd OpenClimb/sync-server + +# Run the deployment script +./deploy.sh +``` + +The script will: +- Create necessary directories +- Pull the latest container image +- Stop any existing containers +- Start the new container +- Verify deployment success + +### 2. Manual Deployment + +```bash +# Pull the latest image +docker pull your-registry.com/username/openclimb-sync-server:latest + +# Create environment file +cp .env.example .env.prod +# Edit .env.prod with your configuration + +# Deploy with docker-compose +docker-compose -f docker-compose.prod.yml up -d +``` + +## Configuration + +### Environment Variables + +Create a `.env.prod` file with the following variables: + +```bash +# Container registry settings +REPO_HOST=your-registry.example.com +REPO_OWNER=your-username + +# Server configuration +AUTH_TOKEN=your-secure-auth-token-here-make-it-long-and-random +PORT=8080 + +# Optional: Custom domain (for Traefik) +TRAEFIK_HOST=sync.openclimb.example.com +``` + +### Required Secrets (GitHub) + +Configure these secrets in your GitHub repository settings: + +- `REPO_HOST`: Your container registry hostname +- `DEPLOY_TOKEN`: Authentication token for the registry + +## Container Build Process + +The GitHub Action (`sync-server-deploy.yml`) automatically: + +1. **Triggers on:** + - Push to `main` branch (when sync-server files change) + - Pull requests to `main` branch + +2. **Build Process:** + - Uses multi-stage Docker build + - Compiles Go binary in builder stage + - Creates minimal Alpine-based runtime image + - Pushes to container registry with tags: + - `latest` (always points to newest) + - `` (specific version) + +3. **Caching:** + - Uses GitHub Actions cache for faster builds + - Incremental builds when possible + +## Deployment Options + +### Option 1: Simple Docker Run +```bash +docker run -d \ + --name openclimb-sync-server \ + -p 8080:8080 \ + -v $(pwd)/data:/root/data \ + -e AUTH_TOKEN=your-token-here \ + your-registry.com/username/openclimb-sync-server:latest +``` + +### Option 2: Docker Compose (Recommended) +```bash +docker-compose -f docker-compose.prod.yml up -d +``` + +### Option 3: Kubernetes +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: openclimb-sync-server +spec: + replicas: 1 + selector: + matchLabels: + app: openclimb-sync-server + template: + metadata: + labels: + app: openclimb-sync-server + spec: + containers: + - name: sync-server + image: your-registry.com/username/openclimb-sync-server:latest + ports: + - containerPort: 8080 + env: + - name: AUTH_TOKEN + valueFrom: + secretKeyRef: + name: openclimb-secrets + key: auth-token + volumeMounts: + - name: data-volume + mountPath: /root/data + volumes: + - name: data-volume + persistentVolumeClaim: + claimName: openclimb-data +``` + +## Data Persistence + +The sync server stores data in `/root/data` inside the container. **Always mount a volume** to preserve data: + +```bash +# Local directory mounting +-v $(pwd)/data:/root/data + +# Named volume (recommended for production) +-v openclimb-data:/root/data +``` + +### Data Structure +``` +data/ +├── climb_data.json # Main sync data +├── images/ # Uploaded images +│ ├── problem_*.jpg +│ └── ... +└── logs/ # Server logs (optional) +``` + +## Monitoring and Maintenance + +### Health Check +```bash +curl http://localhost:8080/health +``` + +### View Logs +```bash +# Docker Compose +docker-compose -f docker-compose.prod.yml logs -f + +# Direct Docker +docker logs -f openclimb-sync-server +``` + +### Update to Latest Version +```bash +# Using deploy script +./deploy.sh + +# Manual update +docker-compose -f docker-compose.prod.yml pull +docker-compose -f docker-compose.prod.yml up -d +``` + +## Reverse Proxy Setup (Optional) + +### Nginx +```nginx +server { + listen 80; + server_name sync.openclimb.example.com; + + location / { + proxy_pass http://localhost:8080; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} +``` + +### Traefik (Labels included in docker-compose.prod.yml) +```yaml +labels: + - "traefik.enable=true" + - "traefik.http.routers.openclimb-sync.rule=Host(`sync.openclimb.example.com`)" + - "traefik.http.routers.openclimb-sync.tls.certresolver=letsencrypt" +``` + +## Security Considerations + +1. **AUTH_TOKEN**: Use a long, random token (32+ characters) +2. **HTTPS**: Always use HTTPS in production (via reverse proxy) +3. **Firewall**: Only expose port 8080 to your reverse proxy, not publicly +4. **Updates**: Regularly update to the latest container image +5. **Backups**: Regularly backup the `data/` directory + +## Troubleshooting + +### Container Won't Start +```bash +# Check logs +docker logs openclimb-sync-server + +# Common issues: +# - Missing AUTH_TOKEN environment variable +# - Port 8080 already in use +# - Insufficient permissions on data directory +``` + +### Sync Fails from Mobile Apps +```bash +# Verify server is accessible +curl -H "Authorization: Bearer your-token" http://your-server:8080/sync + +# Check server logs for authentication errors +docker logs openclimb-sync-server | grep "401\|403" +``` + +### Image Upload Issues +```bash +# Check disk space +df -h + +# Verify data directory permissions +ls -la data/ +``` + +## Performance Tuning + +For high-load deployments: + +```yaml +# docker-compose.prod.yml +services: + openclimb-sync-server: + deploy: + resources: + limits: + memory: 512M + cpus: '0.5' + reservations: + memory: 256M + cpus: '0.25' +``` + +## Backup Strategy + +```bash +#!/bin/bash +# backup.sh - Run daily via cron + +DATE=$(date +%Y%m%d_%H%M%S) +BACKUP_DIR="/backups/openclimb" + +# Create backup directory +mkdir -p "$BACKUP_DIR" + +# Backup data directory +tar -czf "$BACKUP_DIR/openclimb_data_$DATE.tar.gz" \ + -C /path/to/sync-server data/ + +# Keep only last 30 days +find "$BACKUP_DIR" -name "openclimb_data_*.tar.gz" -mtime +30 -delete +``` + +## Support + +- **Issues**: Create an issue in the GitHub repository +- **Documentation**: Check the main OpenClimb README +- **Logs**: Always diff --git a/sync-server/.env.example b/sync/.env.example similarity index 100% rename from sync-server/.env.example rename to sync/.env.example diff --git a/sync-server/.gitignore b/sync/.gitignore similarity index 100% rename from sync-server/.gitignore rename to sync/.gitignore diff --git a/sync-server/Dockerfile b/sync/Dockerfile similarity index 100% rename from sync-server/Dockerfile rename to sync/Dockerfile diff --git a/sync-server/docker-compose.yml b/sync/docker-compose.yml similarity index 90% rename from sync-server/docker-compose.yml rename to sync/docker-compose.yml index b1bb740..ca7977d 100644 --- a/sync-server/docker-compose.yml +++ b/sync/docker-compose.yml @@ -1,8 +1,6 @@ -version: "3.8" - services: openclimb-sync: - build: . + image: ${IMAGE} ports: - "8080:8080" environment: diff --git a/sync-server/go.mod b/sync/go.mod similarity index 100% rename from sync-server/go.mod rename to sync/go.mod diff --git a/sync-server/main.go b/sync/main.go similarity index 100% rename from sync-server/main.go rename to sync/main.go diff --git a/sync-server/run.sh b/sync/run.sh similarity index 100% rename from sync-server/run.sh rename to sync/run.sh diff --git a/sync/version.md b/sync/version.md new file mode 100644 index 0000000..3eefcb9 --- /dev/null +++ b/sync/version.md @@ -0,0 +1 @@ +1.0.0