CI/CD — Docker-Compose, Elastic Beanstalk, and Github Actions

Continuous Integration and Continuous Deployments creates and environment of less bug by running test against all commits to a codebase.

AWS

The aim of this post is to set up a CI/CD pipeline with Github Actions so that every commit made to the master branch will trigger a set of actions to run against our code and deploy to Elastic Beanstalk if all actions pass. the code base will be below. First, note that the has been full explained in my previous post. In addition, the concepts of Elastic Beanstalk and the has been explained in previous post.

Setting up Github Actions

Github actions allow us to perform actions and commands every time a specific even fires against our codebase in a virtual environment. Github actions is configured in in the directory.

Navigate to a personal Github repository and click Github offers a few templates on how to start a this is helpful if we need language specific commands(npm) to run events like However, this case only needs to interact with Docker and AWS.

To build a custom, click and use the search bar to search up helpful actions. Actions in are open source and greatly reduce complexity. All workflows will have the structure of name, event, and jobs.

#NAME
name: Push images to Dockerhub and deploy on ELastic Beanstalk
#EVENT
on:
push:
branches:
- master
#JOBS
jobs:
build_docker_images:
name: build docker images
runs-on: [ubuntu-latest]
steps:
- name: checkout
uses: actions/checkout@v2
...

The event section is triggered on the term and can be configured to run on a magnitude of different Github events. Specifically, this will run every time there is a push on the master branch. Then the jobs section is signalled with the term where every has a name like Each job has an it runs on. In addition, each job has a set of with a name property. We use the term to pull from the help of open source actions like cloning the repo into the step or logging into docker.

In order for Elastic Beanstalk to successfully deploy the content of the git commit, the first step is to configure out Github Action to build and push the new images to This means we will need to log into in Github’s virtual environment. We can leverage another community action, to log into our Docker account. The pulls from the secrets encrypted in out Github profile — basically variables.

- name: Docker Login
uses: docker/login-action@v1.8.0
with:
username: ${{secrets.DOCKERHUB_USERNAME}}
password: ${{secrets.DOCKERHUB_TOKEN}}
logout: true

Now that we have access to our Dockerhub account, all that remains is building and pushing our images to their repositories. When pushing images to Dockerhub, the commands below will build, tag, and push the image built from the in the directory.

docker build -t keithkfield/blog-server . 
docker tag keithkfield/blog-server keithkfield/blog-server:latest
docker push keithkfield/blog-server:latest

These three commands should be the only three needed to push images built from our source code into Dockerhub.

- name: Build Server image
run: docker build -t keithkfield/blog-server -f
./Server/Dockerfile ./Server
- name: Tag our Image
run: docker tag keithkfield/blog-server
keithkfield/blog-server:latest
- name: Push to dockerhub
run: docker push keithkfield/blog-server

Now just repeat these three steps for the and container.

Using AWS

After getting our images to be continually deployed, we will need access to our account. Again, we can use another open source action —

- name: Deploy to EB
uses: einaregilsson/beanstalk-deploy@v14
with:
aws_access_key: ${{ secrets.AWS_ACCESS_KEY }}
aws_secret_key: ${{ secrets.AWS_ACCESS_SECRET_KEY }}
application_name: medium-compose-series
environment_name: Mediumblogseries-dev
version_label: "app-cbe0-210131_121135"
region: us-east-1

We pull the and from our encrypted secrets. The will be gathered from the process of creating an Elastic Beanstalk application.

Creating Elastic Beanstalk App

For this process to even work we will need to create the application and environment name beforehand. To start, use the command

eb init -r <region> <application_name>

to begin the process of creating an application.

Process of creating app

The only configuration that needs to stray from default is the platform question. Instead of the default 1, this application is so select 2.

Select a platform branch.
1) Docker running on 64bit Amazon Linux 2
2) Multi-container Docker running on 64bit Amazon Linux
3) Docker running on 64bit Amazon Linux

After this command, there will be a directory with a file. In aws, the file directs how multiple container within an application should work.

Dockerrun.aws.json

The resembles a file. Its format is and list all its containers in the key. The main points is that only the image has port mappings and it links the and images.

Now that the configuration file is built, we can now use the command

eb create <enviorment-name> 

to create an environment variable. Running this command, looks to the for instructions. First, it notes that is set to this means that this is a multi-container application. Elastic beanstalk pulls all three images from dockerhub and networks them together by the configuration of the load balancer. This process takes a while but establishes the base application we can build from.

Put Together

Now that we have defined the application and environment name, we can put them into the last step of our workflow. All that remains is getting the version label. To get this run the command

eb appversion

to get a list of valid versions to use.

My final command in my workflow is below.

Activating the Flow

To simply activate this flow, push these changes to the master branch. This triggers the action with the name of the commit in the tab. After a few minutes we can check the Elastic Beanstalk console to get the URL generated and visit the site.

Initial Push

Successfully, our application is healthy! Now making any change to the UI and pushing it will result in a deployment of the same application.

Success!!

Note that this is a long process and usually takes hours to get it correct.

It took 30 flows to get my CI/CD pipeline to work perfectly.

Software Dev