harbor/casa-app-workflow.md

182 lines
5.1 KiB
Markdown

# CasaOS New App Deployment Workflow
## Target: casa VM (192.168.122.33) on pre
### Prerequisites
- SSH access: `ssh pre` then `ssh casaos` (or `ssh -J pre casaos`)
- Sudo password: same as user password
- Cloudflare API token and zone ID in `settings/credentials.env`
- NPM access on linode via API
---
## Step 1: Research the Docker Image
- Find the official or linuxserver.io image
- Note: default port, required volumes, environment variables
- Check dashboard-icons for app icon: `https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/webp/<app-name>.webp`
## Step 2: Check Casa for Port Conflicts
```bash
ssh pre "ssh casaos 'echo happy2026 | sudo -S ss -tlnp | grep LISTEN'"
```
Current port map:
| Port | Service |
|---|---|
| 80 | CasaOS gateway |
| 3000 | ConvertX |
| 8080 | OmniTools |
| 8443 | Code Server |
| 8888 | Dozzle |
## Step 3: Create Docker Compose
```bash
ssh pre "ssh casaos 'mkdir -p ~/docker/<app-name>'"
```
Template (`~/docker/<app-name>/docker-compose.yml`):
```yaml
name: <app-name>
services:
<app-name>:
image: <image>:<tag>
container_name: <app-name>
environment:
- PUID=1000
- PGID=1000
- TZ=America/Chicago
labels:
icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/webp/<app-name>.webp
volumes:
- /DATA/AppData/<app-name>:/config
ports:
- <host-port>:<container-port>
restart: unless-stopped
x-casaos:
author: self
category: self
hostname: <app-name>.snsnetlabs.com
icon: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/webp/<app-name>.webp
index: /
is_uncontrolled: false
port_map: "<host-port>"
scheme: https
store_app_id: <app-name>
title:
custom: ""
en_us: <App Display Name>
```
## Step 4: Deploy Container
```bash
ssh pre "ssh casaos 'echo happy2026 | sudo -S mkdir -p /DATA/AppData/<app-name> && \
echo happy2026 | sudo -S chown -R 1000:1000 /DATA/AppData/<app-name> && \
cd ~/docker/<app-name> && echo happy2026 | sudo -S docker compose up -d'"
```
## Step 5: Register with CasaOS Dashboard
```bash
ssh pre "ssh casaos 'echo happy2026 | sudo -S mkdir -p /var/lib/casaos/apps/<app-name> && \
echo happy2026 | sudo -S cp ~/docker/<app-name>/docker-compose.yml /var/lib/casaos/apps/<app-name>/'"
```
## Step 6: Create Cloudflare A Record
```bash
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/d4c9b425bad556070dc80848cb58e3ad/dns_records" \
-H "Authorization: Bearer AYLGpIUaw-6GvlzAltkttKp-nh3JWEVXtWuJbGvl" \
-H "Content-Type: application/json" \
--data '{"type":"A","name":"<app-name>.snsnetlabs.com","content":"172.238.163.85","ttl":1,"proxied":false}'
```
## Step 7: Create NPM SSL Certificate
```bash
# From linode (via pre):
TOKEN=$(curl -s -X POST http://localhost:81/api/tokens \
-H "Content-Type: application/json" \
-d '{"identity":"samueljamesinc@gmail.com","secret":"Happy2025!"}' | python3 -c "import sys,json; print(json.load(sys.stdin)['token'])")
curl -s -X POST http://localhost:81/api/nginx/certificates \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"provider": "letsencrypt",
"nice_name": "<app-name>.snsnetlabs.com",
"domain_names": ["<app-name>.snsnetlabs.com"],
"meta": {
"dns_challenge": true,
"dns_provider": "cloudflare",
"dns_provider_credentials": "dns_cloudflare_api_token=AYLGpIUaw-6GvlzAltkttKp-nh3JWEVXtWuJbGvl"
}
}'
# Note the returned cert ID
```
## Step 8: Create NPM Proxy Host
```bash
curl -s -X POST http://localhost:81/api/nginx/proxy-hosts \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"domain_names": ["<app-name>.snsnetlabs.com"],
"forward_host": "192.168.122.33",
"forward_port": <host-port>,
"forward_scheme": "http",
"access_list_id": 0,
"certificate_id": <cert-id>,
"ssl_forced": false,
"caching_enabled": true,
"block_exploits": false,
"allow_websocket_upgrade": true,
"http2_support": false,
"hsts_enabled": false,
"hsts_subdomains": false,
"meta": {
"dns_challenge": true,
"dns_provider": "cloudflare",
"dns_provider_credentials": "# Cloudflare API token\ndns_cloudflare_api_token=AYLGpIUaw-6GvlzAltkttKp-nh3JWEVXtWuJbGvl"
}
}'
```
## Step 9: Verify
```bash
curl -s -o /dev/null -w "HTTP %{http_code}\n" -L https://<app-name>.snsnetlabs.com
```
---
## Dashboard Icons
Source: `https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/webp/<name>.webp`
Search available icons: https://github.com/homarr-labs/dashboard-icons
Formats available: webp (preferred), png, svg
## Traffic Flow
```
Internet → <app>.snsnetlabs.com
→ Cloudflare DNS (A record → 172.238.163.85 / linode)
→ linode NPM (HTTPS termination, Let's Encrypt cert via CF DNS challenge)
→ http://192.168.122.33:<port> (via NetBird tunnel to casa VM)
```
## Deployed Apps
| App | Port | Domain | NPM ID | Cert ID |
|---|---|---|---|---|
| CasaOS | 80 | casaos.snsnetlabs.com | 39 | 48 |
| ConvertX | 3000 | convertx.snsnetlabs.com | 47 | 60 |
| OmniTools | 8080 | omnitools.snsnetlabs.com | 44 | 58 |
| Code Server | 8443 | code.snsnetlabs.com | 45 | 55 |
| Dozzle | 8888 | dozzle.snsnetlabs.com | 46 | 59 |