v2.15.0 cf76057

remote-cli.md RawHistoryFolder

Remote CLI Management

Manage Gordon instances remotely using the CLI with the --remote flag or saved remotes.

What You'll Learn

  • Using global --remote and --token flags
  • Saving and managing remote connections
  • Environment variable configuration
  • Token security best practices
  • Remote command workflows

Prerequisites

  • Gordon CLI installed
  • A remote Gordon instance running with admin API enabled
  • Authentication token for the remote instance

Understanding the Remote URL

The --remote URL must be the gordon_domain configured on the remote Gordon instance. This domain serves both the container registry and the Admin API.

# On the remote Gordon server
[server]
gordon_domain = "gordon.example.com"  # Use this as --remote URL

The CLI connects to https://gordon.example.com/admin/* endpoints.

Quick Start

One-off Remote Command

gordon routes list --remote https://gordon.mydomain.com --token $TOKEN

Using Environment Variables

export GORDON_REMOTE=https://gordon.mydomain.com
export GORDON_TOKEN=$TOKEN
gordon routes list

Using Saved Remotes

# Add a remote
gordon remotes add prod https://gordon.mydomain.com --token-env PROD_TOKEN

# Set as active
gordon remotes use prod

# Now use without flags
gordon routes list

Global Flags

These flags are available on all commands:

Flag Description
--remote <URL> Remote Gordon URL
--token <TOKEN> Authentication token
# List routes on remote
gordon routes list --remote https://gordon.mydomain.com --token $TOKEN

# Manage secrets on remote
gordon secrets list myapp.example.com --remote https://gordon.mydomain.com --token $TOKEN

Environment Variables

Variable Description
GORDON_REMOTE Remote Gordon URL
GORDON_TOKEN Authentication token

Environment variables are useful for CI/CD pipelines and shell sessions:

# Set for current session
export GORDON_REMOTE=https://gordon.mydomain.com
export GORDON_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

# Commands automatically use these
gordon routes list
gordon secrets list myapp.example.com

Saved Remotes

Save frequently used remotes to avoid repeating URLs and tokens.

Configuration File

Remotes are stored in ~/.config/gordon/remotes.toml:

active = "prod"

[remotes.prod]
url = "https://gordon.mydomain.com"
token_env = "PROD_TOKEN"

[remotes.staging]
url = "https://staging.mydomain.com"
token = "eyJ..."

Managing Remotes

List Remotes

gordon remotes list

Output:

Saved Remotes

Name            URL                                    Token           Status
──────────────────────────────────────────────────────────────────────────────
prod            https://gordon.mydomain.com            $PROD_TOKEN     active
staging         https://staging.mydomain.com           set
dev             https://dev.mydomain.com               none

Add a Remote

# Basic (no token)
gordon remotes add prod https://gordon.mydomain.com

# With direct token
gordon remotes add prod https://gordon.mydomain.com --token eyJ...

# With environment variable reference (recommended)
gordon remotes add prod https://gordon.mydomain.com --token-env PROD_TOKEN
Flag Description
--token <TOKEN> Store token directly in config
--token-env <VAR> Store env variable name (token resolved at runtime)

Authenticate with Password Auth

For servers using password authentication, you can log in interactively:

# Login to active remote
gordon auth login

# Login to specific remote
gordon auth login --remote prod

# Pre-fill username
gordon auth login --username admin

This prompts for your username and password, authenticates with the remote server, and stores the returned token automatically.

Note: Only works with servers that have password authentication enabled (username + password_hash configured). For token-only servers, use gordon remotes set-token instead.

Set Token Manually

For servers using token-based auth, or to update a token manually:

# Set token directly
gordon remotes set-token prod eyJhbGciOiJIUzI1NiIs...

# Set token from file
gordon remotes set-token staging $(cat token.txt)

Remove a Remote

# With confirmation prompt
gordon remotes remove staging

# Skip confirmation
gordon remotes remove staging --force

Set Active Remote

gordon remotes use prod

When a remote is active, it's used automatically for all remote-capable commands:

gordon remotes use prod
gordon routes list              # Uses prod remote
gordon secrets list app.com     # Uses prod remote

Resolution Precedence

When multiple sources specify remote or token, the CLI uses this priority order:

Remote URL:

  1. --remote flag
  2. GORDON_REMOTE environment variable
  3. Active remote from remotes.toml

Token:

  1. --token flag
  2. GORDON_TOKEN environment variable
  3. Token from active remote in remotes.toml

