Liferay with MySQL@Docker

Goal

Making it available a docker environment with Liferay and MySQL

Description

In the last two weeks, I have been investigating Docker (I’m using version 1.12.5) and, because I have also been recently investigating Liferay 7, I decided to investigate how to create a docker environment with Liferay and MySQL. In this regard, my goal was to create an automated way, through a bash script or similar, of provisioning of the environment for myself as well as my development team members (everybody on my team works in Linux or MAC environments). This recipe will provide you with a simple but functional script that has proven to fulfil my goal.

How to

At the end of the execution of the bash script, you should have:

  • One data container for MySQL (from what I’ve been reading about Docker, it seems to be a good idea to separate data volumes to store data, namely separating specific data from generic container images, allowing us to maintain the container image size small, reusing the same data across multiple containers, etc., so I tried to follow that practice)
  • One container for MySQL server
  • One data container for Liferay
  • One container for Liferay 7.2

Next, you’ll find the steps to create the mechanism that will result in your environment being automatically generated.

  1. The first file you’ll see is the automating-liferay.sh (${PWD}/automating-liferay.sh), which contains the relevant commands to create one container for  data volume for MySQL (I will assume, during this recipe, that you already have your docker environment fully configured and ready).
    #!/bin/bash
    
    # 1, Init variables
    mysqlVolumeContainer="mysqldata_liferay"
    mysqlContainer="mysql_5.6.33"
    liferayVolumeContainer="liferaydata_linkare_portal"
    liferayContainer="liferay_linkare_portal"
    
    # 2. Cleanup potentially existing containers
    ./cleanup_docker_container.sh $mysqlContainer
    ./cleanup_docker_container.sh $mysqlVolumeContainer
    ./cleanup_docker_container.sh $liferayContainer
    ./cleanup_docker_container.sh $liferayVolumeContainer
    
    # 3. Prepare mysql volume
    sudo docker create --name mysqldata_liferay -v ${PWD}/volumes/mysqldata busybox
    
    # 4. Building mysql image
    sudo docker build -t mysql:5.6.33 mysql/.
    
    # 5. Run mysql image - publish format: host:host port:container port
    sudo docker run --name $mysqlContainer -e MYSQL_ROOT_PASSWORD=secret --volumes-from $mysqlVolumeContainer --publish 0.0.0.0:3307:3306 -d mysql:5.6.33
    
    # 6. Prepare liferay volume
    sudo docker run -v ${PWD}/volumes/liferaydata:/opt/liferay-portal/data --name liferaydata_linkare_portal busybox
    
    # 7. Building liferay image
    sudo docker build -t liferay:7.0.GA3 liferay/.
    
    # 8. Run liferay image
    sudo docker run --name liferay_linkare_portal -it -v /tmp/deploy:/opt/liferay-portal/deploy --volumes-from liferaydata_linkare_portal --link $mysqlContainer:mysql --publish 0.0.0.0:8080:8080 -d liferay:7.0.GA3
    

    Note: Notice that in step 5. Run mysql image, you’ll expose mysql server container through the –publish flag, which runs in port 3306 by default at port 3307 in your local machine. I did this because I already have a MySQL server running at my machine. Doing that, will allow you to connect to your container’s mysql in a command line with one of the following commands:

    mysql -uroot -psecret -P3307 --protocol=tcp
    

    The –protocol flag will force your mysql client to use a tcp connection that will use your 3307 port instead of a unix socket which would ignore the port 3307 and would try to connect to MySQL that you may have running on your local host

    mysql -uroot -psecret -h[ip_address_of_your_container]
    

    You can get your mysql container IP through a command similar to “docker inspect mysql_5.6.33 | grep IPAddress”

    Notice also that in step 8.  Run liferay image, you’ll link your Liferay container with your MySQL server container, through the –link flag.

  2. You may run the previous command as many times as you wish because, at each run, you’ll stop and remove any previously existing containers. In order to do that, you’ll need the cleanup_docker_container.sh (${PWD}/cleanup_docker_container.sh):
    #!/bin/bash
    
    containerName=$1
    
    if [[ $# -eq 0 ]] ; then
     echo 'You must provide the container name'
     exit 1
    fi
    
    # Stop and remove containerName, if exists
    matchingStarted=$(sudo docker ps --filter="name=$containerName" -q | xargs)
    [[ -n $matchingStarted ]] && sudo docker stop $matchingStarted && echo "Container $containerName has been stopped"
    
    matching=$(sudo docker ps -a --filter="name=$containerName" -q | xargs)
    [[ -n $matching ]] && sudo docker rm -v $matching && echo "Container $containerName has been removed"
    
  3. The Dockerfile for mysql (${PWD}/mysql/Dockerfile) is defined as follows:
    FROM mysql:5.6.33
    
    ADD resources/initdb.sql /docker-entrypoint-initdb.d/
    

    Note: Notice that this container is fetched from MySQL official container, at version 5.6.33 and it adds a specific file that will create the initial Liferay database and an application user to be used by Liferay installation

  4. The initdb.sql ({${PWD}/mysql/resources/initdb.sql) file is defined as follows:
    create user lportal identified by 'lportal';
    CREATE DATABASE lportal DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
    grant all privileges on lportal.* to lportal;
    flush privileges;
    
  5. The Dockerfile for Liferay (${PWD}/liferay/Dockerfile) is defined as follows:
    FROM airdock/oracle-jdk:1.8
    
    # Install unzip
    RUN apt-get update && apt-get install -y unzip
    
    # Download and install liferay
    RUN curl -OLk "https://sourceforge.net/projects/lportal/files/Liferay Portal/7.0.2 GA3/liferay-ce-portal-tomcat-7.0-ga3-20160804222206210.zip"
    RUN unzip liferay-ce-portal-tomcat-7.0-ga3-20160804222206210.zip -d /opt
    RUN rm liferay-ce-portal-tomcat-7.0-ga3-20160804222206210.zip
    
    RUN ln -s /opt/liferay-ce-portal-7.0-ga3 /opt/liferay-portal
    
    # Add configuration files
    ADD resources/portal-ext.properties /opt/liferay-portal/portal-ext.properties
    ADD resources/portal-setup-wizard.properties /opt/liferay-portal/portal-setup-wizard.properties
    ADD resources/setenv.sh /opt/liferay-portal/tomcat-8.0.32/bin/setenv.sh
    
    # Liferay data will be stored in a separate data volume
    VOLUME /opt/liferay-portal/data
    
    # Expose port 8080 (optionally, 8000, if we want to run Tomcat in debug mode)
    EXPOSE 8080
    # Expose debug port 8000 (if we specify setenv.sh with debugging options)
    #EXPOSE 8000
    
    # Set JAVA_HOME
    ENV JAVA_HOME /srv/java/jdk
    
    # Execute liferay
    ENTRYPOINT ["/opt/liferay-portal/tomcat-8.0.32/bin/catalina.sh"]
    CMD ["run"] 

    Note: This container is one that already contains the Oracle JDK 8 and on top of that, we will download Liferay from Liferay website, unzip it locally to /opt, create a symbolic link to make it easier referencing.  We will also add the required portal-ext.properties with the Liferay properties of our new installation, an empty portal-setup-wizard.properties and a setenv.sh file which will contain specific JVM options (for instance, if necessary, one could add the necessary options to make it possible to start our tomcat in debug mode. After that, we will define our entrypoint to be catalina.sh file with the run command so that our docker running container will stop if our Liferay’s tomcat stops.

  6. portal-ext.properties (${PWD}/liferay/resources/portal-ext.properties) file could be defined with something similar to the following (only the part to connect to the database will be shown because it is the only relevant part for this recipe):
    setup.wizard.enabled=false
    liferay.home=/opt/liferay-portal
    
    jdbc.default.driverClassName=com.mysql.jdbc.Driver
    jdbc.default.url=jdbc:mysql://mysql:3306/lportal?characterEncoding=UTF-8&dontTrackOpenResources=true&holdResultsOpenOverStatementClose=true&useFastDateParsing=false&useUnicode=true
    jdbc.default.username=lportal
    jdbc.default.password=lportal
    

    Note: Notice that we will connect to mysql with the host mysql. That is available in the Liferay container because of the link option. If you want to check the IP address that you got for your mysql server container inside your liferay container, you may execute the following command “sudo docker exec -it liferay_linkare_portal cat /etc/hosts” which should return something like:

    127.0.0.1 localhost
    ::1 localhost ip6-localhost ip6-loopback
    fe00::0 ip6-localnet
    ff00::0 ip6-mcastprefix
    ff02::1 ip6-allnodes
    ff02::2 ip6-allrouters
    172.17.0.1 mysql a4711059524c mysql_5.6.33
    172.17.0.2 1f9435b0e568
    
  7. Finally, setenv.sh (${PWD}/liferay/resources/setenv.sh) file is (optionally, if you want to make your tomcat be in debug mode, you could add the options “-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000”:
    CATALINA_OPTS="$CATALINA_OPTS -Dfile.encoding=UTF8 -Djava.net.preferIPv4Stack=true  -Dorg.apache.catalina.loader.WebappClassLoader.ENABLE_CLEAR_REFERENCES=false -Duser.timezone=Europe/Lisbon -Xms1024m -Xmx1024m -XX:MaxPermSize=384m"
    

After the execution of automating-liferay.sh, anytime you want to start/stop your container images, all you have to do is “sudo docker start mysql_5.6.32” and “sudo docker start liferay_linkare_portal”.

Explanations

All explanations were made in place. Therefore, there’s nothing useful to add here, I suppose…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s