main bac21c6

generic-ci.md RawHistoryFolder

Generic CI/CD Deployment

Deploy with Gordon from any CI/CD system.

Requirements

  • Docker available on CI runner (for building images)
  • Network access to the public Gordon HTTPS domain; do not expose or target the loopback server.registry_port
  • Gordon binary (optional but recommended)

1. Generate Deployment Token

On your Gordon server:

gordon auth token generate \
  --subject ci-deploy \
  --scopes "push,pull,admin:apps:read,admin:apps:write" \
  --expiry 0

2. Configure CI Secrets

Add these secrets to your CI system:

Secret Value
GORDON_TOKEN The generated token
GORDON_REMOTE https://gordon.example.com

3. Pipeline Steps

# 1. Install Gordon binary
curl -fsSL https://git.bnema.dev/gordon/releases/latest/download/gordon_linux_amd64 \
  -o /usr/local/bin/gordon
chmod +x /usr/local/bin/gordon

# 2. Build, push, and deploy
export GORDON_TOKEN="$GORDON_TOKEN"
gordon images push --build \
  --remote "$GORDON_REMOTE" \

Gordon auto-detects the version from CI environment variables:

CI System Variable Example
GitHub Actions $GITHUB_REF refs/tags/v1.2.0
GitLab CI $CI_COMMIT_TAG v1.2.0
Azure DevOps $BUILD_SOURCEBRANCH refs/tags/v1.2.0
Other --tag flag gordon images push --tag v1.2.0

Alternative: docker push

If installing the Gordon binary is not possible:

# 1. Login to Gordon registry
echo "$GORDON_TOKEN" | docker login gordon.example.com \
  -u ci-deploy --password-stdin

# 2. Build and push
docker build -t gordon.example.com/myapp:v1.0.0 .
docker push gordon.example.com/myapp:v1.0.0

This requires the token subject (ci-deploy) as the username. Pushing only stores the image; deploy explicitly with gordon apps deploy afterwards.

CI System Examples

Jenkins

pipeline {
    agent any
    environment {
        GORDON_TOKEN = credentials('gordon-token')
        GORDON_REMOTE = 'https://gordon.example.com'
    }
    stages {
        stage('Deploy') {
            steps {
                sh '''
                    curl -fsSL https://git.bnema.dev/gordon/releases/latest/download/gordon_linux_amd64 \
                      -o /usr/local/bin/gordon
                    chmod +x /usr/local/bin/gordon
                    gordon images push --build --remote "$GORDON_REMOTE"
                '''
            }
        }
    }
}

CircleCI

version: 2.1

jobs:
  deploy:
    docker:
      - image: docker:24
    steps:
      - checkout
      - setup_remote_docker
      - run:
          name: Install Gordon
          command: |
            apk add --no-cache curl
            curl -fsSL https://git.bnema.dev/gordon/releases/latest/download/gordon_linux_amd64 \
              -o /usr/local/bin/gordon
            chmod +x /usr/local/bin/gordon
      - run:
          name: Deploy
          command: |
            gordon images push --build \
              --remote "$GORDON_REMOTE"

workflows:
  deploy:
    jobs:
      - deploy:
          filters:
            tags:
              only: /^v.*/
            branches:
              ignore: /.*/

Drone

kind: pipeline
type: docker
name: deploy

steps:
  - name: deploy
    image: docker:24
    environment:
      GORDON_TOKEN:
        from_secret: gordon_token
      GORDON_REMOTE:
        from_secret: gordon_remote
    commands:
      - apk add --no-cache curl
      - curl -fsSL https://git.bnema.dev/gordon/releases/latest/download/gordon_linux_amd64 -o /usr/local/bin/gordon
      - chmod +x /usr/local/bin/gordon
      - gordon images push --build --remote "$GORDON_REMOTE"

trigger:
  event:
    - tag

Token Scopes Reference

Use the minimum scopes for the steps the pipeline performs. A repository restriction limits registry access only; it does not narrow admin:* permissions.

Workflow Required Scopes
Build + push, then apply + deploy push,pull,admin:apps:read,admin:apps:write
gordon images push only (no deploy) push,pull,admin:apps:read
docker push only (no deploy) push,pull
docker push, then apply + deploy push,pull + admin:apps:read,admin:apps:write for the CLI step

Troubleshooting

"failed to verify token"

The token is invalid or has been revoked. Generate a new one.

"deploy target not found" / app has no desired state

Push only stores the image. Declare the app first:

gordon apps apply --file myapp.toml --remote "$GORDON_REMOTE"
gordon apps deploy myapp --remote "$GORDON_REMOTE"

Version shows "latest"

Gordon could not detect a version tag. Either:

  • Tag your git repo: git tag v1.0.0 && git push --tags
  • Pass explicitly: gordon images push --tag v1.0.0

Large images time out

Gordon uploads in 50MB chunks. For very large images (> 1GB), the push may take several minutes. Ensure your CI runner timeout is sufficient.

