docs(wiki): add remote CLI management guide
- commit
- d22c73401ed60cf7195f884c50603e3f7243fa81
- author
- bnema · · 2026-01-16 21:11 UTC
- parent
- 1b2bc7b
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
2 files · +384 -0
M wiki/guides/index.md +4 -0
| @@ -11,6 +11,10 @@ In-depth guides for specific Gordon setups and integrations. | |||
| 11 | 11 | ||
| 12 | 12 | - [Cloudflare DNS & Proxy Setup](./cloudflare-setup.md) - HTTPS termination with Cloudflare | |
| 13 | 13 | ||
| 14 | + | ## Remote Management | |
| 15 | + | ||
| 16 | + | - [Remote CLI Management](./remote-cli.md) - Manage Gordon instances remotely | |
| 17 | + | ||
| 14 | 18 | ## Secrets Management | |
| 15 | 19 | ||
| 16 | 20 | - [Using Pass for Secrets](./secrets-pass.md) - Unix password manager integration | |
| @@ -11,6 +11,10 @@ In-depth guides for specific Gordon setups and integrations. | |||||
| 11 | 11 | ||||
| 12 | - [Cloudflare DNS & Proxy Setup](./cloudflare-setup.md) - HTTPS termination with Cloudflare | 12 | - [Cloudflare DNS & Proxy Setup](./cloudflare-setup.md) - HTTPS termination with Cloudflare | ||
| 13 | 13 | ||||
| 14 | + | ## Remote Management | |||
| 15 | + | ||||
| 16 | + | - [Remote CLI Management](./remote-cli.md) - Manage Gordon instances remotely | |||
| 17 | + | ||||
| 14 | ## Secrets Management | 18 | ## Secrets Management | ||
| 15 | 19 | ||||
| 16 | - [Using Pass for Secrets](./secrets-pass.md) - Unix password manager integration | 20 | - [Using Pass for Secrets](./secrets-pass.md) - Unix password manager integration | ||
A wiki/guides/remote-cli.md +380 -0
| @@ -0,0 +1,380 @@ | |||
| 1 | + | # Remote CLI Management | |
| 2 | + | ||
| 3 | + | Manage Gordon instances remotely using the CLI with the `--remote` flag or saved remotes. | |
| 4 | + | ||
| 5 | + | ## What You'll Learn | |
| 6 | + | ||
| 7 | + | - Using global `--remote` and `--token` flags | |
| 8 | + | - Saving and managing remote connections | |
| 9 | + | - Environment variable configuration | |
| 10 | + | - Token security best practices | |
| 11 | + | - Remote command workflows | |
| 12 | + | ||
| 13 | + | ## Prerequisites | |
| 14 | + | ||
| 15 | + | - Gordon CLI installed | |
| 16 | + | - A remote Gordon instance running with admin API enabled | |
| 17 | + | - Authentication token for the remote instance | |
| 18 | + | ||
| 19 | + | ## Quick Start | |
| 20 | + | ||
| 21 | + | ### One-off Remote Command | |
| 22 | + | ||
| 23 | + | ```bash | |
| 24 | + | gordon routes list --remote https://gordon.mydomain.com --token $TOKEN | |
| 25 | + | ``` | |
| 26 | + | ||
| 27 | + | ### Using Environment Variables | |
| 28 | + | ||
| 29 | + | ```bash | |
| 30 | + | export GORDON_REMOTE=https://gordon.mydomain.com | |
| 31 | + | export GORDON_TOKEN=$TOKEN | |
| 32 | + | gordon routes list | |
| 33 | + | ``` | |
| 34 | + | ||
| 35 | + | ### Using Saved Remotes | |
| 36 | + | ||
| 37 | + | ```bash | |
| 38 | + | # Add a remote | |
| 39 | + | gordon remotes add prod https://gordon.mydomain.com --token-env PROD_TOKEN | |
| 40 | + | ||
| 41 | + | # Set as active | |
| 42 | + | gordon remotes use prod | |
| 43 | + | ||
| 44 | + | # Now use without flags | |
| 45 | + | gordon routes list | |
| 46 | + | ``` | |
| 47 | + | ||
| 48 | + | ## Global Flags | |
| 49 | + | ||
| 50 | + | These flags are available on all commands: | |
| 51 | + | ||
| 52 | + | | Flag | Description | | |
| 53 | + | |------|-------------| | |
| 54 | + | | `--remote <URL>` | Remote Gordon URL | | |
| 55 | + | | `--token <TOKEN>` | Authentication token | | |
| 56 | + | ||
| 57 | + | ```bash | |
| 58 | + | # List routes on remote | |
| 59 | + | gordon routes list --remote https://gordon.mydomain.com --token $TOKEN | |
| 60 | + | ||
| 61 | + | # Manage secrets on remote | |
| 62 | + | gordon secrets list myapp.example.com --remote https://gordon.mydomain.com --token $TOKEN | |
| 63 | + | ``` | |
| 64 | + | ||
| 65 | + | ## Environment Variables | |
| 66 | + | ||
| 67 | + | | Variable | Description | | |
| 68 | + | |----------|-------------| | |
| 69 | + | | `GORDON_REMOTE` | Remote Gordon URL | | |
| 70 | + | | `GORDON_TOKEN` | Authentication token | | |
| 71 | + | ||
| 72 | + | Environment variables are useful for CI/CD pipelines and shell sessions: | |
| 73 | + | ||
| 74 | + | ```bash | |
| 75 | + | # Set for current session | |
| 76 | + | export GORDON_REMOTE=https://gordon.mydomain.com | |
| 77 | + | export GORDON_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... | |
| 78 | + | ||
| 79 | + | # Commands automatically use these | |
| 80 | + | gordon routes list | |
| 81 | + | gordon secrets list myapp.example.com | |
| 82 | + | ``` | |
| 83 | + | ||
| 84 | + | ## Saved Remotes | |
| 85 | + | ||
| 86 | + | Save frequently used remotes to avoid repeating URLs and tokens. | |
| 87 | + | ||
| 88 | + | ### Configuration File | |
| 89 | + | ||
| 90 | + | Remotes are stored in `~/.config/gordon/remotes.toml`: | |
| 91 | + | ||
| 92 | + | ```toml | |
| 93 | + | active = "prod" | |
| 94 | + | ||
| 95 | + | [remotes.prod] | |
| 96 | + | url = "https://gordon.mydomain.com" | |
| 97 | + | token_env = "PROD_TOKEN" | |
| 98 | + | ||
| 99 | + | [remotes.staging] | |
| 100 | + | url = "https://staging.mydomain.com" | |
| 101 | + | token = "eyJ..." | |
| 102 | + | ``` | |
| 103 | + | ||
| 104 | + | ### Managing Remotes | |
| 105 | + | ||
| 106 | + | #### List Remotes | |
| 107 | + | ||
| 108 | + | ```bash | |
| 109 | + | gordon remotes list | |
| 110 | + | ``` | |
| 111 | + | ||
| 112 | + | Output: | |
| 113 | + | ||
| 114 | + | ``` | |
| 115 | + | Saved Remotes | |
| 116 | + | ||
| 117 | + | Name URL Token Status | |
| 118 | + | ────────────────────────────────────────────────────────────────────────────── | |
| 119 | + | prod https://gordon.mydomain.com $PROD_TOKEN active | |
| 120 | + | staging https://staging.mydomain.com set | |
| 121 | + | dev https://dev.mydomain.com none | |
| 122 | + | ``` | |
| 123 | + | ||
| 124 | + | #### Add a Remote | |
| 125 | + | ||
| 126 | + | ```bash | |
| 127 | + | # Basic (no token) | |
| 128 | + | gordon remotes add prod https://gordon.mydomain.com | |
| 129 | + | ||
| 130 | + | # With direct token | |
| 131 | + | gordon remotes add prod https://gordon.mydomain.com --token eyJ... | |
| 132 | + | ||
| 133 | + | # With environment variable reference (recommended) | |
| 134 | + | gordon remotes add prod https://gordon.mydomain.com --token-env PROD_TOKEN | |
| 135 | + | ``` | |
| 136 | + | ||
| 137 | + | | Flag | Description | | |
| 138 | + | |------|-------------| | |
| 139 | + | | `--token <TOKEN>` | Store token directly in config | | |
| 140 | + | | `--token-env <VAR>` | Store env variable name (token resolved at runtime) | | |
| 141 | + | ||
| 142 | + | #### Remove a Remote | |
| 143 | + | ||
| 144 | + | ```bash | |
| 145 | + | # With confirmation prompt | |
| 146 | + | gordon remotes remove staging | |
| 147 | + | ||
| 148 | + | # Skip confirmation | |
| 149 | + | gordon remotes remove staging --force | |
| 150 | + | ``` | |
| 151 | + | ||
| 152 | + | #### Set Active Remote | |
| 153 | + | ||
| 154 | + | ```bash | |
| 155 | + | gordon remotes use prod | |
| 156 | + | ``` | |
| 157 | + | ||
| 158 | + | When a remote is active, it's used automatically for all remote-capable commands: | |
| 159 | + | ||
| 160 | + | ```bash | |
| 161 | + | gordon remotes use prod | |
| 162 | + | gordon routes list # Uses prod remote | |
| 163 | + | gordon secrets list app.com # Uses prod remote | |
| 164 | + | ``` | |
| 165 | + | ||
| 166 | + | ## Resolution Precedence | |
| 167 | + | ||
| 168 | + | When multiple sources specify remote or token, the CLI uses this priority order: | |
| 169 | + | ||
| 170 | + | **Remote URL:** | |
| 171 | + | 1. `--remote` flag | |
| 172 | + | 2. `GORDON_REMOTE` environment variable | |
| 173 | + | 3. Active remote from `remotes.toml` | |
| 174 | + | ||
| 175 | + | **Token:** | |
| 176 | + | 1. `--token` flag | |
| 177 | + | 2. `GORDON_TOKEN` environment variable | |
| 178 | + | 3. Token from active remote in `remotes.toml` | |
| 179 | + | ||
| 180 | + | This allows overriding specific values while keeping defaults: | |
| 181 | + | ||
| 182 | + | ```bash | |
| 183 | + | # Active remote is prod, but use different token | |
| 184 | + | gordon routes list --token $TEMPORARY_TOKEN | |
| 185 | + | ``` | |
| 186 | + | ||
| 187 | + | ## Commands Supporting Remote | |
| 188 | + | ||
| 189 | + | These commands work with remote targeting: | |
| 190 | + | ||
| 191 | + | | Command | Description | | |
| 192 | + | |---------|-------------| | |
| 193 | + | | `gordon routes list` | List all routes | | |
| 194 | + | | `gordon routes add <domain> <image>` | Add a route | | |
| 195 | + | | `gordon routes remove <domain>` | Remove a route | | |
| 196 | + | | `gordon routes deploy <domain>` | Deploy/redeploy a route | | |
| 197 | + | | `gordon secrets list <domain>` | List secrets for a domain | | |
| 198 | + | | `gordon secrets set <domain> KEY=value` | Set secrets | | |
| 199 | + | | `gordon secrets remove <domain> <key>` | Remove a secret | | |
| 200 | + | | `gordon status` | Show server status | | |
| 201 | + | ||
| 202 | + | ## Token Security | |
| 203 | + | ||
| 204 | + | ### Option 1: Environment Variable Reference (Recommended) | |
| 205 | + | ||
| 206 | + | Store the environment variable name, not the actual token: | |
| 207 | + | ||
| 208 | + | ```bash | |
| 209 | + | gordon remotes add prod https://gordon.mydomain.com --token-env PROD_TOKEN | |
| 210 | + | ``` | |
| 211 | + | ||
| 212 | + | The `remotes.toml` stores only: | |
| 213 | + | ||
| 214 | + | ```toml | |
| 215 | + | [remotes.prod] | |
| 216 | + | url = "https://gordon.mydomain.com" | |
| 217 | + | token_env = "PROD_TOKEN" | |
| 218 | + | ``` | |
| 219 | + | ||
| 220 | + | At runtime, Gordon reads `$PROD_TOKEN` from the environment. | |
| 221 | + | ||
| 222 | + | **Benefits:** | |
| 223 | + | - Token not stored in plaintext config | |
| 224 | + | - Works with secret managers that inject env vars | |
| 225 | + | - Easy rotation without editing config | |
| 226 | + | ||
| 227 | + | ### Option 2: Direct Token Storage | |
| 228 | + | ||
| 229 | + | ```bash | |
| 230 | + | gordon remotes add prod https://gordon.mydomain.com --token eyJ... | |
| 231 | + | ``` | |
| 232 | + | ||
| 233 | + | The token is stored directly in `remotes.toml`: | |
| 234 | + | ||
| 235 | + | ```toml | |
| 236 | + | [remotes.prod] | |
| 237 | + | url = "https://gordon.mydomain.com" | |
| 238 | + | token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." | |
| 239 | + | ``` | |
| 240 | + | ||
| 241 | + | **Security note:** Ensure `remotes.toml` has restricted permissions: | |
| 242 | + | ||
| 243 | + | ```bash | |
| 244 | + | chmod 600 ~/.config/gordon/remotes.toml | |
| 245 | + | ``` | |
| 246 | + | ||
| 247 | + | ### Option 3: Environment Variables Only | |
| 248 | + | ||
| 249 | + | For maximum security, don't save tokens at all: | |
| 250 | + | ||
| 251 | + | ```bash | |
| 252 | + | # Add remote without token | |
| 253 | + | gordon remotes add prod https://gordon.mydomain.com | |
| 254 | + | ||
| 255 | + | # Set token via environment | |
| 256 | + | export GORDON_TOKEN=$TOKEN | |
| 257 | + | ||
| 258 | + | # Use normally | |
| 259 | + | gordon remotes use prod | |
| 260 | + | gordon routes list | |
| 261 | + | ``` | |
| 262 | + | ||
| 263 | + | ## Workflow Examples | |
| 264 | + | ||
| 265 | + | ### Development Workflow | |
| 266 | + | ||
| 267 | + | ```bash | |
| 268 | + | # Add dev and staging remotes | |
| 269 | + | gordon remotes add dev https://gordon.dev.local --token-env DEV_TOKEN | |
| 270 | + | gordon remotes add staging https://gordon.staging.example.com --token-env STAGING_TOKEN | |
| 271 | + | ||
| 272 | + | # Work with dev | |
| 273 | + | gordon remotes use dev | |
| 274 | + | gordon routes list | |
| 275 | + | gordon routes add myapp.dev.local myapp:latest | |
| 276 | + | ||
| 277 | + | # Switch to staging | |
| 278 | + | gordon remotes use staging | |
| 279 | + | gordon routes list | |
| 280 | + | ``` | |
| 281 | + | ||
| 282 | + | ### CI/CD Pipeline | |
| 283 | + | ||
| 284 | + | ```yaml | |
| 285 | + | # GitHub Actions example | |
| 286 | + | env: | |
| 287 | + | GORDON_REMOTE: ${{ secrets.GORDON_URL }} | |
| 288 | + | GORDON_TOKEN: ${{ secrets.GORDON_TOKEN }} | |
| 289 | + | ||
| 290 | + | steps: | |
| 291 | + | - name: Deploy to Gordon | |
| 292 | + | run: | | |
| 293 | + | gordon routes deploy myapp.example.com | |
| 294 | + | ``` | |
| 295 | + | ||
| 296 | + | ```bash | |
| 297 | + | # GitLab CI example | |
| 298 | + | deploy: | |
| 299 | + | script: | |
| 300 | + | - export GORDON_REMOTE=$GORDON_URL | |
| 301 | + | - export GORDON_TOKEN=$GORDON_TOKEN | |
| 302 | + | - gordon routes deploy myapp.example.com | |
| 303 | + | ``` | |
| 304 | + | ||
| 305 | + | ### Multi-Environment Management | |
| 306 | + | ||
| 307 | + | ```bash | |
| 308 | + | # Add all environments | |
| 309 | + | gordon remotes add prod https://gordon.example.com --token-env PROD_TOKEN | |
| 310 | + | gordon remotes add staging https://gordon.staging.example.com --token-env STAGING_TOKEN | |
| 311 | + | gordon remotes add dev https://gordon.dev.example.com --token-env DEV_TOKEN | |
| 312 | + | ||
| 313 | + | # Compare routes across environments | |
| 314 | + | gordon routes list --remote https://gordon.example.com --token $PROD_TOKEN | |
| 315 | + | gordon routes list --remote https://gordon.staging.example.com --token $STAGING_TOKEN | |
| 316 | + | ||
| 317 | + | # Or switch active | |
| 318 | + | gordon remotes use prod && gordon routes list | |
| 319 | + | gordon remotes use staging && gordon routes list | |
| 320 | + | ``` | |
| 321 | + | ||
| 322 | + | ## Troubleshooting | |
| 323 | + | ||
| 324 | + | ### "unauthorized" Error | |
| 325 | + | ||
| 326 | + | Token is missing, expired, or invalid. | |
| 327 | + | ||
| 328 | + | ```bash | |
| 329 | + | # Check if token is set | |
| 330 | + | echo $GORDON_TOKEN | |
| 331 | + | ||
| 332 | + | # Verify token works | |
| 333 | + | gordon routes list --remote https://gordon.mydomain.com --token $TOKEN | |
| 334 | + | ``` | |
| 335 | + | ||
| 336 | + | ### "connection refused" Error | |
| 337 | + | ||
| 338 | + | Remote Gordon isn't running or URL is wrong. | |
| 339 | + | ||
| 340 | + | ```bash | |
| 341 | + | # Verify URL is correct | |
| 342 | + | curl https://gordon.mydomain.com/health | |
| 343 | + | ||
| 344 | + | # Check if admin API is enabled on remote | |
| 345 | + | # The remote gordon.toml needs: | |
| 346 | + | # [admin] | |
| 347 | + | # enabled = true | |
| 348 | + | ``` | |
| 349 | + | ||
| 350 | + | ### Remote Not Found | |
| 351 | + | ||
| 352 | + | The specified remote doesn't exist in `remotes.toml`. | |
| 353 | + | ||
| 354 | + | ```bash | |
| 355 | + | # List available remotes | |
| 356 | + | gordon remotes list | |
| 357 | + | ||
| 358 | + | # Add the remote | |
| 359 | + | gordon remotes add myremote https://gordon.mydomain.com | |
| 360 | + | ``` | |
| 361 | + | ||
| 362 | + | ### Active Remote Cleared | |
| 363 | + | ||
| 364 | + | After removing the active remote, you need to set a new active: | |
| 365 | + | ||
| 366 | + | ```bash | |
| 367 | + | gordon remotes use prod | |
| 368 | + | ``` | |
| 369 | + | ||
| 370 | + | Or use explicit flags: | |
| 371 | + | ||
| 372 | + | ```bash | |
| 373 | + | gordon routes list --remote https://gordon.mydomain.com --token $TOKEN | |
| 374 | + | ``` | |
| 375 | + | ||
| 376 | + | ## Related | |
| 377 | + | ||
| 378 | + | - [CLI Commands](/docs/cli/commands.md) | |
| 379 | + | - [Authentication](/docs/config/registry-auth.md) | |
| 380 | + | - [Admin API](/docs/config/admin.md) | |
| @@ -0,0 +1,380 @@ | |||||
| 1 | + | # Remote CLI Management | |||
| 2 | + | ||||
| 3 | + | Manage Gordon instances remotely using the CLI with the `--remote` flag or saved remotes. | |||
| 4 | + | ||||
| 5 | + | ## What You'll Learn | |||
| 6 | + | ||||
| 7 | + | - Using global `--remote` and `--token` flags | |||
| 8 | + | - Saving and managing remote connections | |||
| 9 | + | - Environment variable configuration | |||
| 10 | + | - Token security best practices | |||
| 11 | + | - Remote command workflows | |||
| 12 | + | ||||
| 13 | + | ## Prerequisites | |||
| 14 | + | ||||
| 15 | + | - Gordon CLI installed | |||
| 16 | + | - A remote Gordon instance running with admin API enabled | |||
| 17 | + | - Authentication token for the remote instance | |||
| 18 | + | ||||
| 19 | + | ## Quick Start | |||
| 20 | + | ||||
| 21 | + | ### One-off Remote Command | |||
| 22 | + | ||||
| 23 | + | ```bash | |||
| 24 | + | gordon routes list --remote https://gordon.mydomain.com --token $TOKEN | |||
| 25 | + | ``` | |||
| 26 | + | ||||
| 27 | + | ### Using Environment Variables | |||
| 28 | + | ||||
| 29 | + | ```bash | |||
| 30 | + | export GORDON_REMOTE=https://gordon.mydomain.com | |||
| 31 | + | export GORDON_TOKEN=$TOKEN | |||
| 32 | + | gordon routes list | |||
| 33 | + | ``` | |||
| 34 | + | ||||
| 35 | + | ### Using Saved Remotes | |||
| 36 | + | ||||
| 37 | + | ```bash | |||
| 38 | + | # Add a remote | |||
| 39 | + | gordon remotes add prod https://gordon.mydomain.com --token-env PROD_TOKEN | |||
| 40 | + | ||||
| 41 | + | # Set as active | |||
| 42 | + | gordon remotes use prod | |||
| 43 | + | ||||
| 44 | + | # Now use without flags | |||
| 45 | + | gordon routes list | |||
| 46 | + | ``` | |||
| 47 | + | ||||
| 48 | + | ## Global Flags | |||
| 49 | + | ||||
| 50 | + | These flags are available on all commands: | |||
| 51 | + | ||||
| 52 | + | | Flag | Description | | |||
| 53 | + | |------|-------------| | |||
| 54 | + | | `--remote <URL>` | Remote Gordon URL | | |||
| 55 | + | | `--token <TOKEN>` | Authentication token | | |||
| 56 | + | ||||
| 57 | + | ```bash | |||
| 58 | + | # List routes on remote | |||
| 59 | + | gordon routes list --remote https://gordon.mydomain.com --token $TOKEN | |||
| 60 | + | ||||
| 61 | + | # Manage secrets on remote | |||
| 62 | + | gordon secrets list myapp.example.com --remote https://gordon.mydomain.com --token $TOKEN | |||
| 63 | + | ``` | |||
| 64 | + | ||||
| 65 | + | ## Environment Variables | |||
| 66 | + | ||||
| 67 | + | | Variable | Description | | |||
| 68 | + | |----------|-------------| | |||
| 69 | + | | `GORDON_REMOTE` | Remote Gordon URL | | |||
| 70 | + | | `GORDON_TOKEN` | Authentication token | | |||
| 71 | + | ||||
| 72 | + | Environment variables are useful for CI/CD pipelines and shell sessions: | |||
| 73 | + | ||||
| 74 | + | ```bash | |||
| 75 | + | # Set for current session | |||
| 76 | + | export GORDON_REMOTE=https://gordon.mydomain.com | |||
| 77 | + | export GORDON_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... | |||
| 78 | + | ||||
| 79 | + | # Commands automatically use these | |||
| 80 | + | gordon routes list | |||
| 81 | + | gordon secrets list myapp.example.com | |||
| 82 | + | ``` | |||
| 83 | + | ||||
| 84 | + | ## Saved Remotes | |||
| 85 | + | ||||
| 86 | + | Save frequently used remotes to avoid repeating URLs and tokens. | |||
| 87 | + | ||||
| 88 | + | ### Configuration File | |||
| 89 | + | ||||
| 90 | + | Remotes are stored in `~/.config/gordon/remotes.toml`: | |||
| 91 | + | ||||
| 92 | + | ```toml | |||
| 93 | + | active = "prod" | |||
| 94 | + | ||||
| 95 | + | [remotes.prod] | |||
| 96 | + | url = "https://gordon.mydomain.com" | |||
| 97 | + | token_env = "PROD_TOKEN" | |||
| 98 | + | ||||
| 99 | + | [remotes.staging] | |||
| 100 | + | url = "https://staging.mydomain.com" | |||
| 101 | + | token = "eyJ..." | |||
| 102 | + | ``` | |||
| 103 | + | ||||
| 104 | + | ### Managing Remotes | |||
| 105 | + | ||||
| 106 | + | #### List Remotes | |||
| 107 | + | ||||
| 108 | + | ```bash | |||
| 109 | + | gordon remotes list | |||
| 110 | + | ``` | |||
| 111 | + | ||||
| 112 | + | Output: | |||
| 113 | + | ||||
| 114 | + | ``` | |||
| 115 | + | Saved Remotes | |||
| 116 | + | ||||
| 117 | + | Name URL Token Status | |||
| 118 | + | ────────────────────────────────────────────────────────────────────────────── | |||
| 119 | + | prod https://gordon.mydomain.com $PROD_TOKEN active | |||
| 120 | + | staging https://staging.mydomain.com set | |||
| 121 | + | dev https://dev.mydomain.com none | |||
| 122 | + | ``` | |||
| 123 | + | ||||
| 124 | + | #### Add a Remote | |||
| 125 | + | ||||
| 126 | + | ```bash | |||
| 127 | + | # Basic (no token) | |||
| 128 | + | gordon remotes add prod https://gordon.mydomain.com | |||
| 129 | + | ||||
| 130 | + | # With direct token | |||
| 131 | + | gordon remotes add prod https://gordon.mydomain.com --token eyJ... | |||
| 132 | + | ||||
| 133 | + | # With environment variable reference (recommended) | |||
| 134 | + | gordon remotes add prod https://gordon.mydomain.com --token-env PROD_TOKEN | |||
| 135 | + | ``` | |||
| 136 | + | ||||
| 137 | + | | Flag | Description | | |||
| 138 | + | |------|-------------| | |||
| 139 | + | | `--token <TOKEN>` | Store token directly in config | | |||
| 140 | + | | `--token-env <VAR>` | Store env variable name (token resolved at runtime) | | |||
| 141 | + | ||||
| 142 | + | #### Remove a Remote | |||
| 143 | + | ||||
| 144 | + | ```bash | |||
| 145 | + | # With confirmation prompt | |||
| 146 | + | gordon remotes remove staging | |||
| 147 | + | ||||
| 148 | + | # Skip confirmation | |||
| 149 | + | gordon remotes remove staging --force | |||
| 150 | + | ``` | |||
| 151 | + | ||||
| 152 | + | #### Set Active Remote | |||
| 153 | + | ||||
| 154 | + | ```bash | |||
| 155 | + | gordon remotes use prod | |||
| 156 | + | ``` | |||
| 157 | + | ||||
| 158 | + | When a remote is active, it's used automatically for all remote-capable commands: | |||
| 159 | + | ||||
| 160 | + | ```bash | |||
| 161 | + | gordon remotes use prod | |||
| 162 | + | gordon routes list # Uses prod remote | |||
| 163 | + | gordon secrets list app.com # Uses prod remote | |||
| 164 | + | ``` | |||
| 165 | + | ||||
| 166 | + | ## Resolution Precedence | |||
| 167 | + | ||||
| 168 | + | When multiple sources specify remote or token, the CLI uses this priority order: | |||
| 169 | + | ||||
| 170 | + | **Remote URL:** | |||
| 171 | + | 1. `--remote` flag | |||
| 172 | + | 2. `GORDON_REMOTE` environment variable | |||
| 173 | + | 3. Active remote from `remotes.toml` | |||
| 174 | + | ||||
| 175 | + | **Token:** | |||
| 176 | + | 1. `--token` flag | |||
| 177 | + | 2. `GORDON_TOKEN` environment variable | |||
| 178 | + | 3. Token from active remote in `remotes.toml` | |||
| 179 | + | ||||
| 180 | + | This allows overriding specific values while keeping defaults: | |||
| 181 | + | ||||
| 182 | + | ```bash | |||
| 183 | + | # Active remote is prod, but use different token | |||
| 184 | + | gordon routes list --token $TEMPORARY_TOKEN | |||
| 185 | + | ``` | |||
| 186 | + | ||||
| 187 | + | ## Commands Supporting Remote | |||
| 188 | + | ||||
| 189 | + | These commands work with remote targeting: | |||
| 190 | + | ||||
| 191 | + | | Command | Description | | |||
| 192 | + | |---------|-------------| | |||
| 193 | + | | `gordon routes list` | List all routes | | |||
| 194 | + | | `gordon routes add <domain> <image>` | Add a route | | |||
| 195 | + | | `gordon routes remove <domain>` | Remove a route | | |||
| 196 | + | | `gordon routes deploy <domain>` | Deploy/redeploy a route | | |||
| 197 | + | | `gordon secrets list <domain>` | List secrets for a domain | | |||
| 198 | + | | `gordon secrets set <domain> KEY=value` | Set secrets | | |||
| 199 | + | | `gordon secrets remove <domain> <key>` | Remove a secret | | |||
| 200 | + | | `gordon status` | Show server status | | |||
| 201 | + | ||||
| 202 | + | ## Token Security | |||
| 203 | + | ||||
| 204 | + | ### Option 1: Environment Variable Reference (Recommended) | |||
| 205 | + | ||||
| 206 | + | Store the environment variable name, not the actual token: | |||
| 207 | + | ||||
| 208 | + | ```bash | |||
| 209 | + | gordon remotes add prod https://gordon.mydomain.com --token-env PROD_TOKEN | |||
| 210 | + | ``` | |||
| 211 | + | ||||
| 212 | + | The `remotes.toml` stores only: | |||
| 213 | + | ||||
| 214 | + | ```toml | |||
| 215 | + | [remotes.prod] | |||
| 216 | + | url = "https://gordon.mydomain.com" | |||
| 217 | + | token_env = "PROD_TOKEN" | |||
| 218 | + | ``` | |||
| 219 | + | ||||
| 220 | + | At runtime, Gordon reads `$PROD_TOKEN` from the environment. | |||
| 221 | + | ||||
| 222 | + | **Benefits:** | |||
| 223 | + | - Token not stored in plaintext config | |||
| 224 | + | - Works with secret managers that inject env vars | |||
| 225 | + | - Easy rotation without editing config | |||
| 226 | + | ||||
| 227 | + | ### Option 2: Direct Token Storage | |||
| 228 | + | ||||
| 229 | + | ```bash | |||
| 230 | + | gordon remotes add prod https://gordon.mydomain.com --token eyJ... | |||
| 231 | + | ``` | |||
| 232 | + | ||||
| 233 | + | The token is stored directly in `remotes.toml`: | |||
| 234 | + | ||||
| 235 | + | ```toml | |||
| 236 | + | [remotes.prod] | |||
| 237 | + | url = "https://gordon.mydomain.com" | |||
| 238 | + | token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." | |||
| 239 | + | ``` | |||
| 240 | + | ||||
| 241 | + | **Security note:** Ensure `remotes.toml` has restricted permissions: | |||
| 242 | + | ||||
| 243 | + | ```bash | |||
| 244 | + | chmod 600 ~/.config/gordon/remotes.toml | |||
| 245 | + | ``` | |||
| 246 | + | ||||
| 247 | + | ### Option 3: Environment Variables Only | |||
| 248 | + | ||||
| 249 | + | For maximum security, don't save tokens at all: | |||
| 250 | + | ||||
| 251 | + | ```bash | |||
| 252 | + | # Add remote without token | |||
| 253 | + | gordon remotes add prod https://gordon.mydomain.com | |||
| 254 | + | ||||
| 255 | + | # Set token via environment | |||
| 256 | + | export GORDON_TOKEN=$TOKEN | |||
| 257 | + | ||||
| 258 | + | # Use normally | |||
| 259 | + | gordon remotes use prod | |||
| 260 | + | gordon routes list | |||
| 261 | + | ``` | |||
| 262 | + | ||||
| 263 | + | ## Workflow Examples | |||
| 264 | + | ||||
| 265 | + | ### Development Workflow | |||
| 266 | + | ||||
| 267 | + | ```bash | |||
| 268 | + | # Add dev and staging remotes | |||
| 269 | + | gordon remotes add dev https://gordon.dev.local --token-env DEV_TOKEN | |||
| 270 | + | gordon remotes add staging https://gordon.staging.example.com --token-env STAGING_TOKEN | |||
| 271 | + | ||||
| 272 | + | # Work with dev | |||
| 273 | + | gordon remotes use dev | |||
| 274 | + | gordon routes list | |||
| 275 | + | gordon routes add myapp.dev.local myapp:latest | |||
| 276 | + | ||||
| 277 | + | # Switch to staging | |||
| 278 | + | gordon remotes use staging | |||
| 279 | + | gordon routes list | |||
| 280 | + | ``` | |||
| 281 | + | ||||
| 282 | + | ### CI/CD Pipeline | |||
| 283 | + | ||||
| 284 | + | ```yaml | |||
| 285 | + | # GitHub Actions example | |||
| 286 | + | env: | |||
| 287 | + | GORDON_REMOTE: ${{ secrets.GORDON_URL }} | |||
| 288 | + | GORDON_TOKEN: ${{ secrets.GORDON_TOKEN }} | |||
| 289 | + | ||||
| 290 | + | steps: | |||
| 291 | + | - name: Deploy to Gordon | |||
| 292 | + | run: | | |||
| 293 | + | gordon routes deploy myapp.example.com | |||
| 294 | + | ``` | |||
| 295 | + | ||||
| 296 | + | ```bash | |||
| 297 | + | # GitLab CI example | |||
| 298 | + | deploy: | |||
| 299 | + | script: | |||
| 300 | + | - export GORDON_REMOTE=$GORDON_URL | |||
| 301 | + | - export GORDON_TOKEN=$GORDON_TOKEN | |||
| 302 | + | - gordon routes deploy myapp.example.com | |||
| 303 | + | ``` | |||
| 304 | + | ||||
| 305 | + | ### Multi-Environment Management | |||
| 306 | + | ||||
| 307 | + | ```bash | |||
| 308 | + | # Add all environments | |||
| 309 | + | gordon remotes add prod https://gordon.example.com --token-env PROD_TOKEN | |||
| 310 | + | gordon remotes add staging https://gordon.staging.example.com --token-env STAGING_TOKEN | |||
| 311 | + | gordon remotes add dev https://gordon.dev.example.com --token-env DEV_TOKEN | |||
| 312 | + | ||||
| 313 | + | # Compare routes across environments | |||
| 314 | + | gordon routes list --remote https://gordon.example.com --token $PROD_TOKEN | |||
| 315 | + | gordon routes list --remote https://gordon.staging.example.com --token $STAGING_TOKEN | |||
| 316 | + | ||||
| 317 | + | # Or switch active | |||
| 318 | + | gordon remotes use prod && gordon routes list | |||
| 319 | + | gordon remotes use staging && gordon routes list | |||
| 320 | + | ``` | |||
| 321 | + | ||||
| 322 | + | ## Troubleshooting | |||
| 323 | + | ||||
| 324 | + | ### "unauthorized" Error | |||
| 325 | + | ||||
| 326 | + | Token is missing, expired, or invalid. | |||
| 327 | + | ||||
| 328 | + | ```bash | |||
| 329 | + | # Check if token is set | |||
| 330 | + | echo $GORDON_TOKEN | |||
| 331 | + | ||||
| 332 | + | # Verify token works | |||
| 333 | + | gordon routes list --remote https://gordon.mydomain.com --token $TOKEN | |||
| 334 | + | ``` | |||
| 335 | + | ||||
| 336 | + | ### "connection refused" Error | |||
| 337 | + | ||||
| 338 | + | Remote Gordon isn't running or URL is wrong. | |||
| 339 | + | ||||
| 340 | + | ```bash | |||
| 341 | + | # Verify URL is correct | |||
| 342 | + | curl https://gordon.mydomain.com/health | |||
| 343 | + | ||||
| 344 | + | # Check if admin API is enabled on remote | |||
| 345 | + | # The remote gordon.toml needs: | |||
| 346 | + | # [admin] | |||
| 347 | + | # enabled = true | |||
| 348 | + | ``` | |||
| 349 | + | ||||
| 350 | + | ### Remote Not Found | |||
| 351 | + | ||||
| 352 | + | The specified remote doesn't exist in `remotes.toml`. | |||
| 353 | + | ||||
| 354 | + | ```bash | |||
| 355 | + | # List available remotes | |||
| 356 | + | gordon remotes list | |||
| 357 | + | ||||
| 358 | + | # Add the remote | |||
| 359 | + | gordon remotes add myremote https://gordon.mydomain.com | |||
| 360 | + | ``` | |||
| 361 | + | ||||
| 362 | + | ### Active Remote Cleared | |||
| 363 | + | ||||
| 364 | + | After removing the active remote, you need to set a new active: | |||
| 365 | + | ||||
| 366 | + | ```bash | |||
| 367 | + | gordon remotes use prod | |||
| 368 | + | ``` | |||
| 369 | + | ||||
| 370 | + | Or use explicit flags: | |||
| 371 | + | ||||
| 372 | + | ```bash | |||
| 373 | + | gordon routes list --remote https://gordon.mydomain.com --token $TOKEN | |||
| 374 | + | ``` | |||
| 375 | + | ||||
| 376 | + | ## Related | |||
| 377 | + | ||||
| 378 | + | - [CLI Commands](/docs/cli/commands.md) | |||
| 379 | + | - [Authentication](/docs/config/registry-auth.md) | |||
| 380 | + | - [Admin API](/docs/config/admin.md) | |||