Streamlining DevOps Workflows: Integrating Atlassian BitBucket and Slack for Seamless Pipelines and Docker Management
Published: 2023-09-11 17:17:31

In today's rapidly evolving software development landscape, the successful execution of DevOps practices has become instrumental in delivering high-quality software at speed. DevOps, which is a fusion of development and operations, emphasises collaboration, automation, and continuous integration/continuous deployment (CI/CD) pipelines to streamline the software development lifecycle.

To achieve this seamless workflow, organisations are increasingly turning to robust tools like Atlassian BitBucket for version control, collaboration, and code deployment. Additionally, Slack has emerged as a leading communication and collaboration platform, providing teams with a central hub for real-time communication and integrations with various development tools.

In this comprehensive guide, we will explore how to harness the power of Atlassian BitBucket and Slack to create a harmonious environment for managing CI/CD pipelines and Docker containers. This integration will empower your development and operations teams to collaborate effectively, automate workflows, and deploy code with confidence.


### Accessing Your BitBucket Dashboard

Our journey begins on the BitBucket dashboard, the central control panel for managing repositories, code, and collaborations. If you don't already have a BitBucket account, you can sign up for one on their website. Once you're logged in, follow these steps:

- Creating a New Repository:

> - Click on Create a new repository

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dcru8og1ey63sffbi13r.png)

> - On the Create a new repository do the following:

> A. Project name: Give your project a meaningful name to categorize your work effectively.
> B. Repository name: Provide a unique name for the repository, reflecting the project or application.
> C. Click on the "Create Repository" button to finalize the setup.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4yo1k3gv77542tpahbt2.png)


> D. Confirm that the repository was created successfully.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hvfazovucqj3ckdfmxcf.png)


### Setting Up Slack 

Effective communication and collaboration are paramount in DevOps, and Slack provides a perfect platform for real-time interactions. Here's how to set up a Slack workspace:

- Go to the Slack website and click on the "Try For Free" button.


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u97ncwbw0u2rzzea4xb3.png)



- Provide your email address and click "Continue".

- On the "Create a New Slack Workspace" page, click the "Create a Workspace" button.

- Provide a name for your company or team.

> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zmktfke8cxhlulbwl3jo.png)


- Next, add a workspace name and click "Next".


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z57678c3dw5q8tkaaqrv.png)

- While you can invite team members, for this article's sake, let's skip this step and click "Next".


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pcllr13414o718ij1k93.png)

- Provide information about what your team is currently working on.


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c50k01d8nldzmspqtewv.png)


- Confirm that your workspace is now active.


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/16yr461syxkz8nuamb0p.png)


- Create a channel named "devops-engineering".


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4i3t6bx4bhk7ek3xvn71.png)


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/42gp39mbupgoreiqma9x.png)

### Connecting BitBucket to Slack

With your BitBucket repository and Slack workspace in place, it's time to connect the two for seamless collaboration and automated notifications:

- Return to your BitBucket repository page and click on "Repository settings."


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/51udhrncxv2ps8rkrgrv.png)



- Under the "Slack" section, click on the "Connect" button.


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dpqq7f0g8ziaqn3jb23b.png)


- Allow BitBucket Cloud to access your Slack workspace by clicking "Allow".


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nskq14800rk3bqq6ujs5.png)


- Add a chat subscription by selecting your workspace and channel. Click the "Add" button.


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ufi2wyn3tbzzn0hkias2.png)


- Confirm the subscription.

> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ju7jlei80z7x9aj6bz9s.png)


### Cloning Your BitBucket Repository

To start working with your code locally, you'll need to clone the BitBucket repository to your local machine:

- On the BitBucket repository page, click "Clone" and copy the repository URL link.

> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jraw831u7w06uesrl8d8.png)


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dblwmctx12cec5jd5zoq.png)


- Use the repository URL link to run git clone in your command line.

```
git clone repo_url
```


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mc71yu5zzs44ntrdy2ar.png)

- Navigate into the cube360 directory.

```
cd cube360
```
- Create a new file called index.html and add <p>Hello World!!!</p>

```
touch index.html

<p>Hello World!!!</p>
```

> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ba5zfr5kaz6fl87knyaf.png)

- Add index.html to the staging area with git add index.html.

```
git add index.html
```

> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8hkjz63o0j1cao8fg30u.png)



- Run git status to check the status of your repository.

```
git status
```

> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fcplz1dcw5srf297xp5x.png)

- Commit the changes with git commit -m "Initial commit of project Hello World!!".

```
git commit -m "Initial commit of project Hello World!!"
```

> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l3drivw3dpfa3amwokjc.png)

- Push your code to BitBucket with git push.

```
git push
``` 

> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rduibn3w2wx050lkv48w.png)

