# Server Setup Guide - KLZ Cables

This guide explains how to set up the production environment on the deployment server.

## Prerequisites

- Server: `alpha.mintel.me`
- User: `deploy` (with sudo access)
- Docker and Docker Compose installed
- Traefik reverse proxy running
- External network `infra` created

## Initial Server Setup

### 1. Create Project Directory

```bash
# SSH to the server as root or deploy user
ssh root@alpha.mintel.me

# Create project directory
mkdir -p /home/deploy/sites/klz-cables.com
cd /home/deploy/sites/klz-cables.com
```

### 2. Create Environment File

Create the `.env` file with production configuration:

```bash
# Create .env file from template
cat > /home/deploy/sites/klz-cables.com/.env << 'EOF'
# ============================================================================
# KLZ Cables - Production Environment Configuration
# ============================================================================

# Application
NODE_ENV=production
NEXT_PUBLIC_BASE_URL=https://klz-cables.com

# Analytics (Umami)
NEXT_PUBLIC_UMAMI_WEBSITE_ID=your-umami-website-id
NEXT_PUBLIC_UMAMI_SCRIPT_URL=https://analytics.infra.mintel.me/script.js

# Error Tracking (GlitchTip/Sentry)
SENTRY_DSN=https://your-sentry-dsn@errors.infra.mintel.me/project-id

# Email Configuration (Mailgun)
MAIL_HOST=smtp.eu.mailgun.org
MAIL_PORT=587
MAIL_USERNAME=your-mailgun-username
MAIL_PASSWORD=your-mailgun-password
MAIL_FROM=KLZ Cables <noreply@klz-cables.com>
MAIL_RECIPIENTS=info@klz-cables.com

# Redis Cache
REDIS_URL=redis://redis:6379/2
REDIS_KEY_PREFIX=klz:
EOF
```

**Important**: Replace all placeholder values with actual production credentials.

### 3. Secure the Environment File

```bash
# Set proper permissions (readable only by owner)
chmod 600 /home/deploy/sites/klz-cables.com/.env

# Verify ownership
chown deploy:deploy /home/deploy/sites/klz-cables.com/.env

# Verify permissions
ls -la /home/deploy/sites/klz-cables.com/.env
# Should show: -rw------- 1 deploy deploy
```

### 4. Create Docker Compose File

```bash
# Copy docker-compose.yml from repository
# This should be done automatically by the deployment script
# Or manually:
cat > /home/deploy/sites/klz-cables.com/docker-compose.yml << 'EOF'
services:
  app:
    image: registry.infra.mintel.me/mintel/klz-cables.com:latest
    restart: always
    networks:
      - infra
    ports:
      - "3000:3000"
    env_file:
      - .env
    healthcheck:
      test: ["CMD-SHELL", "wget --quiet --tries=1 --spider http://localhost:3000/health || wget --quiet --tries=1 --spider http://localhost:3000/ || true"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.klz-cables-web.rule=(Host(`klz-cables.com`) || Host(`www.klz-cables.com`) || Host(`staging.klz-cables.com`)) && !PathPrefix(`/.well-known/acme-challenge/`)"
      - "traefik.http.routers.klz-cables-web.entrypoints=web"
      - "traefik.http.routers.klz-cables-web.middlewares=redirect-https"
      - "traefik.http.routers.klz-cables.rule=Host(`klz-cables.com`) || Host(`www.klz-cables.com`) || Host(`staging.klz-cables.com`)"
      - "traefik.http.routers.klz-cables.entrypoints=websecure"
      - "traefik.http.routers.klz-cables.tls.certresolver=le"
      - "traefik.http.routers.klz-cables.tls=true"
      - "traefik.http.routers.klz-cables.service=klz-cables"
      - "traefik.http.services.klz-cables.loadbalancer.server.port=3000"
      - "traefik.http.services.klz-cables.loadbalancer.server.scheme=http"
      - "traefik.http.middlewares.klz-forward.headers.customrequestheaders.X-Forwarded-Proto=https"
      - "traefik.http.middlewares.klz-forward.headers.customrequestheaders.X-Forwarded-Ssl=on"
      - "traefik.http.routers.klz-cables.middlewares=klz-forward,compress"

networks:
  infra:
    external: true
EOF
```

### 5. Create Deployment Script

