By Robert Hall
In the process of developing portals with Liferay, it is often necessary to set up and tear down servers with a Liferay instance on them. There are many ways of accomplishing this, such as using VMs, AWS EC2 instances, etc. One approach that has the promise of being simple, repeatable and lightweight is using new open source tools such as Vagrant and Docker to create a virtual application container. This post will explore a simple scenario--bringing up a Liferay server in a lightweight container on a virtual server instance.
What is Vagrant
Vagrant is an open-source tool for creating and configuring virtual development environments. It can be used to create Linux (various distributions such as Ubuntu and CentOS are supported) instances on a variety of hosting platforms, including Virtual Box (local to your computer) or cloud services such as AWS.
What is Docker
Docker is an open-source engine to automate the deployment of applications as self-contained, portable containers independent of hardware, language, framework, packaging system and hosting provider. Think of it as building a sandbox with a deployed, configured application inside.
Creating a Ubuntu VM with Vagrant
If you are already working on Linux, you can skip this section and go to ‘Creating a Docker container’. As I am working on a Mac, I have to set up a Linux--in this case, Ubuntu, environment with Vagrant before installing Docker as Docker presently only works on Linux. Note: In the example scenarios in this post, '%' or '#' denote a Linux command prompt.
1. create work folder such as '/home/user/dev/vagrant
2. create a Vagrant file. This example is for Ubuntu with Virutal Box. Other hosting providers such as AWS can be specified. Think of this as the configuration of your new virtual machine. The 'config.vm.forward_port' is of importance as this a directive to tell Vagrant to forward port 8080 as 7991. So when we run Liferay on the virtual server on port 8080, it will be accessible via the browser as localhost:7991.
3. run vagrant up. This will instantiate a virtual machine instance using the Vagrantfile configuration.
Vagrant::Config.run do |config| config.vm.box = "raring" config.vm.box_url = "http://cloud-images.ubuntu.com/raring/current/raring-server-cloudimg-vagrant-amd64-disk1.box" config.vm.forward_port 8080, 7991 config.vm.share_folder("vagrant-root", "/vagrant", ".") config.vm.customize ["modifyvm", :id, "--memory", 2048 end
4. log into the instance
% /Applications/Vagrant/bin/vagrant up
Due to a bug in LXC (control package for Linux containers), Docker works best on the 3.8 kernel. Precise comes with a 3.2 kernel, so we need to upgrade it. The kernel we install comes with AUFS built-in. We also include the generic headers to enable packages that depend on them, like ZFS and the VirtualBox guest additions. If you didn’t install the headers for your “precise” kernel, then you can skip these headers for the “raring” kernel. But it is safer to include them if you’re not sure.
% /Applications/Vagrant/bin/vagrant ssh
5. Install the back-ported kernel
6. install basic tools and common software
% sudo apt-get install linux-image-extra-$(uname -r) (answer 'y') % sudo apt-get install linux-image-generic-lts-raring linux-headers-generic-lts-raring
% sudo apt-get install vim curl git sudo zip % sudo apt-get install software-properties-common % sudo apt-get install python-software-properties
% sudo apt-get update
Use vagrant ssh to get back in.
% sudo reboot
Creating a Docker Container
Docker is available as a Ubuntu PPA (Personal Package Archive), hosted on launchpad which makes installing Docker on Ubuntu straightforward.
1. Add the PPA sources to your apt sources list.
2. Update your sources
% sudo add-apt-repository ppa:dotcloud/lxc-docker (ENTER to continue when prompted)
3. Install docker, you will see another warning that the package cannot be authenticated. Confirm install.
% sudo apt-get update
4. pull a base image
% sudo apt-get install lxc-docker (y to continue)
5. inspect images
% sudo docker pull base
6. start docker shell
% sudo docker images
You will see a shell prompt such as the following:
% sudo docker run -i -t ubuntu /bin/bash
In this container – which is a lightweight and sealed vm-like space isolated from the rest of your computer – we can install a JVM and its dependencies:
1. install some dependencies
2. create /etc/hosts with name 'dockerlr'. This will be useful later with Oracle and Liferay.
# apt-get install software-properties-common (y to continue) # apt-get install python-software-properties (y to continue) # apt-get install sudo vim curl zip (y to continue)
3. Add the ppa that will allow us to install Java:
# echo '127.0.0.1 localhost 209c4fc1eeaa dockerlr' | cat > /etc/hosts
4. Install Java:
# add-apt-repository ppa:webupd8team/java (ENTER to continue when prompted) # apt-get update
Get the process id of the instance you just exited
# apt-get install software-properties-common -y apt-add-repository ppa:webupd8team/java -y # apt-get update echo oracle-java7-installer shared/accepted-oracle-license-v1-1 select true | sudo /usr/bin/debconf-set-selections # apt-get install oracle-java7-installer -y # exit
Commit it, thus creating a reusable image:
% sudo docker ps -a 209c4fc1eeaa ubuntu:12.04 /bin/bash 32 minutes ago Exit 0
Then, to see the images:
% sudo docker commit 209c4fc1eeaa rhall/java7
% sudo docker images REPOSITORY TAG ID CREATED SIZE base latest b750fe79269d 4 months ago 24.65 kB (virtual 180.1 MB) base ubuntu-12.10 b750fe79269d 4 months ago 24.65 kB (virtual 180.1 MB) base ubuntu-quantal b750fe79269d 4 months ago 24.65 kB (virtual 180.1 MB) base ubuntu-quantl b750fe79269d 4 months ago 24.65 kB (virtual 180.1 MB) ubuntu 12.04 8dbd9e392a96 4 months ago 131.5 MB (virtual 131.5 MB) ubuntu 12.10 b750fe79269d 4 months ago 24.65 kB (virtual 180.1 MB) ubuntu latest 8dbd9e392a96 4 months ago 131.5 MB (virtual 131.5 MB) ubuntu precise 8dbd9e392a96 4 months ago 131.5 MB (virtual 131.5 MB) ubuntu quantal b750fe79269d 4 months ago 24.65 kB (virtual 180.1 MB) rhall/java7 latest 23143436f87b 55 seconds ago 472.9 MB (virtual 604.4 MB)
Installing Liferay CE
We now have a reusable Docker container consisting of Ubuntu with Java 7 installed. This is the minimum for installing Liferay CE. Spin up a Docker instance using the java7 image.
Install the latest LR CE---in this example, we use the CE (Community Edition) of Liferay as we don't have to deal with a license and the IP address/Mac address limitations of a production license.
% sudo docker run -i -t -h dockerlr -p :8080 -v /opt/lr-home rhall/java7 /bin/bash
Obtain the URL below from www.liferay.com->Downloads Liferay 6.1 CE and use wget to download the distribution.
# cd /opt/lr-home
# wget http://sourceforge.net/projects/lportal/files/Liferay%20Portal/6.1.1%20GA2/ liferay-portal-tomcat-6.1.1-ce-ga2-20120731132656558.zip
# unzip *.zip
Setup liferay as a service
# sudo /opt/lr-home/liferay-portal-6.1.1-ce-ga2/tomcat-7.0.27/bin/startup.sh -fg
Place this in the script file called 'liferay':
# sudo vi /etc/init.d/liferay
You will need to make the script executable by running the chmod command:
# Liferay auto-start # description: Auto-starts liferay # processname: liferay # pidfile: /var/run/liferay.pid case $1 in start) sh /opt/lr-home/liferay-portal-6.1.1-ce-ga2/tomcat-7.0.27/bin/startup.sh ;; stop) sh /opt/lr-home/liferay-portal-6.1.1-ce-ga2/tomcat-7.0.27/bin/shutdown.sh ;; restart) sh /opt/lr-home/liferay-portal-6.1.1-ce-ga2/tomcat-7.0.27/bin/shutdown.sh sh /opt/lr-home/liferay-portal-6.1.1-ce-ga2/tomcat-7.0.27/bin/startup.sh ;; esac exit 0
The last step is actually linking this script to the startup folders with a symbolic link. Execute these two commands and we should be on our way.
# sudo chmod 755 /etc/init.d/liferay
Liferay should now be fully installed and operational.
# sudo ln -s /etc/init.d/liferay /etc/rc1.d/K99liferay # sudo ln -s /etc/init.d/liferay /etc/rc2.d/S99liferay
To start Liferay from the command line,
Screenshot on localhost:7991-initial
# service liferay start
Liferay is now up in it’s most basic form using the classic theme and hsql. Time to configure an administrator user, email, and password and complete the basic installation.
Screenshot on localhost:7991 after configuration
To shut down Liferay,
Exit the instance
# service liferay stop
Check the recent processes
Commit the latest update as it has installed and configured Liferay.
% sudo docker ps -a ID IMAGE COMMAND CREATED STATUS PORTS 50b10bb82488 rhall/java7:latest /bin/bash 17 minutes ago Exit 0 209c4fc1eeaa ubuntu:12.04 /bin/bash 26 minutes ago Exit 0
Check that the new configuration is available as a named image:
% sudo docker commit 50b10bb82488 rhall/liferayCEConfigured
% sudo docker images
In a manner similar to a Vagrantfile, Docker supports scripting with a Dockerfile. This configuration can be built, comitted as an image, and run. For example, a Dockerfile for running Liferay could be:
build and commit this Dockerfile
FROM rhall/LiferayCEConfigured MAINTAINER Robert Hall "email@example.com" EXPOSE 8080 CMD service liferay start && tail -f /opt/lr-home/liferay-portal-6.1.1-ce-ga2/tomcat-7.0.27/logs/catalina.out
run it (wait 30-60 seconds before opening the browser on localhost:7991)
% sudo docker build -t rhall/LiferayCERun .
To kill it, issue
% sudo docker run -d -h dockerlr -p :8080 rhall/LiferayCERun
to get the id. Then
% sudo docker ps -a
In this simple Liferay scenario, Liferay CE is using the default hsql (in-memory database) scenario. More complex configurations can be scripted in a Dockerfile---such as installation of a database server such as MySQL, setup of a user and database in MySQL, and configuration of connection properties in a portal-ext.properties file. Additionally, the install steps for Java and Liferay could be scripted as well.
% sudo docker kill ff59dd05989a
Creating and provisioning working, isolated environments for application containers/servers such as Liferay, Tomcat or others can be simplified and standardized by using such virtualization tools as Vagrant and Docker. By using them together, you can quickly create a reusable, consistent operating environment for your application container.