- Check the "devops-engineering" channel in Slack, and you should see an alert about the push action.


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7vp0z9li9zgab3vsfcer.png)

- To further test the integration, add <p>This is a great DevOps Collaboration feature</p> to index.html.

```
<p>This is a great DevOps Collaboration feature</p>
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1wi2aw1v86yi4i93tan3.png)

- Run git add * and git commit -m "Added more code".

```
git add * and git commit -m "Added more code"
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h6mepwkxnhw2n4kywgjt.png)

- Push your changes to BitBucket with git push.

```
git push  
```
> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rduibn3w2wx050lkv48w.png)


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b1etan42ltlmmx3258gy.png)

### BitBucket Pipelines for Building and Deployment

Now, let's delve into the heart of DevOps - automation. BitBucket Pipelines is a robust CI/CD solution that enables automated building, testing, and deployment of your code. We'll start by configuring the necessary files and directories:

- Return to your BitBucket repository dashboard and select the "Pipelines" option.


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uhksg8hiyeks8pffmzp5.png)

- On your local machine, create the following files and directories:

> A. Create a file called "Dockerfile" with touch Dockerfile.

```
touch Dockerfile
```
> B. Create another file named "bitbucket-pipelines.yml" with touch bitbucket-pipelines.yaml.

```
touch bitbucket-pipelines.yaml
```
> C. Create a new file named "nginx.conf" with touch nginx.conf.

```
touch nginx.conf
```
> D. Create a directory called "www-data" with mkdir www-data.

```
mkdir www-data
```


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vuo8a4wtu4s0npsvte1s.png)

> E. Move index.html into the "www-data/" directory with mv index.html www-data/.

```
mv index.html www-data/
```
> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4tz5wkkzlek57foz7cdk.png)


- Add, commit, and push your changes to BitBucket with the following commands:

```
git add .
```
```
git status
```
```
git commit -m "Updated with Docker code"
```
```
git push
```

> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kaqor7r1k0f1kacdru6t.png)

- Now confirm the recent changes on Bitbucket repository dashboard.

> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/abv5zx204vdyhrdc0lt6.png)

- Now, update the files on your local machine and commit them to your remote repository:

> A. Update your Dockerfile.
```
# docker pull xxxxxxxx/yyyyyyy:zzzzzzzzz
# docker run --name nginx-webserver -d -p 8080:80 xxxxxxxx/yyyyyyy:zzzzzzzzz

FROM ubuntu:14.04
RUN apt-get update
RUN apt-get install -y nginx
ADD nginx.conf /etc/nginx/nginx.conf

ADD ./www-data /www-data

EXPOSE 80
CMD ["nginx"] 

```

> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b74egnyb5ru6oiwhc0u0.png)


This is a Dockerfile, a text-based script used to define a Docker image. The Dockerfile describes how to build an image for running an NGINX web server using an Ubuntu 14.04 base image. Here's a breakdown of each part of the Dockerfile:

**Base Image Selection**:

   ```
   FROM ubuntu:14.04
   ```

This line specifies the base image for the new image being built. In this case, it uses the "ubuntu:14.04" image as the starting point. The resulting image will have Ubuntu 14.04 as its base operating system.

**Package Installation**:

   ```
   RUN apt-get update
   RUN apt-get install -y nginx
   ```
These lines use the `RUN` instruction to execute commands within the image during the build process.

The first command, `apt-get update`, updates the package repositories to ensure the package manager (APT) has the latest package information.

The second command, `apt-get install -y nginx`, installs the NGINX web server. The `-y` flag automatically confirms any prompts during the installation.


**Configuration File Addition**:
   ```
   ADD nginx.conf /etc/nginx/nginx.conf
   ```
This line copies a file named "nginx.conf" from the context (the directory where the Dockerfile is located) into the image.

Specifically, it adds the configuration file to the "/etc/nginx/nginx.conf" location within the image. This is where NGINX looks for its configuration by default.

**Directory Addition**:
   ```
   ADD ./www-data /www-data
   ```
This line copies the contents of a directory named "www-data" from the context into the image.

It places the contents into the "/www-data" directory within the image.

**Port Exposure**:
   ```
   EXPOSE 80
   ```
This line informs Docker that the container will listen on port 80 at runtime. It doesn't actually publish the port, but it documents that the container expects external traffic on port 80.

**Command Execution**:
   ```
   CMD ["nginx"]
   ```
This line specifies the default command to run when a container based on this image is started.

It runs the "nginx" command, which starts the NGINX web server within the container.


> B. Update your `bitbucket-pipelines.yml` file.

