3

I am trying to deploy my Java EE application using a Glassfish 4.1 server and I would like to deploy it as a Docker container.

I'd like writing the correct Docker command to download/start a Glassfish server and then deploy my application on it, using the corresponding GIT repository.

Currently I am able to build a Docker container starting a Glassfish server with the following Dockerfile:

FROM        java:8-jdk

ENV         JAVA_HOME         /usr/lib/jvm/java-8-openjdk-amd64
ENV         GLASSFISH_HOME    /usr/local/glassfish4
ENV         PATH              $PATH:$JAVA_HOME/bin:$GLASSFISH_HOME/bin

RUN         apt-get update && \
            apt-get install -y curl unzip zip inotify-tools && \
            rm -rf /var/lib/apt/lists/

RUN         curl -L -o /tmp/glassfish-4.1.zip http://download.java.net/glassfish/4.1/release/glassfish-4.1.zip && \
            unzip /tmp/glassfish-4.1.zip -d /usr/local && \
            rm -f /tmp/glassfish-4.1.zip

EXPOSE      8080 4848 8181

WORKDIR     /usr/local/glassfish4

# verbose causes the process to remain in the foreground so that docker can track it
CMD         asadmin start-domain --verbose

Then, I build the Docker container (named 'myglassfish')

docker build -t myglassfish .

Finally, I launch the glassfish on my port 8080 using the following command line:

docker run -d -ti -p 4848:4848 -p 8080:8080 myglassfish

The glassfish server is correctly started because I can see the following information by taping 'localhost:8080' on my browser :

'Your server is now running...' (I cannot display the screenshot)

Now, I would like deploying my web application on that server, ideally using the GIT repository of my project (prefered solution) or a war file export of the application.

Let's take the simplest example, supposing I want to deploy my war named myapp.war (in the path /path1/path2/myapp.war) on my server. Is the next dockerfile correct (just add 'CMD asadmin deploy...' at the end of the dockerfile)?

FROM        java:8-jdk

ENV         JAVA_HOME         /usr/lib/jvm/java-8-openjdk-amd64
ENV         GLASSFISH_HOME    /usr/local/glassfish4
ENV         PATH              $PATH:$JAVA_HOME/bin:$GLASSFISH_HOME/bin

