Skip to content

CI/CD & Deployment Guide

This document provides comprehensive instructions for setting up and managing the CI/CD pipeline and deployment process for the Bookr monorepo project.

Overview

The project uses:

  • Gitea Actions for CI/CD workflows
  • Docker for containerization
  • Gitea Container Registry for image storage
  • Dokploy for deployment orchestration
  • Turbo for monorepo build optimization

Quick Setup

  1. Configure Gitea Secrets
  2. Set up Dokploy Applications
  3. Update Deployment Configuration
  4. Push to trigger your first deployment!

Gitea Secrets Configuration

Navigate to your repository settings → Secrets and add the following secrets:

Required Secrets

Secret NameDescriptionExample Value
GITEA_REGISTRY_USERNAMEYour Gitea username for container registryyour-username
GITEA_REGISTRY_PASSWORDYour Gitea password or access tokenyour-password-or-token
DOKPLOY_URLBase URL of your Dokploy instancehttps://dokploy.example.com
DOKPLOY_API_TOKENDokploy API token for deploymentsdp_xxx...

How to Get These Values

Gitea Registry Credentials

  1. Go to your Gitea instance
  2. Navigate to User Settings → Applications → Access Tokens
  3. Create a new token with package:write permissions
  4. Use your username and this token

Dokploy API Token

  1. Log into your Dokploy dashboard
  2. Go to Settings → API Tokens
  3. Create a new token with deployment permissions
  4. Copy the token (starts with dp_)

Dokploy Setup

1. Create Applications

For each application (api, web, sample-app), create corresponding applications in Dokploy:

  1. Create Application:

    • Name: bookr-{app-name}-{environment} (e.g., bookr-api-development)
    • Source: Docker Image
    • Image: gitea.bookr.dev:3000/usr_unknown/bookr-{app-name}:latest
  2. Configure Environment:

    • Set appropriate environment variables
    • Configure port mappings
    • Set health check endpoints (if applicable)
  3. Note the Application ID:

    • After creation, note the application ID from the URL
    • Example: https://dokploy.example.com/dashboard/project/123/application/456 → ID is 456

2. Environment Setup

