In earlier versions of Docker, links were used to connect two containers by enabling network access as well as sharing environment variables. This approach is being deprecated in favor of a shared network between the services. And instead of environment propagation, environment values will need to be explicitly added to each service that requires them.
In a previous article, I showed how to use Docker Compose to bring up a standalone Spring Boot based web application with in-memory persistence. Now we expand on that idea by introducing an external MongoDB instance as the persistence store. This MongoDB instance will come from a completely different docker-compose.yml file and will be linked by virtue of a common network.
Prerequisites
In order to move forward with this article, run all the instructions in my previous article on Docker which includes installing Java and creating the executable spring-music.jar which is mandatory for the upcoming steps.
Run MongoDB from a Docker container
The first step is to run a MongoDB server from a docker container. I more fully explain each step in my article here, but below is the abbreviated set of instructions.
First, grab my project from github.
$ sudo apt-get install git -y $ git clone https://github.com/fabianlee/docker-mongodb.git $ cd docker-mongodb
If you look at the snippet below of docker-compose.yml, you will see a named network “mongo_net“, and the “my-mongodb” service uses this network.
services: my-mongodb: image: mongo networks: - mongo_net networks: mongo_net: driver: bridge
Now build and run using docker-compose to stand up the instance of MongoDB.
$ sudo docker-compose build $ sudo docker-compose up -d ... Creating network "docker-mongodb_mongo_net" with driver "bridge" Creating my-mongodb ... done Creating my-mongoclient ... done
Notice that the network created, “docker-mongodb_mongo_net” is the directory name followed by network name. When we connect our Spring app to this service in the next step, this will be the network identifier.
Run Spring Boot app
In a previous article I stood up the spring-music app with docker-compose, but as a standalone app with in-memory persistence. Now we will go through similar steps again, but this time with the file “docker-compose-mongo.yml” a snippet of which is shown below.
services: my-springmusic: image: my-springmusic build: . ports: - 8080:8080 environment: # explicit profile required so that datasource is recognized and non-local - SPRING_PROFILES_ACTIVE=mongodb,remote # standard spring data property - spring.data.mongodb.uri=mongodb://admin:admin@my-mongodb:27017/test volumes: - javatmp:/tmp networks: - docker-mongodb_mongo_net volumes: # default dir /var/lib/docker/volumes javatmp: networks: docker-mongodb_mongo_net: external: true
“docker-mongodb_mongo_net” was created when we instantiated the MongoDB instance earlier, and is the one we refer to here. It must be marked as “external: true”.
Also see that we must explicitly provide environment variables that tell our application how to connect to MongoDB. In the “spring.data.mongodb.uri” environment variable we are able to refer to “my-mongodb” as the name of the MongoDB server because the shared network makes this DNS resolution possible.
Now bring up the spring-music container with the commands below.
$ sudo docker-compose -f docker-compose-mongo.yml build $ sudo docker-compose -f docker-compose-mongo.yml up ... my-springmusic_1 | 2018-05-26T12:30:36.218+0000 INFO main o.c.s.m.Application:597 [log_framework=logback;app_name=spring-music;app_version=1.0;instance_id=0] The following profiles are active: mongodb,remote,mongodb-remote MULTIEXCEPTION ... my-springmusic_1 | 2018-05-26T12:30:41.341+0000 INFO main o.c.s.m.Application:57 [log_framework=logback;app_name=spring-music;app_version=1.0;instance_id=0] Started Application in 5.629 seconds (JVM running for 5.976) MULTIEXCEPTION
Similar to the log entries above, you should see that the mongodb Spring profile is active and a JVM startup message.
Validate Application
Pointing your browser at http://127.0.0.1:8080 should show you the web interface similar to below with a listing of albums.
Try changing one of the album names, and then Ctrl-C to stop the spring-music container. This stops the Spring Boot application (not the MongoDB database). When you restart the web application with the command below all you changes should remain intact.
$ sudo docker-compose -f docker-compose-mongo.yml up
If you were using in-memory persistence, you would get a fresh start every time and none of your changes would survive a restart.
REFERENCES
https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#repositories.core-concepts
https://spring.io/guides/gs/accessing-data-mongodb/
https://docs.spring.io/spring-data/mongodb/docs/1.2.0.RELEASE/reference/html/mongo.repositories.html
https://www.mkyong.com/spring-boot/spring-boot-spring-data-mongodb-example/
https://docs.docker.com/compose/compose-file/#external_links
https://springframework.guru/configuring-spring-boot-for-mongo/
NOTES
Delete spring app and its volume
sudo docker-compose -f docker-compose-mongo.yml down -v
Delete mongodb and its volume
sudo docker-compose down -v