9 Steps for building a CI/CD pipeline with Travis-CI, Docker and AWS.

William Okafor
8 min readFeb 15, 2020

--

I would be using a simple React app for the frontend, docker for containerisation and AWS for deployment

Requirements:

  • A Github account
  • A minimum of a free tier AWS account.
  • A basic knowledge of Docker

Travis-CI is a hosted continuous integration(CI) service used to build and test software projects hosted at GitHub.

It basically helps developers automate the process of deploying their code from it’s repository onto the live environment while ensuring all the set tests of the application are passing before it’s allowed unto production.

Step 1: React —

I used an npm package called create-react-app to quickly spin up a react application by running create-react-app sample-app

After this is done, you should see a folder structure like this:

New react app

Step 2: Docker —

If you’re at this point, we would need to create a docker image of this application and for this, we would be adding two files named below to the root of our application:

  • Dockerfile — Used for building the image that contains the optimized version of this application
  • Dockerfile.dev — Used for building the image that contains the development version which would be used to run tests

A Dockerfile file contains instructions that docker uses to build an image of an application

To keep things short, I’d just show you the actual code:

  • Dockerfile:
  • Dockerfile.dev:

At this point, you should create a new github repository (You can name it sample-docker-react like I did for consistency) and push the simple-app to it.

Your repository should look something like this:

Now we need to connect our repository to travis-ci and for this, we’d move on to:

New repository for our sample app

Step 3: Travis-CI!

I’m assuming you already have an account with travis-ci using your Github account. This gives travis the access it needs to your repositories.

Next, click on your profile icon > settings then toggle on the sample-docker-react repository we just pushed to Github.

Activating a repo for monitoring.

This tells travis-ci to start monitoring the repository. but for this we need a YAML file called .travis.yml to be added to the application as this would contain the instructions on what you want travis-ci to do with your code when a build is triggered.

Here are some instructions you should add to your .travis.yml file:

sudo: required language: node_js
node_js:
- "stable"

services:
- docker

