v2.31.0-dev20 020cc00

rollback.md RawHistoryFolder

Rollback

Roll back to previous versions when deployments fail.

gordon pin is the built-in rollback and roll-forward workflow for route images:

gordon pin app.example.com
gordon pin app.example.com --tag v2.30.1
gordon pin list app.example.com

Use it when the target image already exists in the Gordon registry and you want Gordon to update the route and redeploy it for you.

Rollback Strategies

1. Config-Based Rollback

Update the route to point to the previous version:

# Current (broken)
[routes]
"app.mydomain.com" = "myapp:v2.1.0"

# Rollback to previous
[routes]
"app.mydomain.com" = "myapp:v2.0.0"

Then reload:

gordon reload

2. Push Previous Version

Re-push the previous image with the latest tag:

docker pull registry.mydomain.com/myapp:v2.0.0
docker tag registry.mydomain.com/myapp:v2.0.0 registry.mydomain.com/myapp:latest
docker push registry.mydomain.com/myapp:latest

3. Manifest-Based Rollback

Use OCI manifest annotations for version control:

# Rollback to v2.0.0
export VERSION=v2.0.0
podman manifest create myapp:latest --amend
podman manifest add myapp:latest registry.mydomain.com/myapp:$VERSION
podman manifest annotate myapp:latest --annotation version=$VERSION registry.mydomain.com/myapp:$VERSION
podman manifest push myapp:latest registry.mydomain.com/myapp:latest

Version Management

Keep Previous Versions

Always push versioned tags alongside latest:

VERSION=$(git describe --tags)
docker tag myapp registry.mydomain.com/myapp:$VERSION
docker tag myapp registry.mydomain.com/myapp:latest
docker push registry.mydomain.com/myapp:$VERSION
docker push registry.mydomain.com/myapp:latest

Semantic Versioning

Use semantic versions for clear rollback targets:

v2.1.0  ← Current (broken)
v2.0.0  ← Rollback target
v1.9.0  ← Older stable

Git SHA Tags

Tag with commit SHA for precise rollbacks:

# Deploy
SHA=$(git rev-parse --short HEAD)
docker push registry.mydomain.com/myapp:$SHA

# Rollback to specific commit
docker pull registry.mydomain.com/myapp:abc1234
docker tag registry.mydomain.com/myapp:abc1234 registry.mydomain.com/myapp:latest
docker push registry.mydomain.com/myapp:latest

Rollback Workflow

Quick Rollback

# 1. Identify last working version
docker image ls registry.mydomain.com/myapp

# 2. Tag as latest
docker tag registry.mydomain.com/myapp:v2.0.0 registry.mydomain.com/myapp:latest

# 3. Push
docker push registry.mydomain.com/myapp:latest

Config Rollback

# 1. Edit config
vim ~/.config/gordon/gordon.toml

# 2. Change version
# "app.mydomain.com" = "myapp:v2.0.0"

# 3. Reload
gordon reload

Automated Rollback

GitHub Actions

Add rollback capability to your workflow:

name: Rollback

on:
  workflow_dispatch:
    inputs:
      version:
        description: 'Version to rollback to (e.g., v2.0.0)'
        required: true

jobs:
  rollback:
    runs-on: ubuntu-latest
    steps:
      - name: Login to Registry
        run: |
          echo "${{ secrets.GORDON_TOKEN }}" | \
          docker login -u ${{ secrets.GORDON_USERNAME }} --password-stdin ${{ secrets.GORDON_REGISTRY }}

      - name: Rollback
        run: |
          docker pull ${{ secrets.GORDON_REGISTRY }}/myapp:${{ github.event.inputs.version }}
          docker tag ${{ secrets.GORDON_REGISTRY }}/myapp:${{ github.event.inputs.version }} \
                     ${{ secrets.GORDON_REGISTRY }}/myapp:latest
          docker push ${{ secrets.GORDON_REGISTRY }}/myapp:latest

      - name: Summary
        run: |
          echo "## Rollback Complete" >> $GITHUB_STEP_SUMMARY
          echo "Rolled back to version: ${{ github.event.inputs.version }}" >> $GITHUB_STEP_SUMMARY