Create applications for each environment:

  • Development: For develop, feat/* branches
  • Staging: For staging branch
  • Production: For main/master branches

Deployment Configuration

Update deployment.json

Edit the deployment.json file in your repository root:

json
{
	"environments": {
		"development": {
			"api_app_id": "your-actual-api-dev-id",
			"web_app_id": "your-actual-web-dev-id",
			"sample_app_id": "your-actual-sample-app-dev-id"
		},
		"staging": {
			"api_app_id": "your-actual-api-staging-id",
			"web_app_id": "your-actual-web-staging-id",
			"sample_app_id": "your-actual-sample-app-staging-id"
		},
		"production": {
			"api_app_id": "your-actual-api-prod-id",
			"web_app_id": "your-actual-web-prod-id",
			"sample_app_id": "your-actual-sample-app-prod-id"
		}
	},

	"registry": {
		"url": "gitea.bookr.dev:3000",
		"namespace": "your-gitea-username-or-org"
	}
}

Registry Configuration

Update the registry settings in deployment.json:

  • url: Your Gitea instance registry URL
  • namespace: Your Gitea username or organization name

Workflows

Check Workflow (.gitea/workflows/check.yaml)

Triggers: Push to main branches, pull requests

Steps:

  1. Install dependencies
  2. Run type checking
  3. Run linting
  4. Run tests

Branch Configuration:

  • Runs on: main, master, develop, staging, feat/deployment
  • PR target: main, master, develop

Deploy Workflow (.gitea/workflows/deploy.yaml)

Triggers:

  • Push to deployment branches
  • Manual workflow dispatch

Steps:

  1. Checks: Runs check workflow first
  2. Prepare:
    • Determines target environment
    • Detects changed applications
    • Reads deployment configuration
  3. Build:
    • Builds only changed applications
    • Creates and pushes Docker images
    • Tags images appropriately
  4. Deploy:
    • Deploys via Dokploy API
    • Runs in parallel for multiple apps

Branch-to-Environment Mapping

Branch PatternTarget Environment
main, masterproduction
stagingstaging
develop, feat/*development

Manual Deployment

Via Gitea UI

  1. Go to Actions tab in your repository
  2. Select "Deploy" workflow
  3. Click "Run workflow"
  4. Choose:
    • Branch to deploy from
    • Target environment
    • Whether to force deploy all apps

Via Command Line

You can also deploy manually using the scripts:

bash
# Deploy specific app to specific environment
node scripts/deploy.js development api
node scripts/deploy.js production web

# Build and push Docker image
node scripts/docker-build.js api latest gitea.bookr.dev:3000 usr_unknown

Application Detection

The workflow automatically detects which applications need deployment:

Change Detection

  • App Changes: Monitors apps/{app-name}/ directories
  • Shared Changes: If packages/ changes, deploys all apps
  • Force Deploy: Manual override to deploy all apps

Build Optimization

  • Uses Turbo to build only changed applications
  • Builds dependencies automatically via dependsOn configuration

Docker Image Tagging Strategy

EnvironmentTag Pattern
Developmentlatest
Staging{git-sha}-staging
Production{git-sha}-production

Images are always tagged as both specific version and latest for the environment.

Troubleshooting

Common Issues

1. "App ID not configured"

Solution: Update deployment.json with actual Dokploy application IDs

2. "Docker login failed"

Solution: Verify Gitea registry credentials in secrets

3. "Deployment API call failed"

Solution:

  • Check Dokploy API token validity
  • Verify Dokploy URL is accessible
  • Ensure application exists in Dokploy

4. "No applications detected for deployment"

Solution:

  • Ensure changes are in monitored directories (apps/, packages/)
  • Use manual deployment with force deploy option

Debug Information

View Deployment Logs

  1. Check Gitea Actions logs for build issues
  2. Check Dokploy application logs for deployment issues
  3. Review Docker registry for image availability

Verify Configuration

bash
# Test deployment script locally
export DOKPLOY_URL="your-dokploy-url"
export DOKPLOY_API_TOKEN="your-token"
node scripts/deploy.js development api

# Test Docker build locally
node scripts/docker-build.js api latest

Security Best Practices

  1. Secrets Management:

    • Use Gitea secrets for sensitive data
    • Rotate API tokens regularly
    • Use least privilege access
  2. Image Security:

    • Regular base image updates
    • Scan images for vulnerabilities
    • Use multi-stage builds to minimize attack surface
  3. Environment Isolation:

    • Separate Dokploy projects per environment
    • Different credentials per environment
    • Network isolation between environments

Environment Variables

Application-Level Environment Variables

Each application should manage its own environment variables:

API Application (apps/api)

  • Database connections
  • API keys
  • Service endpoints

Web Application (apps/web)

  • API base URLs
  • Feature flags
  • Analytics tokens

Sample Application (apps/sample-app)

  • Configuration specific to sample app

Dokploy Environment Configuration

Configure environment variables in Dokploy for each application:

  1. Navigate to Application Settings
  2. Go to Environment Variables section
  3. Add variables as key-value pairs
  4. Use secrets for sensitive values

Monitoring and Observability

Health Checks

The deployment includes health check configuration:

yaml
healthcheck:
    test:
        [
            'CMD',
            'node',
            '-e',
            "require('http').get('http://localhost:3001/health', res => process.exit(res.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))",
        ]
    interval: 1m30s
    timeout: 30s
    retries: 5
    start_period: 30s

Deployment Status

Monitor deployments via:

  • Gitea Actions for CI/CD pipeline status
  • Dokploy dashboard for application status
  • Application health endpoints

Advanced Configuration

Custom Build Arguments

Modify scripts/docker-build.js to accept additional build arguments:

bash
# Example: Custom Node version
node scripts/docker-build.js api latest gitea.bookr.dev:3000 usr_unknown 20

Environment-Specific Builds

Customize builds per environment by modifying the Dockerfile:

dockerfile
ARG NODE_ENV=production
ARG BUILD_ENV=development

Multi-Registry Support

The scripts support pushing to multiple registries:

bash
# Push to different registry
node scripts/docker-build.js api v1.0.0 my-registry.com my-org

Migration from Webhook Approach

If migrating from the old webhook-based deployment:

  1. Update Secrets: Replace webhook URLs with API tokens
  2. Configure App IDs: Add application IDs to deployment.toml
  3. Test Deployments: Run manual deployments to verify setup
  4. Remove Old Webhooks: Clean up webhook secrets after verification

Support

For issues or questions:

  1. Check the troubleshooting section above
  2. Review Gitea Actions logs
  3. Check Dokploy application status
  4. Verify all configuration files and secrets

This documentation covers the complete CI/CD and deployment setup. Keep it updated as your infrastructure evolves.