This allows overriding specific values while keeping defaults:

# Active remote is prod, but use different token
gordon routes list --token $TEMPORARY_TOKEN

Commands Supporting Remote

These commands work with remote targeting:

Command Description
gordon routes list List all routes
gordon routes add <domain> <image> Add a route
gordon routes remove <domain> Remove a route
gordon routes deploy <domain> Deploy/redeploy a route
gordon attachments list [target] List all or targeted attachments
gordon attachments add <target> <image> Add an attachment
gordon attachments remove <target> <image> Remove an attachment
gordon secrets list <domain> List secrets for a domain
gordon secrets set <domain> KEY=value Set secrets
gordon secrets remove <domain> <key> Remove a secret
gordon status Show server status
gordon reload Reload config and start new routes
gordon logs View Gordon process logs
gordon logs <domain> View container logs

Remote Logs Requirement

The gordon logs command requires file logging to be enabled on the remote server. Without it, you'll get a "failed to get logs" error.

On the remote Gordon server, add to config.toml:

[logging.file]
enabled = true
# path is optional - defaults to {data_dir}/logs/gordon.log
# path = "/var/log/gordon/gordon.log"

Then restart Gordon. The log directory will be created automatically in your data directory (e.g., ~/.gordon/logs/).

If you specify a custom path, ensure the directory exists and is writable:

sudo mkdir -p /var/log/gordon
sudo chown gordon:gordon /var/log/gordon  # adjust user as needed

Note: When running as a systemd service, Gordon logs to journalctl by default. However, the remote admin API cannot read from journalctl—it reads from the configured log file. Both can be used simultaneously.

Token Security

Store the environment variable name, not the actual token:

gordon remotes add prod https://gordon.mydomain.com --token-env PROD_TOKEN

The remotes.toml stores only:

[remotes.prod]
url = "https://gordon.mydomain.com"
token_env = "PROD_TOKEN"

At runtime, Gordon reads $PROD_TOKEN from the environment.

Benefits:

  • Token not stored in plaintext config
  • Works with secret managers that inject env vars
  • Easy rotation without editing config

Option 2: Direct Token Storage

gordon remotes add prod https://gordon.mydomain.com --token eyJ...

The token is stored directly in remotes.toml:

[remotes.prod]
url = "https://gordon.mydomain.com"
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Security note: Ensure remotes.toml has restricted permissions:

chmod 600 ~/.config/gordon/remotes.toml

Option 3: Environment Variables Only

For maximum security, don't save tokens at all:

# Add remote without token
gordon remotes add prod https://gordon.mydomain.com

# Set token via environment
export GORDON_TOKEN=$TOKEN

# Use normally
gordon remotes use prod
gordon routes list

Workflow Examples

Development Workflow

# Add dev and staging remotes
gordon remotes add dev https://gordon.dev.local --token-env DEV_TOKEN
gordon remotes add staging https://gordon.staging.example.com --token-env STAGING_TOKEN

# Work with dev
gordon remotes use dev
gordon routes list
gordon routes add myapp.dev.local myapp:latest

# Switch to staging
gordon remotes use staging
gordon routes list

CI/CD Pipeline

# GitHub Actions example
env:
  GORDON_REMOTE: ${{ secrets.GORDON_URL }}
  GORDON_TOKEN: ${{ secrets.GORDON_TOKEN }}

steps:
  - name: Deploy to Gordon
    run: |
      gordon routes deploy myapp.example.com
# GitLab CI example
deploy:
  script:
    - export GORDON_REMOTE=$GORDON_URL
    - export GORDON_TOKEN=$GORDON_TOKEN
    - gordon routes deploy myapp.example.com

Multi-Environment Management

# Add all environments
gordon remotes add prod https://gordon.example.com --token-env PROD_TOKEN
gordon remotes add staging https://gordon.staging.example.com --token-env STAGING_TOKEN
gordon remotes add dev https://gordon.dev.example.com --token-env DEV_TOKEN

# Compare routes across environments
gordon routes list --remote https://gordon.example.com --token $PROD_TOKEN
gordon routes list --remote https://gordon.staging.example.com --token $STAGING_TOKEN

# Or switch active
gordon remotes use prod && gordon routes list
gordon remotes use staging && gordon routes list

Troubleshooting

"unauthorized" Error

Token is missing, expired, or invalid.

# Check if token is set
echo $GORDON_TOKEN

