206 lines
6.3 KiB
Markdown
206 lines
6.3 KiB
Markdown
# ByteLyst NoteLett - Agent Instructions
|
|
|
|
> This file is read automatically by Claude Code. For full project instructions
|
|
> shared across all AI tools, see [`CONTEXT.md`](CONTEXT.md).
|
|
|
|
## Critical Deployment Patterns (Learned from Production Deployment)
|
|
|
|
### 1. Docker Build Preparation
|
|
**Before building Docker images, you MUST run the dependency packing script:**
|
|
```bash
|
|
bash scripts/docker-prep.sh
|
|
```
|
|
|
|
This script:
|
|
- Builds all @bytelyst/* packages from learning_ai_common_plat
|
|
- Packs them as tarballs in `.docker-deps/`
|
|
- Rewrites package.json files to reference the tarballs
|
|
- Injects pnpm.overrides for version consistency
|
|
|
|
**After building, ALWAYS restore the package.json files:**
|
|
```bash
|
|
bash scripts/docker-prep.sh --restore
|
|
```
|
|
|
|
### 2. Dockerfile Configuration
|
|
**Dockerfiles MUST be updated to remove Gitea secrets and use .docker-deps:**
|
|
|
|
**Backend Dockerfile changes:**
|
|
- Remove `--mount=type=secret,id=gitea_npm_token` lines
|
|
- Remove TOKEN environment setup
|
|
- Add `COPY .docker-deps/ ../.docker-deps/` before install
|
|
- Simplified install command: `RUN pnpm install --ignore-scripts --lockfile=false`
|
|
|
|
**Web Dockerfile changes:**
|
|
- Remove `--mount=type=secret,id=gitea_npm_token` lines
|
|
- Remove GITEA_NPM_TOKEN environment setup
|
|
- Ensure .docker-deps is copied before install
|
|
|
|
### 3. Public API URL Configuration
|
|
**NEXT_PUBLIC_ environment variables MUST use public URLs, not internal Docker network names:**
|
|
|
|
**Incorrect:**
|
|
```yaml
|
|
NEXT_PUBLIC_NOTES_API_URL: http://localhost:4016/api
|
|
NEXT_PUBLIC_NOTES_API_URL: http://backend:4011
|
|
```
|
|
|
|
**Correct:**
|
|
```yaml
|
|
NEXT_PUBLIC_NOTES_API_URL: https://api.bytelyst.com/notelett
|
|
```
|
|
|
|
This is because browsers cannot access internal Docker network names. The web app needs to connect to the public API endpoint.
|
|
|
|
### 4. Docker Compose Environment Variable Format
|
|
**Use YAML mapping syntax, NOT array syntax:**
|
|
|
|
**Incorrect:**
|
|
```yaml
|
|
environment:
|
|
- NODE_ENV=production
|
|
- PORT=4016
|
|
```
|
|
|
|
**Correct:**
|
|
```yaml
|
|
environment:
|
|
NODE_ENV: production
|
|
PORT: 4016
|
|
```
|
|
|
|
### 5. Production vs Development Mode
|
|
**Production mode (NODE_ENV=production) requires:**
|
|
- DB_PROVIDER: cosmos (not memory)
|
|
- FIELD_ENCRYPT_ENABLED: true (not false)
|
|
- FIELD_ENCRYPT_KEY_PROVIDER: akv or env (not memory)
|
|
|
|
**If these are not configured, use development mode:**
|
|
```yaml
|
|
NODE_ENV: development
|
|
```
|
|
|
|
### 6. Container Names for Caddy Routing
|
|
**Container names MUST match Caddyfile configuration:**
|
|
- Backend: `notelett-backend`
|
|
- Web: `notelett-web`
|
|
|
|
Add to docker-compose.yml:
|
|
```yaml
|
|
services:
|
|
backend:
|
|
container_name: notelett-backend
|
|
web:
|
|
container_name: notelett-web
|
|
```
|
|
|
|
### 7. Caddy Network Connectivity
|
|
**Caddy MUST be connected to the app networks for reverse proxy:**
|
|
```bash
|
|
docker network connect learning_ai_notes_default caddy
|
|
docker network connect learning_ai_common_plat_default caddy
|
|
```
|
|
|
|
### 8. DNS Configuration
|
|
**For new subdomains, add DNS records via GoDaddy API:**
|
|
```bash
|
|
# Example for notes.bytelyst.com
|
|
curl -X PUT "https://api.godaddy.com/v1/domains/bytelyst.com/records/A/notes" \
|
|
-H "Authorization: sso-key $GODADDY_API_KEY:$GODADDY_API_SECRET" \
|
|
-H "Content-Type: application/json" \
|
|
-d '[{"data": "187.124.159.82", "name": "notes", "ttl": 600, "type": "A"}]'
|
|
```
|
|
|
|
Use the same IP as other bytelyst.com subdomains (187.124.159.82).
|
|
|
|
### 9. Caddy Configuration Pattern
|
|
**Add subdomain routing to /opt/bytelyst/Caddyfile:**
|
|
```caddy
|
|
notes.bytelyst.com {
|
|
encode gzip
|
|
reverse_proxy notelett-web:3045
|
|
}
|
|
```
|
|
|
|
Then reload Caddy:
|
|
```bash
|
|
docker exec caddy caddy reload --config /etc/caddy/Caddyfile
|
|
```
|
|
|
|
### 10. Deployment Script Usage
|
|
**ALWAYS use the deployment script from learning_ai_devops_tools:**
|
|
```bash
|
|
cd ../learning_ai_devops_tools
|
|
bash deploy-notes.sh
|
|
```
|
|
|
|
Options:
|
|
- Option 1: Normal deployment (with cache, with health checks)
|
|
- Option 5: Force + No-cache (skip checks, force rebuild) - use when config changes
|
|
- Option 6: Force + Skip health checks (skip both) - use when health checks are flaky
|
|
|
|
## Deployment Checklist
|
|
|
|
Before deploying:
|
|
1. [ ] Run `bash scripts/docker-prep.sh` to package dependencies
|
|
2. [ ] Update Dockerfiles to remove Gitea secrets and use .docker-deps
|
|
3. [ ] Set NEXT_PUBLIC_ variables to use public API URLs
|
|
4. [ ] Use YAML mapping syntax for environment variables
|
|
5. [ ] Set correct NODE_ENV (development unless Cosmos/AKV configured)
|
|
6. [ ] Set container names to match Caddyfile
|
|
7. [ ] Update Caddyfile with subdomain routing
|
|
8. [ ] Add DNS records via GoDaddy API
|
|
9. [ ] Connect Caddy to app networks
|
|
10. [ ] Run deployment script with appropriate options
|
|
|
|
After deploying:
|
|
1. [ ] Run `bash scripts/docker-prep.sh --restore` to restore package.json
|
|
2. [ ] Test public URL accessibility
|
|
3. [ ] Test API endpoint accessibility
|
|
4. [ ] Verify SSL certificates are working
|
|
5. [ ] Check container logs for errors
|
|
6. [ ] Commit and push changes
|
|
|
|
## Common Deployment Errors and Solutions
|
|
|
|
### Error: "failed to calculate checksum of ref: /.docker-deps: not found"
|
|
**Solution:** Run `bash scripts/docker-prep.sh` before building
|
|
|
|
### Error: "HTTP 400 urn:ietf:params:acme:error:dns - DNS problem: NXDOMAIN"
|
|
**Solution:** DNS records not propagated yet. Wait 5-30 minutes after adding DNS records, then restart Caddy.
|
|
|
|
### Error: "Production DB_PROVIDER must be cosmos"
|
|
**Solution:** Either configure Cosmos DB credentials or set NODE_ENV to development
|
|
|
|
### Error: "services.web.environment.[3]: unexpected type map[string]interface {}"
|
|
**Solution:** Convert environment variables from array syntax to YAML mapping syntax
|
|
|
|
### Error: React hydration errors or backend connection failures
|
|
**Solution:** Check that NEXT_PUBLIC_ variables use public API URLs, not internal Docker network names
|
|
|
|
## Quick Deployment Commands
|
|
|
|
```bash
|
|
# Prepare dependencies
|
|
bash scripts/docker-prep.sh
|
|
|
|
# Deploy
|
|
cd ../learning_ai_devops_tools
|
|
echo "5" | bash deploy-notes.sh # Force + No-cache
|
|
|
|
# Restore after deployment
|
|
bash scripts/docker-prep.sh --restore
|
|
|
|
# Test
|
|
curl -I https://notes.bytelyst.com
|
|
curl -s https://api.bytelyst.com/notelett/health
|
|
```
|
|
|
|
## Key Files for Deployment
|
|
|
|
- `docker-compose.yml` - Container configuration
|
|
- `backend/Dockerfile` - Backend container build
|
|
- `web/Dockerfile` - Web container build
|
|
- `scripts/docker-prep.sh` - Dependency packaging script
|
|
- `/opt/bytelyst/Caddyfile` - Reverse proxy configuration
|
|
- `../learning_ai_devops_tools/deploy-notes.sh` - Deployment script |