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)
Recommended: gordon images push
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
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://github.com/bnema/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://github.com/bnema/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://github.com/bnema/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://github.com/bnema/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://github.com/bnema/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://github.com/bnema/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://github.com/bnema/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://github.com/bnema/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)