Remotes Commands
Manage saved remote Gordon instances for easier CLI usage.
gordon remotes
Subcommands
| Subcommand | Description |
|---|---|
list |
List saved remotes |
add |
Add a new remote |
remove |
Remove a saved remote |
use |
Set active remote |
set-token |
Set or update token for a remote |
gordon remotes list
List all saved 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
gordon remotes add
Add a new remote.
gordon remotes add <name> <url> [options]
Arguments
| Argument | Description |
|---|---|
<name> |
Name for the remote (e.g., prod, staging) |
<url> |
Gordon URL (the gordon_domain from remote config) |
Note:
<url>must match the configuredgordon_domain. Older servers that only setregistry_domainmay need a config migration before remote CLI works.
Options
| Option | Description |
|---|---|
--token |
Store token directly in config |
--token-env |
Store environment variable name (token resolved at runtime) |
--insecure |
Skip TLS certificate verification for this remote |
Examples
# 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
# With self-signed certificate
gordon remotes add dev https://dev.internal --insecure
Token Security
Option 1: pass Store (Recommended)
When pass is installed and initialized, Gordon stores tokens encrypted via GPG automatically. No extra flags are needed -- gordon auth login and gordon remotes set-token use pass when available.
Tokens are stored at the path gordon/remotes/<name>/token inside the pass store. If pass is unavailable, Gordon falls back to plaintext config with a warning.
Option 2: Environment Variable Reference
gordon remotes add prod https://gordon.mydomain.com --token-env PROD_TOKEN
The remotes.toml stores only the variable name:
[remotes.prod]
url = "https://gordon.mydomain.com"
token_env = "PROD_TOKEN"
At runtime, Gordon reads $PROD_TOKEN from the environment.
Option 3: Direct Token Storage
gordon remotes add prod https://gordon.mydomain.com --token eyJ...
The token is stored directly in ~/.config/gordon/remotes.toml. Ensure restricted permissions:
chmod 600 ~/.config/gordon/remotes.toml
gordon remotes remove
Remove a saved remote.
gordon remotes remove <name>
gordon remotes remove <name> --force # Skip confirmation
Arguments
| Argument | Description |
|---|---|
<name> |
Name of the remote to remove |
Options
| Option | Description |
|---|---|
--force |
Skip confirmation prompt |
Example
gordon remotes remove staging
gordon remotes use
Set the active remote.
gordon remotes use <name>
Arguments
| Argument | Description |
|---|---|
<name> |
Name of the remote to set as active |
Description
When a remote is active, it's used automatically for most remote-capable commands without needing to specify --remote and --token.
If no remote is active and you do not pass --remote, Gordon can also auto-infer a saved remote for gordon images push and gordon images tags <repository>. It only auto-selects when exactly one saved remote matches. Ambiguous matches and probe failures require an explicit --remote.
gordon remotes use prod
gordon apps list # Uses prod remote automatically
gordon daemon status # Uses prod remote automatically
Example
gordon remotes use prod
gordon remotes set-token
Set or update the authentication token for a saved remote.
gordon remotes set-token <name> <token>
Arguments
| Argument | Description |
|---|---|
<name> |
Name of the remote |
<token> |
The JWT token to set |
Description
This command is useful when:
- You have a pre-generated token from
gordon auth token generate - You want to update an expired token
Examples
# Set token for prod remote
gordon remotes set-token prod eyJhbGciOiJIUzI1NiIs...
# Set token from file
gordon remotes set-token staging $(cat token.txt)
# Set token from environment variable
gordon remotes set-token prod "$GORDON_TOKEN"
Output
✓ Token updated for remote 'prod'
Configuration File
Remotes are stored in ~/.config/gordon/remotes.toml:
active = "prod"
[remotes.prod]
url = "https://gordon.mydomain.com"
token_env = "PROD_TOKEN"
insecure_tls = true
[remotes.staging]
url = "https://staging.mydomain.com"
token = "eyJ..."
Resolution Precedence
When multiple sources specify remote or token, the CLI uses this priority:
For aggregate views, --remote and GORDON_REMOTE are the explicit single-target selectors. Without either one, those commands aggregate local + saved remotes even when an active remote exists.
Auto-inference is not used for those aggregate views.
Remote target selection:
--remoteflagGORDON_REMOTEenvironment variable- Active remote from
remotes.toml - Auto-inferred saved remote for supported target-based commands
Token:
--tokenflagGORDON_TOKENenvironment variable- Token from client config (
gordon.toml) passstore (gordon/remotes/<name>/token)- Token from active remote in
remotes.toml
Insecure TLS:
--insecureflagGORDON_INSECUREenvironment variable (true/false)[client] insecure_tlsingordon.tomlinsecure_tlsfrom the selected remote inremotes.toml
This allows overriding specific values while keeping defaults:
# Force one target
GORDON_REMOTE=prod gordon daemon status
Workflow Examples
Multi-Environment Setup
# 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
# Work with prod
gordon remotes use prod
gordon apps list
gordon daemon status
# Switch to staging
gordon remotes use staging
GORDON_REMOTE=staging gordon daemon status
CI/CD Pipeline
# GitHub Actions example
env:
GORDON_REMOTE: ${{ secrets.GORDON_URL }}
GORDON_TOKEN: ${{ secrets.GORDON_TOKEN }}
steps:
- name: Push to Gordon
run: |
gordon images push myapp --build --remote ${{ secrets.GORDON_URL }}
Compare Environments
# Compare one target at a time
gordon daemon status --remote https://gordon.example.com --token $PROD_TOKEN
GORDON_REMOTE=staging gordon daemon status
# Or switch between active remotes for other commands
gordon remotes use prod && gordon apps list
gordon remotes use staging && gordon apps list
Private Admin + Wildcard App Domains
Recommended default: use your normal Gordon admin domain with a valid public certificate.
# ~/.config/gordon/remotes.toml
active = "prod"
[remotes.prod]
url = "https://gordon.example.com"
token_env = "GORDON_TOKEN"
A common Tailscale setup is to point your domain's DNS at the machine's Tailscale IP (Cloudflare DNS-only / grey cloud). Since the server isn't publicly reachable, there is no external CA to issue a trusted certificate — Gordon's internal CA handles TLS automatically. Clients need to trust the internal CA:
insecure_tls = trueon the remote — skips certificate verification entirelysudo gordon ca install— on the Gordon host only: installs the root CA into system, Firefox, and Java trust storesgordon ca export --remote <name> --out gordon-ca.crt— fetches the root CA PEM from the remote for manual installation- Visit
https://<gordon-host>/.well-known/gordon/ca(or your mapped edge address) in a browser — onboarding page with downloads for macOS, Linux, Windows, iOS, and Android
If you have your own certificate for the domain (e.g. from a corporate CA), you can provide it via tls_cert_file/tls_key_file — see Server Configuration. The static cert is served for SNI-matching domains; everything else falls through to the internal CA.
insecure_tls only affects CLI -> Gordon admin HTTPS verification. It does not change runtime routing: the reverse proxy can still serve wildcard app domains like *.example.com.
Migration from [client] Config
The [client] section in gordon.toml is deprecated. On first run, Gordon
auto-migrates it to a default remote entry in remotes.toml and sets it
as active. No manual action needed.