---
title: "Bitbucket Pipelines"
description: "Integrate HawkScan security testing into Bitbucket Pipelines. Setup guide for external, localhost, and Docker Compose scanning scenarios."
url: https://docs.stackhawk.com/integrations/ci-cd/bitbucket-pipelines/
---

# Bitbucket Pipelines

![Atlassian Bitbucket](https://docs.stackhawk.com/images/integrations/logos/bitbucket.svg)

Adding StackHawk to [Bitbucket Pipelines](https://bitbucket.org/product/features/pipelines) is simple. In this guide we will describe how to do it with concrete examples you can try yourself. We will describe three scenarios, each installing the `hawk` CLI with the hawk CLI [install script](https://docs.stackhawk.com/stackhawk-cli/#install-with-a-script), with Docker alternatives:

1. [Scan a publicly available endpoint such as example.com](#scenario-one-external-site-scanning)
2. [Scan a service running on localhost](#scenario-two-localhost-scanning)
3. [Scan an application stack running locally in Docker Compose](#scenario-three-docker-compose-scanning)

## Create a Bitbucket Repository

If you don’t have one already, create a new [Bitbucket](https://bitbucket.org/) account. Then create a new repository to contain the configurations for the examples below.

## Secure Your API Key

Your API key should be kept secret. Rather than saving it in your repository, store it as a secret environment variable in Bitbucket Pipelines.

Log on to Bitbucket and navigate to your repository. From the left-hand pane , select (⚙️) Repository settings, and then below PIPELINES, select Repository variables.

![Repository Settings Screenshot](https://docs.stackhawk.com/images/integrations/cicd/bitbucket-pipelines/repository-settings.png)

![Repository Variables Screenshot](https://docs.stackhawk.com/images/integrations/cicd/bitbucket-pipelines/repository-variables.png)

Add an environment variable called `HAWK_API_KEY`, and enter your API key from the HawkScan app. If you need to look up your API key or create a new one, navigate to your [API Keys](https://app.stackhawk.com/settings/apikeys) in the StackHawk platform.

---

Now you’re ready to define your scan and pipeline configurations.

## Scenario One: External Site Scanning

In this scenario you will scan an existing external site. Typically, this would be your own integration test site running your latest pre-production code. For this simple example we will use example.com as our external site.

At the base of your repository, create a `bitbucket-pipelines.yml` file with the following contents.

```yaml title="bitbucket-pipelines.yml"
image: atlassian/default-image:4
pipelines:
  default:
    - step:
        name: Scan Example.COM
        script:
          # Optional: pin a version (6.0.0 or later). Leave it unset to install the latest release.
          # - export HAWK_INSTALL_VERSION=6.6.0
          - curl -fsSL https://download.stackhawk.com/hawk/install.sh | sh
          - export PATH="$HOME/.hawk/bin:$PATH"
          - hawk --api-key="$HAWK_API_KEY" scan
```

This is a single step pipeline that installs the `hawk` CLI with the [install script](https://docs.stackhawk.com/stackhawk-cli/#install-with-a-script) and runs a scan. The script installs the latest HawkScan release and checks its checksum. It doesn’t change the PATH, so the next line adds its install directory, `~/.hawk/bin`; the commands in a Bitbucket step share one shell, so the `hawk` command that follows can find it.

Notice that we pass the API key to HawkScan using the `--api-key="$HAWK_API_KEY"` flag.

### Docker Alternative

If you’d rather run HawkScan as a Docker container instead:

```yaml title="bitbucket-pipelines.yml"
image: atlassian/default-image:4
pipelines:
  default:
    - step:
        name: Scan Example.COM
        services: [docker]
        script:
          - >
            docker run -v $(pwd):/hawk:rw -t
            -e API_KEY=$HAWK_API_KEY
            stackhawk/hawkscan
```

This step enables Docker, and then runs HawkScan as a Docker container. The Docker command to run HawkScan is a little long, so we break it up into multiple lines using the YAML special character `>` to fold the following lines into one long line, removing any newline characters.

Next, add a HawkScan configuration file to the root of your repository like so.

```yaml title="stackhawk.yml"
app:
  applicationId: xxXXXXXX-xXXX-xxXX-XXxX-xXXxxXXXXxXX
  host: http://example.com
  env: Bitbucket Pipelines
```

Set `app.applicationId` to the StackHawk application ID for your application. You can find it in [StackHawk Applications](https://app.stackhawk.com/applications).

Commit your code and push it to Bitbucket to initiate a pipeline run. You can watch your scan progress in Bitbucket, and check the [StackHawk Scans](https://app.stackhawk.com/scans) console to see your results.

## Scenario Two: Localhost Scanning

In this scenario we will start a service locally and scan it on the localhost address. You can use this approach to scan your own application within the Bitbucket Pipelines build environment.

For this scenario, you will fire up Nginx in a Docker container, and scan it at the localhost address. Any application running on the localhost address can be scanned. It doesn’t need to be in a Docker container!

At the base of your repository, create a `bitbucket-pipelines.yml` file with the following contents.

```yaml title="bitbucket-pipelines.yml"
image: atlassian/default-image:4
pipelines:
  default:
    - step:
        name: Scan localhost
        services: [docker]
        script:
          - docker run --detach --publish 8080:80 nginx
          - while ! curl -s -o /dev/null localhost:8080; do echo Waiting for app; sleep 1; done
          - curl -fsSL https://download.stackhawk.com/hawk/install.sh | sh
          - export PATH="$HOME/.hawk/bin:$PATH"
          - hawk --api-key="$HAWK_API_KEY" scan
```

The script in this pipeline has three steps:

1. start an Nginx container, listening on localhost port 8080
2. wait for Nginx to become responsive at <http://localhost:8080>
3. install the `hawk` CLI, put it on the PATH, and run HawkScan.

Because the `hawk` CLI runs directly in the build container, it reaches the application at `localhost` with no extra network configuration.

### Docker Alternative

To run HawkScan as a Docker container instead, replace the last three script lines with:

```yaml title="bitbucket-pipelines.yml"
          - >
            docker run -v $(pwd):/hawk:rw -t
            -e API_KEY=$HAWK_API_KEY
            --add-host host.docker.internal:$BITBUCKET_DOCKER_HOST_INTERNAL
            stackhawk/hawkscan
```

Notice the flag to the HawkScan Docker command line that reads, “`--add-host host.docker.internal:$BITBUCKET_DOCKER_HOST_INTERNAL`.” This allows the HawkScan container to reach services on the localhost address, such as the Nginx container started in step 1 of the script. See this Bitbucket [security bulletin](https://community.atlassian.com/t5/Bitbucket-articles/Changes-to-make-your-containers-more-secure-on-Bitbucket/ba-p/998464) for more information on why this flag is necessary.

Add a HawkScan configuration to the root of your repository:

```yaml title="stackhawk.yml"
app:
  applicationId: xxXXXXXX-xXXX-xxXX-XXxX-xXXxxXXXXxXX
  host: http://localhost:8080
  env: Bitbucket Pipelines
```

Set `app.applicationId` to the StackHawk application ID for your application. You can find it from the [StackHawk Applications](https://app.stackhawk.com/applications) screen.

Commit your code and push it to Bitbucket to initiate a pipeline run. You can watch your scan progress in Bitbucket, and check the [StackHawk Scans](https://app.stackhawk.com/scans) console to see your results.

## Scenario Three: Docker Compose Scanning

Docker Compose is a great way to build up a multi-tier application or set of microservices to create a repeatable integration test environment. You can bring the environment up with Docker Compose and scan the port it publishes with the `hawk` CLI.

For this scenario, we will start up an Nginx container using Docker Compose, and then scan it from the build container.

Create the following pipeline configuration file in the base of your repository.

```yaml title="bitbucket-pipelines.yml"
image: atlassian/default-image:4
pipelines:
  default:
    - step:
        name: Scan docker-compose
        services: [docker]
        script:
          - docker-compose -f docker-compose-base.yml up --detach
          - while ! curl -s -o /dev/null localhost; do echo Waiting for app; sleep 1; done
          - curl -fsSL https://download.stackhawk.com/hawk/install.sh | sh
          - export PATH="$HOME/.hawk/bin:$PATH"
          - hawk --api-key="$HAWK_API_KEY" scan
```

There are three steps in the script defined above:

1. Bring up the `docker-compose-base.yml` Docker Compose configuration, which contains the service, `nginx-test`.
2. Wait for the `nginx-test` container to become reachable on localhost.
3. Install the `hawk` CLI, put it on the PATH, and run HawkScan.

Add the `docker-compose-base.yml` Docker Compose configuration file to your repo.

```yaml title="docker-compose-base.yml"
version: "3.7"

services:
  nginx-test:
    image: nginx
    ports:
      - 80:80
    logging:
      driver: none
```

The `nginx-test` service runs the `nginx` docker container and publishes it on localhost port 80, where HawkScan scans it.

We also set the logging driver for `nginx-test` to `none`. Since HawkScan will be probing many URLs on `nginx-test`, logging would generate excessive output in your pipeline results.

Add your HawkScan configuration file, `stackhawk.yml`, to the base of your repo.

```yaml title="stackhawk.yml"
app:
  applicationId: xxXXXXXX-xXXX-xxXX-XXxX-xXXxxXXXXxXX
  host: http://localhost
  env: Bitbucket Pipelines
```

Set `app.applicationId` to the StackHawk application ID for your application. You can find it from the Applications screen.

Commit your code and push it to Bitbucket to initiate a pipeline run. You can watch your scan progress in Bitbucket, and check the [StackHawk Scans](https://app.stackhawk.com/scans) console to see your results.

### Docker Compose Alternative

You can also run HawkScan as a service in its own Docker Compose overlay, and scan your application by its service name on the private bridge network that Docker Compose sets up. Replace the last three script lines in `bitbucket-pipelines.yml` with:

```yaml title="bitbucket-pipelines.yml"
          - docker-compose -f docker-compose-base.yml -f docker-compose-hawkscan.yml up --abort-on-container-exit
```

The flag `--abort-on-container-exit` tells Docker Compose to bring down the whole environment when HawkScan finishes and the `hawkscan` container exits.

Then create a Docker Compose configuration for HawkScan in a file named `docker-compose-hawkscan.yml`.

```yaml title="docker-compose-hawkscan.yml"
version: "3.7"

services:
  hawkscan:
    image: stackhawk/hawkscan
    environment:
      API_KEY: "${HAWK_API_KEY}"
    volumes:
      - .:/hawk
    tty: true
    depends_on:
      - nginx-test
```

This file creates the service `hawkscan` which runs the container `stackhawk/hawkscan`. It passes along the `HAWK_API_KEY` environment variable from your secured Repository Variables. And it mounts the current working directory `.` to `/hawk` within the container so that HawkScan can find your HawkScan configuration files.

Point `stackhawk.yml` at the service name, which is reachable within the Docker Compose private bridge network:

```yaml title="stackhawk.yml"
app:
  applicationId: xxXXXXXX-xXXX-xxXX-XXxX-xXXxxXXXXxXX
  host: http://nginx-test
  env: Bitbucket Pipelines
```

For a more in-depth example of scanning a realistic integration test environment using Docker Compose, see our tutorial, [Test-Driven Security With StackHawk Travis CI and Docker Compose](https://www.stackhawk.com/blog/test-driven-security-with-travis-ci-and-docker-compose/). In this tutorial we build, seed, and scan a Django application with an Nginx proxy front-end and PostgreSQL database backend, all in Docker Compose.