source
1# Generic CI/CD Deployment
2
3Deploy with Gordon from any CI/CD system.
4
5## Requirements
6
7- Docker available on CI runner (for building images)
8- Network access to the public Gordon HTTPS domain; do not expose or target the loopback `server.registry_port`
9- Gordon binary (optional but recommended)
10
11## Recommended: gordon images push
12
13### 1. Generate Deployment Token
14
15On your Gordon server:
16
17```bash
18gordon auth token generate \
19  --subject ci-deploy \
20  --scopes "push,pull,admin:apps:read,admin:apps:write" \
21  --expiry 0
22```
23
24### 2. Configure CI Secrets
25
26Add these secrets to your CI system:
27
28| Secret | Value |
29|--------|-------|
30| `GORDON_TOKEN` | The generated token |
31| `GORDON_REMOTE` | `https://gordon.example.com` |
32
33### 3. Pipeline Steps
34
35```bash
36# 1. Install Gordon binary
37curl -fsSL https://git.bnema.dev/gordon/releases/latest/download/gordon_linux_amd64 \
38  -o /usr/local/bin/gordon
39chmod +x /usr/local/bin/gordon
40
41# 2. Build, push, and deploy
42export GORDON_TOKEN="$GORDON_TOKEN"
43gordon images push --build \
44  --remote "$GORDON_REMOTE" \
45
46```
47
48Gordon auto-detects the version from CI environment variables:
49
50| CI System | Variable | Example |
51|-----------|----------|---------|
52| GitHub Actions | `$GITHUB_REF` | `refs/tags/v1.2.0` |
53| GitLab CI | `$CI_COMMIT_TAG` | `v1.2.0` |
54| Azure DevOps | `$BUILD_SOURCEBRANCH` | `refs/tags/v1.2.0` |
55| Other | `--tag` flag | `gordon images push --tag v1.2.0` |
56
57## Alternative: docker push
58
59If installing the Gordon binary is not possible:
60
61```bash
62# 1. Login to Gordon registry
63echo "$GORDON_TOKEN" | docker login gordon.example.com \
64  -u ci-deploy --password-stdin
65
66# 2. Build and push
67docker build -t gordon.example.com/myapp:v1.0.0 .
68docker push gordon.example.com/myapp:v1.0.0
69```
70
71This requires the token subject (`ci-deploy`) as the username.
72Pushing only stores the image; deploy explicitly with `gordon apps deploy` afterwards.
73
74## CI System Examples
75
76### Jenkins
77
78```groovy
79pipeline {
80    agent any
81    environment {
82        GORDON_TOKEN = credentials('gordon-token')
83        GORDON_REMOTE = 'https://gordon.example.com'
84    }
85    stages {
86        stage('Deploy') {
87            steps {
88                sh '''
89                    curl -fsSL https://git.bnema.dev/gordon/releases/latest/download/gordon_linux_amd64 \
90                      -o /usr/local/bin/gordon
91                    chmod +x /usr/local/bin/gordon
92                    gordon images push --build --remote "$GORDON_REMOTE"
93                '''
94            }
95        }
96    }
97}
98```
99
100### CircleCI
101
102```yaml
103version: 2.1
104
105jobs:
106  deploy:
107    docker:
108      - image: docker:24
109    steps:
110      - checkout
111      - setup_remote_docker
112      - run:
113          name: Install Gordon
114          command: |
115            apk add --no-cache curl
116            curl -fsSL https://git.bnema.dev/gordon/releases/latest/download/gordon_linux_amd64 \
117              -o /usr/local/bin/gordon
118            chmod +x /usr/local/bin/gordon
119      - run:
120          name: Deploy
121          command: |
122            gordon images push --build \
123              --remote "$GORDON_REMOTE"
124
125workflows:
126  deploy:
127    jobs:
128      - deploy:
129          filters:
130            tags:
131              only: /^v.*/
132            branches:
133              ignore: /.*/
134```
135
136### Drone
137
138```yaml
139kind: pipeline
140type: docker
141name: deploy
142
143steps:
144  - name: deploy
145    image: docker:24
146    environment:
147      GORDON_TOKEN:
148        from_secret: gordon_token
149      GORDON_REMOTE:
150        from_secret: gordon_remote
151    commands:
152      - apk add --no-cache curl
153      - curl -fsSL https://git.bnema.dev/gordon/releases/latest/download/gordon_linux_amd64 -o /usr/local/bin/gordon
154      - chmod +x /usr/local/bin/gordon
155      - gordon images push --build --remote "$GORDON_REMOTE"
156
157trigger:
158  event:
159    - tag
160```
161
162## Token Scopes Reference
163
164Use the minimum scopes for the steps the pipeline performs. A repository restriction limits registry access only; it does not narrow `admin:*` permissions.
165
166| Workflow | Required Scopes |
167|----------|----------------|
168| Build + push, then apply + deploy | `push,pull,admin:apps:read,admin:apps:write` |
169| `gordon images push` only (no deploy) | `push,pull,admin:apps:read` |
170| `docker push` only (no deploy) | `push,pull` |
171| docker push, then apply + deploy | `push,pull` + `admin:apps:read,admin:apps:write` for the CLI step |
172
173## Troubleshooting
174
175### "failed to verify token"
176
177The token is invalid or has been revoked. Generate a new one.
178
179### "deploy target not found" / app has no desired state
180
181Push only stores the image. Declare the app first:
182
183```bash
184gordon apps apply --file myapp.toml --remote "$GORDON_REMOTE"
185gordon apps deploy myapp --remote "$GORDON_REMOTE"
186```
187
188### Version shows "latest"
189
190Gordon could not detect a version tag. Either:
191- Tag your git repo: `git tag v1.0.0 && git push --tags`
192- Pass explicitly: `gordon images push --tag v1.0.0`
193
194### Large images time out
195
196Gordon uploads in 50MB chunks. For very large images (> 1GB), the push may take several minutes. Ensure your CI runner timeout is sufficient.
197
198## Related
199
200- [GitHub Actions](./github-actions.md)
201- [GitLab CI](./gitlab-ci.md)
202- [Deployment Overview](./index.md)
203- [Authentication](../config/auth.md)
204- [Images Commands](../cli/images.md#gordon-images-push)

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