Perform repetitive tasks, are the way to succeed or hit boredom. For example, practice guitar everyday can make you better, don’t learn anything new, boring.
Most of these projects send HTTP requests to the application server for sending push messages. The minimum set up below is required for testing:
- JDK 1.7
- Maven 3.1.1 or superior
- JBoss AS 7 or Wildfly 8.1 Final
- Node.js, npm and bower
- Set the environment variables properly
- Configure SSL certificates
It’s near to impossible to configure everything in less than an hour — Java is tricky sometimes. Minutes later, it starts to get boring. Automation scripts can be helpful, but does not guarantee any portability. This is where Docker comes into play.
The Moby Dock
On OSx, additional steps are required, because Docker engine have specific features tied to the Linux kernel. For this reason, VirtualBox and boot2docker are required. There are two alternatives to install: download from GitHub, which already contains the whole environment required or make use of Homebrew.
On Homebrew, ensure that everything is up to date and the system is ready to brew before getting started:
$ brew update && brew doctor
Next, install boot2docker:
$ brew install boot2docker -y
Assuming the installation went well, docker and boot2docker should be available through command line. Now, let’s create a new VM:
$ boot2docker init Downloading boot2docker ISO image... Latest release is v1.2.0 Success: downloaded https://github.com/boot2docker/boot2docker/releases/download/v1.2.0/boot2docker.iso
The ISO image can be found at $HOME/.boot2docker folder and visualized on VirtualBox
We are all set to start with Docker. As time goes by, the following commands will start become part of routine:
$ boot2docker up Waiting for VM and Docker daemon to start... ............................................. Started. To connect the Docker client to the Docker daemon, please set: export DOCKER_HOST=tcp://192.168.59.103:2375 $ $(boot2docker shellinit)
Eventually your VM may run into issues like successively timeouts or aborting, that’s the reason why shellinit so important. It’s responsible for configure DOCKER_HOST and TLS variable (if configured).
For shutting down the image:
$ boot2docker down
To save time, create the following aliases with the basic commands like this:
$ alias -g b2d-up='boot2docker up && $(boot2docker shellinit)' $ alias -g b2d-down='boot2docker down'
Eventually upgrade the ISO image is needed for improvements:
$ boot2docker upgrade
Docker Hub and the basics
Most of the official repositories contain images like: Ubuntu, Fedora, Debian and popular application servers easily found at Docker Hub.
Before start, sign up with the GitHub account on Docker Hub. Then attempt to login:
$ docker login
After being prompted for your credentials, you will be able to search for images:
$ docker search fedora NAME DESCRIPTION STARS OFFICIAL AUTOMATED fedora (Semi) Official Fedora base image. 73 [OK] ...
Let’s suppose that something must be tested on Fedora:
//Run interactively $ docker run -it fedora bash Unable to find image 'fedora' locally Pulling repository fedora 88b42ffd1f7c: Download complete ... //You are now able to try Fedora bash-4.2#
Visualize the downloaded images:
$ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE fedora latest 88b42ffd1f7c 8 weeks ago 373.7 MB
Keep in mind is that Docker won’t save the state of your containers. Until you commit the changes, nothing will be persisted to the local container. In other words, if you exit from console, everything will be lost.
Erratum: Is possible to retrive the state of your container, using the ID. Thanks Marc for correcting me. Use commit to save, update and manage the changes into the Docker image.
For testing, run and install some dependencies like Git:
$ docker run -it fedora bash bash-4.2# yum update && yum install git
Open a new console to visualize the running containers:
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS 7ebd5f9abfa1 fedora:latest "bash" 13 minutes ago Up 13 minutes
To guarantee that nothing will be lost, persist latest changes:
$ docker commit docker commit 7ebd5f9abfa1 golum $ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE golum latest ac16c9177afa 2 minutes ago 373.7 MB fedora latest 88b42ffd1f7c 8 weeks ago 373.7 MB $ docker run -it golum bash
Build your own image
After play with Docker, is not that hard to realize that’s nearly impossible to memorize all the steps and configuration required to create a custom image. It is recommended to include the instructions in a Dockerfile — the descriptor for building images.
$ docker search wildfly NAME DESCRIPTION STARS OFFICIAL AUTOMATED jboss/wildfly WildFly application server image 27 [OK]
With the base image already there, is possible to extend it on Dockerfile, just providing parameters to FROM:
Our image will have to deal with multiple environment variables to run Java and Node.js, ENV can make it easy. Also, it can also be used on Dockerfile to specify repository names and software versions. Here’s an example:
ENV REPO_NAME aerogear-unifiedpush-server ENV JAVA_HOME /usr/lib/jvm/java-1.7.0-openjdk ENV MAVEN_VERSION 3.1.1 ...
For command line instructions like
yum install, execution of shell scripts or downloading files RUN is widely used:
RUN sudo yum -q -y install java-1.7.0-openjdk-devel nodejs npm gcc make libpng libpng-devel git && yum -q clean all
By default everything on Dockerfile is executed as root, is strongly encouraged to use non-root credentials instead. Modify the current user quite simple:
RUN useradd -m aerogear -d /opt/aerogear -s /sbin/nologin USER aerogear //Execute all the commands below as aerogear RUN sudo yum install -q -y nodejs npm gcc make libpng libpng-devel git && yum -q clean all
Other commands like WORKDIR, EXPOSE and ENTRYPOINT are particularly handy for the boot time definition. For example, copy the project to
/opt/aerogear, expose SSL ports and start WildFly:
# Switch to the working dir /opt/aerogear WORKDIR /opt/aerogear # Clone the official repository RUN git clone https://github.com/aerogear/$REPO_NAME.git # Expose SSL default port EXPOSE 8443 # Set the default command to run on boot ENTRYPOINT ["/opt/aerogear/server/bin/standalone.sh", "-b", "0.0.0.0", "-bmanagement", "0.0.0.0"]
Sharing is caring
For automated builds, the documentation has a detailed explanation about it. If you prefer to build the image by yourself, from the directory where Dockerfile is located run:
$ docker build -t abstractj/wildfly . Sending build context to Docker daemon 53.25 kB Sending build context to Docker daemon Step 0 : FROM jboss/wildfly Pulling repository jboss/wildfly ...
Check if the image is there:
$ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE abstractj/wildfly latest d775c6675b27 3 minutes ago 1.192 GB
The interaction with Docker Hub through command line interface is pretty much close to Git. If you are already familiar with it:
$ docker push abstractj/wildfly
The default tag is always
latest, depending on how many changes are done into your image, might be interesting to tag it:
$ docker tag abstractj/wildfly abstractj/wildfly:0.0.1
Now with the image available for download everyone can take advantage of it, no matter the experience level with Java. But how to test?
Downloading and exposing the SSL port
$ docker run -it -p 8443:8443 abstractj/unifiedpush-wildfly
Exposing to the private network
For accessing the image, is necessary to discover its IP address:
$ boot2docker ip The VM's Host only interface IP address is: 192.168.59.103
The host machine (computer with running image) will always have access to Docker containers. But what about other devices?
Consider the following scenario:
- computer, mobile devices: 10.0.1.0/24
- VirtualBox: 192.168.59.0/24
It can be accessible via internal network IP address, if we properly configure the port forwarding:
$ boot2docker stop $ VBoxManage modifyvm "boot2docker-vm" --natpf1 "tcp-port8443,tcp,,8443,,8443" $ boot2docker up && $(boot2docker shellinit)
Now the application server will be accessible to the network.
Docker provides a lot of features for people easily get started with application servers and Linux distros. On AeroGear it helped a lot to put client and server side developers on the same page.
For questions, feel free to contact me. I hope I didn’t bore you too much.