docs: restructure documentation into organized folders
Some checks failed
Deploy to Coolify / Code Quality (pull_request) Has been cancelled
Deploy to Coolify / Run Tests (pull_request) Has been cancelled
Deploy to Coolify / Deploy to Development (pull_request) Has been cancelled
Deploy to Coolify / Deploy to Production (pull_request) Has been cancelled
Deploy to Coolify / Deploy to Test (pull_request) Has been cancelled
Pull Request Checks / Validate PR (pull_request) Has been cancelled
Some checks failed
Deploy to Coolify / Code Quality (pull_request) Has been cancelled
Deploy to Coolify / Run Tests (pull_request) Has been cancelled
Deploy to Coolify / Deploy to Development (pull_request) Has been cancelled
Deploy to Coolify / Deploy to Production (pull_request) Has been cancelled
Deploy to Coolify / Deploy to Test (pull_request) Has been cancelled
Pull Request Checks / Validate PR (pull_request) Has been cancelled
Organized docs into logical subdirectories:
**New Structure:**
- docs/
- README.md (index with quick links)
- PROJECT_PLAN.md (root level - main roadmap)
- development/
- getting-started.md (5-min quickstart)
- local-setup.md (detailed Docker Compose guide)
- workflow.md (daily development)
- git-workflow.md (branching strategy)
- architecture/
- overview.md (tech stack, design)
- database.md (schema, RLS, migrations)
- api.md (endpoints, functions)
- deployment/
- production.md (Docker, Coolify)
- ci-cd.md (automated pipelines)
**Cleaned Up:**
- Moved DEV_SETUP.md → docs/development/local-setup.md
- Removed outdated SETUP.md (referenced old Coolify setup)
- Replaced with getting-started.md (current Docker Compose flow)
- Updated README.md links to new structure
All paths tested, no broken links.
This commit is contained in:
311
docs/deployment/ci-cd.md
Normal file
311
docs/deployment/ci-cd.md
Normal file
@@ -0,0 +1,311 @@
|
||||
# Pantry - CI/CD Pipeline
|
||||
|
||||
**Version:** 1.0
|
||||
**Last Updated:** 2026-02-08
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Overview
|
||||
|
||||
Pantry uses **Gitea Actions** for CI/CD, automatically deploying to **Coolify** on push.
|
||||
|
||||
### Workflow Strategy
|
||||
|
||||
```
|
||||
Feature Branch → PR → Code Review → Merge → Auto-Deploy
|
||||
↓
|
||||
PR Checks
|
||||
(no deploy)
|
||||
```
|
||||
|
||||
**Environments:**
|
||||
- **Development** (`develop` branch) → Auto-deploy to dev.pantry
|
||||
- **Production** (`main` branch) → Auto-deploy to pantry
|
||||
- **Test** (manual trigger) → On-demand testing
|
||||
|
||||
---
|
||||
|
||||
## 📋 Workflows
|
||||
|
||||
### 1. `deploy.yml` - Main Deployment Pipeline
|
||||
|
||||
**Triggers:**
|
||||
- Push to `main` → Deploy to production
|
||||
- Push to `develop` → Deploy to development
|
||||
- Pull requests → Run quality checks only
|
||||
|
||||
**Jobs:**
|
||||
|
||||
1. **quality-check** - Runs on all pushes/PRs
|
||||
- Type checking
|
||||
- Linting
|
||||
- Code formatting validation
|
||||
|
||||
2. **test** - Runs unit tests
|
||||
- Unit tests (Vitest)
|
||||
- Integration tests (future)
|
||||
|
||||
3. **deploy-dev** - Development deployment
|
||||
- Trigger: Push to `develop`
|
||||
- Target: Coolify dev environment
|
||||
- Auto-deploy
|
||||
|
||||
4. **deploy-prod** - Production deployment
|
||||
- Trigger: Push to `main`
|
||||
- Target: Coolify production environment
|
||||
- Auto-deploy
|
||||
|
||||
5. **deploy-test** - Test deployment (optional)
|
||||
- Trigger: Manual (`workflow_dispatch`)
|
||||
- Target: Coolify test environment
|
||||
|
||||
### 2. `pr-checks.yml` - Pull Request Validation
|
||||
|
||||
**Triggers:**
|
||||
- Pull requests to `main` or `develop`
|
||||
|
||||
**Jobs:**
|
||||
- Type checking
|
||||
- Linting
|
||||
- Tests
|
||||
- Migration validation
|
||||
- PR summary generation
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Required Secrets
|
||||
|
||||
Configure these in **Gitea Repository Settings → Secrets**:
|
||||
|
||||
### Coolify Webhook URLs
|
||||
|
||||
1. **`COOLIFY_WEBHOOK_DEV`**
|
||||
- Coolify webhook URL for dev environment
|
||||
- Format: `https://coolify.jeanlucmakiola.de/api/v1/deploy/webhooks/{uuid}`
|
||||
|
||||
2. **`COOLIFY_WEBHOOK_PROD`**
|
||||
- Coolify webhook URL for production environment
|
||||
- Same format as above
|
||||
|
||||
3. **`COOLIFY_WEBHOOK_TEST`** (optional)
|
||||
- Coolify webhook URL for test environment
|
||||
|
||||
### How to Get Webhook URLs
|
||||
|
||||
**Via Coolify UI:**
|
||||
1. Go to Coolify → Projects → Pantry
|
||||
2. Select environment (dev/prod/test)
|
||||
3. Click on the resource (application)
|
||||
4. Go to "Webhooks" or "Deploy" tab
|
||||
5. Copy webhook URL
|
||||
|
||||
**Via Coolify API:**
|
||||
```bash
|
||||
source ~/.openclaw/workspace/coolify-helpers.sh
|
||||
COOLIFY_URL=$(grep COOLIFY_URL ~/.coolify-credentials | cut -d= -f2)
|
||||
COOLIFY_TOKEN=$(grep COOLIFY_TOKEN ~/.coolify-credentials | cut -d= -f2)
|
||||
|
||||
# Get application UUID (once created)
|
||||
curl -s -H "Authorization: Bearer $COOLIFY_TOKEN" \
|
||||
"${COOLIFY_URL}/api/v1/applications" | jq '.[] | select(.name | contains("pantry"))'
|
||||
|
||||
# Webhook format:
|
||||
# ${COOLIFY_URL}/api/v1/deploy/webhooks/{application_uuid}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Deployment Flow
|
||||
|
||||
### Development Workflow
|
||||
|
||||
```bash
|
||||
# 1. Create feature branch
|
||||
git checkout -b feature/barcode-scanner
|
||||
|
||||
# 2. Make changes
|
||||
# ... code ...
|
||||
|
||||
# 3. Commit and push
|
||||
git add .
|
||||
git commit -m "feat: Add barcode scanner component"
|
||||
git push origin feature/barcode-scanner
|
||||
|
||||
# 4. Create PR to 'develop'
|
||||
# → PR checks run automatically
|
||||
|
||||
# 5. Merge PR
|
||||
# → Auto-deploys to dev environment
|
||||
```
|
||||
|
||||
### Production Release
|
||||
|
||||
```bash
|
||||
# 1. Ensure develop is stable
|
||||
git checkout develop
|
||||
git pull
|
||||
|
||||
# 2. Create release PR to main
|
||||
git checkout -b release/v0.1.0
|
||||
|
||||
# 3. Update version, changelog
|
||||
# ... updates ...
|
||||
|
||||
# 4. Push and create PR to main
|
||||
git push origin release/v0.1.0
|
||||
# → PR checks run
|
||||
|
||||
# 5. Merge to main
|
||||
# → Auto-deploys to production
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ Coolify Setup (Per Environment)
|
||||
|
||||
### Prerequisites
|
||||
|
||||
Each environment needs:
|
||||
1. **Supabase service** (already configured for dev)
|
||||
2. **Pantry app resource** (to be created)
|
||||
|
||||
### Creating App Resource in Coolify
|
||||
|
||||
**For each environment (dev/prod/test):**
|
||||
|
||||
1. **Go to Coolify → Projects → Pantry → [Environment]**
|
||||
|
||||
2. **Add New Resource:**
|
||||
- Type: **Application**
|
||||
- Source: **Git Repository**
|
||||
|
||||
3. **Configure Git:**
|
||||
- Repository: `https://gitea.jeanlucmakiola.de/pantry-app/pantry.git`
|
||||
- Branch:
|
||||
- Dev: `develop`
|
||||
- Prod: `main`
|
||||
- Test: `develop` (or specific branch)
|
||||
|
||||
4. **Build Configuration:**
|
||||
- Build Pack: **Nixpacks** or **Dockerfile**
|
||||
- Dockerfile Path: `app/Dockerfile` (when created)
|
||||
- Build Command: `bun install && bun run build`
|
||||
- Start Command: `bun run start`
|
||||
|
||||
5. **Environment Variables:**
|
||||
- Import from `.env.development` or `.env.production`
|
||||
- Link to Supabase service environment
|
||||
|
||||
6. **Domain:**
|
||||
- Dev: `pantry-dev.jeanlucmakiola.de`
|
||||
- Prod: `pantry.jeanlucmakiola.de`
|
||||
- Test: `pantry-test.jeanlucmakiola.de`
|
||||
|
||||
7. **Enable Webhook:**
|
||||
- Go to resource → Webhooks
|
||||
- Copy webhook URL
|
||||
- Add to Gitea secrets
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Monitoring Deployments
|
||||
|
||||
### Via Gitea
|
||||
|
||||
- **Actions Tab** in repository
|
||||
- View workflow runs
|
||||
- Check logs for each job
|
||||
|
||||
### Via Coolify
|
||||
|
||||
- **Resources** → Select environment
|
||||
- **Deployments** tab shows history
|
||||
- **Logs** show build/runtime output
|
||||
|
||||
### Manual Trigger (Emergency Deploy)
|
||||
|
||||
```bash
|
||||
# Via Gitea Actions UI
|
||||
# Repository → Actions → deploy.yml → Run workflow
|
||||
|
||||
# Or via webhook directly
|
||||
curl -X POST "https://coolify.jeanlucmakiola.de/api/v1/deploy/webhooks/{uuid}"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Troubleshooting
|
||||
|
||||
### Workflow Not Running
|
||||
|
||||
**Check:**
|
||||
- Gitea Actions is enabled (repo settings)
|
||||
- `.gitea/workflows/` directory exists
|
||||
- YAML syntax is valid
|
||||
|
||||
**Enable Gitea Actions:**
|
||||
```bash
|
||||
# If self-hosted Gitea instance
|
||||
# Check Gitea admin panel → Actions → Enabled
|
||||
```
|
||||
|
||||
### Deployment Failed
|
||||
|
||||
**Check:**
|
||||
1. **Gitea Actions logs** - See which step failed
|
||||
2. **Coolify deployment logs** - Build/runtime errors
|
||||
3. **Environment variables** - Missing/incorrect values
|
||||
4. **Webhook URL** - Correct and accessible
|
||||
|
||||
### Secrets Not Working
|
||||
|
||||
**Verify:**
|
||||
```bash
|
||||
# In Gitea UI:
|
||||
# Repository → Settings → Secrets → Actions
|
||||
# Ensure COOLIFY_WEBHOOK_* secrets exist
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Workflow Status Badges
|
||||
|
||||
Add to `README.md`:
|
||||
|
||||
```markdown
|
||||
[](https://gitea.jeanlucmakiola.de/pantry-app/pantry/actions)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔮 Future Improvements
|
||||
|
||||
### v0.2+
|
||||
- [ ] E2E tests in pipeline (Playwright)
|
||||
- [ ] Database migration validation
|
||||
- [ ] Performance benchmarks
|
||||
- [ ] Lighthouse CI (PWA scores)
|
||||
- [ ] Automatic changelog generation
|
||||
- [ ] Slack/Discord notifications
|
||||
|
||||
### v0.3+
|
||||
- [ ] Staging environment
|
||||
- [ ] Blue-green deployments
|
||||
- [ ] Rollback automation
|
||||
- [ ] Database backup before migrations
|
||||
|
||||
---
|
||||
|
||||
## 📚 References
|
||||
|
||||
- [Gitea Actions Docs](https://docs.gitea.com/usage/actions/overview)
|
||||
- [Coolify Webhooks](https://coolify.io/docs/knowledge-base/git/github/webhooks)
|
||||
- [GitHub Actions Syntax](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions) (compatible with Gitea)
|
||||
|
||||
---
|
||||
|
||||
**Next Steps:**
|
||||
1. Get Coolify webhook URLs for dev/prod
|
||||
2. Add secrets to Gitea repository
|
||||
3. Create Pantry app resources in Coolify
|
||||
4. Test deployment pipeline
|
||||
642
docs/deployment/production.md
Normal file
642
docs/deployment/production.md
Normal file
@@ -0,0 +1,642 @@
|
||||
# Pantry - Deployment Guide
|
||||
|
||||
**Version:** 1.0
|
||||
**Last Updated:** 2026-02-08
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Deployment Options
|
||||
|
||||
### 1. Docker Compose (Recommended)
|
||||
- Single-server deployment
|
||||
- All services in one stack
|
||||
- Easy to self-host
|
||||
|
||||
### 2. Coolify
|
||||
- UI-based deployment
|
||||
- Automatic SSL via Traefik
|
||||
- One-click updates
|
||||
|
||||
### 3. Manual (Advanced)
|
||||
- Custom infrastructure
|
||||
- Kubernetes, etc.
|
||||
|
||||
---
|
||||
|
||||
## 🐳 Docker Compose Deployment
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Docker 24+ & Docker Compose
|
||||
- Domain name (for SSL)
|
||||
- Minimum 2GB RAM
|
||||
- 10GB disk space
|
||||
|
||||
### Quick Deploy
|
||||
|
||||
```bash
|
||||
# Clone repository
|
||||
git clone https://gitea.jeanlucmakiola.de/pantry-app/pantry.git
|
||||
cd pantry
|
||||
|
||||
# Copy production config
|
||||
cp .env.example .env.production
|
||||
nano .env.production # Edit variables
|
||||
|
||||
# Start services
|
||||
docker-compose -f docker/docker-compose.prod.yml up -d
|
||||
|
||||
# Check status
|
||||
docker-compose ps
|
||||
|
||||
# View logs
|
||||
docker-compose logs -f
|
||||
```
|
||||
|
||||
### Production Configuration
|
||||
|
||||
**docker/docker-compose.prod.yml:**
|
||||
```yaml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# PostgreSQL (Supabase)
|
||||
postgres:
|
||||
image: supabase/postgres:15
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
||||
POSTGRES_DB: pantry
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
networks:
|
||||
- pantry-network
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
# Supabase Auth (GoTrue)
|
||||
auth:
|
||||
image: supabase/gotrue:v2.151.0
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
GOTRUE_DB_DRIVER: postgres
|
||||
GOTRUE_DB_DATABASE_URL: postgres://postgres:${DB_PASSWORD}@postgres:5432/pantry
|
||||
GOTRUE_SITE_URL: ${PUBLIC_APP_URL}
|
||||
GOTRUE_URI_ALLOW_LIST: ${PUBLIC_APP_URL}
|
||||
GOTRUE_JWT_SECRET: ${JWT_SECRET}
|
||||
GOTRUE_JWT_EXP: 3600
|
||||
# Email/Password
|
||||
GOTRUE_EXTERNAL_EMAIL_ENABLED: true
|
||||
# OIDC (optional)
|
||||
GOTRUE_EXTERNAL_GOOGLE_ENABLED: ${AUTH_GOOGLE_ENABLED:-false}
|
||||
GOTRUE_EXTERNAL_GOOGLE_CLIENT_ID: ${AUTH_GOOGLE_CLIENT_ID}
|
||||
GOTRUE_EXTERNAL_GOOGLE_SECRET: ${AUTH_GOOGLE_SECRET}
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- pantry-network
|
||||
|
||||
# Supabase Realtime
|
||||
realtime:
|
||||
image: supabase/realtime:v2.30.23
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
DB_HOST: postgres
|
||||
DB_NAME: pantry
|
||||
DB_USER: postgres
|
||||
DB_PASSWORD: ${DB_PASSWORD}
|
||||
DB_PORT: 5432
|
||||
SECRET_KEY_BASE: ${REALTIME_SECRET}
|
||||
REPLICATION_MODE: RLS
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- pantry-network
|
||||
|
||||
# Supabase Storage (optional - for product images)
|
||||
storage:
|
||||
image: supabase/storage-api:v1.0.6
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGREST_URL: http://rest:3000
|
||||
PGRST_JWT_SECRET: ${JWT_SECRET}
|
||||
DATABASE_URL: postgres://postgres:${DB_PASSWORD}@postgres:5432/pantry
|
||||
STORAGE_BACKEND: file
|
||||
FILE_STORAGE_BACKEND_PATH: /var/lib/storage
|
||||
volumes:
|
||||
- storage_data:/var/lib/storage
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- pantry-network
|
||||
|
||||
# PostgREST (Supabase API)
|
||||
rest:
|
||||
image: postgrest/postgrest:v12.0.2
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
PGRST_DB_URI: postgres://postgres:${DB_PASSWORD}@postgres:5432/pantry
|
||||
PGRST_DB_SCHEMAS: public,storage
|
||||
PGRST_DB_ANON_ROLE: anon
|
||||
PGRST_JWT_SECRET: ${JWT_SECRET}
|
||||
PGRST_DB_USE_LEGACY_GUCS: false
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- pantry-network
|
||||
|
||||
# Pantry App (Nuxt)
|
||||
app:
|
||||
build:
|
||||
context: ../app
|
||||
dockerfile: Dockerfile
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
SUPABASE_URL: http://rest:3000
|
||||
SUPABASE_ANON_KEY: ${SUPABASE_ANON_KEY}
|
||||
PUBLIC_APP_URL: ${PUBLIC_APP_URL}
|
||||
ports:
|
||||
- "3000:3000"
|
||||
depends_on:
|
||||
- rest
|
||||
- auth
|
||||
- realtime
|
||||
networks:
|
||||
- pantry-network
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:3000"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
# Reverse Proxy (Caddy with auto-SSL)
|
||||
caddy:
|
||||
image: caddy:2-alpine
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./Caddyfile:/etc/caddy/Caddyfile
|
||||
- caddy_data:/data
|
||||
- caddy_config:/config
|
||||
networks:
|
||||
- pantry-network
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
storage_data:
|
||||
caddy_data:
|
||||
caddy_config:
|
||||
|
||||
networks:
|
||||
pantry-network:
|
||||
driver: bridge
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
**.env.production:**
|
||||
```bash
|
||||
# Database
|
||||
DB_PASSWORD=<generate-strong-password>
|
||||
|
||||
# JWT (generate: openssl rand -hex 32)
|
||||
JWT_SECRET=<generate-strong-jwt-secret>
|
||||
|
||||
# Realtime
|
||||
REALTIME_SECRET=<generate-strong-secret>
|
||||
|
||||
# Supabase Keys (generate via supabase CLI or manually)
|
||||
SUPABASE_ANON_KEY=<your-anon-key>
|
||||
SUPABASE_SERVICE_KEY=<your-service-key>
|
||||
|
||||
# App
|
||||
PUBLIC_APP_URL=https://pantry.yourdomain.com
|
||||
|
||||
# OIDC (optional)
|
||||
AUTH_GOOGLE_ENABLED=false
|
||||
AUTH_GOOGLE_CLIENT_ID=
|
||||
AUTH_GOOGLE_SECRET=
|
||||
|
||||
# Open Food Facts
|
||||
OPENFOODFACTS_API_URL=https://world.openfoodfacts.org
|
||||
```
|
||||
|
||||
### Generate Secrets
|
||||
|
||||
```bash
|
||||
# DB Password
|
||||
openssl rand -hex 32
|
||||
|
||||
# JWT Secret (needs to be the same for all Supabase services)
|
||||
openssl rand -hex 32
|
||||
|
||||
# Supabase Keys (use supabase CLI)
|
||||
supabase init
|
||||
supabase start
|
||||
# Copy anon key and service key from output
|
||||
```
|
||||
|
||||
### Caddy Configuration
|
||||
|
||||
**docker/Caddyfile:**
|
||||
```
|
||||
{
|
||||
email your-email@example.com
|
||||
}
|
||||
|
||||
pantry.yourdomain.com {
|
||||
reverse_proxy app:3000
|
||||
|
||||
# WebSocket support (for Supabase Realtime)
|
||||
@websockets {
|
||||
header Connection *Upgrade*
|
||||
header Upgrade websocket
|
||||
}
|
||||
reverse_proxy @websockets realtime:4000
|
||||
}
|
||||
```
|
||||
|
||||
### Database Migrations
|
||||
|
||||
```bash
|
||||
# Apply migrations on first deploy
|
||||
docker-compose -f docker/docker-compose.prod.yml exec postgres \
|
||||
psql -U postgres -d pantry -f /migrations/001_schema.sql
|
||||
|
||||
# Or use Supabase CLI
|
||||
supabase db push --db-url postgres://postgres:${DB_PASSWORD}@localhost:5432/pantry
|
||||
```
|
||||
|
||||
### SSL Certificates
|
||||
|
||||
**Caddy (automatic):**
|
||||
- Caddy automatically requests Let's Encrypt certificates
|
||||
- Renews certificates automatically
|
||||
|
||||
**Manual (Certbot):**
|
||||
```bash
|
||||
# Install certbot
|
||||
sudo apt-get install certbot
|
||||
|
||||
# Request certificate
|
||||
sudo certbot certonly --standalone -d pantry.yourdomain.com
|
||||
|
||||
# Add to Nginx/Caddy config
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ☁️ Coolify Deployment
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Coolify instance running
|
||||
- Domain name
|
||||
- Git repository access
|
||||
|
||||
### Deploy Steps
|
||||
|
||||
**1. Add Resource in Coolify:**
|
||||
- Type: Docker Compose
|
||||
- Source: Git Repository
|
||||
- Repository: `https://gitea.jeanlucmakiola.de/pantry-app/pantry.git`
|
||||
- Branch: `main`
|
||||
- Compose File: `docker/docker-compose.prod.yml`
|
||||
|
||||
**2. Configure Environment:**
|
||||
- Add environment variables from `.env.production`
|
||||
- Generate secrets via Coolify UI
|
||||
|
||||
**3. Set Domain:**
|
||||
- Domain: `pantry.yourdomain.com`
|
||||
- SSL: Enable (Let's Encrypt automatic)
|
||||
|
||||
**4. Deploy:**
|
||||
- Click "Deploy"
|
||||
- Coolify builds and starts services
|
||||
- Traefik automatically handles SSL
|
||||
|
||||
**5. Verify:**
|
||||
- Visit `https://pantry.yourdomain.com`
|
||||
- Check logs in Coolify UI
|
||||
|
||||
### Coolify-Specific Config
|
||||
|
||||
**docker/docker-compose.coolify.yml:**
|
||||
```yaml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# ... (same as prod, but with Coolify labels)
|
||||
|
||||
app:
|
||||
build:
|
||||
context: ../app
|
||||
dockerfile: Dockerfile
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
SUPABASE_URL: http://rest:3000
|
||||
SUPABASE_ANON_KEY: ${SUPABASE_ANON_KEY}
|
||||
labels:
|
||||
- "coolify.managed=true"
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.pantry.rule=Host(`${DOMAIN}`)"
|
||||
- "traefik.http.services.pantry.loadbalancer.server.port=3000"
|
||||
networks:
|
||||
- pantry-network
|
||||
- coolify # Coolify proxy network
|
||||
|
||||
networks:
|
||||
pantry-network:
|
||||
driver: bridge
|
||||
coolify:
|
||||
external: true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📦 App Dockerfile
|
||||
|
||||
**app/Dockerfile:**
|
||||
```dockerfile
|
||||
FROM oven/bun:1 AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install dependencies
|
||||
COPY package.json bun.lockb ./
|
||||
RUN bun install --frozen-lockfile
|
||||
|
||||
# Copy source
|
||||
COPY . .
|
||||
|
||||
# Build app
|
||||
RUN bun run build
|
||||
|
||||
# Production image
|
||||
FROM oven/bun:1-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy built app
|
||||
COPY --from=builder /app/.output /app/.output
|
||||
|
||||
# Expose port
|
||||
EXPOSE 3000
|
||||
|
||||
# Start app
|
||||
CMD ["bun", "run", ".output/server/index.mjs"]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Post-Deployment
|
||||
|
||||
### 1. Apply Migrations
|
||||
|
||||
```bash
|
||||
# Via Supabase CLI
|
||||
supabase db push --db-url postgres://postgres:PASSWORD@your-server:5432/pantry
|
||||
|
||||
# Or manually via psql
|
||||
psql -h your-server -U postgres -d pantry -f supabase/migrations/001_schema.sql
|
||||
```
|
||||
|
||||
### 2. Seed Default Data
|
||||
|
||||
```bash
|
||||
# Apply seed migrations
|
||||
psql -h your-server -U postgres -d pantry -f supabase/migrations/002_seed_units.sql
|
||||
psql -h your-server -U postgres -d pantry -f supabase/migrations/003_seed_tags.sql
|
||||
```
|
||||
|
||||
### 3. Create First User
|
||||
|
||||
**Via Supabase Studio:**
|
||||
- Access at `http://your-server:54323` (if exposed)
|
||||
- Go to "Authentication" → "Users"
|
||||
- Add user manually
|
||||
|
||||
**Via API:**
|
||||
```bash
|
||||
curl -X POST https://pantry.yourdomain.com/auth/v1/signup \
|
||||
-H "apikey: YOUR_ANON_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"email": "admin@example.com", "password": "secure-password"}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Monitoring
|
||||
|
||||
### Health Checks
|
||||
|
||||
**App:**
|
||||
```bash
|
||||
curl https://pantry.yourdomain.com/health
|
||||
```
|
||||
|
||||
**Supabase:**
|
||||
```bash
|
||||
curl http://your-server:54321/health
|
||||
```
|
||||
|
||||
### Logs
|
||||
|
||||
**Docker Compose:**
|
||||
```bash
|
||||
# All services
|
||||
docker-compose logs -f
|
||||
|
||||
# Specific service
|
||||
docker-compose logs -f app
|
||||
docker-compose logs -f postgres
|
||||
```
|
||||
|
||||
**Coolify:**
|
||||
- View logs in Coolify UI
|
||||
- Real-time log streaming
|
||||
|
||||
### Metrics
|
||||
|
||||
**Disk Usage:**
|
||||
```bash
|
||||
docker system df
|
||||
```
|
||||
|
||||
**Database Size:**
|
||||
```sql
|
||||
SELECT
|
||||
pg_size_pretty(pg_database_size('pantry')) AS db_size;
|
||||
```
|
||||
|
||||
**Container Stats:**
|
||||
```bash
|
||||
docker stats
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Updates
|
||||
|
||||
### Pull Latest Changes
|
||||
|
||||
```bash
|
||||
# Stop services
|
||||
docker-compose down
|
||||
|
||||
# Pull latest code
|
||||
git pull origin main
|
||||
|
||||
# Rebuild app
|
||||
docker-compose build app
|
||||
|
||||
# Start services
|
||||
docker-compose up -d
|
||||
|
||||
# Apply new migrations
|
||||
supabase db push
|
||||
```
|
||||
|
||||
### Coolify Auto-Updates
|
||||
|
||||
**Enable in Coolify UI:**
|
||||
- Resource Settings → Auto Deploy
|
||||
- Trigger: Git push to `main`
|
||||
- Coolify rebuilds and redeploys automatically
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Security Checklist
|
||||
|
||||
- [ ] Strong passwords for all services
|
||||
- [ ] JWT secret rotated and secured
|
||||
- [ ] SSL certificates valid
|
||||
- [ ] Firewall rules configured (only 80/443 exposed)
|
||||
- [ ] Database backups enabled
|
||||
- [ ] Environment variables not committed to git
|
||||
- [ ] Supabase service key kept secret (not exposed to frontend)
|
||||
- [ ] Rate limiting configured (if needed)
|
||||
- [ ] CORS configured properly
|
||||
|
||||
---
|
||||
|
||||
## 💾 Backup & Restore
|
||||
|
||||
### Backup Database
|
||||
|
||||
```bash
|
||||
# Full backup
|
||||
docker-compose exec postgres pg_dump -U postgres pantry > backup.sql
|
||||
|
||||
# Compressed
|
||||
docker-compose exec postgres pg_dump -U postgres pantry | gzip > backup.sql.gz
|
||||
|
||||
# Scheduled backup (cron)
|
||||
0 2 * * * docker-compose -f /path/to/docker-compose.prod.yml exec postgres pg_dump -U postgres pantry | gzip > /backups/pantry-$(date +\%Y\%m\%d).sql.gz
|
||||
```
|
||||
|
||||
### Restore Database
|
||||
|
||||
```bash
|
||||
# From backup
|
||||
docker-compose exec -T postgres psql -U postgres pantry < backup.sql
|
||||
|
||||
# From compressed
|
||||
gunzip -c backup.sql.gz | docker-compose exec -T postgres psql -U postgres pantry
|
||||
```
|
||||
|
||||
### Backup Volumes
|
||||
|
||||
```bash
|
||||
# Backup postgres data volume
|
||||
docker run --rm \
|
||||
-v pantry_postgres_data:/data \
|
||||
-v $(pwd):/backup \
|
||||
alpine tar czf /backup/postgres-data.tar.gz /data
|
||||
|
||||
# Restore
|
||||
docker run --rm \
|
||||
-v pantry_postgres_data:/data \
|
||||
-v $(pwd):/backup \
|
||||
alpine tar xzf /backup/postgres-data.tar.gz -C /
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚨 Troubleshooting
|
||||
|
||||
### App won't start
|
||||
|
||||
**Check logs:**
|
||||
```bash
|
||||
docker-compose logs app
|
||||
```
|
||||
|
||||
**Common issues:**
|
||||
- Environment variables missing
|
||||
- Can't connect to Supabase
|
||||
- Port 3000 already in use
|
||||
|
||||
### Database connection failed
|
||||
|
||||
**Check PostgreSQL:**
|
||||
```bash
|
||||
docker-compose ps postgres
|
||||
docker-compose logs postgres
|
||||
```
|
||||
|
||||
**Test connection:**
|
||||
```bash
|
||||
docker-compose exec postgres psql -U postgres -d pantry -c "SELECT 1;"
|
||||
```
|
||||
|
||||
### SSL not working
|
||||
|
||||
**Caddy:**
|
||||
```bash
|
||||
# Check Caddy logs
|
||||
docker-compose logs caddy
|
||||
|
||||
# Verify DNS points to server
|
||||
dig pantry.yourdomain.com
|
||||
```
|
||||
|
||||
**Coolify:**
|
||||
- Check Traefik logs in Coolify
|
||||
- Verify domain configuration
|
||||
|
||||
### Out of disk space
|
||||
|
||||
```bash
|
||||
# Clean Docker
|
||||
docker system prune -a
|
||||
|
||||
# Clean old images
|
||||
docker image prune -a
|
||||
|
||||
# Clean volumes (careful!)
|
||||
docker volume prune
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 Resources
|
||||
|
||||
- [Docker Compose Docs](https://docs.docker.com/compose/)
|
||||
- [Coolify Docs](https://coolify.io/docs)
|
||||
- [Supabase Self-Hosting](https://supabase.com/docs/guides/self-hosting)
|
||||
- [Caddy Docs](https://caddyserver.com/docs/)
|
||||
|
||||
---
|
||||
|
||||
**All documentation complete!** Ready to start development.
|
||||
Reference in New Issue
Block a user