v2.3.0 fc65046

rollback.md RawHistoryFolder

Rollback

Roll back to previous versions when deployments fail.

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