harbor/workflow.md
2026-05-04 11:13:25 +00:00

3.5 KiB

Harbor Deployment Workflow

Inputs

Parameter Required Example
app_name yes code-server
image yes lscr.io/linuxserver/code-server:latest
host_port yes 8443
container_port yes 8443
display_name no Code Server
env_vars no PUID=1000, PASSWORD=happy2026
volumes no /DATA/AppData/code-server:/config

Workflow Steps

1. Pre-flight Checks

# Check port availability
ssh pre "ssh casaos 'echo happy2026 | sudo -S ss -tlnp | grep :<host_port>'"

# Check if icon exists
curl -s -o /dev/null -w "%{http_code}" "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/webp/<app_name>.webp"

# Check Cloudflare for existing record
curl -s "https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/dns_records?name=<app_name>.snsnetlabs.com" \
  -H "Authorization: Bearer ${CF_API_TOKEN}"

2. Create Docker Compose

Write to ~/docker/<app_name>/docker-compose.yml on casa:

name: <app_name>
services:
  <app_name>:
    image: <image>
    container_name: <app_name>
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/Chicago
      # additional env vars
    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: <display_name>

3. Deploy Container

sudo mkdir -p /DATA/AppData/<app_name>
sudo chown -R 1000:1000 /DATA/AppData/<app_name>
cd ~/docker/<app_name> && sudo docker compose up -d

4. Register with CasaOS

sudo mkdir -p /var/lib/casaos/apps/<app_name>
sudo cp ~/docker/<app_name>/docker-compose.yml /var/lib/casaos/apps/<app_name>/

5. Create Cloudflare A Record

curl -X POST "https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/dns_records" \
  -H "Authorization: Bearer ${CF_API_TOKEN}" \
  -d '{"type":"A","name":"<app_name>.snsnetlabs.com","content":"172.238.163.85","ttl":1,"proxied":false}'

6. Create SSL Certificate (NPM)

curl -X POST http://localhost:81/api/nginx/certificates \
  -H "Authorization: Bearer ${NPM_TOKEN}" \
  -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=${CF_API_TOKEN}"
    }
  }'

7. Create NPM Proxy Host

curl -X POST http://localhost:81/api/nginx/proxy-hosts \
  -H "Authorization: Bearer ${NPM_TOKEN}" \
  -d '{
    "domain_names": ["<app_name>.snsnetlabs.com"],
    "forward_host": "192.168.122.33",
    "forward_port": <host_port>,
    "forward_scheme": "http",
    "certificate_id": <cert_id>,
    "allow_websocket_upgrade": true,
    "caching_enabled": true,
    "meta": {
      "dns_challenge": true,
      "dns_provider": "cloudflare",
      "dns_provider_credentials": "dns_cloudflare_api_token=${CF_API_TOKEN}"
    }
  }'

8. Verify

curl -s -o /dev/null -w "HTTP %{http_code}" -L https://<app_name>.snsnetlabs.com

9. Update Manifest

Append to manifest.md with app name, port, domain, NPM ID, cert ID.