Pantheon’s Terminus CLI tool is a great way to interact with your sites. If you’re not familiar with Terminus here’s a quote from their docs:

Our command line interface, Terminus, provides advanced interaction with Pantheon. Terminus enables you to do almost everything in a terminal that you can do in the Dashboard, and much more.

Docker setup

While Terminus makes deployments from your local machine simple I wanted the ability to run it from our CI/CD servers on git push. To do that I created a Docker image that our servers can use; The Dockerfile looks like the following

1
2
3
4
FROM composer
RUN composer global require pantheon-systems/terminus
ENV PATH="/tmp/vendor/bin:${PATH}"
ENV TERMINUS_USER_HOME=/tmp

The composer image sets composers home to /tmp so we’re doing the same with Terminus as well as adding the /tmp/vendor/bin to that path. Now we can execute terminus by just referencing the name and not write out the full path to the bin file within the container.

CI/CD Pipeline Setup

You can now user Terminus in your pipeline builds, such as within your bitbucket-pipelines.yml, it would look something like:

bitbucket-pipelines.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
pipelines:
master:
# Auto deploy to test server and clear cache
- step:
image: subhaze/terminus
deployment: test
name: Deploying to dev server and clearing cache
script:
- git remote add upstream ssh://[email protected]$SITE_ID.drush.in:2222/~/repository.git
- git push upstream master
- terminus auth:login --machine-token=$PANTHEON_USER_MACHINE_TOKEN
- terminus env:clear-cache $SITE_NAME.dev

# Wait for user input to sync production data/files to dev
- step:
image: subhaze/terminus
name: Syncing files/data from production and clear cache
trigger: manual
script:
- terminus auth:login --machine-token=$PANTHEON_USER_MACHINE_TOKEN
- terminus env:clone-content $SITE_NAME.live dev -y
- terminus env:clear-cache $SITE_NAME.dev

# Deploy to test server and clear cache
- step:
image: subhaze/terminus
name: Staging Deploy
deployment: staging
trigger: manual
script:
- terminus auth:login --machine-token=$PANTHEON_USER_MACHINE_TOKEN
- terminus env:deploy $SITE_NAME.test --cc --note="Build Number:$BITBUCKET_BUILD_NUMBER; Commit SHA:$BITBUCKET_COMMIT;"
# Wait for user input to sync production data/files to test
- step:
image: subhaze/terminus
name: Syncing files/data from production and clear cache
trigger: manual
script:
- terminus auth:login --machine-token=$PANTHEON_USER_MACHINE_TOKEN
- terminus env:clone-content $SITE_NAME.live test -y
- terminus env:clear-cache $SITE_NAME.test

# Deploy to production and clear cache
- step:
image: subhaze/terminus
name: Production Deploy
deployment: production
trigger: manual
script:
- terminus auth:login --machine-token=$PANTHEON_USER_MACHINE_TOKEN
- terminus env:deploy $SITE_NAME.live --cc --note="Build Number:$BITBUCKET_BUILD_NUMBER; Commit SHA:$BITBUCKET_COMMIT;"
# the --cc flag "should" clear the cache but it's proven to be kind of flaky, so adding one more CC for good measure
- terminus env:clear-cache $SITE_NAME.live

Above we’re using three environment variables that you would set with your specific info.

1
2
3
$SITE_NAME = '<unique name of your pantheon site>'
$SITE_ID = "<the id of your site, it's formatted like xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx>"
$PANTHEON_USER_MACHINE_TOKEN = '<token you generated with your user profile>'

Using Docker Image Locally

You can also use this image to run terminus on your local machine. This can be handy if you don’t want deal with installing all the requirements for Terminus. To do this simply run the following (docker is required):

1
docker run --rm -it --volume ~/.terminus:/tmp/.terminus subhaze/terminus terminus [args...]

Here we’re mounting ${HOME}/.terminus:/tmp/.terminus so that we can cache our auth token so we can access our remote sites. You could set this up as a bash function and just call it via terminus with the following:

1
2
3
terminus(){
docker run -it --rm --volume ${HOME}/.terminus:/tmp/.terminus --entrypoint=terminus subhaze/terminus "${@}"
}

The function above sets --entrypoint=terminus so you can use it more naturally, this essentially tells docker to behave like an executable and accept arguments to pass to that executable.

Now you can use it as if it were installed locally: terminus --version, terminus auth:login --machine-token=<your token>, terminus site:list.