Rollback Script

Create a local rollback script:

#!/bin/bash
# rollback.sh

REGISTRY="registry.mydomain.com"
IMAGE="myapp"
VERSION=$1

if [ -z "$VERSION" ]; then
  echo "Usage: ./rollback.sh <version>"
  echo "Available versions:"
  docker image ls "$REGISTRY/$IMAGE" --format "{{.Tag}}"
  exit 1
fi

echo "Rolling back to $IMAGE:$VERSION..."
docker pull "$REGISTRY/$IMAGE:$VERSION"
docker tag "$REGISTRY/$IMAGE:$VERSION" "$REGISTRY/$IMAGE:latest"
docker push "$REGISTRY/$IMAGE:latest"
echo "Rollback complete!"

Verifying Rollback

After rollback:

# Check container is running correct version
docker inspect gordon-app-mydomain-com | grep Image

# Check application responds
curl -I https://app.mydomain.com

# Check logs
gordon logs -f

Best Practices

  1. Always tag versions - Don't rely solely on latest
  2. Keep N previous versions - Maintain rollback options
  3. Test before deploy - Reduce need for rollbacks
  4. Document known-good versions - Track stable releases
  5. Automate rollback - Reduce time to recovery
source
1# Rollback
2
3Roll back to previous versions when deployments fail.
4
5## Recommended: Use `gordon pin`
6
7`gordon pin` is the built-in rollback and roll-forward workflow for route images:
8
9```bash
10gordon pin app.example.com
11gordon pin app.example.com --tag v2.30.1
12gordon pin list app.example.com
13```
14
15Use it when the target image already exists in the Gordon registry and you want Gordon to update the route and redeploy it for you.
16
17## Rollback Strategies
18
19### 1. Config-Based Rollback
20
21Update the route to point to the previous version:
22
23```toml
24# Current (broken)
25[routes]
26"app.mydomain.com" = "myapp:v2.1.0"
27
28# Rollback to previous
29[routes]
30"app.mydomain.com" = "myapp:v2.0.0"
31```
32
33Then reload:
34
35```bash
36gordon reload
37```
38
39### 2. Push Previous Version
40
41Re-push the previous image with the `latest` tag:
42
43```bash
44docker pull registry.mydomain.com/myapp:v2.0.0
45docker tag registry.mydomain.com/myapp:v2.0.0 registry.mydomain.com/myapp:latest
46docker push registry.mydomain.com/myapp:latest
47```
48
49### 3. Manifest-Based Rollback
50
51Use OCI manifest annotations for version control:
52
53```bash
54# Rollback to v2.0.0
55export VERSION=v2.0.0
56podman manifest create myapp:latest --amend
57podman manifest add myapp:latest registry.mydomain.com/myapp:$VERSION
58podman manifest annotate myapp:latest --annotation version=$VERSION registry.mydomain.com/myapp:$VERSION
59podman manifest push myapp:latest registry.mydomain.com/myapp:latest
60```
61
62## Version Management
63
64### Keep Previous Versions
65
66Always push versioned tags alongside `latest`:
67
68```bash
69VERSION=$(git describe --tags)
70docker tag myapp registry.mydomain.com/myapp:$VERSION
71docker tag myapp registry.mydomain.com/myapp:latest
72docker push registry.mydomain.com/myapp:$VERSION
73docker push registry.mydomain.com/myapp:latest
74```
75
76### Semantic Versioning
77
78Use semantic versions for clear rollback targets:
79
80```
81v2.1.0  ← Current (broken)
82v2.0.0  ← Rollback target
83v1.9.0  ← Older stable
84```
85
86### Git SHA Tags
87
88Tag with commit SHA for precise rollbacks:
89
90```bash
91# Deploy
92SHA=$(git rev-parse --short HEAD)
93docker push registry.mydomain.com/myapp:$SHA
94
95# Rollback to specific commit
96docker pull registry.mydomain.com/myapp:abc1234
97docker tag registry.mydomain.com/myapp:abc1234 registry.mydomain.com/myapp:latest
98docker push registry.mydomain.com/myapp:latest
99```
100
101## Rollback Workflow
102
103### Quick Rollback
104
105```bash
106# 1. Identify last working version
107docker image ls registry.mydomain.com/myapp
108
109# 2. Tag as latest
110docker tag registry.mydomain.com/myapp:v2.0.0 registry.mydomain.com/myapp:latest
111
112# 3. Push
113docker push registry.mydomain.com/myapp:latest
114```
115
116### Config Rollback
117
118```bash
119# 1. Edit config
120vim ~/.config/gordon/gordon.toml
121
122# 2. Change version
123# "app.mydomain.com" = "myapp:v2.0.0"
124
125# 3. Reload
126gordon reload
127```
128
129## Automated Rollback
130
131### GitHub Actions
132
133Add rollback capability to your workflow:
134
135```yaml
136name: Rollback
137
138on:
139  workflow_dispatch:
140    inputs:
141      version:
142        description: 'Version to rollback to (e.g., v2.0.0)'
143        required: true
144
145jobs:
146  rollback:
147    runs-on: ubuntu-latest
148    steps:
149      - name: Login to Registry
150        run: |
151          echo "${{ secrets.GORDON_TOKEN }}" | \
152          docker login -u ${{ secrets.GORDON_USERNAME }} --password-stdin ${{ secrets.GORDON_REGISTRY }}
153
154      - name: Rollback
155        run: |
156          docker pull ${{ secrets.GORDON_REGISTRY }}/myapp:${{ github.event.inputs.version }}
157          docker tag ${{ secrets.GORDON_REGISTRY }}/myapp:${{ github.event.inputs.version }} \
158                     ${{ secrets.GORDON_REGISTRY }}/myapp:latest
159          docker push ${{ secrets.GORDON_REGISTRY }}/myapp:latest
160
161      - name: Summary
162        run: |
163          echo "## Rollback Complete" >> $GITHUB_STEP_SUMMARY
164          echo "Rolled back to version: ${{ github.event.inputs.version }}" >> $GITHUB_STEP_SUMMARY
165```
166
167### Rollback Script
168
169Create a local rollback script:
170
171```bash
172#!/bin/bash
173# rollback.sh
174
175REGISTRY="registry.mydomain.com"
176IMAGE="myapp"
177VERSION=$1
178
179if [ -z "$VERSION" ]; then
180  echo "Usage: ./rollback.sh <version>"
181  echo "Available versions:"
182  docker image ls "$REGISTRY/$IMAGE" --format "{{.Tag}}"
183  exit 1
184fi
185
186echo "Rolling back to $IMAGE:$VERSION..."
187docker pull "$REGISTRY/$IMAGE:$VERSION"
188docker tag "$REGISTRY/$IMAGE:$VERSION" "$REGISTRY/$IMAGE:latest"
189docker push "$REGISTRY/$IMAGE:latest"
190echo "Rollback complete!"
191```
192
193## Verifying Rollback
194
195After rollback:
196
197```bash
198# Check container is running correct version
199docker inspect gordon-app-mydomain-com | grep Image
200
201# Check application responds
202curl -I https://app.mydomain.com
203
204# Check logs
205gordon logs -f
206```
207
208## Best Practices
209
2101. **Always tag versions** - Don't rely solely on `latest`
2112. **Keep N previous versions** - Maintain rollback options
2123. **Test before deploy** - Reduce need for rollbacks
2134. **Document known-good versions** - Track stable releases
2145. **Automate rollback** - Reduce time to recovery
215
216## Related
217
218- [Deployment Overview](./index.md)
219- [GitHub Actions](./github-actions.md)
220- [Routes Configuration](../config/routes.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