• Home
  • About Me

Software Theory and Practice

  • Home
  • About Me
Home  /  Cloud • Docker • Groovy • Java • MongoDB • NoSql Database • Programming • Spring • Spring Boot  /  Spring Boot App deployed with Docker and Data Only Container Pattern Explained.
16 January 2015
Cloud

Spring Boot App deployed with Docker and Data Only Container Pattern Explained.

Alvin Henrick 2 Comments

The more I use and learn about Docker and the more I feel like I can’t live without it.This blog is about Docker amazing feature Volume Containers.I  wanted to write the Spring Boot app and deploy it to the Docker Container with MongoDB as my document store.

I read through the Docker documentation and figured out it was very  easy to mount the volume and start MongoDB so the data could be persisted locally on the host after the container  shuts down. Everything went well as expected when running on ubuntu linux machine and then I was stuck and it was not working on Macintosh.

The purpose of the POC was to make developers life easier to quickly start the local environment on their desktop computers.I encountered an issues when using boot2docker and had to make it work on Macintosh because most of the  developers are using Mac Book Pro.The issue was when mounting the volume MongoDB always failed to start.Here is the reason why because the boot2docker on Macintosh runs a small light weight virtual machine inside the Virtual Box which does not support fsync() operation on mounted directories and it seems MongoDB requires it.

To deal with the above issue I ended learning volume/data only container concept.You can read more details at docker website here https://docs.docker.com/userguide/dockervolumes/

Step 1 : Create Data only Container

1
docker run -v /data/db --name mongodata busybox true

The above command will create the data only container named mongodata.

Step 2: Build the docker image for deploying and running  springboot app .

1
git clone https://github.com/alvinhenrick/springboot-docker

It contains the Dockerfile to build the image .Its very easy to read the file and understand it. All it does it to install Java , MongoDB  and copy the springboot sample application executable jar.

1
docker build -t alvinhenrick/springboot .

I have already build the jar file and added to the docker build so you don’t have to build it.The jar file is inside springboot-docker project we cloned in the above step. Look inside springboot-example folder.The application  (MongoDB , Spring Data, Spock, Groovy Rest Client )  can be downloaded from here.

1
2
3
4
git clone https://github.com/alvinhenrick/springboot-example
cd /springboot-example
#Make sure you have gradle installed.
gradle clean build

Step 3: Start the docker container with the image we built above.

1
docker run -d -p 27017:27017 -p 8080:8080 --volumes-from mongodata --name sboot alvinhenrick/springboot

Notice how the volume only container is mounted (–volumes-from mongodata) and now there will be no issues starting the app on Macintosh and yes this is better way of dealing with data storage in docker.

NOTE: Mac user can do local port forwarding via boot2docker to access the spring boot web app.

1
boot2docker ssh -L 8000:localhost:8000

We can test the app is working and deployed successfully via the unit test inside the springboot-example project by making the http request to spring controller REST endpoint.

Step4: Run the spock test to confirm that container is running and responding.

1
RestClientTest.groovy

 Step 5: Run Docker Inspect

1
2
3
docker ps -a
# capture the container id
docker inspect {#yourcontainerid}

You should see the similar output with volume mounted.

1
2
3
4
5
6
"Volumes": {
        "/data/db": "/mnt/sda1/var/lib/docker/vfs/dir/b5e73af364ef8ad708f4b3a881a3690458935727cc4d0777c71ca8ab7744d560"
    },
    "VolumesRW": {
        "/data/db": true
    }

Step 6: Check the Logs

1
2
3
4
5
6
7
8
9
10
11
12
13
docker logs {#yourcontainerid}
/usr/lib/python2.7/dist-packages/supervisor/options.py:295: UserWarning: Supervisord is running as root and it is searching for its configuration file in default locations (including its current working directory); you probably want to specify a "-c" argument specifying an absolute path to a configuration file for improved security.
  'Supervisord is running as root and it is searching '
2015-01-17 05:25:49,490 CRIT Supervisor running as root (no user in config file)
2015-01-17 05:25:49,490 WARN Included extra file "/etc/supervisor/conf.d/supervisord.conf" during parsing
2015-01-17 05:25:49,505 INFO RPC interface 'supervisor' initialized
2015-01-17 05:25:49,505 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2015-01-17 05:25:49,505 INFO supervisord started with pid 1
2015-01-17 05:25:50,509 INFO spawned: 'springbootapp' with pid 9
2015-01-17 05:25:50,510 INFO spawned: 'mongod' with pid 10
2015-01-17 05:25:51,902 INFO success: springbootapp entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2015-01-17 05:25:51,902 INFO success: mongod entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
➜  springboot git:(master) ✗

Step 7: List the /data/db directory

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
docker run --volumes-from mongodata busybox ls -al /data/db
 
total 458768
drwxrwxrwx    3 root     root          4096 Nov  8 14:38 .
drwxr-xr-x    3 root     root          4096 Jan 17 05:32 ..
-rw-------    1 501      root      67108864 Oct 22 02:27 OLETV.0
-rw-------    1 501      root     134217728 Oct 22 14:15 OLETV.1
-rw-------    1 501      root      16777216 Oct 22 14:15 OLETV.ns
-rw-------    1 501      root      67108864 Nov  4 17:46 RRFDB.0
-rw-------    1 501      root      16777216 Nov  4 17:46 RRFDB.ns
-rw-------    1 501      root      67108864 Nov  8 14:40 TEST_DB.0
-rw-------    1 501      root      16777216 Nov  8 14:40 TEST_DB.ns
drwxr-xr-x    2 501      root          4096 Jan 17 05:25 journal
-rw-------    1 501      root      67108864 Jan 17 05:25 local.0
-rw-------    1 501      root      16777216 Jan 17 05:25 local.ns
-rwxr-xr-x    1 501      root             3 Jan 17 05:25 mongod.lock

The good thing about springboot app is that we don’t have to install separate web container etc.It is a self contained app which is running in the embedded tomcat web container  and supervised via supervisor daemon inside docker container.

 In the next post I will explain  how to take the backup and restore the data from volume container.

Happy Reading !!!

About Author

Alvin Henrick

Previous Article Apache Storm and Kafka Cluster with Docker
Next Article Docker backup and restore volume container

Related Posts

  • How to index geospatial data with Apache Spark Solr Connector and query with Solr Client

    How to index geospatial data with Apache Spark Solr Connector and query with Solr Client

  • Apache Spark Analytical Window Functions

    Apache Spark Analytical Window Functions

  • Docker backup and restore volume container

    Docker backup and restore volume container

Search

Recent Posts

  • How to index geospatial data with Apache Spark Solr Connector and query with Solr Client August 1, 2018
  • Apache Spark Analytical Window Functions May 16, 2017
  • Apache Spark User Defined Functions July 10, 2016
  • Query Nested JSON via Spark SQL November 26, 2015
  • Docker backup and restore volume container January 26, 2015

Calendar

January 2015
M T W T F S S
 1234
567891011
12131415161718
19202122232425
262728293031  
« Aug   Nov »
© Copyright 2015. Alvin Henrick