Guide for working with Immich's Cloudflare Workers monorepo - building, testing, deploying worker services and managing infrastructure with Terraform/Terragrunt.
This skill provides guidance for working with the Immich Workers repository - a monorepo for Cloudflare Workers that provide backend/API services deployed independently from frontend applications.
The Immich Workers repository is structured as a pnpm workspace monorepo containing multiple Cloudflare Workers, shared libraries, and Terraform/Terragrunt infrastructure definitions.
Follow this directory organization:
```
apps/
├── hello/ # Example hello world worker
└── .../ # Other worker applications
deployment/
├── modules/ # Terraform modules
│ └── cloudflare/
│ └── workers/
│ └── <worker-name>/ # Worker-specific Terraform config
└── state.hcl # Terragrunt state configuration
src/
└── lib/ # Shared libraries and utilities
```
Each worker in `apps/<worker-name>/` must contain:
Run these from the repository root:
```bash
pnpm install # Install all dependencies
pnpm run lint # Lint all workers (eslint . --max-warnings 0)
pnpm run lint:fix # Auto-fix linting issues
pnpm run format # Check formatting with Prettier
pnpm run format:fix # Auto-fix formatting issues
pnpm run test # Run all tests in all workers
pnpm run check # Type-check all workers (tsc --noEmit && pnpm -r typecheck)
pnpm run build # Build all workers (pnpm -r build)
```
Navigate to a specific worker directory first:
```bash
cd apps/<worker-name>
pnpm run dev # Start development server with Wrangler
pnpm run build # Build for production (dry-run deploy to dist/)
pnpm run tail # Tail production logs
pnpm run test # Run tests with Vitest
pnpm run check # Type-check worker (tsc --noEmit)
```
Workers use Vitest with Cloudflare's test utilities. Access the worker via the `SELF` import:
```typescript
import { SELF } from 'cloudflare:test';
import { describe, expect, it } from 'vitest';
describe('Worker', () => {
it('should handle request', async () => {
const response = await SELF.fetch('https://example.com/');
expect(response.status).toBe(200);
});
});
```
The base Vitest configuration at `vitest.base.config.ts` uses `@cloudflare/vitest-pool-workers` for proper Worker environment emulation.
Follow these steps to create a new worker:
1. **Create directory structure**:
```bash
mkdir -p apps/<worker-name>/src
cd apps/<worker-name>
```
2. **Copy template from hello worker**:
- Use `apps/hello/` as a reference template
- Copy: `package.json`, `wrangler.toml`, `tsconfig.json`, `vitest.config.ts`
3. **Update `wrangler.toml`**:
- Set `name = "<worker-name>-immich-app"`
- Configure any KV namespaces, Durable Objects, etc.
4. **Implement worker logic** in `src/index.ts`:
```typescript
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const url = new URL(request.url);
switch (url.pathname) {
case '/':
return new Response(JSON.stringify({ message: 'Hello' }), {
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
});
default:
return new Response(
JSON.stringify({ error: 'Not Found', path: url.pathname }),
{
status: 404,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
},
);
}
},
};
```
5. **Add tests** in `src/index.test.ts`
6. **Create Terraform module**:
- Create directory: `deployment/modules/cloudflare/workers/<worker-name>/`
- Copy hello worker module as template
- Update `app_name` in `terragrunt.hcl`
- Include: `terragrunt.hcl`, `variables.tf`, `config.tf`, `worker.tf`, `providers.tf`, `remote-state.tf`
Create `.dev.vars` in the worker directory for local secrets:
```
SECRET_KEY=local_secret
API_ENDPOINT=https://api.example.com
```
Set production secrets using Wrangler:
```bash
wrangler secret put SECRET_KEY
```
Or configure via Terraform in the worker module.
Deploy workers directly using Wrangler:
```bash
cd apps/<worker-name>
wrangler deploy # Deploy to production
wrangler deploy --env staging # Deploy to staging environment
```
Each worker has a Terraform module in `deployment/modules/cloudflare/workers/<worker-name>/`.
**Required environment variables**:
```bash
export TF_VAR_tf_state_postgres_conn_str="postgresql://user:pass@host/dbname"
export TF_VAR_env="dev" # Environment (dev/staging/prod)
export TF_VAR_stage="" # Stage suffix (optional)
export TF_VAR_app_name="hello" # Worker app name
export TF_VAR_cloudflare_account_id="your-account-id"
```
**Deploy infrastructure**:
```bash
cd deployment/modules/cloudflare/workers/<worker-name>
terragrunt init
terragrunt plan
terragrunt apply
```
**Key Terragrunt/Terraform patterns**:
All API responses include CORS headers for cross-origin access:
```typescript
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
}
```
Use this consistent error response format:
```typescript
return new Response(
JSON.stringify({
error: 'Not Found',
path: url.pathname,
}),
{
status: 404,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
},
);
```
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/immich-workers-development/raw