```
# This is a sample build configuration for Docker.
# Check our guides at https://confluence.atlassian.com/x/O1toN for more examples.
# Only use spaces to indent your .yml configuration.
# -----
# You can specify a custom docker image from Docker Hub as your build environment.
image: atlassian/default-image:2

pipelines:
  default:
    - step:
        name: Build NGINX Docker Image
        services:
          - docker
        script: # Modify the commands below to build your repository.
          # Set $DOCKER_HUB_USERNAME and $DOCKER_HUB_PASSWORD as environment variables in repository settings
          - export IMAGE_NAME=oloruntobi/my-nginx-image:$BITBUCKET_COMMIT
          
          # build the Docker image (this will use the Dockerfile in the root of the repo)
          - docker build -t $IMAGE_NAME .
          # authenticate with the Docker Hub registry
          - docker login --username $DOCKER_HUB_USERNAME --password $DOCKER_HUB_PASSWORD
          # push the new Docker image to the Docker registry
          - docker push $IMAGE_NAME

          - echo "finished building!"
```


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1qwv6ef1n4bsnxosgiy1.png)


This code is a configuration file written in YAML format for defining a build process using Docker within an Atlassian Bitbucket Pipelines. It describes how to build a Docker image for an NGINX web server and push it to a Docker registry, like Docker Hub. Here's a breakdown of the code:

**Docker Image Configuration**:
   - `image: atlassian/default-image:2`: This specifies the Docker image to be used as the build environment. In this case, it's using the "atlassian/default-image" version 2 image as the base image for running the build steps.

**Pipelines Configuration**:
   - `pipelines`: This section defines the pipelines for different stages of the build process. In this case, there's only one pipeline named "default."

**Pipeline Step**:
   - `- step:`: This indicates the start of a build step within the "default" pipeline.

**Step Name**:
   - `name: Build NGINX Docker Image`: This is the name of the build step and is used for identification and display purposes.

**Service Configuration**:
   - `services:`: This section specifies the services that should be available during the build step. In this case, it includes the "docker" service, indicating that Docker should be available to execute Docker-related commands.

**Build Script**:
   - `script:`: This section defines the sequence of commands to be executed during the build step. These commands will be run within the Docker image specified earlier.

**Environment Variable Setup**:
   - `export IMAGE_NAME=oloruntobi/my-nginx-image:$BITBUCKET_COMMIT`: This command sets an environment variable called `IMAGE_NAME`. It uses the repository name "oloruntobi/my-nginx-image" and appends the Bitbucket commit hash to create a unique name for the Docker image.

**Docker Build**:
   - `docker build -t $IMAGE_NAME .`: This command builds a Docker image using the Dockerfile located in the root of the repository. The `-t` flag assigns a tag (in this case, the value of `IMAGE_NAME`) to the image.

**Docker Login**:
   - `docker login --username $DOCKER_HUB_USERNAME --password $DOCKER_HUB_PASSWORD`: This command authenticates with the Docker Hub registry using the provided Docker Hub username and password. This authentication is necessary to push the Docker image to Docker Hub.

**Docker Push**:
    - `docker push $IMAGE_NAME`: This command pushes the newly built Docker image to the Docker registry (in this case, Docker Hub). It uses the `IMAGE_NAME` variable as the image name and tag.

**Echo Finished**:
    - `echo "finished building!"`: This is a simple informational message that will be printed to the build log, indicating that the build process has finished.

> C. Update the nginx.conf file.

```
daemon off;
pid /var/lib/nginx/nginx.pid;

events {
  worker_connections 1024;
}

http {
  include /etc/nginx/mime.types;
  index index.html;

  server {
    listen *:80;
    
    location / {
      root /www-data;
    }
  }
}
```


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7t2q51lruzo4did70i31.png)


Let's break down the different sections and directives in this configuration:

**Global Directives**:

``daemon off;``: This directive controls whether NGINX runs in the background as a daemon. Setting it to "off" means NGINX will run in the foreground, which is useful for Docker containers or when running NGINX directly from the command line.

``pid /var/lib/nginx/nginx.pid;``: This directive specifies the path where NGINX will write its process ID (PID) file. This file contains the process ID of the running NGINX instance.

**events Block**:

``events { ... }``: This block contains event-related configuration directives.

``worker_connections 1024;``: This directive sets the maximum number of connections that a worker process can handle simultaneously. In this case, it's set to 1024 connections, which is a reasonable default value.

**http Block**:

``http { ... }``: This block defines HTTP-related configuration directives for NGINX.

**include Directive**:

``include /etc/nginx/mime.types;``: This directive includes the specified file, "/etc/nginx/mime.types," which contains a mapping of file extensions to MIME types. It's used to determine the MIME type of files served by NGINX.

**index Directive**:

``index index.html;``: This directive specifies the default file to serve when a directory is requested. In this case, if a directory is requested, NGINX will look for an "index.html" file and serve it if found.

**server Block**:

