---
title: "Jenkins"
description: "Integrate Alpacon into Jenkins pipelines with Docker. Learn pipeline configuration, service token setup, ACL rules, and remote command execution for CI/CD automation."
---

> Full documentation index: https://docs.alpacax.com/llms.txt

# Jenkins integration

Integrate Alpacon into Jenkins pipelines using the official Docker container.

## Prerequisites

- Jenkins with Docker Pipeline plugin
- An Alpacon workspace, and the application the pipeline's service token will belong to

A workspace on the Free plan holds one application, so the pipeline shares the one already there rather than getting its own.

## Quick start

### 1. Create a service token

CI and automation run on service tokens. A service token belongs to an application rather than to a person, so it survives staff changes, and its ACL bounds exactly what the pipeline may do.

1. Go to **IAM** → [applications](/use/iam/applications/) and open the application this pipeline belongs to, or create one.
2. Open the **Tokens** tab and click **Create token**.
3. Name the token and set its expiry, choose its permissions from an access template or one by one, prepare its servers, commands, and paths, and on the review step write the reason it is needed.
4. Copy or download the key when it is shown. It starts with `alpst-`, and it is shown only once.

Before issuing the token, give the application a server account and a global role covering the required scopes. The examples use `ci-deploy`; replace it with that application-owned account. Prepare deployment directories and Docker access for this account. A service token cannot run as `root` or open an interactive Websh session.

On Alpacon Cloud, service-token sudo is allowed below Critical, including unassessed commands, and refused at Critical unless the workspace is Advisory. In Advisory, it is not refused for risk at any level, and the decision is recorded. Outside Advisory, a workspace `token_exec` rule can tighten the risk threshold. The workspace sudo setting must be on; otherwise sudo is refused with `workspace_sudo_with_mfa_disabled`. A default self-hosted installation refuses every service-token sudo attempt. The command rule must match the whole submitted line, including `sudo`. See [Service tokens](/use/iam/applications/service-tokens/).

Command and file-transfer scopes always wait for approval in the web console. Have a Superuser or an approver for the request approve the token before adding ACLs or starting the pipeline.

### 2. Add the ACL rules

A new service token reaches nothing until you add ACL rules. Servers, commands, and file paths are each deny-by-default, so a token with no rules is refused everywhere.

After approval, open the token's **Access rules** tab and apply the prepared rules, or add server and file rules there. On Alpacon Cloud, a **Command ACL admins** member adds commands under **Pre-approved commands** on the same tab. This access is separate from the workspace role. On self-hosted deployments, use command ACLs. Configure:

| Rule | What it bounds |
|--------|-----------------|
| Server ACL | Which servers the pipeline may reach |
| Command access | The whole commands submitted by the examples, such as `cd /opt/myapp && git pull && pm2 restart app`, `cd /opt/myapp && git pull origin main`, `cd /opt/myapp && npm ci --omit=dev`, and `pm2 restart myapp` |
| File ACL | Which paths it may upload to or download from |

A file transfer checks the server rule first, then the file rule. Skip the **Access rules** tab and the pipeline fails on its first command.

### 3. Add credentials

In **Manage Jenkins → Credentials**, add:

- **ALPACON_WORKSPACE**: Your workspace name, for example `your-workspace` (Secret text)
- **ALPACON_REGION**: Your workspace region, `us1` or `ap1` (Secret text)
- **ALPACON_SERVICE_TOKEN**: The `alpst-` key from step 1 (Secret text)

### 4. Create pipeline

```groovy
pipeline {
    agent {
        docker {
            image 'alpacax/alpacon-cli:latest'
            args '--entrypoint=""'
        }
    }

    environment {
        ALPACON_WORKSPACE = credentials('ALPACON_WORKSPACE')
        ALPACON_REGION = credentials('ALPACON_REGION')
        ALPACON_SERVICE_TOKEN = credentials('ALPACON_SERVICE_TOKEN')
    }

    stages {
        stage('Deploy') {
            steps {
                sh 'alpacon login --workspace $ALPACON_WORKSPACE --region $ALPACON_REGION -t $ALPACON_SERVICE_TOKEN'
                sh 'alpacon exec ci-deploy@prod-server "cd /opt/myapp && git pull && pm2 restart app"'
            }
        }
    }
}
```

**Important:** `args '--entrypoint=""'` is required to override the container's default entrypoint.

The CLI reads the token from `alpacon login` only. There is no environment-variable auth path, so every pipeline keeps that login step before the first Alpacon command.

## Usage examples

### Deploy application

