Deploy a Docker Container on Amazon Elastic Beanstalk

In this episode we are going to deploy a NodeJS Express API as a Docker container on Amazon Elastic Beanstalk.

Before we continue, make sure you have the following things installed on your computer:

  • Elastic Beanstalk CLI (to be able to deploy)
  • NodeJS
  • Docker (for local testing)

Setup project

The name of our little project will be rocket_science, sounds good enough.

$ mkdir rocket_science
$ cd rocket_science
$ npm init -y
$ npm install express --save

Create index.js with a basic server

const express = require('express')
const app = express();
app.get('/', (req, res) => res.json('Alive and kicking!'));
app.listen(4000);

Add the start script to package.json

scripts: {
  "start": "node index.js"
}

Test the server locally:

$ npm start

Open another terminal, and enter:

$ curl http://localhost:4000

You should get the following output:

"Alive and kicking!"

GOOD! Everything works!

Create Dockerfile

# Set the Docker image you want to base your image off.
# I chose this one because it has NodeJS preinstalled.
FROM node:8.7.0

RUN mkdir /app
WORKDIR /app

# Install Node Deps
ADD package.json ./
RUN npm install

# Install app
ADD . .

# Exposes this port from the docker container to the host machine
EXPOSE 4000

# The command to run when this image starts up
CMD ["npm", "start"]

Now test your Dockerfile locally:

$ docker build -t rocket .
$ docker run -d -p 4000:4000 rocket
$ curl http://localhost:4000

Output should be

"Alive and kicking!"

Create Dockerrun.aws.json

To be able to use Docker on Elastic Beanstalk, we need to create a special file called Dockerrun.aws.json. Make sure the volume has a"host.sourcePath" that matches WORKDIR in Dockerfile.

{
  "AWSEBDockerrunVersion": 1,
  "volumes": [
    {
      "name": "rocket_science",
      "host": {
        "sourcePath": "/app"
      }
    }
  ],
  "containerDefinitions": [
    {
      "name": "rocket_science",
      "essential": true,
      "portMappings": [
        {
          "hostPort": 80,
          "containerPort": 4000
        }
      ]
    }
  ]
}

Initialize Elastic Beanstalk

Run eb init

$ eb init
Select a default region
(): I select eu-west-1 EU (Ireland) because it's closest to my location
Select an application to use
(): Create new application
Enter application name
(): default is "rocket_science" (just press enter)
It appears you are using Node.js. Is this correct?
Well yes, thank you for noticing :D

Commit your work

$ git init
$ git add .
$ git commit -m "Initial commit"

Create a dummy Elastic Beanstalk Environment

$ eb create dummy
.. Creating application version ...
.. LOTS OF JUNK ..
.. just wait for it to complete

Deploy!

$ eb deploy
Creating application version archive "app-XXX".
Uploading static_blog/app-XXX.zip to S3. This may take a while.
Upload Complete.
INFO: Environment update is starting.
INFO: Deploying new version to instance(s).
INFO: Environment health has transitioned from Ok to Info. Application update in progress on 1 instance. 0 out of 1 instance completed (running for 17 seconds).
INFO: Successfully built aws_beanstalk/staging-app
INFO: Docker container 95c2f5b00406 is running aws_beanstalk/current-app.
INFO: New application version was deployed to running EC2 instances.

To verify that everything works,

$ eb open

Should open your browser and display “Alive and kicking!”