{"id":3316,"date":"2017-04-21T04:52:51","date_gmt":"2017-04-21T11:52:51","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=3316"},"modified":"2023-06-19T02:39:16","modified_gmt":"2023-06-19T09:39:16","slug":"docker-vaadin-meet-couchbase-part2","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/","title":{"rendered":"Docker and Vaadin Meet Couchbase &#8211; Part 2"},"content":{"rendered":"<p><em><a href=\"https:\/\/www.linkedin.com\/in\/ratnopam-chakrabarti\" target=\"_blank\" rel=\"noopener noreferrer\">Ratnopam Chakrabarti<\/a><\/em><em>\u00a0is a software developer currently working for Ericsson Inc. He has been focused on IoT, machine-to-machine technologies, connected cars, and smart city domains for quite a while. He loves learning new technologies and putting them to work. When he\u2019s not working, he enjoys spending time with his 3-year-old son.<\/em><\/p>\n<h3>Introduction<\/h3>\n<p>Welcome to the part two of the series where I describe how to develop and run a Couchbase powered, fully functional Spring Boot web application using the Docker toolset. In <a href=\"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part1\/\">part one <\/a>of the series, I demonstrated how to run two Docker containers to run a functional application with a presentable UI. The two Docker containers that we were running are:<\/p>\n<ol>\n<li>A <a href=\"https:\/\/www.couchbase.com\/containers\/\">Couchbase container<\/a> with preconfigured settings<\/li>\n<li>An application container talking to the Couchbase container (Run in step 1)<\/li>\n<\/ol>\n<p>While this method is useful, it\u2019s not fully automated \u2013 meaning the automated orchestration is not there. You have to run two different Docker run commands to run the entire setup.<\/p>\n<p>Is there a way to build and run the application container which also triggers running of the Couchbase container? Of course there\u2019s a way.<\/p>\n<h3>Enter Docker Compose<\/h3>\n<p>Using <a href=\"https:\/\/www.couchbase.com\/blog\/couchbase-using-docker-compose\/\">Docker Compose<\/a>, you can orchestrate the running of multi-container environments, which is exactly what we need for our use case. We need to run the Couchbase container first, and then the application container should run and talk to the Couchbase container.<\/p>\n<p>Here\u2019s the docker-compose.yml file to achieve this:<\/p>\n<pre class=\"lang:default decode:true\">version: \"2\"\r\n\r\nservices:\r\n\r\n\u00a0 app:\r\n\r\n\u00a0 \u00a0 build: .\r\n\r\n\u00a0 \u00a0 ports:\r\n\r\n\u00a0 \u00a0 \u00a0 - 8080:8080\r\n\r\n\u00a0 \u00a0 environment:\r\n\r\n\u00a0 \u00a0 \u00a0 - BUCKET_NAME=books\r\n\r\n\u00a0 \u00a0 \u00a0 - HOST=192.168.99.100\r\n\r\n\u00a0 \u00a0 depends_on:\r\n\r\n\u00a0 \u00a0 \u00a0 - db\r\n\r\n\u00a0 db:\r\n\r\n\u00a0 \u00a0 image: chakrar27\/couchbase:books\r\n\r\n\u00a0 \u00a0 ports:\r\n\r\n\u00a0 \u00a0 \u00a0 - 8091:8091\r\n\r\n\u00a0 \u00a0 \u00a0 - 8092:8092\r\n\r\n\u00a0 \u00a0 \u00a0 - 8093:8093\r\n\r\n\u00a0 \u00a0 \u00a0 - 8094:8094\r\n\r\n\u00a0 \u00a0 \u00a0 - 11210:11210\r\n\r\n<\/pre>\n<p>Our app \u201cdepends_on\u201d the db image which is the Couchbase container. In other words, the Couchbase container runs first and then the app container starts running. There\u2019s one potential issue here: the \u201cdepends_on\u201d keyword doesn\u2019t guarantee that the Couchbase container has finished configuring the image and started running. All it ensures is that the container is started first; it doesn\u2019t check whether the container is actually running or ready to be accepting requests by an application. In order to ensure that the Couchbase container is actually running and that all the pre-configuration steps, such as setting up the query, index services, and bucket, is completed, we need to do a check from the application container.<\/p>\n<p>Here\u2019s the Dockerfile of the app container that invokes a script which, in turn, checks whether the bucket \u201cbooks\u201d has been set up already or not. It goes into a loop till the bucket is set up and then triggers the app container.<\/p>\n<p><u><a href=\"https:\/\/github.com\/ratchakr\/bookstoreapp\/blob\/master\/Dockerfile-v1\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/github.com\/ratchakr\/bookstoreapp\/blob\/master\/Dockerfile-v1<\/a><\/u><\/p>\n<p>The script can be seen at <u><a href=\"https:\/\/github.com\/ratchakr\/bookstoreapp\/blob\/master\/run_app.sh\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/github.com\/ratchakr\/bookstoreapp\/blob\/master\/run_app.sh<\/a><\/u><\/p>\n<p>The script does the following things:<\/p>\n<p>It uses the REST endpoint supported by Couchbase for querying the bucket.<\/p>\n<p>Curl is used to call REST endpoints. Installation of curl is covered in the Dockerfile of the application.<\/p>\n<p>The script parses the JSON\u00a0response of the REST call by using a tool called jq.<\/p>\n<p>If the bucket is set\u00a0up, it then runs the app container; otherwise it waits for the bucket to be set\u00a0up first.<\/p>\n<p>It\u2019s worth mentioning that more checks,\u00a0such as verifying\u00a0if the index service and the query service are\u00a0set\u00a0up properly or not,\u00a0can be added in the shell script to make it more robust. One word of caution is to confirm\u00a0your particular use case and requirement before following the docker-compose approach; there\u2019s not a sure-fire way to determine if the Couchbase db container is fully up and running and ready to serve requests from the client application. Some of the approaches that might work are as follows:<\/p>\n<ol>\n<li>If you have a preconfigured bucket,\u00a0you can test if the bucket exists<\/li>\n<li>Check if the indexes are in place<\/li>\n<li>If you know the record-count in a bucket (let\u2019s say for a .csv file which has been imported into a bucket at the time of initial data load), you can check if the count matches the number of records in the .csv file). For our use case, the one mentioned above works nicely.<\/li>\n<\/ol>\n<h3>Build and Run<\/h3>\n<p>Now that we have our docker-compose file and Dockerfile, we can build the application image by using the simple <em>docker-compose up<\/em>\u00a0command.<\/p>\n<p>Here\u2019s the output snippet from the Docker console:<\/p>\n<pre class=\"lang:default decode:true \">$ docker-compose up\r\n\r\nCreating network \"bookstoreapp_default\" with the default driver\r\n\r\nPulling db (chakrar27\/couchbase:books)...\r\n\r\nbooks: Pulling from chakrar27\/couchbase\r\n\r\nDigest: sha256:4bc356a1f2b5b3d7ee3daf10cd5c55480ab831a0a147b07f5b14bea3de909fd9\r\n\r\nStatus: Downloaded newer image for chakrar27\/couchbase:books\r\n\r\nBuilding app\r\n\r\nStep 1\/8 : FROM frolvlad\/alpine-oraclejdk8:full\r\n\r\nfull: Pulling from frolvlad\/alpine-oraclejdk8\r\n\r\nDigest: sha256:a344745faa77a9aa5229f26bc4f5c596d13bcfc8fcac051a701b104a469aff1f\r\n\r\nStatus: Downloaded newer image for frolvlad\/alpine-oraclejdk8:full\r\n\r\n---&gt; 5f7037acb78d\r\n\r\nStep 2\/8 : VOLUME \/tmp\r\n\r\n---&gt; Running in 7d18e0b90bfd\r\n\r\n---&gt; 6a43ccb712dc\r\n\r\nRemoving intermediate container 7d18e0b90bfd\r\n\r\nStep 3\/8 : ADD target\/bookstore-1.0.0-SNAPSHOT.jar app.jar\r\n\r\n---&gt; a3b4bf7745e0\r\n\r\nRemoving intermediate container 0404f1d094d3\r\n\r\nStep 4\/8 : RUN sh -c 'touch \/app.jar'\r\n\r\n---&gt; Running in 64d1c82a0694\r\n\r\n---&gt; 1ec5a68cafa9\r\n\r\nRemoving intermediate container 64d1c82a0694\r\n\r\nStep 5\/8 : RUN apk update &amp;&amp; apk add curl\r\n\r\n---&gt; Running in 1f912e8341bd\r\n\r\nfetch https:\/\/dl-cdn.alpinelinux.org\/alpine\/v3.5\/main\/x86_64\/APKINDEX.tar.gz\r\n\r\nfetch https:\/\/dl-cdn.alpinelinux.org\/alpine\/v3.5\/community\/x86_64\/APKINDEX.tar.gz\r\n\r\nv3.5.2-16-g53ad101cf8 [https:\/\/dl-cdn.alpinelinux.org\/alpine\/v3.5\/main]\r\n\r\nv3.5.2-14-gd7ba0e189f [https:\/\/dl-cdn.alpinelinux.org\/alpine\/v3.5\/community]\r\n\r\nOK: 7961 distinct packages available\r\n\r\n(1\/4) Installing ca-certificates (20161130-r1)\r\n\r\n(2\/4) Installing libssh2 (1.7.0-r2)\r\n\r\n(3\/4) Installing libcurl (7.52.1-r2)\r\n\r\n(4\/4) Installing curl (7.52.1-r2)\r\n\r\nExecuting busybox-1.25.1-r0.trigger\r\n\r\nExecuting ca-certificates-20161130-r1.trigger\r\n\r\nExecuting glibc-bin-2.25-r0.trigger\r\n\r\nOK: 12 MiB in 18 packages\r\n\r\n---&gt; 8f99863af926\r\n\r\nRemoving intermediate container 1f912e8341bd\r\n\r\nStep 6\/8 : ADD run_app.sh .\r\n\r\n---&gt; cedb8d545070\r\n\r\nRemoving intermediate container 8af5ac3ab0a0\r\n\r\nStep 7\/8 : RUN chmod +x run_app.sh\r\n\r\n---&gt; Running in 74a141de2f52\r\n\r\n---&gt; 77ffd7425bea\r\n\r\nRemoving intermediate container 74a141de2f52\r\n\r\nStep 8\/8 : CMD sh run_app.sh\r\n\r\n---&gt; Running in 6f81c8ebaa37\r\n\r\n---&gt; 56a3659005ef\r\n\r\nRemoving intermediate container 6f81c8ebaa37\r\n\r\nSuccessfully built 56a3659005ef\r\n\r\nImage for service app was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.\r\n\r\nCreating bookstoreapp_db_1\r\n\r\nCreating bookstoreapp_app_1\r\n\r\nAttaching to bookstoreapp_db_1, bookstoreapp_app_1\r\n\r\ndb_1 \u00a0 | docker host ip = \u00a0192.168.99.100\r\n\r\ndb_1 \u00a0 | sleeping...\r\n\r\napp_1 \u00a0| Starting application run script...........\r\n\r\napp_1 \u00a0| couchbase is running on 192.168.99.100\r\n\r\napp_1 \u00a0| bucket to check is books\r\n\r\ndb_1 \u00a0 | &lt; Date: Fri, 24 Mar 2017 06:53:00 GMT\r\n\r\ndb_1 \u00a0 | &lt; Content-Length: 0\r\n\r\ndb_1 \u00a0 | &lt; Cache-Control: no-cache\r\n\r\ndb_1 \u00a0 | &lt;\r\n\r\n100 \u00a0 \u00a055 \u00a0 \u00a00 \u00a0 \u00a0 0 \u00a0100 \u00a0 \u00a055 \u00a0 \u00a0 \u00a00 \u00a0 \u00a0827 --:--:-- --:--:-- --:--:-- \u00a0 833\r\n\r\ndb_1 \u00a0 | * Connection #0 to host 127.0.0.1 left intact\r\n\r\ndb_1 \u00a0 | bucket set up done\r\n\r\napp_1 \u00a0| response from cb\r\n\r\napp_1 \u00a0| ************************************************\r\n\r\napp_1 \u00a0| ************************************************\r\n\r\napp_1 \u00a0| response from cb books\r\n\r\napp_1 \u00a0| ************************************************\r\n\r\napp_1 \u00a0| ************************************************\r\n\r\napp_1 \u00a0| bucket is now ready bucket name books\r\n\r\napp_1 \u00a0| Run application container now\r\n\r\napp_1 \u00a0| ************************************************\r\n\r\napp_1 \u00a0|\r\n\r\napp_1 \u00a0| \u00a0 . \u00a0 ____ \u00a0 \u00a0 \u00a0 \u00a0 \u00a0_ \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0__ _ _\r\n\r\napp_1 \u00a0| \u00a0\/\\\\ \/ ___'_ __ _ _(_)_ __ \u00a0__ _ \\ \\ \\ \\\r\n\r\napp_1 \u00a0| ( ( )\\___ | '_ | '_| | '_ \\\/ _` | \\ \\ \\ \\\r\n\r\napp_1 \u00a0| \u00a0\\\\\/ \u00a0___)| |_)| | | | | || (_| | \u00a0) ) ) )\r\n\r\napp_1 \u00a0| \u00a0 ' \u00a0|____| .__|_| |_|_| |_\\__, | \/ \/ \/ \/\r\n\r\napp_1 \u00a0| \u00a0=========|_|==============|___\/=\/_\/_\/_\/\r\n\r\napp_1 \u00a0| \u00a0:: Spring Boot :: \u00a0 \u00a0 \u00a0 \u00a0(v1.4.2.RELEASE)\r\n\r\napp_1 \u00a0|\r\n\r\napp_1 \u00a0| 2017-03-24 06:53:59.839 \u00a0INFO 31 --- [ \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 main] c.chakrar.sample.books.BookStoreRunner \u00a0 : Book Details = Book [id=06bad9c4-85fc-4c0b-83a7-ad21b2fdd405, title=The Immortal Irishman, author=Timothy Egan, isbn=ISBN444, category=History]\r\n\r\napp_1 \u00a0| 2017-03-24 06:53:59.839 \u00a0INFO 31 --- [ \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 main] c.chakrar.sample.books.BookStoreRunner \u00a0 : Book Details = Book [id=328eaf44-edff-43c6-9f55-62d7e095256d, title=The Kite Runner, author=Khaled Hosseini, isbn=ISBN663, category=Fiction]\r\n\r\napp_1 \u00a0| 2017-03-24 06:53:59.839 \u00a0INFO 31 --- [ \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 main] c.chakrar.sample.books.BookStoreRunner \u00a0 : Book Details = Book [id=56882f5a-d466-457f-82c1-1c3bca0c6d75, title=Breaking Blue, author=Timothy Egan, isbn=ISBN777, category=Thriller]\r\n\r\napp_1 \u00a0| 2017-03-24 06:53:59.839 \u00a0INFO 31 --- [ \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 main] c.chakrar.sample.books.BookStoreRunner \u00a0 : Book Details = Book [id=845a2fe8-cbbf-4780-b216-41abf86d7d61, title=History of Mankind, author=Gabriel Garcia, isbn=ISBN123, category=History]\r\n\r\napp_1 \u00a0| 2017-03-24 06:53:59.840 \u00a0INFO 31 --- [ \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 main] c.chakrar.sample.books.BookStoreRunner \u00a0 : Book Details = Book [id=9d2833c3-e005-4c4f-98f9-75b69bbb7bf5, title=The Night Gardener, author=Eric Fan, isbn=ISBN333, category=Kids Books]\r\n\r\napp_1 \u00a0| 2017-03-24 06:53:59.840 \u00a0INFO 31 --- [ \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 main] c.chakrar.sample.books.BookStoreRunner \u00a0 : Book Details = Book [id=5756bf4d-551c-429e-8bc3-2339dc065ff8, title=Grit: The Power of Passion and Perseverance, author=Angela Duckworth, isbn=ISBN555, category=Business]\r\n\r\napp_1 \u00a0| 2017-03-24 06:53:59.840 \u00a0INFO 31 --- [ \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 main] c.chakrar.sample.books.BookStoreRunner \u00a0 : Book Details = Book [id=e8e34f30-6fdf-4ca7-9cef-e06f504f8778, title=War and Turpentine, author=Stefan Hertmans, isbn=ISBN222, category=Fiction]\r\n\r\napp_1 \u00a0| 2017-03-24 06:54:00.234 \u00a0INFO 31 --- [ \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 main] c.chakrar.sample.books.BookStoreRunner \u00a0 : Books by Timothy Egan = Book [id=06bad9c4-85fc-4c0b-83a7-ad21b2fdd405, title=The Immortal Irishman, author=Timothy Egan, isbn=ISBN444, category=History]\r\n\r\napp_1 \u00a0| 2017-03-24 06:54:00.238 \u00a0INFO 31 --- [ \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 main] c.chakrar.sample.books.BookStoreRunner \u00a0 : Books by Timothy Egan = Book [id=56882f5a-d466-457f-82c1-1c3bca0c6d75, title=Breaking Blue, author=Timothy Egan, isbn=ISBN777, category=Thriller]\r\n\r\napp_1 \u00a0| 2017-03-24 06:54:00.346 \u00a0INFO 31 --- [ \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 main] c.chakrar.sample.books.BookStoreRunner \u00a0 : Book Starting with title 'The' = Book [id=06bad9c4-85fc-4c0b-83a7-ad21b2fdd405, title=The Immortal Irishman, author=Timothy Egan, isbn=ISBN444, category=History]\r\n\r\napp_1 \u00a0| 2017-03-24 06:54:00.349 \u00a0INFO 31 --- [ \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 main] c.chakrar.sample.books.BookStoreRunner \u00a0 : Book Starting with title 'The' = Book [id=328eaf44-edff-43c6-9f55-62d7e095256d, title=The Kite Runner, author=Khaled Hosseini, isbn=ISBN663, category=Fiction]\r\n\r\napp_1 \u00a0| 2017-03-24 06:54:00.349 \u00a0INFO 31 --- [ \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 main] c.chakrar.sample.books.BookStoreRunner \u00a0 : Book Starting with title 'The' = Book [id=9d2833c3-e005-4c4f-98f9-75b69bbb7bf5, title=The Night Gardener, author=Eric Fan, isbn=ISBN333, category=Kids Books]\r\n\r\napp_1 \u00a0| 2017-03-24 06:54:00.443 \u00a0INFO 31 --- [ \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 main] c.chakrar.sample.books.BookStoreRunner \u00a0 : Book in Fiction = Book [id=328eaf44-edff-43c6-9f55-62d7e095256d, title=The Kite Runner, author=Khaled Hosseini, isbn=ISBN663, category=Fiction]\r\n\r\napp_1 \u00a0| 2017-03-24 06:54:00.453 \u00a0INFO 31 --- [ \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 main] c.chakrar.sample.books.BookStoreRunner \u00a0 : Book in Fiction = Book [id=e8e34f30-6fdf-4ca7-9cef-e06f504f8778, title=War and Turpentine, author=Stefan Hertmans, isbn=ISBN222, category=Fiction]\r\n\r\napp_1 \u00a0| 2017-03-24 06:54:02.745 \u00a0INFO 31 --- [nio-8080-exec-1] o.v.spring.servlet.Vaadin4SpringServlet \u00a0: Could not find a SystemMessagesProvider in the application context, using default\r\n\r\napp_1 \u00a0| 2017-03-24 06:54:02.753 \u00a0INFO 31 --- [nio-8080-exec-1] o.v.spring.servlet.Vaadin4SpringServlet \u00a0: Custom Vaadin4Spring servlet initialization completed\r\n\r\napp_1 \u00a0| 2017-03-24 06:54:02.864 \u00a0INFO 31 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[\/] \u00a0 \u00a0 \u00a0 : Initializing Spring FrameworkServlet 'dispatcherServlet'\r\n\r\napp_1 \u00a0| 2017-03-24 06:54:02.865 \u00a0INFO 31 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet \u00a0 \u00a0 \u00a0 \u00a0: FrameworkServlet 'dispatcherServlet': initialization started<\/pre>\n<p>At this point our application is up and running with a single docker-compose orchestration command.<\/p>\n<p>Type <u>192.168.99.100:8080<\/u>\u00a0into\u00a0the browser; you should see the following screen:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/04\/pasted-image-0-12.png\" alt=\"pasted image 0 12\" \/><\/p>\n<p>Docker Compose is a nice way to orchestrate multi-container Docker environments. It has almost similar command chains as \u201cdocker\u201d command sets. For instance, to see a list of running containers, you simply\u00a0type:<\/p>\n<p>docker-compose ps &gt; which would give you<\/p>\n<pre class=\"lang:default decode:true \">$ docker-compose ps\r\n\r\nName \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 Command \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 State \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0Ports\r\n\r\n---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\r\n\r\nbookstoreapp_app_1\u00a0 \u00a0\/bin\/sh -c sh run_app.sh \u00a0 \u00a0 \u00a0 \u00a0 Up \u00a0 \u00a0 \u00a00.0.0.0:8080-&gt;8080\/tcp\r\n\r\nbookstoreapp_db_1\u00a0 \u00a0 \/entrypoint.sh \/opt\/couchb ... \u00a0 Up \u00a0 \u00a0 \u00a011207\/tcp, 0.0.0.0:11210-&gt;11210\/tcp, 11211\/tcp, 18091\/tcp, 18092\/tcp, 18093\/tcp, 0.0.0.0:8091-&gt;8091\/tcp, 0.0.0.0:8092-&gt;8092\/tcp, 0.0.0.0:8093-&gt;8093\/tcp, 0.0.0.0:8094-&gt;8094\/tcp\r\n\r\n<\/pre>\n<p>The name of the containers are shown in bold here.<\/p>\n<p>If you need to stop or tear down your orchestrated environment with Docker Compose, you can do that with the <strong>docker-compose down <\/strong>command as shown below:<\/p>\n<p>A sample run produces:<\/p>\n<pre class=\"lang:default decode:true\">$ docker-compose down\r\n\r\nStopping bookstoreapp_app_1 ... done\r\n\r\nStopping bookstoreapp_db_1 ... done\r\n\r\nRemoving bookstoreapp_app_1 ... done\r\n\r\nRemoving bookstoreapp_db_1 ... done\r\n\r\nRemoving network bookstoreapp_default<\/pre>\n<p>Now, if you do a docker-compose ps, it shows that no container is currently running.<\/p>\n<pre class=\"lang:default decode:true \">$ docker-compose ps\r\n\r\nName \u00a0 Command \u00a0 State \u00a0 Ports\r\n\r\n---------------------------------------------------------------<\/pre>\n<p>You can also use Docker compose for an automated test environment where you fire up your Docker containers, run the tests, then tear down the complete infrastructure \u2013 all with Compose. For a detailed overview of Docker compose, please visit the <u><a href=\"https:\/\/docs.docker.com\/compose\/overview\/\" target=\"_blank\" rel=\"noopener noreferrer\">official website<\/a><\/u>.<\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/community\/community-writers-program\/\"><em>This post is part of the Couchbase Community Writing Program<\/em><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>How to develop and run a Couchbase powered, fully functional Spring Boot web application using the Docker toolset. In part one of the series, I demonstrated how to run two Docker containers to run a functional application with a presentable UI.<\/p>\n","protected":false},"author":53,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1816],"tags":[1519,1594],"ppma_author":[9026],"class_list":["post-3316","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-couchbase-server","tag-docker","tag-vaadin"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.7.1 (Yoast SEO v25.7) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Docker and Vaadin Meet Couchbase - Part 2 - The Couchbase Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Docker and Vaadin Meet Couchbase - Part 2\" \/>\n<meta property=\"og:description\" content=\"How to develop and run a Couchbase powered, fully functional Spring Boot web application using the Docker toolset. In part one of the series, I demonstrated how to run two Docker containers to run a functional application with a presentable UI.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2017-04-21T11:52:51+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-06-19T09:39:16+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/04\/pasted-image-0-12.png\" \/>\n<meta name=\"author\" content=\"Laura Czajkowski, Developer Community Manager, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Laura Czajkowski, Developer Community Manager, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/\"},\"author\":{\"name\":\"Laura Czajkowski, Developer Community Manager, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/5f1a0ece4e644bc8c037686fbc8f3220\"},\"headline\":\"Docker and Vaadin Meet Couchbase &#8211; Part 2\",\"datePublished\":\"2017-04-21T11:52:51+00:00\",\"dateModified\":\"2023-06-19T09:39:16+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/\"},\"wordCount\":882,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"keywords\":[\"docker\",\"vaadin\"],\"articleSection\":[\"Couchbase Server\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/\",\"name\":\"Docker and Vaadin Meet Couchbase - Part 2 - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2017-04-21T11:52:51+00:00\",\"dateModified\":\"2023-06-19T09:39:16+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Docker and Vaadin Meet Couchbase &#8211; Part 2\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/5f1a0ece4e644bc8c037686fbc8f3220\",\"name\":\"Laura Czajkowski, Developer Community Manager, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/9deb07d5daaa00220534c31768bc4409\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g\",\"caption\":\"Laura Czajkowski, Developer Community Manager, Couchbase\"},\"description\":\"Laura Czajkowski is the Snr. Developer Community Manager at Couchbase overseeing the community. She\u2019s responsible for our monthly developer newsletter.\",\"url\":\"https:\/\/www.couchbase.com\/blog\/author\/laura-czajkowski\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Docker and Vaadin Meet Couchbase - Part 2 - The Couchbase Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/","og_locale":"en_US","og_type":"article","og_title":"Docker and Vaadin Meet Couchbase - Part 2","og_description":"How to develop and run a Couchbase powered, fully functional Spring Boot web application using the Docker toolset. In part one of the series, I demonstrated how to run two Docker containers to run a functional application with a presentable UI.","og_url":"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/","og_site_name":"The Couchbase Blog","article_published_time":"2017-04-21T11:52:51+00:00","article_modified_time":"2023-06-19T09:39:16+00:00","og_image":[{"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/04\/pasted-image-0-12.png","type":"","width":"","height":""}],"author":"Laura Czajkowski, Developer Community Manager, Couchbase","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Laura Czajkowski, Developer Community Manager, Couchbase","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/"},"author":{"name":"Laura Czajkowski, Developer Community Manager, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/5f1a0ece4e644bc8c037686fbc8f3220"},"headline":"Docker and Vaadin Meet Couchbase &#8211; Part 2","datePublished":"2017-04-21T11:52:51+00:00","dateModified":"2023-06-19T09:39:16+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/"},"wordCount":882,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","keywords":["docker","vaadin"],"articleSection":["Couchbase Server"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/","url":"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/","name":"Docker and Vaadin Meet Couchbase - Part 2 - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2017-04-21T11:52:51+00:00","dateModified":"2023-06-19T09:39:16+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/docker-vaadin-meet-couchbase-part2\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Docker and Vaadin Meet Couchbase &#8211; Part 2"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"The Couchbase Blog","description":"Couchbase, the NoSQL Database","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/5f1a0ece4e644bc8c037686fbc8f3220","name":"Laura Czajkowski, Developer Community Manager, Couchbase","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/9deb07d5daaa00220534c31768bc4409","url":"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g","caption":"Laura Czajkowski, Developer Community Manager, Couchbase"},"description":"Laura Czajkowski is the Snr. Developer Community Manager at Couchbase overseeing the community. She\u2019s responsible for our monthly developer newsletter.","url":"https:\/\/www.couchbase.com\/blog\/author\/laura-czajkowski\/"}]}},"authors":[{"term_id":9026,"user_id":53,"is_guest":0,"slug":"laura-czajkowski","display_name":"Laura Czajkowski, Developer Community Manager, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g","author_category":"","last_name":"Czajkowski","first_name":"Laura","job_title":"","user_url":"","description":"Laura Czajkowski is the Snr. Developer Community Manager at Couchbase overseeing the community. She\u2019s responsible for our monthly developer newsletter."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/3316","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/users\/53"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=3316"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/3316\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=3316"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=3316"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=3316"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=3316"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}