# Environment Variables Cleanup - Summary

## What Was Done

Cleaned up the fragile, overkill environment variable mess and replaced it with a simple, clean, robust **fully automated** system.

## Changes Made

### 1. Dockerfile ✅
**Before**: 4 build args including runtime-only variables (SENTRY_DSN)
**After**: 3 build args - only `NEXT_PUBLIC_*` variables that need to be baked into the client bundle

```dockerfile
# Only these build args now:
ARG NEXT_PUBLIC_BASE_URL
ARG NEXT_PUBLIC_UMAMI_WEBSITE_ID
ARG NEXT_PUBLIC_UMAMI_SCRIPT_URL
```

### 2. docker-compose.yml ✅
**Before**: 12+ individual environment variables listed
**After**: Single `env_file: .env` directive

```yaml
app:
  image: registry.infra.mintel.me/mintel/klz-cables.com:latest
  env_file:
    - .env  # All runtime vars loaded from here
```

### 3. .gitea/workflows/deploy.yml ✅
**Before**: Passing 12+ environment variables individually via SSH command (fragile!)
**After**: **Fully automated** - workflow creates `.env` file from Gitea secrets and uploads it

```yaml
# Before (FRAGILE):
ssh root@alpha.mintel.me \
  "MAIL_FROM='${{ secrets.MAIL_FROM }}' \
   MAIL_HOST='${{ secrets.MAIL_HOST }}' \
   ... (12+ variables) \
   /home/deploy/deploy.sh"

# After (AUTOMATED):
# 1. Create .env from secrets
cat > /tmp/klz-cables.env << EOF
NODE_ENV=production
NEXT_PUBLIC_BASE_URL=${{ secrets.NEXT_PUBLIC_BASE_URL }}
# ... all other vars from secrets
EOF

# 2. Upload to server
scp /tmp/klz-cables.env root@alpha.mintel.me:/home/deploy/sites/klz-cables.com/.env

# 3. Deploy
ssh root@alpha.mintel.me "cd /home/deploy/sites/klz-cables.com && docker-compose up -d"
```

### 4. New Files Created ✅

- **`.env.production`** - Template for reference (not used in automation)
- **`docs/DEPLOYMENT.md`** - Complete deployment guide
- **`docs/SERVER_SETUP.md`** - Server setup instructions
- **`docs/ENV_MIGRATION.md`** - Migration guide from old to new system

### 5. Updated Files ✅

- **`.env.example`** - Clear documentation of all variables with build-time vs runtime notes

## Architecture

### Build Time (CI/CD)
```
Gitea Workflow
  ↓
  Only passes NEXT_PUBLIC_* as --build-arg
  ↓
Docker Build
  ↓
  Validates env vars
  ↓
  Bakes NEXT_PUBLIC_* into client bundle
  ↓
Push to Registry
```

### Runtime (Production Server) - FULLY AUTOMATED
```
Gitea Secrets
  ↓
  Workflow creates .env file
  ↓
  SCP uploads to server
  ↓
  Secured (chmod 600, chown deploy:deploy)
  ↓
docker-compose.yml (env_file: .env)
  ↓
  Loads .env into container
  ↓
Application runs with full config
```

## Key Benefits

### 1. Simplicity
- **Before**: 15+ Gitea secrets, variables in 3+ places
- **After**: All secrets in Gitea, automatically deployed

### 2. Clarity
- **Before**: Confusing duplication, unclear which vars go where
- **After**: Clear separation - build args vs runtime env file

### 3. Robustness
- **Before**: Fragile SSH command with 12+ inline variables
- **After**: Robust automated file generation and upload

### 4. Security
- **Before**: Secrets potentially exposed in CI logs
- **After**: Secrets masked in logs, .env auto-secured on server

### 5. Maintainability
- **Before**: Update in 3 places (Dockerfile, docker-compose.yml, deploy.yml)
- **After**: Update Gitea secrets only - deployment is automatic

### 6. **Zero Manual Steps** 🎉
- **Before**: Manual .env file creation on server (error-prone, can be forgotten)
- **After**: **Fully automated** - .env file created and uploaded on every deployment

## What You Need to Do

### Required Gitea Secrets

Ensure these secrets are configured in your Gitea repository:

**Build-Time (NEXT_PUBLIC_*):**
- `NEXT_PUBLIC_BASE_URL` - Production URL (e.g., `https://klz-cables.com`)
- `NEXT_PUBLIC_UMAMI_WEBSITE_ID` - Umami analytics ID
- `NEXT_PUBLIC_UMAMI_SCRIPT_URL` - Umami script URL

**Runtime:**
- `SENTRY_DSN` - Error tracking DSN
- `MAIL_HOST` - SMTP server
- `MAIL_PORT` - SMTP port (e.g., `587`)
- `MAIL_USERNAME` - SMTP username
- `MAIL_PASSWORD` - SMTP password
- `MAIL_FROM` - Sender email
- `MAIL_RECIPIENTS` - Recipient emails (comma-separated)