before_install:
- docker build -t wilpat/sample-app -f Dockerfile.dev .
script:
- docker run -e CI=true wilpat/sample-app npm run test -- --coverage
  • sudo: required- Travis ci requires the user to be with elevated permission
  • language: node_js- A way to specify the language that should be used in building the app
  • services- Used to tell travis-ci that we need an instance of docker running for this build
  • before_install- An array of things to do with your code before running tests or deploying your code(The instruction here builds the docker image using our Dockerfile.dev file and tags it with the name wilpat/sample-app)
  • scripts: An array of scripts to run before deploying your code.(Tests typically go here (The instruction here runs the our test by running image named wilpat/sample-app and overriding the command specified in the Dockerfile.dev)

We’d be needing one more instruction to tell travis-ci how and where to deploy our application, but we first need to setup AWS to receive our code.

Step 4: AWS Elastic Beanstalk—

Disclaimer: Nothing prepares you enough for the maze called AWS

AWS Elastic Beanstalk is an easy-to-use service for deploying and scaling web applications and services developed with Java, . NET, PHP, Node. js, Python, Ruby, Go, and Docker on familiar servers such as Apache, Nginx, Passenger, and IIS.

We need to sign into AWS, hover on services and select Elastic Beanstalk then select Create New Application by the top right as seen below:

Elastic Beanstalk

Enter the application name sample-docker-react, enter a description (optional) and then submit.

You should be redirected to the application itself and you’d notice a screen like:

New Application On ELB

We need to create an environment for our application to run in so click the Create one now link.

On the next page, select a Web server environment and you should get directed to a page like below:

Web server environment setup

Choose docker as the platform for this environment. Then leave the application code at Sample application then submit it and wait for the environment to be built up.

PS: You might need to refresh the page to show the finished environment

If everything went as planned, you should see something like this when it’s finished:

New Docker Environment

Step 5: AWS IAM —

Identity and Access Management (IAM) provides a way for external platforms to access elastic beanstalk apps in our AWS account.

For this to be possible, we need to create an IAM user and grant the user the appropriate privileges.

Go to Services(at the top left) > IAM > users > Add user on the page.

You should be directed to a page where you’re asked to enter the user name and the access type. I used sample-docker-react as the username and selected Programmatic access as that’s what this app needs.

The next page asks you to add the set permissions for this user, all you need here is:

  • Select Attach existing policies directly
  • Search for “elasticbeanstalk” in the table that shows up
  • Tick all the options that shows up
  • Click next till you create the user.

On success, you’d see a table showing you your AccessKeyID and SecretAccessKey as see below.

PS: You need to store these somewhere as we would be using them in Travis-CI for deploying our app and you’re only able to see the secret key visible once.

Successfully created IAM user

Step 6: AWS S3 Buckets—

Amazon S3 or Amazon Simple Storage Service is a service offered by Amazon Web Services (AWS) that provides object storage through a web service interface.

Also, while creating an elastic beanstalk environment, AWS selects a server location closest to you for hosting it(You can select a different location too).

Also, after the environment is created, an S3 bucket is also created bearing a name that’s contains an identifier of this server location (e.g us-east-1, us-west-1) and it is used to store applications that you deployed in environments existing in this same server location.

Secondly, you need to specify a folder(aka bucket path in travis) that would be used by travis-ci for deployment

Goto Services > Storage > S3

Select the bucket with a name that has the identifier of the server location of your environment in it’s name.

Create a folder and you can name it the same name with your application( sample-docker-react `) this name choice is optional and I do it to help me remember what app it’s for.

Step 7: Back to Travis-CI

You’d need to save the AccessKeyID and SecretAccessKey as an environment variable in Travis-CI.

Go to your dashboard and select the sample-docker-react repository > click on the options by the top right > click on settings.

On this settings page you should add AWS_ACCESS_KEY and AWS_SECRET_KEY like I have done:

Environment variables for travis

Step 8: Back to React —

We need to update our .travis-yml file with the instructions for deploying our code and then push to github.

Update yours with the following:

deploy:  provider: elasticbeanstalk  region: "your-server-location"
app: "sample-docker-react"
env: "SampleDockerReact-env" bucket_name: "elasticbeanstalk-us-east-2-XXXXXXXXXXXX" bucket_path: "sample-app" on: branch: master access_key_id: $AWS_ACCESS_KEY secret_access_key: secure: "$AWS_SECRET_KEY"
  • deploy: Tells Travis-ci how to deploy your app
  • provider: Platform to be used
  • region: Where the server of your elastic beanstalk app environment exists(Update the file with yours)
  • app: Then name you gave your application
  • bucket_name: The s3 bucket generated for the server location used for your environment
  • bucket_path: The folder we created on aws to receive the app sent from travis-ci
  • on: Tells travis-ci which github branch update should trigger a build
  • access_key_id: IAM access key generated in AWS but stored in travis ci
  • secret_access_key: IAM secret key generated in IAM of AWS but stored in travis ci

Now our .travis.yml file should look something like:

Step 9: Push to git —

Cross check your files and setup to ensure you did all I talked about in this walkthrough then Add, commit and push your updates to the repo on github.

Since we’ve added a .travis.yml file, travis-ci would pick up the update in few seconds and trigger a build.

After a successful build, Go to your application on AWS and you should see it get updated with the new code from travis, build the docker image, and start up the application which can be access when you click the link provided.

Fin!

Now anytime we update the master branch of our application, travis-ci picks up the changes and updates our application that lives in AWS.

:-D

If you made it here, thanks a lot for reading through! Here are little hints that you deserve ;)

  • Using the after_success instruction in the .travis.yml, we could separate concerns by letting travis-ci handle all the docker builds and then push the docker image to docker hub and setup AWS to only pull the new image instead of having to send the whole app to AWS and get it to build it there.
  • All code for this can be gotten here: https://github.com/wilpat/sample-docker-react
  • If you don’t want to get charged for using AWS, please delete the elastic beanstalk application.

--

--