|
| 1 | +# -*- mode: Python -*- |
| 2 | +# Cabotage Local Development with Tilt |
| 3 | +# |
| 4 | +# Usage: |
| 5 | +# tilt up |
| 6 | +# |
| 7 | +# This Tiltfile sets up the complete Cabotage development environment on OrbStack K8s. |
| 8 | +# Hot reload is handled by: |
| 9 | +# - hostPath volume mounts (source code mounted directly into pods) |
| 10 | +# - Hupper (Python process watcher, auto-reloads on file changes) |
| 11 | + |
| 12 | +# Configuration |
| 13 | +k8s_context('orbstack') |
| 14 | +load('ext://namespace', 'namespace_create') |
| 15 | + |
| 16 | +# Create namespace |
| 17 | +namespace_create('cabotage-dev') |
| 18 | + |
| 19 | +# ============================================================================= |
| 20 | +# Docker Image Build |
| 21 | +# ============================================================================= |
| 22 | + |
| 23 | +# Build the development image with DEVEL=yes for dev dependencies |
| 24 | +docker_build( |
| 25 | + 'cabotage-app:dev', |
| 26 | + '.', |
| 27 | + dockerfile='Dockerfile', |
| 28 | + build_args={'DEVEL': 'yes'}, |
| 29 | + # Since we use hostPath mounts, we don't need live_update for file sync |
| 30 | + # Hupper handles process reload automatically |
| 31 | +) |
| 32 | + |
| 33 | +# ============================================================================= |
| 34 | +# Infrastructure Resources |
| 35 | +# ============================================================================= |
| 36 | + |
| 37 | +# Deploy infrastructure in dependency order |
| 38 | +# (namespace already created by namespace_create above) |
| 39 | + |
| 40 | +# ============================================================================= |
| 41 | +# OrbStack DNS - No Port Conflicts! |
| 42 | +# ============================================================================= |
| 43 | +# All services are accessible via OrbStack's automatic DNS: |
| 44 | +# - http://cabotage-app.cabotage-dev.orb.local (web app) |
| 45 | +# - db.cabotage-dev.orb.local:5432 (postgres) |
| 46 | +# - redis.cabotage-dev.orb.local:6379 (redis) |
| 47 | +# - consul.cabotage-dev.orb.local:8500 (consul) |
| 48 | +# - vault.cabotage-dev.orb.local:8200 (vault) |
| 49 | +# - minio.cabotage-dev.orb.local:9000 (minio) |
| 50 | +# - registry.cabotage-dev.orb.local:5001 (registry) |
| 51 | +# |
| 52 | +# Uncomment port_forwards below if you need localhost access for specific tools. |
| 53 | +# ============================================================================= |
| 54 | + |
| 55 | +# Postgres - must come first (Vault needs it for DB creds) |
| 56 | +k8s_yaml('k8s/dev/infra/postgres.yaml') |
| 57 | +k8s_resource( |
| 58 | + 'postgres', |
| 59 | + objects=['postgres-initdb:configmap'], |
| 60 | + # port_forwards=['5432:5432'], |
| 61 | + labels=['infra'], |
| 62 | +) |
| 63 | + |
| 64 | +# Redis |
| 65 | +k8s_yaml('k8s/dev/infra/redis.yaml') |
| 66 | +k8s_resource( |
| 67 | + 'redis', |
| 68 | + # port_forwards=['6379:6379'], |
| 69 | + labels=['infra'], |
| 70 | +) |
| 71 | + |
| 72 | +# Consul |
| 73 | +k8s_yaml('k8s/dev/infra/consul.yaml') |
| 74 | +k8s_resource( |
| 75 | + 'consul', |
| 76 | + # port_forwards=['8500:8500'], |
| 77 | + labels=['infra'], |
| 78 | +) |
| 79 | + |
| 80 | +# Vault - depends on postgres |
| 81 | +k8s_yaml('k8s/dev/infra/vault.yaml') |
| 82 | +k8s_resource( |
| 83 | + 'vault', |
| 84 | + objects=['vault-config:configmap'], |
| 85 | + # port_forwards=['8200:8200'], |
| 86 | + resource_deps=['postgres'], |
| 87 | + labels=['infra'], |
| 88 | +) |
| 89 | + |
| 90 | +# MinIO (S3-compatible storage for registry) |
| 91 | +k8s_yaml('k8s/dev/infra/minio.yaml') |
| 92 | +k8s_resource( |
| 93 | + 'minio', |
| 94 | + # port_forwards=['9000:9000', '9001:9001'], |
| 95 | + labels=['infra'], |
| 96 | +) |
| 97 | + |
| 98 | +# Docker Registry - depends on minio |
| 99 | +k8s_yaml('k8s/dev/infra/registry.yaml') |
| 100 | +k8s_resource( |
| 101 | + 'registry', |
| 102 | + objects=['registry-config:configmap'], |
| 103 | + # port_forwards=['5001:5001'], |
| 104 | + resource_deps=['minio'], |
| 105 | + labels=['infra'], |
| 106 | +) |
| 107 | + |
| 108 | +# BuildKit |
| 109 | +k8s_yaml('k8s/dev/infra/buildkit.yaml') |
| 110 | +k8s_resource( |
| 111 | + 'buildkit', |
| 112 | + objects=['buildkit-config:configmap'], |
| 113 | + # port_forwards=['1234:1234'], |
| 114 | + resource_deps=['registry'], |
| 115 | + labels=['infra'], |
| 116 | +) |
| 117 | + |
| 118 | +# ============================================================================= |
| 119 | +# Application Resources |
| 120 | +# ============================================================================= |
| 121 | + |
| 122 | +k8s_yaml('k8s/dev/app.yaml') |
| 123 | +k8s_yaml('k8s/dev/ingress.yaml') |
| 124 | + |
| 125 | +# Cabotage Web App |
| 126 | +# Access via: http://cabotage.192-168-139-2.nip.io (through nginx ingress) |
| 127 | +k8s_resource( |
| 128 | + 'cabotage-app', |
| 129 | + objects=['cabotage-app:ingress'], # Include the ingress with this resource |
| 130 | + resource_deps=['postgres', 'redis', 'vault', 'consul'], |
| 131 | + labels=['app'], |
| 132 | + trigger_mode=TRIGGER_MODE_AUTO, |
| 133 | +) |
| 134 | + |
| 135 | +# Cabotage Celery Worker |
| 136 | +k8s_resource( |
| 137 | + 'cabotage-app-worker', |
| 138 | + resource_deps=['postgres', 'redis', 'vault', 'consul'], |
| 139 | + labels=['app'], |
| 140 | + trigger_mode=TRIGGER_MODE_AUTO, |
| 141 | +) |
| 142 | + |
| 143 | +# ============================================================================= |
| 144 | +# Local Commands |
| 145 | +# ============================================================================= |
| 146 | + |
| 147 | +# Working directory for kubectl exec commands (must cd first, then use python -m) |
| 148 | +EXEC_PREFIX = 'kubectl exec -n cabotage-dev deploy/cabotage-app -- sh -c "cd /opt/cabotage-app/src && ' |
| 149 | + |
| 150 | +# Run database migrations (auto-runs on startup, safe to run multiple times) |
| 151 | +local_resource( |
| 152 | + 'db-migrate', |
| 153 | + cmd=EXEC_PREFIX + 'python3 -m flask db upgrade"', |
| 154 | + resource_deps=['cabotage-app'], |
| 155 | + labels=['setup'], |
| 156 | + auto_init=True, |
| 157 | +) |
| 158 | + |
| 159 | +# Create admin user (auto-runs on startup, script should handle existing user) |
| 160 | +local_resource( |
| 161 | + 'create-admin', |
| 162 | + cmd=EXEC_PREFIX + 'python3 -m cabotage.scripts.create_admin"', |
| 163 | + resource_deps=['db-migrate'], |
| 164 | + labels=['setup'], |
| 165 | + auto_init=True, |
| 166 | +) |
| 167 | + |
| 168 | +# View Flask routes |
| 169 | +local_resource( |
| 170 | + 'routes', |
| 171 | + cmd=EXEC_PREFIX + 'python3 -m flask routes"', |
| 172 | + resource_deps=['cabotage-app'], |
| 173 | + labels=['commands'], |
| 174 | + auto_init=False, |
| 175 | + trigger_mode=TRIGGER_MODE_MANUAL, |
| 176 | +) |
| 177 | + |
| 178 | +# ============================================================================= |
| 179 | +# Development Workflow |
| 180 | +# ============================================================================= |
| 181 | + |
| 182 | +# Watch Python files for changes (informational - Hupper handles actual reload) |
| 183 | +watch_file('cabotage/') |
| 184 | +watch_file('migrations/') |
| 185 | + |
| 186 | +# Watch templates for changes |
| 187 | +watch_file('cabotage/client/templates/') |
| 188 | +watch_file('cabotage/client/static/') |
0 commit comments