```groovy
pipeline {
    agent {
        docker {
            image 'alpacax/alpacon-cli:latest'
            args '--entrypoint=""'
        }
    }

    environment {
        ALPACON_WORKSPACE = credentials('ALPACON_WORKSPACE')
        ALPACON_REGION = credentials('ALPACON_REGION')
        ALPACON_SERVICE_TOKEN = credentials('ALPACON_SERVICE_TOKEN')
        TARGET_SERVER = 'prod-server'
    }

    stages {
        stage('Deploy') {
            steps {
                sh 'alpacon login --workspace $ALPACON_WORKSPACE --region $ALPACON_REGION -t $ALPACON_SERVICE_TOKEN'
                sh 'alpacon exec ci-deploy@$TARGET_SERVER "cd /opt/myapp && git pull origin main"'
                sh 'alpacon exec ci-deploy@$TARGET_SERVER "cd /opt/myapp && npm ci --omit=dev"'
                sh 'alpacon exec ci-deploy@$TARGET_SERVER "pm2 restart myapp"'
            }
        }
    }
}
```

### Restart services with sudo

The command rule must match the whole `sudo systemctl restart nginx` line. Cloud allows it below Critical unless a stricter workspace rule applies; Advisory does not refuse it for risk at any level. The workspace sudo setting must be on. Default self-hosted installations refuse service-token sudo.

```groovy
pipeline {
    agent {
        docker {
            image 'alpacax/alpacon-cli:latest'
            args '--entrypoint=""'
        }
    }

    environment {
        ALPACON_WORKSPACE = credentials('ALPACON_WORKSPACE')
        ALPACON_REGION = credentials('ALPACON_REGION')
        ALPACON_SERVICE_TOKEN = credentials('ALPACON_SERVICE_TOKEN')
    }

    stages {
        stage('Restart') {
            steps {
                sh 'alpacon login --workspace $ALPACON_WORKSPACE --region $ALPACON_REGION -t $ALPACON_SERVICE_TOKEN'
                sh 'alpacon exec ci-deploy@prod-server "sudo systemctl restart nginx"'
                sh 'alpacon exec ci-deploy@prod-server "systemctl status nginx"'
            }
        }
    }
}
```

### Deploy with Docker Compose

```groovy
pipeline {
    agent {
        docker {
            image 'alpacax/alpacon-cli:latest'
            args '--entrypoint=""'
        }
    }

    environment {
        ALPACON_WORKSPACE = credentials('ALPACON_WORKSPACE')
        ALPACON_REGION = credentials('ALPACON_REGION')
        ALPACON_SERVICE_TOKEN = credentials('ALPACON_SERVICE_TOKEN')
    }

    stages {
        stage('Deploy') {
            steps {
                sh 'alpacon login --workspace $ALPACON_WORKSPACE --region $ALPACON_REGION -t $ALPACON_SERVICE_TOKEN'
                sh 'alpacon cp docker-compose.yml ci-deploy@prod-server:/opt/myapp/docker-compose.yml'
                sh 'alpacon cp .env ci-deploy@prod-server:/opt/myapp/.env'
                sh 'alpacon exec ci-deploy@prod-server "docker compose -f /opt/myapp/docker-compose.yml pull"'
                sh 'alpacon exec ci-deploy@prod-server "docker compose -f /opt/myapp/docker-compose.yml up -d"'
                sh 'alpacon exec ci-deploy@prod-server "docker compose -f /opt/myapp/docker-compose.yml ps"'
            }
        }
    }
}
```

The two `alpacon cp` lines need a File ACL entry for `/opt/myapp/` on top of the Server ACL entry, and the `docker compose` lines need pre-approved commands on Cloud or command ACL entries on self-hosted deployments.

## Security

All commands executed through Alpacon are recorded in the workspace audit log, attributed to the application that owns the token rather than to a person. Sensitive values (such as passwords and tokens) passed via environment variables are automatically masked in command history.

## Troubleshooting

### Entrypoint error

**Symptom:** Container doesn't run the expected command

**Solution:** Make sure to include `args '--entrypoint=""'` in docker agent configuration.

### Login fails on a valid service token

**Symptom:** `alpacon login` reports `failed to verify user profile`, even though the `alpst-` key was copied correctly

**Solution:** Service tokens need Alpacon CLI v1.7.4 or later. An older CLI doesn't recognize the `alpst-` key and reports this misleading message instead. Check the version your agent actually runs—a self-hosted agent or a pinned `alpacax/alpacon-cli` image tag is the usual cause—and upgrade it.

### Command or file refused

**Symptom:** A command or `alpacon cp` that works from your own terminal is refused in the pipeline

**Solution:** Check the token's server and file ACLs and the account the command runs as. On Cloud, ask a Command ACL admin to review the token's pre-approved commands; on self-hosted deployments, check its command ACL. See [Automation failure modes](/integrate/automation-failure-modes/).

## Next steps

- [GitHub Actions integration](/integrate/github-actions/)
- [GitLab CI integration](/integrate/gitlab-ci/)
- [Service tokens](/use/iam/applications/service-tokens/)
- [CLI reference](/reference/cli/)

Source: https://docs.alpacax.com/integrate/jenkins/
