Changes:
- Create Gitea workflow for ai-stack-deployer
- Trigger on main branch (default branch)
- Use oussamadouhou + REGISTRY_TOKEN for authentication
- Build from ./Dockerfile
This enables :latest tag creation via {{is_default_branch}}.
Tags created:
- git.app.flexinit.nl/oussamadouhou/ai-stack-deployer:latest
- git.app.flexinit.nl/oussamadouhou/ai-stack-deployer:<sha>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
6.1 KiB
AI Stack Deployer - Testing Documentation
🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
Your only and main job now is to accurate follow the orders from the user. Your job is to validate and audit all code for issues, failures or misconfiguration. Your test plan should look like: Phase 1: Preparation & Static Analysis
Code Review (Audit): Have the code reviewed by a colleague or use a static analysis tool (linter) to identify syntax and style errors prior to execution. Logic Validation: Verify that the code logic aligns with the initial requirements (checking what it is supposed to do, not necessarily if it runs yet).
Phase 2: Unit Testing (Automated) 3. Run Unit Tests: Execute tests on small, isolated components (e.g., verifying that the authentication function returns the correct token). 4. Check Code Coverage: Ensure that critical paths and functions are actually being tested.
Phase 3: Integration & Functional Testing 5. Authentication Test: Verify that the application or script can successfully connect to required external systems (databases, APIs, login services). Note: This is a prerequisite for the next steps. 6. Execute Scripts (Happy Path): Run the script or application in the standard, intended way. 7. Monitor Logs: Monitor the output for error logs, warnings, or unexpected behavior during execution.
Phase 4: Evaluation & Reporting 8. Analyze Results: Compare the actual output against the expected results. 9. Report Status: If all tests pass, approve the code for release and inform the user.
🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
Last Updated: 2026-01-09
Infrastructure Context (from memory/docs)
| Service | IP | Port | Notes |
|---|---|---|---|
| Dokploy | 10.100.0.20 | 3000 | Container orchestration, Grafana Loki also here |
| Loki | 10.100.0.20 | 3100 | Logging aggregation |
| Grafana | 10.100.0.20 | 3000 (UI) | Dashboards at https://logs.intra.flexinit.nl |
| Traefik | 10.100.0.12 | - | VM 202 - Reverse proxy, SSL |
| AI Server | 10.100.0.19 | - | VM 209 - OpenCode agents |
Dokploy config location: /etc/dokploy/compose/ on 10.100.0.20
Phase 1 Test Results
1. Hono Server
| Test | Status | Notes |
|---|---|---|
| Server starts | ✅ PASS | Runs on port 3000 |
| Health endpoint | ✅ PASS | Returns JSON with status, timestamp, version |
| Root endpoint | ✅ PASS | Returns API endpoint list |
Commands:
# Start dev server
bun run dev
# Test health endpoint
curl http://localhost:3000/health
# Response: {"status":"healthy","timestamp":"2026-01-09T14:13:50.237Z","version":"0.1.0","service":"ai-stack-deployer"}
# Test root endpoint
curl http://localhost:3000/
# Response: {"message":"AI Stack Deployer API","endpoints":{...}}
2. Hetzner DNS Client
| Test | Status | Notes |
|---|---|---|
| Connection test | ✅ PASS | Successfully connects to Hetzner Cloud API |
| Zone access | ✅ PASS | Zone "flexinit.nl" (ID: 343733) accessible |
| RRSets listing | ✅ PASS | Returns 75 RRSets |
IMPORTANT FINDING:
- Hetzner DNS has been migrated from dns.hetzner.com to api.hetzner.cloud
- The old DNS Console API at
dns.hetzner.com/api/v1is deprecated - Must use new Hetzner Cloud API at
api.hetzner.cloud/v1 - Authentication:
Authorization: Bearer {token}(NOTAuth-API-Token) - Endpoints:
/zones,/zones/{id}/rrsets
Commands:
# Test Hetzner client
bun run src/test-clients.ts
# Manual API test
curl -s "https://api.hetzner.cloud/v1/zones" \
-H "Authorization: Bearer $HETZNER_API_TOKEN"
3. Dokploy Client
| Test | Status | Notes |
|---|---|---|
| Connection test | ❌ FAIL | Returns "Unauthorized" |
| Server accessible | ✅ PASS | Dokploy UI loads at http://10.100.0.20:3000 |
BLOCKER:
- Token
app_deployment...returns 401 Unauthorized - Token was created 2026-01-05 but may be expired or have insufficient permissions
- ACTION REQUIRED: Generate new token from Dokploy dashboard
Steps to generate new Dokploy API token:
- Navigate to https://deploy.intra.flexinit.nl or http://10.100.0.20:3000
- Login with admin credentials
- Go to: Settings (gear icon) → Profile
- Scroll to "API Tokens" section
- Click "Generate" button
- Copy the new token (format:
app_deployment<random>) - Update BWS secret:
bws secret edit 6b3618fc-ba02-49bc-bdc8-b3c9004087bc - Update local
.envfile
Commands:
# Test Dokploy API (currently failing)
curl -s "http://10.100.0.20:3000/api/project.all" \
-H "Authorization: Bearer $DOKPLOY_API_TOKEN"
# Response: {"message":"Unauthorized"}
Environment Configuration
.env File (from .env.example)
PORT=3000
HOST=0.0.0.0
# Hetzner Cloud DNS API (WORKING)
HETZNER_API_TOKEN=<from BWS - HETZNER_DNS_TOKEN>
HETZNER_ZONE_ID=343733
# Dokploy API (NEEDS NEW TOKEN)
DOKPLOY_URL=http://10.100.0.20:3000
DOKPLOY_API_TOKEN=<generate from Dokploy dashboard>
STACK_DOMAIN_SUFFIX=ai.flexinit.nl
STACK_IMAGE=git.app.flexinit.nl/oussamadouhou/oh-my-opencode-free:latest
TRAEFIK_IP=144.76.116.169
RESERVED_NAMES=admin,api,www,root,system,test,demo,portal
BWS Secrets Reference
| Secret | BWS Key | Status |
|---|---|---|
| Hetzner API Token | HETZNER_DNS_TOKEN |
✅ Working |
| Dokploy API Token | DOKPLOY_API_TOKEN (ID: 6b3618fc-ba02-49bc-bdc8-b3c9004087bc) |
❌ Expired/Invalid |
Gotchas & Learnings
1. Hetzner DNS API Migration
- Old API:
dns.hetzner.com/api/v1withAuth-API-Tokenheader - New API:
api.hetzner.cloud/v1withAuthorization: Bearerheader - Zone ID 343733 works in new API
- RRSets replace Records concept
2. Dokploy Token Format
- Format:
app_deployment<random> - Created from: Dashboard > Settings > Profile > API Tokens
- Must have permissions for project/application management
Next Steps
- Generate new Dokploy API token from dashboard
- Update BWS with new token
- Verify Dokploy client works
- Proceed to Phase 2 implementation