**Infrastructure:**
- `REGISTRY_USER` - Docker registry username
- `REGISTRY_PASS` - Docker registry password
- `ALPHA_SSH_KEY` - SSH private key for deployment server

**Notifications:**
- `GOTIFY_URL` - Gotify notification server URL
- `GOTIFY_TOKEN` - Gotify application token

### That's It!

**No manual steps required.** Just push to main branch and the workflow will:
1. ✅ Build Docker image with NEXT_PUBLIC_* build args
2. ✅ Create .env file from all secrets
3. ✅ Upload .env to server
4. ✅ Secure .env file (600 permissions, deploy:deploy ownership)
5. ✅ Pull latest image
6. ✅ Deploy with docker-compose

## Files Changed

```
Modified:
  ├── Dockerfile                      (removed redundant build args)
  ├── docker-compose.yml              (use env_file instead of individual vars)
  ├── .gitea/workflows/deploy.yml     (automated .env creation & upload)
  ├── .env.example                    (clear documentation)
  ├── lib/services/create-services.ts (removed redundant dotenv usage)
  └── scripts/migrate-*.ts            (removed redundant dotenv usage)

Created:
  ├── .env.production                 (reference template)
  ├── docs/DEPLOYMENT.md              (deployment guide)
  ├── docs/SERVER_SETUP.md            (server setup guide)
  ├── docs/ENV_MIGRATION.md           (migration guide)
  └── ENV_CLEANUP_SUMMARY.md          (this file)
```

## Deployment Flow

```
┌─────────────────────────────────────────────────────────────┐
│ Developer pushes to main branch                             │
└─────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────┐
│ Gitea Workflow Triggered                                    │
│                                                             │
│ 1. Build Docker image (NEXT_PUBLIC_* build args)           │
│ 2. Push to registry                                        │
│ 3. Generate .env from secrets                              │
│ 4. Upload .env to server via SCP                           │
│ 5. SSH to server and deploy                                │
└─────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────┐
│ Production Server                                           │
│                                                             │
│ 1. .env file secured (600, deploy:deploy)                  │
│ 2. Docker login to registry                                │
│ 3. Pull latest image                                       │
│ 4. docker-compose down                                     │
│ 5. docker-compose up -d (loads .env)                       │
│ 6. Health checks pass                                      │
└─────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────┐
│ ✅ Deployment Complete - Gotify Notification Sent          │
└─────────────────────────────────────────────────────────────┘
```

## Comparison: Before vs After

| Aspect | Before | After |
|--------|--------|-------|
| **Gitea Secrets** | 15+ secrets | Same secrets, better organized |
| **Build Args** | 4 vars (including runtime-only) | 3 vars (NEXT_PUBLIC_* only) |
| **Runtime Vars** | Passed via SSH command | Auto-generated .env file |
| **Manual Steps** | ❌ Manual .env creation | ✅ Fully automated |
| **Maintenance** | Update in 3 places | Update Gitea secrets only |
| **Security** | Secrets in CI logs | Secrets masked, .env secured |
| **Clarity** | Confusing duplication | Clear separation |
| **Robustness** | Fragile SSH command | Robust automation |
| **Error-Prone** | ❌ Can forget .env | ✅ Impossible to forget |

## Documentation

- **[DEPLOYMENT.md](docs/DEPLOYMENT.md)** - Complete deployment guide
- **[SERVER_SETUP.md](docs/SERVER_SETUP.md)** - Server setup instructions (mostly automated now)
- **[ENV_MIGRATION.md](docs/ENV_MIGRATION.md)** - Migration from old to new system
- **[.env.example](.env.example)** - Environment variables reference
- **[.env.production](.env.production)** - Production template (for reference)

## Troubleshooting

### Deployment Fails

1. **Check Gitea secrets** - Ensure all required secrets are set
2. **Check workflow logs** - Look for specific error messages
3. **SSH to server** - Verify .env file exists and has correct permissions
4. **Check container logs** - `docker-compose logs -f app`

### .env File Issues

The workflow automatically:
- Creates .env from secrets
- Uploads to server
- Sets 600 permissions
- Sets deploy:deploy ownership

If there are issues, check the workflow logs for the "📝 Preparing environment configuration" step.

### Missing Environment Variables

If a variable is missing:
1. Add it to Gitea secrets
2. Update `.gitea/workflows/deploy.yml` to include it in the .env generation
3. Push to trigger new deployment

---

**Result**: Environment variable management is now simple, clean, robust, and **fully automated**! 🎉

No more manual .env file creation. No more forgotten configuration. No more fragile SSH commands. Just push and deploy!
