> ## Documentation Index
> Fetch the complete documentation index at: https://www.aptible.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# How to deploy to Aptible with CI/CD

## Overview

To make it easier to deploy on Aptible—whether you're migrating from another platform or deploying your first application—we offer integrations with several continuous integration services.

* [Deploying with Git](https://www.aptible.com/docs/how-to-guides/app-guides/how-to-deploy-aptible-ci-cd.md#deploying-with-git)

* [Deploying with Docker](https://www.aptible.com/docs/how-to-guides/app-guides/how-to-deploy-aptible-ci-cd.md#deploying-with-docker)

If your team is already using a Git-based deployment workflow, deploying your app to Aptible should be relatively straightforward.

Before you deploy, lint Dockerfiles and scan built images in CI so vulnerable or misconfigured images never reach production. See [Image and Vulnerability Scanning](https://www.aptible.com/docs/how-to-guides/platform-guides/image-vulnerability-scanning.md).

## Deploying with Git

### Prerequisites

To deploy to Aptible via Git, you must have a public SSH key associated with your account. We recommend creating a robot user to manage your deployment:

1. Create a "Robots" [custom role](https://www.aptible.com/docs/core-concepts/security-compliance/access-permissions.md) in your Aptible [organization](https://www.aptible.com/docs/core-concepts/security-compliance/access-permissions.md), and grant it "Full Visibility" and "Deployment" [permissions](https://www.aptible.com/docs/core-concepts/security-compliance/access-permissions.md) for the [environment](https://www.aptible.com/docs/core-concepts/architecture/environments.md) where you will be deploying.

2. Invite a new robot user with a valid email address (for example, `deploy@yourdomain.com`) to the `Robots` role.

3. Sign out of your Aptible account, accept the invitation from the robot user's email address, and set a password for the robot's Aptible account.

4. Generate a new SSH key pair to be used by the robot user, and don't set a password: `ssh-keygen -t ed25519 -C "your_email@example.com"`

5. Register the [SSH Public Key](https://www.aptible.com/docs/core-concepts/security-compliance/authentication/ssh-keys.md) with Aptible for the robot user.

> [tab] GitHub Actions
>
> ### Configuring the Environment
>
> First, you'll need to configure a few [environment variables](https://docs.github.com/en/actions/learn-github-actions/variables#defining-configuration-variables-for-multiple-workflows) and [secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets#using-encrypted-secrets-in-a-workflow) for your repository:
>
> 1. Environment variable: `APTIBLE_APP`, the name of the App to deploy.
> 2. Environment variable: `APTIBLE_ENVIRONMENT`, the name of the Aptible environment in which your App lives.
> 3. Secret: `APTIBLE_USERNAME`, the username of the Aptible user with which to deploy the App.
> 4. Secret: `APTIBLE_PASSWORD`, the password of the Aptible user with which to deploy the App.
>
> ### Configuring the Workflow
>
> Finally, you must configure the workflow to deploy your application to Aptible:
>
> ```sql theme={null}
> on:
>   push:
>     branches: [ main ]
>
> jobs:
>   deploy:
>     runs-on: ubuntu-latest
>     steps:
>       - uses: actions/checkout@v4
>         with:
>           fetch-depth: 0
>       - name: Deploy to Aptible
>         uses: aptible/aptible-deploy-action@v5
>         with:
>           type: git
>           app: ${{ vars.APTIBLE_APP }}
>           environment: ${{ vars.APTIBLE_ENVIRONMENT }}
>           username: ${{ secrets.APTIBLE_USERNAME }}
>           password: ${{ secrets.APTIBLE_PASSWORD }}
> ```

> [tab] CircleCI
>
> ### Configuring SSH
>
> To deploy to Aptible via CircleCI, [add your SSH Private Key via the CircleCI Dashboard](https://circleci.com/docs/2.0/add-ssh-key/#circleci-cloud-or-server-3-x) with the following values:
>
> * **Hostname:** `beta.aptible.com`
> * **Private Key:** The contents of the SSH Private Key created in the previous step.
>
> ### Configuring the Environment
>
> You also need to set environment variables on your project with the name of your Aptible environment and app, in `APTIBLE_ENVIRONMENT` and `APTIBLE_APP`, respectively. You can add these to your project using [environment variables](https://circleci.com/docs/2.0/env-vars/) on the Circle CI dashboard.
>
> ### Configuring the Deployment
>
> Finally, you must configure the Circle CI project to deploy your application to Aptible:
>
> ```sql theme={null}
> version: 2.1
>
> jobs:
>   git-deploy:
>     docker:
>       - image: debian:latest
>     filters:
>       branches:
>         only:
>           - circle-deploy
>     steps:
>       # Add your private key to your repo: https://circleci.com/docs/2.0/configuration-reference/#add-ssh-keys
>       - checkout
>       - run:
>           name: Git push and deploy to Aptible
>           command: |
>             apt-get update && apt-get install -y git openssh-client
>             ssh-keyscan beta.aptible.com >> ~/.ssh/known_hosts
>             git remote add aptible git@beta.aptible.com:$APTIBLE_ENVIRONMENT/$APTIBLE_APP.git
>             git push aptible $CIRCLE_SHA1:master
>
> workflows:
>   version: 2
>   deploy:
>     jobs:
>       - git-deploy
> ```
>
> Let’s break down how this works. We begin by defining when the deployment should run (when a push is made to the `circle-deploy` branch):
>
> ```sql theme={null}
> jobs:
>   git-deploy:
>     docker:
>       - image: debian:latest
>     filters:
>       branches:
>         only:
>           - circle-deploy
> ```
>
> The most important part of this configuration is the value of the `command` key under the `run` step. Here we add our SSH private key to the Circle CI environment, configure a new remote for our repository on Aptible’s platform, and push our branch to Aptible:
>
> ```sql theme={null}
> jobs:
>   git-deploy:
>     # # #
>     steps:
>       - checkout
>       - run:
>           name: Git push and deploy to Aptible
>           command: |
>             apt-get update && apt-get install -y git openssh-client
>             ssh-keyscan beta.aptible.com >> ~/.ssh/known_hosts
>             git remote add aptible git@beta.aptible.com:$APTIBLE_ENVIRONMENT/$APTIBLE_APP.git
>             git push aptible $CIRCLE_SHA1:master
> ```
>
> From there, the procedure for a [Dockerfile-based deployment](https://www.aptible.com/docs/how-to-guides/app-guides/deploy-from-git.md) remains the same!

> [tab] Travis CI
>
> ### Configuring SSH
>
> To deploy to Aptible via Travis CI, [add your SSH Private Key via the Travis CI repository settings](https://docs.travis-ci.com/user/environment-variables/#defining-variables-in-repository-settings) with the following values:
>
> * **Name:** `APTIBLE_GIT_SSH_KEY`
>
> * **Value:** The ***base64-encoded*** contents of the SSH Private Key created in the previous step.
>
> > [!WARNING]
> >
> > Warning
> >
> > The SSH private key added to the Travis CI environment variable must be base64-encoded.
>
> ### Configuring the Environment
>
> You also need to set environment variables on your project with the name of your Aptible environment and app, in `APTIBLE_ENVIRONMENT` and `APTIBLE_APP`, respectively. You can add these to your project using [environment variables](https://docs.travis-ci.com/user/environment-variables/#defining-variables-in-repository-settings) on the Travis CI dashboard.
>
> ### Configuring the Deployment
>
> Finally, you must configure the Travis CI project to deploy your application to Aptible:
>
> ```sql theme={null}
> language: generic
> sudo: true
>
> services:
>   - docker
>
> jobs:
>   include:
>     - stage: push
>       if: branch = travis-deploy
>       addons:
>         ssh_known_hosts: beta.aptible.com
>       before_script:
>         - mkdir -p ~/.ssh
>         # to save it, cat <<KEY>> | base64 and save that in secrets
>         - echo "$APTIBLE_GIT_SSH_KEY" | base64 -d > ~/.ssh/id_rsa
>         - chmod 0400 ~/.ssh/id_rsa
>         - eval "$(ssh-agent -s)"
>         - ssh-add ~/.ssh/id_rsa
>         - ssh-keyscan beta.aptible.com >> ~/.ssh/known_hosts
>
>       script:
>         - git remote add aptible git@beta.aptible.com:$APTIBLE_ENVIRONMENT/$APTIBLE_APP.git
>         - git push aptible $TRAVIS_COMMIT:master
> ```
>
> Let’s break down how this works. We begin by defining when the deployment should run (when a push is made to the `travis-deploy` branch) and where we are going to deploy (so we add `beta.aptible.com` as a known host):
>
> ```sql theme={null}
> # # #
> jobs:
>   include:
>     - stage: push
>       if: branch = travis-deploy
>       addons:
>         ssh_known_hosts: beta.aptible.com
> ```
>
> The Travis CI configuration then allows us to split our script into two parts, with the `before_script` configuring the Travis CI environment to use our SSH key:
>
> ```sql theme={null}
>       # Continued from above
>       before_script:
>         - mkdir -p ~/.ssh
>         # to save it, cat <<KEY>> | base64 and save that in secrets
>         - echo "$APTIBLE_GIT_SSH_KEY" | base64 -d > ~/.ssh/id_rsa
>         - chmod 0400 ~/.ssh/id_rsa
>         - eval "$(ssh-agent -s)"
>         - ssh-add ~/.ssh/id_rsa
>         - ssh-keyscan beta.aptible.com >> ~/.ssh/known_hosts
> ```
>
> Finally, our `script` block configures a new remote for our repository on Aptible’s platform, and pushes our branch to Aptible:
>
> ```sql theme={null}
>       # Continued from above
>       script:
>         - git remote add aptible git@beta.aptible.com:$APTIBLE_ENVIRONMENT/$APTIBLE_APP.git
>         - git push aptible $TRAVIS_COMMIT:master
> ```
>
> From there, the procedure for a [Dockerfile-based deployment](https://www.aptible.com/docs/how-to-guides/app-guides/deploy-from-git.md) remains the same!

> [tab] GitLab CI
>
> ### Configuring SSH
>
> To deploy to Aptible via GitLab CI, [add your SSH Private Key via the GitLab CI dashboard](https://docs.gitlab.com/ee/ci/ssh_keys/#ssh-keys-when-using-the-docker-executor) with the following values:
>
> * **Key:** `APTIBLE_GIT_SSH_KEY`
>
> * **Value:** The ***base64-encoded*** contents of the SSH Private Key created in the previous step.
>
> > [!WARNING]
> >
> > Warning
> >
> > The SSH private key added to the GitLab CI environment variable must be base64-encoded.
>
> ### Configuring the Environment
>
> You also need to set environment variables on your project with the name of your Aptible environment and app, in `APTIBLE_ENVIRONMENT` and `APTIBLE_APP`, respectively. You can add these to your project using [project variables](https://docs.gitlab.com/ee/ci/variables/#add-a-cicd-variable-to-a-project) on the GitLab CI dashboard.
>
> ### Configuring the Deployment
>
> Finally, you must configure the GitLab CI pipeline to deploy your application to Aptible:
>
> ```sql theme={null}
> image: debian:latest
>
> git_deploy_job:
>   only:
>     - gitlab-deploy
>   before_script:
>     - apt-get update && apt-get install -y git
>     # taken from: https://docs.gitlab.com/ee/ci/ssh_keys/
>     - 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )'
>     - eval $(ssh-agent -s)
>     # to save it, cat <<KEY>> | base64 and save that in secrets
>     - echo "$DEMO_APP_APTIBLE_GIT_SSH_KEY" | base64 -d | tr -d '
> ' | ssh-add -
>     - mkdir -p ~/.ssh
>     - chmod 700 ~/.ssh
>   script:
>     - |
>       ssh-keyscan beta.aptible.com >> ~/.ssh/known_hosts
>       git remote add aptible git@beta.aptible.com:$DEMO_APP_APTIBLE_ENVIRONMENT/$DEMO_APP_APTIBLE_APP.git
>       git push aptible $CI_COMMIT_SHA:master
> ```
>
> Let’s break down how this works. We begin by defining when the deployment should run (when a push is made to the `gitlab-deploy` branch), and then we define the `before_script` that will configure SSH in our job environment:
>
> ```sql theme={null}
>   # . . .
>   before_script:
>     - apt-get update && apt-get install -y git
>     # taken from: https://docs.gitlab.com/ee/ci/ssh_keys/
>     - 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )'
>     - eval $(ssh-agent -s)
>     - echo "$DEMO_APP_APTIBLE_GIT_SSH_KEY" | base64 -d | tr -d '
> ' | ssh-add -
>     - mkdir -p ~/.ssh
>     - chmod 700 ~/.ssh
> ```
>
> Finally, our `script` block configures a new remote for our repository on Aptible’s platform, and pushes our branch to Aptible:
>
> ```sql theme={null}
>   # Continued from above
>   script:
>     - |
>       ssh-keyscan beta.aptible.com >> ~/.ssh/known_hosts
>       git remote add aptible git@beta.aptible.com:$DEMO_APP_APTIBLE_ENVIRONMENT/$DEMO_APP_APTIBLE_APP.git
>       git push aptible $CI_COMMIT_SHA:master
> ```
>
> From there, the procedure for a [Dockerfile-based deployment](https://www.aptible.com/docs/how-to-guides/app-guides/deploy-from-git.md) remains the same!

## Deploying with Docker

### Prerequisites

To deploy to Aptible with a Docker image via a CI integration, you should create a robot user to manage your deployment:

1. Create a `Robots` [custom Aptible role](https://www.aptible.com/docs/core-concepts/security-compliance/access-permissions.md) in your Aptible organization. Grant it "Read" and "Manage" permissions for the environment where you would like to deploy.

2. Invite a new robot user with a valid email address (for example, `deploy@yourdomain.com`) to the `Robots` role.

3. Sign out of your Aptible account, accept the invitation from the robot user's email address, and set a password for the robot's Aptible account.

> [tab] GitHub Actions
>
> Some of the below instructions and more information can also be found on the Github Marketplace page for the [Deploy to Aptible Action.](https://github.com/marketplace/actions/deploy-to-aptible#example-with-container-build-and-docker-hub)
>
> ## Configuring the Environment
>
> To deploy to Aptible via GitHub Actions, you must first [create encrypted secrets for your repository](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) with Docker registry and Aptible credentials:
>
> `DOCKERHUB_USERNAME` and `DOCKERHUB_TOKEN`
> The credentials for your private Docker registry (in this case, DockerHub).
>
> `APTIBLE_USERNAME` and `APTIBLE_PASSWORD`
> The credentials for the robot account created to deploy to Aptible.
>
> ## Configuring the Workflow
>
> Additionally, you will need to set some environment variables within the GitHub Actions workflow:
>
> `IMAGE_NAME`
> The Docker image you wish to deploy from your Docker registry.
>
> `APTIBLE_ENVIRONMENT`
> The name of the Aptible environment acting as the target for this deployment.
>
> `APTIBLE_APP`
> The name of the app within the Aptible environment we are deploying with this workflow.
>
> ## Configuring the Workflow
>
> Finally, you must configure the workflow to deploy your application to Aptible:
>
> ```ruby theme={null}
> on:
>   push:
>     branches: [ main ]
>
> env:
>   IMAGE_NAME: user/app:latest
>   APTIBLE_ENVIRONMENT: "my_environment"
>   APTIBLE_APP: "my_app"
>
> jobs:
>   deploy:
>     runs-on: ubuntu-latest
>
>     steps:
>       # Allow multi-platform builds.
>       - name: Set up QEMU
>         uses: docker/setup-qemu-action@v2
>
>       # Allow use of secrets and other advanced docker features.
>       - name: Set up Docker Buildx
>         uses: docker/setup-buildx-action@v2
>
>       # Log into Docker Hub
>       - name: Login to DockerHub
>         uses: docker/login-action@v2
>         with:
>           username: ${{ secrets.DOCKERHUB_USERNAME }}
>           password: ${{ secrets.DOCKERHUB_TOKEN }}
>
>       # Build image using default dockerfile.
>       - name: Build and push
>         uses: docker/build-push-action@v3
>         with:
>           push: true
>           tags: ${{ env.IMAGE_NAME }}
>
>       # Deploy to Aptible
>       - name: Deploy to Aptible
>         uses: aptible/aptible-deploy-action@v5
>         with:
>           username: ${{ secrets.APTIBLE_USERNAME }}
>           password: ${{ secrets.APTIBLE_PASSWORD }}
>           environment: ${{ env.APTIBLE_ENVIRONMENT }}
>           app: ${{ env.APTIBLE_APP }}
>           docker_img: ${{ env.IMAGE_NAME }}
>           private_registry_username: ${{ secrets.DOCKERHUB_USERNAME }}
>           private_registry_password: ${{ secrets.DOCKERHUB_TOKEN }}
> ```

> [tab] TravisCI
>
> ## Configuring the Environment
>
> You also need to set environment variables on your project with the name of your Aptible environment and app, in APTIBLE\_ENVIRONMENT and APTIBLE\_APP, respectively. You can add these to your project using environment variables on the Travis CI dashboard.
>
> To define how the Docker image is built and deployed, you’ll need to set a few additional variables:
>
> `APTIBLE_USERNAME` and `APTIBLE_PASSWORD`
> The credentials for the robot account created to deploy to Aptible.
>
> `APTIBLE_DOCKER_IMAGE`
> The name of the Docker image you wish to deploy to Aptible.
>
> If you are using a private registry to store your Docker image, you also need to specify credentials to be passed to Aptible:
>
> `APTIBLE_PRIVATE_REGISTRY_USERNAME`
> The username of the account that can access the private registry containing the Docker image.
>
> `APTIBLE_PRIVATE_REGISTRY_PASSWORD`
> The password of the account that can access the private registry containing the Docker image.
>
> ## Configuring the Deployment
>
> Finally, you must configure the workflow to deploy your application to Aptible:
>
> ```ruby theme={null}
> language: generic
> sudo: true
>
> services:
>   - docker
>
> jobs:
>   include:
>   - stage: build-and-test
>     script: |
>       make build
>       make test
>   - stage: push
>     if: branch = main
>     script: |
>       # login to your registry
>       docker login \
>         -u $APTIBLE_PRIVATE_REGISTRY_EMAIL \
>         -p $APTIBLE_PRIVATE_REGISTRY_PASSWORD
>       # push your docker image to your registry
>       make push
>
>       # download the latest aptible cli and install it
>       wget https://omnibus-aptible-toolbelt.s3.amazonaws.com/aptible/omnibus-aptible-toolbelt/latest/aptible-toolbelt_latest_debian-9_amd64.deb && \
>         dpkg -i ./aptible-toolbelt_latest_debian-9_amd64.deb && \
>         rm ./aptible-toolbelt_latest_debian-9_amd64.deb
>
>       # login and deploy your app
>       aptible login \
>         --email "$APTIBLE_USERNAME" \
>         --password "$APTIBLE_PASSWORD"
>       aptible deploy \
>         --environment "$APTIBLE_ENVIRONMENT" \
>         --app "$APTIBLE_APP"
> ```
>
> Let’s break down how this works. The script for the `build-and-test` stage does what it says on the label: It builds our Docker image as runs tests on it, as we’ve defined in a Makefile.
>
> Then, script from the `push` stage pushes our image to the Docker registry:
>
> ```ruby theme={null}
> # login to your registry
> docker login \
>   -u $APTIBLE_PRIVATE_REGISTRY_EMAIL \
>   -p $APTIBLE_PRIVATE_REGISTRY_PASSWORD
> # push your docker image to your registry
> make push
> ```
>
> Finally, it installs the Aptible CLI in the Travis CI build environment, logs in to Aptible, and deploys your Docker image to the specified envrionment and app:
>
> ```ruby theme={null}
> # download the latest aptible cli and install it
> wget https://omnibus-aptible-toolbelt.s3.amazonaws.com/aptible/omnibus-aptible-toolbelt/aptible-toolbelt-latest_amd64.deb && \
>   dpkg -i ./aptible-toolbelt-latest_amd64.deb && \
>   rm ./aptible-toolbelt-latest_amd64.deb
>
> # login and deploy your app
> aptible login \
>   --email "$APTIBLE_USERNAME" \
>   --password "$APTIBLE_PASSWORD"
> aptible deploy \
>   --environment "$APTIBLE_ENVIRONMENT" \
>   --app "$APTIBLE_APP"
> ```

From there, you can review our resources for [deploying via Docker image!](https://www.aptible.com/docs/how-to-guides/app-guides/migrate-dockerfile-to-direct-image-deploy.md)
