I tried to put more buzzwords in the title of this blog post but didn’t succeed… So anyway, let’s see what’s really behind these buzzwords.
With this article my goal is to host on Google Compute Engine (GCE) a basic java http server that will answer “Hello World”.
"Use the Api Luke!"
I want to do as much as possible using GCE’s Api because this Api is a big deal. Not all cloud providers give us such a nice tool to automate thing.
"Docker fear you should not"
And to make things more interesting, I’ll use docker to describe the process that will run on my GCE instance. I’d like to keep the configuration on the instance as minimal as possible. Everything should be configured inside a docker container so that I can test it on my local machine too.
Let's start with Google Compute Engine
First, I need to install the GCE command line Api:
$ brew install gcutil
Then, I should create a GCE account. Mine is already created. I’ve got a project named code-story-blog.
Start a new instance
Let’s create and start a simple instance that we are going to call master.
$ gcutil --project="code-story-blog" addinstance "master" --zone="europe-west1-a" --machine_type="n1-standard-1" --image="https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/backports-debian-7-wheezy-v20131127" +--------+----------------+---------------+----------------+---------+ | name | network-ip | external-ip | zone | status | +--------+----------------+---------------+----------------+---------+ | master | 10.240.205.130 | 22.214.171.124 | europe-west1-a | RUNNING | +--------+----------------+---------------+----------------+---------+
Now that our instance is up and running, let’s ssh to install docker.
Connect with ssh
$ gcutil --project="code-story-blog" ssh master $ curl get.docker.io | bash Docker has been successfully installed! If you would like to use Docker as a non-root user, you should now consider adding your user to the "docker" group with something like: $ sudo usermod -aG docker `whoami` $ exit $ gcutil --project="code-story-blog" ssh master
Let's build a docker image
Now almost everything is ready to build a docker image on the instance. I’ve prepared a GitHub repository that contains the Dockerfile that describes my setup. To grab it, docker needs git. So let’s install git. That is the last thing I will install on the instance. The rest will be done inside the docker container.
$ sudo apt-get install -y git
The image descriptor
Here’s what the Dockerfile looks like is you are too lazy to click on the link. Basically, what it does is:
- Start from an ubuntu base
- Install some prerequisite tools
- Setup the source for java 8 packages
- Install Java 8
- Install Git and Maven
- Clone my hello world project
- Build the project using maven
- Tell that it’s going to run something on port 8080
- Tell that it will run inside the helloworld directory
My idea is to clone a java 8 project, build it inside the container with maven. Run it.
from base # Install prerequisites run apt-get update run apt-get install -y software-properties-common # Install java8 run add-apt-repository -y ppa:webupd8team/java run apt-get update run echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | sudo /usr/bin/debconf-set-selections run apt-get install -y oracle-java8-installer # Install tools run apt-get install -y git maven # Clone project run git clone https://github.com/dgageot/helloworld.git # Build project run cd helloworld && mvn verify dependency:copy-dependencies # Expose the http port expose 8080 workdir helloworld
Let's build the image and drink a couple of coffees!
$ docker build -t dgageot/helloworld github.com/dgageot/helloworld
The slowest part of the installation is the part that installs Java 8. You’ll see
Saving to: jdk-8-fcs-bin-b129-linux-x64-07_feb_2014.tar.gz for quite some time. It’s OK.
So, after the coffee break, we now have a fully prepared docker image. Let’s check that it’s properly working by running it.
$ docker run -i -t dgageot/helloworld java -version
It should tell us that java 8 is installed. That’s nice! Let’s run the web server now.
With this command, I tell docker to use the image to run my java application. It will use the sources that was cloned during the image construction. The application is running an http server on port 8080 and I tell docker that this port should be mapped to my host’s 80 port.
$ docker run -p 80:8080 -t -i dgageot/helloworld java -DPROD_MODE=true -jar target/helloworld-1.0-SNAPSHOT.jar $ curl http://localhost/ Hello World
Make it visible from outside the host
Ok. It works on my instance. But can we see the web pages from the outside? Not yet, GCE will block the 80 port. We have to add a firewall rule that will allow traffic on port 80. The api is our friend:
$ gcutil --project="code-story-blog" addfirewall samplehttp --description="Incoming http allowed." --allowed="tcp:http"
From my laptop:
$ curl http://126.96.36.199/ Hello World
Here we are! We started a very simple Java 8 hello world on Google Compute Engine using docker. hence the buzzwords in the title.
If we want to stop the instance, let’s tell it to poweroff. It will kick us out of ssh.
And now we just have to really delete the instance to go back to were we started.
gcutil --project="code-story-blog" deleteinstance master
If you followed this tutorial and tried to delete your instance, gcutil will ask you if you want to keep the disk attached to the
master instance. You can skip its deletion because tomorrow we are going to use this persisted state to start a lot of clones running the same helloword.