v2.5.0 b9b6391

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)

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 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#### Remove a Remote
155
156```bash
157# With confirmation prompt
158gordon remotes remove staging
159
160# Skip confirmation
161gordon remotes remove staging --force
162```
163
164#### Set Active Remote
165
166```bash
167gordon remotes use prod
168```
169
170When a remote is active, it's used automatically for all remote-capable commands:
171
172```bash
173gordon remotes use prod
174gordon routes list              # Uses prod remote
175gordon secrets list app.com     # Uses prod remote
176```
177
178## Resolution Precedence
179
180When multiple sources specify remote or token, the CLI uses this priority order:
181
182**Remote URL:**
1831. `--remote` flag
1842. `GORDON_REMOTE` environment variable
1853. Active remote from `remotes.toml`
186
187**Token:**
1881. `--token` flag
1892. `GORDON_TOKEN` environment variable
1903. Token from active remote in `remotes.toml`
191
192This allows overriding specific values while keeping defaults:
193
194```bash
195# Active remote is prod, but use different token
196gordon routes list --token $TEMPORARY_TOKEN
197```
198
199## Commands Supporting Remote
200
201These commands work with remote targeting:
202
203| Command | Description |
204|---------|-------------|
205| `gordon routes list` | List all routes |
206| `gordon routes add <domain> <image>` | Add a route |
207| `gordon routes remove <domain>` | Remove a route |
208| `gordon routes deploy <domain>` | Deploy/redeploy a route |
209| `gordon secrets list <domain>` | List secrets for a domain |
210| `gordon secrets set <domain> KEY=value` | Set secrets |
211| `gordon secrets remove <domain> <key>` | Remove a secret |
212| `gordon status` | Show server status |
213| `gordon reload` | Reload config and start new routes |
214| `gordon logs` | View Gordon process logs |
215| `gordon logs <domain>` | View container logs |
216
217### Remote Logs Requirement
218
219The `gordon logs` command requires **file logging to be enabled** on the remote server. Without it, you'll get a "failed to get logs" error.
220
221On the remote Gordon server, add to `config.toml`:
222
223```toml
224[logging.file]
225enabled = true
226# path is optional - defaults to {data_dir}/logs/gordon.log
227# path = "/var/log/gordon/gordon.log"
228```
229
230Then restart Gordon. The log directory will be created automatically in your data directory (e.g., `~/.gordon/logs/`).
231
232If you specify a custom path, ensure the directory exists and is writable:
233
234```bash
235sudo mkdir -p /var/log/gordon
236sudo chown gordon:gordon /var/log/gordon  # adjust user as needed
237```
238
239> **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.
240
241## Token Security
242
243### Option 1: Environment Variable Reference (Recommended)
244
245Store the environment variable name, not the actual token:
246
247```bash
248gordon remotes add prod https://gordon.mydomain.com --token-env PROD_TOKEN
249```
250
251The `remotes.toml` stores only:
252
253```toml
254[remotes.prod]
255url = "https://gordon.mydomain.com"
256token_env = "PROD_TOKEN"
257```
258
259At runtime, Gordon reads `$PROD_TOKEN` from the environment.
260
261**Benefits:**
262- Token not stored in plaintext config
263- Works with secret managers that inject env vars
264- Easy rotation without editing config
265
266### Option 2: Direct Token Storage
267
268```bash
269gordon remotes add prod https://gordon.mydomain.com --token eyJ...
270```
271
272The token is stored directly in `remotes.toml`:
273
274```toml
275[remotes.prod]
276url = "https://gordon.mydomain.com"
277token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
278```
279
280**Security note:** Ensure `remotes.toml` has restricted permissions:
281
282```bash
283chmod 600 ~/.config/gordon/remotes.toml
284```
285
286### Option 3: Environment Variables Only
287
288For maximum security, don't save tokens at all:
289
290```bash
291# Add remote without token
292gordon remotes add prod https://gordon.mydomain.com
293
294# Set token via environment
295export GORDON_TOKEN=$TOKEN
296
297# Use normally
298gordon remotes use prod
299gordon routes list
300```
301
302## Workflow Examples
303
304### Development Workflow
305
306```bash
307# Add dev and staging remotes
308gordon remotes add dev https://gordon.dev.local --token-env DEV_TOKEN
309gordon remotes add staging https://gordon.staging.example.com --token-env STAGING_TOKEN
310
311# Work with dev
312gordon remotes use dev
313gordon routes list
314gordon routes add myapp.dev.local myapp:latest
315
316# Switch to staging
317gordon remotes use staging
318gordon routes list
319```
320
321### CI/CD Pipeline
322
323```yaml
324# GitHub Actions example
325env:
326  GORDON_REMOTE: ${{ secrets.GORDON_URL }}
327  GORDON_TOKEN: ${{ secrets.GORDON_TOKEN }}
328
329steps:
330  - name: Deploy to Gordon
331    run: |
332      gordon routes deploy myapp.example.com
333```
334
335```bash
336# GitLab CI example
337deploy:
338  script:
339    - export GORDON_REMOTE=$GORDON_URL
340    - export GORDON_TOKEN=$GORDON_TOKEN
341    - gordon routes deploy myapp.example.com
342```
343
344### Multi-Environment Management
345
346```bash
347# Add all environments
348gordon remotes add prod https://gordon.example.com --token-env PROD_TOKEN
349gordon remotes add staging https://gordon.staging.example.com --token-env STAGING_TOKEN
350gordon remotes add dev https://gordon.dev.example.com --token-env DEV_TOKEN
351
352# Compare routes across environments
353gordon routes list --remote https://gordon.example.com --token $PROD_TOKEN
354gordon routes list --remote https://gordon.staging.example.com --token $STAGING_TOKEN
355
356# Or switch active
357gordon remotes use prod && gordon routes list
358gordon remotes use staging && gordon routes list
359```
360
361## Troubleshooting
362
363### "unauthorized" Error
364
365Token is missing, expired, or invalid.
366
367```bash
368# Check if token is set
369echo $GORDON_TOKEN
370
371# Verify token works
372gordon routes list --remote https://gordon.mydomain.com --token $TOKEN
373```
374
375### "connection refused" Error
376
377Remote Gordon isn't running or URL is wrong.
378
379```bash
380# Verify URL is correct
381curl https://gordon.mydomain.com/health
382
383# Check if admin API is enabled on remote
384# The remote gordon.toml needs:
385# [admin]
386# enabled = true
387```
388
389### Remote Not Found
390
391The specified remote doesn't exist in `remotes.toml`.
392
393```bash
394# List available remotes
395gordon remotes list
396
397# Add the remote
398gordon remotes add myremote https://gordon.mydomain.com
399```
400
401### Active Remote Cleared
402
403After removing the active remote, you need to set a new active:
404
405```bash
406gordon remotes use prod
407```
408
409Or use explicit flags:
410
411```bash
412gordon routes list --remote https://gordon.mydomain.com --token $TOKEN
413```
414
415### "failed to get logs" Error
416
417The remote Gordon server doesn't have file logging enabled.
418
419```bash
420# Error: failed to get process logs: 500 Internal Server Error: failed to get logs
421```
422
423On the remote server, enable file logging in `config.toml`:
424
425```toml
426[logging.file]
427enabled = true
428path = "/var/log/gordon/gordon.log"
429```
430
431See [Remote Logs Requirement](#remote-logs-requirement) for details.
432
433## Related
434
435- [CLI Commands](/docs/cli/commands.md)
436- [Authentication](/docs/config/registry-auth.md)
437- [Admin API](/docs/config/admin.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