```bash
cat > /home/deploy/deploy.sh << 'EOF'
#!/bin/bash
set -e

PROJECT_DIR="/home/deploy/sites/klz-cables.com"

echo "╔══════════════════════════════════════════════════════════════════════════════╗"
echo "║ KLZ Cables - Deployment Script                                               ║"
echo "╚══════════════════════════════════════════════════════════════════════════════╝"
echo ""

cd "$PROJECT_DIR"

# Check if .env file exists
if [ ! -f .env ]; then
    echo "❌ ERROR: .env file not found at $PROJECT_DIR/.env"
    echo "Please create the .env file before deploying."
    exit 1
fi

echo "🔐 Logging into Docker registry..."
echo "$REGISTRY_PASS" | docker login registry.infra.mintel.me -u "$REGISTRY_USER" --password-stdin

echo "🔄 Pulling latest image..."
docker pull registry.infra.mintel.me/mintel/klz-cables.com:latest

echo "🔄 Stopping existing containers..."
docker-compose down

echo "🚀 Starting new containers..."
docker-compose up -d

echo "⏳ Waiting for services to be healthy..."
sleep 10

echo "🔍 Checking service status..."
docker-compose ps

echo ""
echo "✅ Deployment complete!"
echo ""
echo "📊 Service URLs:"
echo "  • Production: https://klz-cables.com"
echo "  • Staging: https://staging.klz-cables.com"
echo ""
EOF

# Make script executable
chmod +x /home/deploy/deploy.sh
```

### 6. Configure Docker Registry Access

The deployment script needs registry credentials. These are passed as environment variables from the CI/CD workflow:

```bash
# The workflow passes these variables:
# REGISTRY_USER - from Gitea secrets
# REGISTRY_PASS - from Gitea secrets
```

## Verification

### Check Environment File

```bash
# Verify .env file exists and has correct permissions
ls -la /home/deploy/sites/klz-cables.com/.env

# Check content (be careful not to expose secrets in logs)
head -n 5 /home/deploy/sites/klz-cables.com/.env
```

### Test Deployment Script

```bash
# Run deployment script manually (requires registry credentials)
REGISTRY_USER=your-user REGISTRY_PASS=your-pass /home/deploy/deploy.sh
```

### Check Running Containers

```bash
cd /home/deploy/sites/klz-cables.com
docker-compose ps
docker-compose logs -f app
```

### Verify Environment Variables in Container

```bash
# Check that environment variables are loaded
docker-compose exec app env | grep -E "NODE_ENV|NEXT_PUBLIC|MAIL|REDIS"
```

## Updating Environment Variables

When you need to update environment variables:

```bash
# 1. SSH to the server
ssh root@alpha.mintel.me

# 2. Edit the .env file
nano /home/deploy/sites/klz-cables.com/.env

# 3. Restart the containers to pick up changes
cd /home/deploy/sites/klz-cables.com
docker-compose down
docker-compose up -d

# 4. Verify the changes
docker-compose logs -f app
```

**Note**: Changes to `NEXT_PUBLIC_*` variables require rebuilding the Docker image, as they are baked into the client bundle at build time.

## Troubleshooting

### .env File Not Found

```bash
# Check if file exists
ls -la /home/deploy/sites/klz-cables.com/.env

# If missing, create it from template
cp .env.production /home/deploy/sites/klz-cables.com/.env
# Then edit with actual values
```

### Permission Denied

```bash
# Fix ownership
chown -R deploy:deploy /home/deploy/sites/klz-cables.com

# Fix .env permissions
chmod 600 /home/deploy/sites/klz-cables.com/.env
```

### Container Won't Start

```bash
# Check logs
docker-compose logs app

# Check if .env is loaded
docker-compose config

# Verify environment variables
docker-compose exec app env
```

### Network Issues

```bash
# Verify infra network exists
docker network ls | grep infra

# If missing, create it
docker network create infra
```

## Security Checklist

- [ ] `.env` file has `600` permissions (readable only by owner)
- [ ] `.env` file is owned by `deploy:deploy`
- [ ] `.env` file is NOT in git repository
- [ ] All sensitive credentials are filled in
- [ ] SSH keys are properly secured
- [ ] Firewall rules are configured
- [ ] HTTPS is enforced via Traefik
- [ ] Regular backups of `.env` file are maintained

## Backup

Create a secure backup of the environment file:

```bash
# Backup .env file
cp /home/deploy/sites/klz-cables.com/.env \
   /home/deploy/backups/klz-cables.env.$(date +%Y%m%d)

# Set proper permissions on backup
chmod 600 /home/deploy/backups/klz-cables.env.*
```

## Additional Resources

- [Deployment Guide](./DEPLOYMENT.md)
- [Docker Compose Documentation](https://docs.docker.com/compose/)
- [Traefik Documentation](https://doc.traefik.io/traefik/)