``server { ... }``: This block defines a server block, which represents an individual HTTP server in NGINX.
listen *:80;: This directive specifies that the server should listen on port 80 for incoming HTTP requests. The asterisk (*) means it will listen on all available network interfaces.

**location Block**:

``location / { ... }``: This block defines a location block within the server block. It specifies how NGINX should handle requests that match the location pattern (in this case, the root path "/").

``root /www-data;``: This directive sets the root directory for serving content for this location. Requests to the root path ("/") will be served from the "/www-data" directory. This is where the web content is expected to be located.

In summary, this NGINX configuration sets up a basic HTTP server listening on port 80, serving content from the "/www-data" directory, and using "index.html" as the default file. 

> D. Use the following commands to add, commit, and push these changes:

```
git add .
```
```
git status
```
```
git commit -m "Adding more code to our repo"
```
```
git push
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wam0kvga44jam1sn796b.png)

> E. Next, configure environment variables in the repository settings:

- Click on "Repository Settings.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c5llzi2hwyfqxiith02d.png)


- Under "Repository Variables," create two variables named DOCKER_HUB_USERNAME and DOCKER_HUB_PASSWORD.


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5yo00e0xool6fh1emnj6.png)


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lwjcmukomgn0ypeiaqzj.png)

> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rfogvi1wgcimrwx5tyam.png)


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z3x9to2g832s3xruubbw.png)


- Update the bitbucket-pipelines.yml file by adding your Docker Hub username and image name.

> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/spsfsu6g6hfl7p6ieqxg.png)

- Push the changes to your BitBucket repository.

```
git add .
```
```
git status
```
```
git commit -m "Adding more code to our repo"
```
```
git push
```

> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ti6y9wgt4nw25doddlni.png)


- Go to the Pipelines page on your BitBucket repository and confirm that the pipeline passes successfully. Additionally, check Docker Hub to verify that your artifact is available.


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s6q713erkxz90pwgybp4.png)


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7t4e0g6olhrjs4t0x1qt.png)


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cntgesn5k3xoncw8pnh2.png)

> F. Now, let's move forward:

- Start the Docker daemon via Docker Desktop.

> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4biduy8yx1icvxdwqaaj.png)

- Run your container with the following steps:
a. Check for containers on your local machine with docker ps -a

```
docker ps -a
```
> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2shn1souphrhf80xryny.png)


b. Pull your image from Docker Hub with docker pull username/my-nginx-image:tag

```
docker pull username/my-nginx-image:tag
```

> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hs4whu56d5fqppfbk1r4.png)

c. Start your container with docker run --name nginx-webserver -d -p 8080:80 username/my-nginx-image:tag 

```
docker run --name nginx-webserver -d -p 8080:80 username/my-nginx-image:tag
```

> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/65voxkdmi0f4kecweb91.png)

d. Confirm the status of the container with docker ps

```
docker ps
```

> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/87y284c1pxlzendf1orp.png)

e. Test your application by running curl localhost:8080

```
curl localhost:8080
```

> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/80mw7rspagrutkwfra2s.png)

### Slack Notifications for BitBucket Pipelines

To receive notifications in Slack when your pipeline succeeds or fails, follow these steps:

- Return to the BitBucket repository page and click on "Repository Settings".

> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v36g0tvpwtejnnnc11k1.png)

- Under the "SLACK" section, click on the "Settings" button.

> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jguzrwg1r39xan3jw3gt.png)

- Add "pipeline failed" and "pipeline succeeded" options under the master section.

> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y6zoku49iy3sco3on7f8.png)

- Add a new line to your index.html page: <p>This DevOps is DevOpsing by automation!</p>.

```
<p>This DevOps is DevOpsing by automation!</p>
```
- Push the change to BitBucket.

```
git add .
```
```
git status
```
```
git commit -m "adding more code to index.html file"
```
```
git push
```

> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yil72rccn6j7vvzpuy5o.png)

- Confirm by checking the Slack channel and BitBucket Pipelines page.


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v86fq2k18rar586dd2xm.png)


> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dnslqrsoe07x4qqo328v.png)

> ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r2yaibfen1icgswe8kwt.png)

### Conclusion

By integrating Atlassian BitBucket and Slack into your DevOps workflow, you've taken a significant step toward streamlining your development process. This comprehensive integration enables you to automate code deployments, manage Docker containers efficiently, and receive real-time notifications on pipeline statuses.

In the fast-paced world of software development, where collaboration and automation are key, this integration empowers your team to deliver code more swiftly and reliably. It fosters a culture of collaboration and transparency, allowing development and operations teams to work together seamlessly.

As you embark on your DevOps journey with BitBucket and Slack, remember that this is just the beginning. Continuous improvement and adaptation to your team's unique needs will further enhance your DevOps practices, helping you deliver exceptional software with speed and confidence. Happy DevOps-ing!