Generally, a docker container is meant to hold exactly one application. For a typical Java web application (in this example we assume a Tomcat 8 servlet container and a Postgres 9.4 database), this will lead to two and a half containers:
webcontainer for our web application (in the example we assume
.WARpackaging) deployed to Tomcat
dbcontainer for our Postgres database
db-datacontainer. This one is necessary because Docker containers are volatile by default. Thus, data stored in a container is lost when they are restarted, so we need a volume to permanently store the database data.
Naturally, the applications within their respective containers need to communicate with each other. The current tool of choice to enable inter-container communication is Docker Compose.
Directory and file structure
The directory structure for our Docker files looks like this:
The database container
We will begin with the Dockerfile of our database in
ENV POSTGRES_USER admin
ENV POSTGRES_PASSWORD password
ENV POSTGRES_DB app_staging
In this example we are using the standard Postgres 9.4 image and configure credentials for a single user and DB.
The application container
The Dockerfile for our
web container in
./web/Dockerfile looks like this:
RUN echo "export JAVA_OPTS=\"-Dapp.env=staging\"" > /usr/local/tomcat/bin/setenv.sh
COPY ./application.war /usr/local/tomcat/webapps/staging.war
CMD ["catalina.sh", "run"]
The image is based on the standard Tomcat 8 image. I have included an example of how to perform basic Tomcat configuration. Here, we pass some JAVA_OPTS to the setenv.sh shell script of Tomcat.
Finally, our application
.WAR is copied the to the Tomcat
webapps directory and deployed in the
The last step is orchestrating our containers in
command: echo 'Data Container for PostgreSQL'
We bind the default Tomcat port 8080 in the container to the 8081 port of our host system and expose the Postgres port 5432 to the
web container which is linked to it. Lastly, we reference the permanent data volume as a volume for our
Running the application
Execute the following command to start our containers:
$ docker-compose up -d
To stop the containers run
$ docker-compose stop
A list of all docker containers is available via
$ docker ps -a
To open a shell in one of the containers (for example to access log files), run the following command:
$ docker exec -it <container_id> /bin/bash
Finally, to redeploy only specific containers, use the following command:
$ docker-compose build <container_id>
$ docker-compose up --no-deps -d <container_id>