RUN         apt-get update && \
            apt-get install -y curl unzip zip inotify-tools && \
            rm -rf /var/lib/apt/lists/*

RUN         curl -L -o /tmp/glassfish-4.1.zip http://download.java.net/glassfish/4.1/release/glassfish-4.1.zip && \
            unzip /tmp/glassfish-4.1.zip -d /usr/local && \
            rm -f /tmp/glassfish-4.1.zip

EXPOSE      8080 4848 8181

WORKDIR     /usr/local/glassfish4

# verbose causes the process to remain in the foreground so that docker can track it
CMD         asadmin start-domain --verbose
CMD         asadmin deploy /path1/path2/myapp.war

If not, how should I modify the previous Dockerfile to load and deploy my application in the Glassfish server before starting it (I specify that I am a noob in linux and command line instructions so please be explicit in your answers)?

EDIT

I am now able to deploy my war file from my GIT repository using the following Dockerfile:

FROM        java:8-jdk

MAINTAINER  firstname name <firstname.name@domain.com>

ENV         JAVA_HOME         /usr/lib/jvm/java-8-openjdk-amd64
ENV         GLASSFISH_HOME    /usr/local/glassfish4
ENV         PATH              $PATH:$JAVA_HOME/bin:$GLASSFISH_HOME/bin

RUN         apt-get update && \
            apt-get install -y curl unzip zip inotify-tools && \
            rm -rf /var/lib/apt/lists/

#download and install the glassfish server

RUN         curl -L -o /tmp/glassfish-4.1.zip http://download.java.net/glassfish/4.1/release/glassfish-4.1.zip && \
            unzip /tmp/glassfish-4.1.zip -d /usr/local && \
            rm -f /tmp/glassfish-4.1.zip

#clone and deploy the project on the glassfish server

RUN     git clone http://myrepository.git /usr/local/mypath
RUN     cp /usr/local/mypath/MyProject/MyProject.war /usr/local/glassfish4/glassfish/domains/domain1/autodeploy/MyProject.war

EXPOSE      8080 4848 8181

WORKDIR     /usr/local/glassfish4

# verbose causes the process to remain in the foreground so that docker can track it

CMD         asadmin start-domain --verbose

This works perfectly (using docker build and docker run) but I would like to dynamically create my war file rather than directly copy an existing war file in my repository.

I tried the command line 'jar -cvf' to create the war archive from the repository but the directory 'classes' containing all the compiled java classes .class is missing in the war. As a consequence, the war file generated cannot be deployed. As the compiled class .class are not present in my GIT repository, how can I get them (I tried the command 'javac' but the majority of the classes does not define a main method)? Concretely, I just need to adding all compilated class .class in a directory 'classes' in my WAR. Should I use a Maven repository for this?

Thanks by advance!

Jerry U
  • 618
  • 9
  • 22
Julien
  • 31
  • 1
  • 5

2 Answers2

1

The best approach (in my opinion) is to create a new image that extends from your 'myglassfish' image and includes the WAR file. This image would have a tag that matches the application's release version. I hope the WAR file has been released to a Maven repository, from which you can download during the image build. In case the WAR file is in your local filesystem, just copy it into the image. One last thing, in case you are having trouble sharing files from your machine and the boot2docker VM, boot2docker automatically shares the Users folder in the VM. I hope I was helpful. In case you have more questions, just shoot.

Alexandre
  • 36
  • 5
  • For the moment, I just'd like to automatically deploy a local war file (on my computer) on my server (I, ve added an example). Then, I'll try to improve the process using a GIT or Maven repository (to be honest I've never used a Maven repository). I am a bit lost so I think the best for me is to progress step by step. When you say 'create a new image that extends from your 'myglassfish' image and includes the WAR file', how can I 'include' that WAR file (how explain to deploy that WAR file on the server (something like RUN asadmin deploy?)). Thanks for your help by the way! – Julien Aug 07 '15 at 08:38
  • You copy the WAR file using the COPY command. Have a look at the documentation: https://docs.docker.com/reference/builder/#copy – Alexandre Aug 07 '15 at 11:07
  • Ok, supposing I can copy the WAR file in my container using COPY command. So now, I have both my glassfish server AND my war file in my container. But I still need to deploy the war file (in the container) on the glassfish server (in the same container). Concretely, how can I enter the command asadmin deploy ...war in my dockerfile? Should I use RUN or CMD? – Julien Aug 07 '15 at 13:19
  • OK, I thought you could just copy the WAR file to a deployment folder and that was it. In case you need to run the asadmin, use the RUN command after the COPY command. The CMD command is used only once at the end of the Dockerfile to specify how to start the Glassfish server. CMD is executed when you run the container, not when you build the image. I don't have experience with Glassfish, so I can't help you with anything specific. – Alexandre Aug 07 '15 at 15:11
  • OK, I understand now what you told me @Alexandre. I used the command ADD and I placed the war file myapp.war to the folder /usr/local/glassfish4/glassfish/domains/domain1/autodeploy of my glassfish server and now it works (no need to use the asadmin deploy command thanks to the autodeploy folder). Thanks, you were right. – Julien Aug 07 '15 at 15:24
0

You could mount a local directory containing your web application (your git project) as a volume into the container. Like:

docker run -d -ti -v your/project/folder:/path/to/webapp/directory -p 4848:4848 -p 8080:8080 myglassfish

That is for development time. When you want to publish it, you can add the project directory contents to the image with the ADD or COPY keyword that you can use in Dockerfiles.

More information you can find in the volume documentation.

Henrik Sachse
  • 51,228
  • 7
  • 46
  • 59
  • Thanks for your quick answer @h3nrik. Actually, I am no longer in the development phase but that point is no so important for the moment. I am a bit lost with that question of directory. As I am able to start and access to the homepage of my glassfish server, I suppose that I create a glassfish4 directory containing all data of the server (including future deployed applications later) but I don't know where it is placed on my machine (i am using boot2docker for windows)... – Julien Aug 05 '15 at 15:37
  • To be honest I never used boot2docker with Windows. But if docker does not share the folder automatically with the `-v` switch on Windows you would need to do something like: share the Windows folder with the boot2docker VM first (VirtualBox setting). Then mount that folder into the boot2docker Linux VM. Then execute from there the `docker -v ...` command. I found some [quite old questions](http://stackoverflow.com/questions/26639968/boot2docker-startup-script-to-mount-local-shared-folder-with-host) on stackoverflow about that topic. Maybe they help? – Henrik Sachse Aug 05 '15 at 18:14
  • I tried what you explained me above but nothing concluding. As I am in the production part, I'll try doing the same the glassfish/ozark dockerfile [link](https://registry.hub.docker.com/u/glassfish/ozark/). I have on my computer a glassfish server (directory 'glassfish4') with my app already deployed on it. I'll then specify to RUN/COPY that directory in /usr/local (in the dockerfile) to directly build the configured server. Is it a right way to proceed? If yes, do you know how to create a container as a copy of my glasfish server (which command use in dockerfile?) Thanks again for your help. – Julien Aug 06 '15 at 08:55