# Verify token works
gordon routes list --remote https://gordon.mydomain.com --token $TOKEN

"connection refused" Error

Remote Gordon isn't running or URL is wrong.

# Verify URL is correct
curl https://gordon.mydomain.com/health

# Check if admin API is enabled on remote
# The remote gordon.toml needs:
# [admin]
# enabled = true

Remote Not Found

The specified remote doesn't exist in remotes.toml.

# List available remotes
gordon remotes list

# Add the remote
gordon remotes add myremote https://gordon.mydomain.com

Active Remote Cleared

After removing the active remote, you need to set a new active:

gordon remotes use prod

Or use explicit flags:

gordon routes list --remote https://gordon.mydomain.com --token $TOKEN

"failed to get logs" Error

The remote Gordon server doesn't have file logging enabled.

# Error: failed to get process logs: 500 Internal Server Error: failed to get logs

On the remote server, enable file logging in config.toml:

[logging.file]
enabled = true
path = "/var/log/gordon/gordon.log"

See Remote Logs Requirement for details.

source
1# Remote CLI Management
2
3Manage 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## Understanding the Remote URL
20
21The `--remote` URL must be the `gordon_domain` configured on the remote Gordon instance. This domain serves both the container registry and the Admin API.
22
23```toml
24# On the remote Gordon server
25[server]
26gordon_domain = "gordon.example.com"  # Use this as --remote URL
27```
28
29The CLI connects to `https://gordon.example.com/admin/*` endpoints.
30
31## Quick Start
32
33### One-off Remote Command
34
35```bash
36gordon routes list --remote https://gordon.mydomain.com --token $TOKEN
37```
38
39### Using Environment Variables
40
41```bash
42export GORDON_REMOTE=https://gordon.mydomain.com
43export GORDON_TOKEN=$TOKEN
44gordon routes list
45```
46
47### Using Saved Remotes
48
49```bash
50# Add a remote
51gordon remotes add prod https://gordon.mydomain.com --token-env PROD_TOKEN
52
53# Set as active
54gordon remotes use prod
55
56# Now use without flags
57gordon routes list
58```
59
60## Global Flags
61
62These flags are available on all commands:
63
64| Flag | Description |
65|------|-------------|
66| `--remote <URL>` | Remote Gordon URL |
67| `--token <TOKEN>` | Authentication token |
68
69```bash
70# List routes on remote
71gordon routes list --remote https://gordon.mydomain.com --token $TOKEN
72
73# Manage secrets on remote
74gordon secrets list myapp.example.com --remote https://gordon.mydomain.com --token $TOKEN
75```
76
77## Environment Variables
78
79| Variable | Description |
80|----------|-------------|
81| `GORDON_REMOTE` | Remote Gordon URL |
82| `GORDON_TOKEN` | Authentication token |
83
84Environment variables are useful for CI/CD pipelines and shell sessions:
85
86```bash
87# Set for current session
88export GORDON_REMOTE=https://gordon.mydomain.com
89export GORDON_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
90
91# Commands automatically use these
92gordon routes list
93gordon secrets list myapp.example.com
94```
95
96## Saved Remotes
97
98Save frequently used remotes to avoid repeating URLs and tokens.
99
100### Configuration File
101
102Remotes are stored in `~/.config/gordon/remotes.toml`:
103
104```toml
105active = "prod"
106
107[remotes.prod]
108url = "https://gordon.mydomain.com"
109token_env = "PROD_TOKEN"
110
111[remotes.staging]
112url = "https://staging.mydomain.com"
113token = "eyJ..."
114```
115
116### Managing Remotes
117
118#### List Remotes
119
120```bash
121gordon remotes list
122```
123
124Output:
125
126```
127Saved Remotes
128
129Name            URL                                    Token           Status
130──────────────────────────────────────────────────────────────────────────────
131prod            https://gordon.mydomain.com            $PROD_TOKEN     active
132staging         https://staging.mydomain.com           set
133dev             https://dev.mydomain.com               none
134```
135
136#### Add a Remote
137
138```bash
139# Basic (no token)
140gordon remotes add prod https://gordon.mydomain.com
141
142# With direct token
143gordon remotes add prod https://gordon.mydomain.com --token eyJ...
144
145# With environment variable reference (recommended)
146gordon remotes add prod https://gordon.mydomain.com --token-env PROD_TOKEN
147```
148
149| Flag | Description |
150|------|-------------|
151| `--token <TOKEN>` | Store token directly in config |
152| `--token-env <VAR>` | Store env variable name (token resolved at runtime) |
153
154#### Authenticate with Password Auth
155
156For servers using password authentication, you can log in interactively:
157
158```bash
159# Login to active remote
160gordon auth login
161
162# Login to specific remote
163gordon auth login --remote prod
164
165# Pre-fill username
166gordon auth login --username admin
167```
168
169This prompts for your username and password, authenticates with the remote server, and stores the returned token automatically.
170
171> **Note:** Only works with servers that have password authentication enabled (`username` + `password_hash` configured). For token-only servers, use `gordon remotes set-token` instead.
172
173#### Set Token Manually
174
175For servers using token-based auth, or to update a token manually:
176
177```bash
178# Set token directly
179gordon remotes set-token prod eyJhbGciOiJIUzI1NiIs...
180
181# Set token from file
182gordon remotes set-token staging $(cat token.txt)
183```
184
185#### Remove a Remote
186
187```bash
188# With confirmation prompt
189gordon remotes remove staging
190
191# Skip confirmation
192gordon remotes remove staging --force
193```
194
195#### Set Active Remote
196
197```bash
198gordon remotes use prod
199```
200
201When a remote is active, it's used automatically for all remote-capable commands:
202
203```bash
204gordon remotes use prod
205gordon routes list              # Uses prod remote
206gordon secrets list app.com     # Uses prod remote
207```
208
209## Resolution Precedence
210
211When multiple sources specify remote or token, the CLI uses this priority order:
212
213**Remote URL:**
2141. `--remote` flag
2152. `GORDON_REMOTE` environment variable
2163. Active remote from `remotes.toml`
217
218**Token:**
2191. `--token` flag
2202. `GORDON_TOKEN` environment variable
2213. Token from active remote in `remotes.toml`
222
223This allows overriding specific values while keeping defaults:
224
225```bash
226# Active remote is prod, but use different token
227gordon routes list --token $TEMPORARY_TOKEN
228```
229
230## Commands Supporting Remote
231
232These commands work with remote targeting:
233
234| Command | Description |
235|---------|-------------|
236| `gordon routes list` | List all routes |
237| `gordon routes add <domain> <image>` | Add a route |
238| `gordon routes remove <domain>` | Remove a route |
239| `gordon routes deploy <domain>` | Deploy/redeploy a route |
240| `gordon attachments list [target]` | List all or targeted attachments |
241| `gordon attachments add <target> <image>` | Add an attachment |
242| `gordon attachments remove <target> <image>` | Remove an attachment |
243| `gordon secrets list <domain>` | List secrets for a domain |
244| `gordon secrets set <domain> KEY=value` | Set secrets |
245| `gordon secrets remove <domain> <key>` | Remove a secret |
246| `gordon status` | Show server status |
247| `gordon reload` | Reload config and start new routes |
248| `gordon logs` | View Gordon process logs |
249| `gordon logs <domain>` | View container logs |
250
251### Remote Logs Requirement
252
253The `gordon logs` command requires **file logging to be enabled** on the remote server. Without it, you'll get a "failed to get logs" error.
254
255On the remote Gordon server, add to `config.toml`:
256
257```toml
258[logging.file]
259enabled = true
260# path is optional - defaults to {data_dir}/logs/gordon.log
261# path = "/var/log/gordon/gordon.log"
262```
263
264Then restart Gordon. The log directory will be created automatically in your data directory (e.g., `~/.gordon/logs/`).
265
266If you specify a custom path, ensure the directory exists and is writable:
267
268```bash
269sudo mkdir -p /var/log/gordon
270sudo chown gordon:gordon /var/log/gordon  # adjust user as needed
271```
272
273> **Note:** When running as a systemd service, Gordon logs to journalctl by default. However, the remote admin API cannot read from journalctl—it reads from the configured log file. Both can be used simultaneously.
274
275## Token Security
276
277### Option 1: Environment Variable Reference (Recommended)
278
279Store the environment variable name, not the actual token:
280
281```bash
282gordon remotes add prod https://gordon.mydomain.com --token-env PROD_TOKEN
283```
284
285The `remotes.toml` stores only:
286
287```toml
288[remotes.prod]
289url = "https://gordon.mydomain.com"
290token_env = "PROD_TOKEN"
291```
292
293At runtime, Gordon reads `$PROD_TOKEN` from the environment.
294
295**Benefits:**
296- Token not stored in plaintext config
297- Works with secret managers that inject env vars
298- Easy rotation without editing config
299
300### Option 2: Direct Token Storage
301
302```bash
303gordon remotes add prod https://gordon.mydomain.com --token eyJ...
304```
305
306The token is stored directly in `remotes.toml`:
307
308```toml
309[remotes.prod]
310url = "https://gordon.mydomain.com"
311token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
312```
313
314**Security note:** Ensure `remotes.toml` has restricted permissions:
315
316```bash
317chmod 600 ~/.config/gordon/remotes.toml
318```
319
320### Option 3: Environment Variables Only
321
322For maximum security, don't save tokens at all:
323
324```bash
325# Add remote without token
326gordon remotes add prod https://gordon.mydomain.com
327
328# Set token via environment
329export GORDON_TOKEN=$TOKEN
330
331# Use normally
332gordon remotes use prod
333gordon routes list
334```
335
336## Workflow Examples
337
338### Development Workflow
339
340```bash
341# Add dev and staging remotes
342gordon remotes add dev https://gordon.dev.local --token-env DEV_TOKEN
343gordon remotes add staging https://gordon.staging.example.com --token-env STAGING_TOKEN
344
345# Work with dev
346gordon remotes use dev
347gordon routes list
348gordon routes add myapp.dev.local myapp:latest
349
350# Switch to staging
351gordon remotes use staging
352gordon routes list
353```
354
355### CI/CD Pipeline
356
357```yaml
358# GitHub Actions example
359env:
360  GORDON_REMOTE: ${{ secrets.GORDON_URL }}
361  GORDON_TOKEN: ${{ secrets.GORDON_TOKEN }}
362
363steps:
364  - name: Deploy to Gordon
365    run: |
366      gordon routes deploy myapp.example.com
367```
368
369```bash
370# GitLab CI example
371deploy:
372  script:
373    - export GORDON_REMOTE=$GORDON_URL
374    - export GORDON_TOKEN=$GORDON_TOKEN
375    - gordon routes deploy myapp.example.com
376```
377
378### Multi-Environment Management
379
380```bash
381# Add all environments
382gordon remotes add prod https://gordon.example.com --token-env PROD_TOKEN
383gordon remotes add staging https://gordon.staging.example.com --token-env STAGING_TOKEN
384gordon remotes add dev https://gordon.dev.example.com --token-env DEV_TOKEN
385
386# Compare routes across environments
387gordon routes list --remote https://gordon.example.com --token $PROD_TOKEN
388gordon routes list --remote https://gordon.staging.example.com --token $STAGING_TOKEN
389
390# Or switch active
391gordon remotes use prod && gordon routes list
392gordon remotes use staging && gordon routes list
393```
394
395## Troubleshooting
396
397### "unauthorized" Error
398
399Token is missing, expired, or invalid.
400
401```bash
402# Check if token is set
403echo $GORDON_TOKEN
404
405# Verify token works
406gordon routes list --remote https://gordon.mydomain.com --token $TOKEN
407```
408
409### "connection refused" Error
410
411Remote Gordon isn't running or URL is wrong.
412
413```bash
414# Verify URL is correct
415curl https://gordon.mydomain.com/health
416
417# Check if admin API is enabled on remote
418# The remote gordon.toml needs:
419# [admin]
420# enabled = true
421```
422
423### Remote Not Found
424
425The specified remote doesn't exist in `remotes.toml`.
426
427```bash
428# List available remotes
429gordon remotes list
430
431# Add the remote
432gordon remotes add myremote https://gordon.mydomain.com
433```
434
435### Active Remote Cleared
436
437After removing the active remote, you need to set a new active:
438
439```bash
440gordon remotes use prod
441```
442
443Or use explicit flags:
444
445```bash
446gordon routes list --remote https://gordon.mydomain.com --token $TOKEN
447```
448
449### "failed to get logs" Error
450
451The remote Gordon server doesn't have file logging enabled.
452
453```bash
454# Error: failed to get process logs: 500 Internal Server Error: failed to get logs
455```
456
457On the remote server, enable file logging in `config.toml`:
458
459```toml
460[logging.file]
461enabled = true
462path = "/var/log/gordon/gordon.log"
463```
464
465See [Remote Logs Requirement](#remote-logs-requirement) for details.
466
467## Related
468
469- [CLI Commands](/docs/cli/index.md)
470- [Authentication](/docs/config/auth.md)
471- [Attachments](/docs/config/attachments.md)

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close