# 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: ```bash 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 ```bash # 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: ```bash # 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 ```groovy 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 ```yaml 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 ```yaml 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: ```bash 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. ## Related - [GitHub Actions](./github-actions.md) - [GitLab CI](./gitlab-ci.md) - [Deployment Overview](./index.md) - [Authentication](../config/auth.md) - [Images Commands](../cli/images.md#gordon-images-push)