{"componentChunkName":"component---src-templates-tag-js","path":"/tags/docker-compose/","result":{"data":{"site":{"siteMetadata":{"title":"LoginRadius Blog"}},"allMarkdownRemark":{"totalCount":1,"edges":[{"node":{"fields":{"slug":"/engineering/production-grade-development-using-docker-compose/"},"html":"<blockquote>\n<p>Assuming that the reader of this blog has a fair idea of the docker ecosystem!</p>\n</blockquote>\n<p>Docker has changed the world of software development! Since the last few years, docker has helped the developer community, enterprises, and startups to create solutions quickly and effectively. Also, deployment is relatively hassle-free with docker (conditions apply). And worth mentioning is, it resolves the “Works fine on my system” problem.  </p>\n<p>Well, just not docker, there are many container ecosystems available as an alternative to Docker. For example, Mesos by Apache and Vagrant by Hashicorp. Docker is more loved for what it is <strong>not</strong>, and that is Bulky! Docker is otherwise lightweight, works mostly with Linux and eventually was identified by Kubernetes in 2015. But, that story... some other time!!</p>\n<p>Straight to the context, Docker Compose! Docker compose is a powerful utility that is bundled with Docker installation. Docker-Compose can be used for production and development, to make things virtually seamless.</p>\n<h3 id=\"microservices-and-docker\" style=\"position:relative;\"><a href=\"#microservices-and-docker\" aria-label=\"microservices and docker permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Microservices and Docker</h3>\n<p>Docker is doing a great job when it comes to describing and developing microservices.</p>\n<p>While working on microservices where quite a few ( <em>being reasonably complicated, in our example 6</em> ) containers talk to each other to complete a task and since it is an end to end task, the whole thing looks very complicated. To rectify :</p>\n<ul>\n<li>the troubles of developing end to end feature</li>\n<li>how it works in integration</li>\n<li>containerizing the application</li>\n</ul>\n<p>the developer has two choices, create a script in a scripting language of choice, or choose docker-compose. Well, docker-compose is an easier option.</p>\n<p>Here in this <em>kind of</em> practical example, we are going to demonstrate a similar situation, where multiple containers talk to each other. We are going to use docker-compose as our primary tool to build and deploy images.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 544px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 61.029411764705884%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAADXElEQVQoz3VTbUwTaRCe3qJe1EsMWkzQ5CIXMUETzXk5cyjKBSPE3Pnj1CNqTIzenYSEgImG+AsQUVAxIm1AK1dDEVGhyke/aCm0hWy72w/abgvlIxSRbbfdQulH9Jfru03EmMtN8iRvJjPzPvPMDMzPz2OhUAgLBoOY3+9f63SOA0mSP0ciLBePx7lYbOXj0tISN+70nPV6fYCAAZyC/7XFxUWIxWKwvLwMiUQCcDMBHR1d+e8W6UQoFH7PMOEkTQc5s9lRbLO7wW53Yxx3A17U/iTQNh2BYdEhGBHlfSn4dmGhcDkaLQyzbGE0Gj0uk3XtTE/P/o7yzn5fd6tp+/0H0q1juGNHs7h9o6TtBbRKFWAQHYS7pbtAfCUHWq/ugRaEVQuHwxxil0I8HuOMRryO4zioqr4HlNt92umk/nnaLoWHog54/lIDqvocUDbsg9pLWZtqL2zDmkoy4MblH6GsrAzKyyv4lulwCNFjmBDDspEPas1IJV/QZBqDnp6B/d1ydX4yuQRa3SgQhjdr634FeNlwNFNen5scFP126Vk5Bponf6fxOTygs0uxpbffIOyW64QDSlPGwbziDdeuVW1HzE+6XK4/Kcp7kmGYM0qlVkh5p0Ez8CqVqLh7oK6rMnNvkibhcfcs78NGxwgB9PZpQaMdA5XaCG1PFYgZDkqlpoBlWQ4V4miaTsnh8UxKpqamK3S64QqKmmj2zgRvhiPxxrk5v/SxpP0AG4mA0WQBMFscApvdIyCtboHL7cWmpvjV8O6h6QDaqLco3j+D3gGrzXXFZqdyB7Wmw0N6Y3Hzw9ZKvd50cdI3+0d1TeMui8V61ePxFa0ORyj8BXbmnIXPWrRJ+9NHRy1VpNXZKOtU/8D7PKhls9kK8XhiNS6lG8A6h4MqGNLjX8aNYd/CufPXQSbrFIjFrSD999EGkrT2EYTNIn+tyEaJaxDWTUxM7EZHcMLnmzxhMJjOI2ZF9Xda0nCzDQxG4usll7TJAcdxgU6nA6VKlcXryKOvTyWanp4RWwhbjd0+ruO1DQSCKY3n5uZXbje0bD7++1+gHjR+85/LQT+CWqOFN7396wOBUP3CO+bJI8mrLL4JJEyaZtCQTZDOIoJ0FVht7mP6YTyvpLR6TWlZDYhbnsEntnIYO9rKgIkAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"title\"\n        title=\"title\"\n        src=\"/static/1bda5aef1d7445dcdf8ea583c442f42c/b3e51/example-arch.png\"\n        srcset=\"/static/1bda5aef1d7445dcdf8ea583c442f42c/b3e51/example-arch.png 544w\"\n        sizes=\"(max-width: 544px) 100vw, 544px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>The picture above depicts the architecture of a hypothetical portal of flash sale.</p>\n<p><em>Flash Sale is an e-commerce concept, where an item is made available for sale to the public on a portal at a specific time and in a limited quantity.</em></p>\n<p>The components of the application are</p>\n<ul>\n<li>Gateway</li>\n<li>Frontend (react)</li>\n<li>API server ( node.js)</li>\n<li>SQS ( In this example SQS Emulator)</li>\n<li>Listener (node.js)</li>\n<li>DataStore (mongo-db)</li>\n</ul>\n<p>The application is otherwise fairly simple. Go to the portal, hit the green button which calls an API, the API drops a message to the queue, the listener picks the messages, grabs the item from the database reduces the quantity and updates the datastore again.</p>\n<p>So far so good!</p>\n<h3 id=\"code\" style=\"position:relative;\"><a href=\"#code\" aria-label=\"code permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Code</h3>\n<p>You may fork a copy from here.</p>\n<p><code>git clone https://github.com/LoginRadius/engineering-blog-samples/tree/master/Docker/docker-compose-dev-sample</code></p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 225px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 100%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAAMBAAAAAAAAAAAAAAAAAAEDBAX/xAAVAQEBAAAAAAAAAAAAAAAAAAABAv/aAAwDAQACEAMQAAAB2xOaK6iszkpF7Ah//8QAGxAAAwEAAwEAAAAAAAAAAAAAAQIREgADITH/2gAIAQEAAQUCCLywo2g0x7pGihRhOygfP//EABURAQEAAAAAAAAAAAAAAAAAAAEg/9oACAEDAQE/AQj/xAAWEQADAAAAAAAAAAAAAAAAAAAAEBH/2gAIAQIBAT8BK//EABwQAAICAgMAAAAAAAAAAAAAAAABESESMQIQUf/aAAgBAQAGPwLRWRJBWjQnEv0bx411/8QAHhABAAICAgMBAAAAAAAAAAAAAQARITFBcVFhkaH/2gAIAQEAAT8hfnY5Y0VWvNMftRixpfERcv6lWC+SyxTdtzAl6E0dT//aAAwDAQACAAMAAAAQPz8A/8QAGBEAAwEBAAAAAAAAAAAAAAAAAAERECH/2gAIAQMBAT8QVBrpc//EABgRAAIDAAAAAAAAAAAAAAAAAAABEBEh/9oACAECAQE/EG9Kz//EABsQAQEAAwEBAQAAAAAAAAAAAAERACExQXFh/9oACAEBAAE/EJRUCyuH3kQxxOAHRp7iRMZVEwAXxq9fMWXu7W8I7hY1KXf5vEsJQoem+5v82f/Z'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"So what is the problem\"\n        title=\"So what is the problem\"\n        src=\"/static/3162769ede82087ce5b5175352957f96/863e1/what-is-the-problem.jpg\"\n        srcset=\"/static/3162769ede82087ce5b5175352957f96/863e1/what-is-the-problem.jpg 225w\"\n        sizes=\"(max-width: 225px) 100vw, 225px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h3 id=\"the-use-of-docker-compose-and-why\" style=\"position:relative;\"><a href=\"#the-use-of-docker-compose-and-why\" aria-label=\"the use of docker compose and why permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The use of docker-compose and why?</h3>\n<p>Exactly! What is the problem? As such, there is no problem, but it may arise if we do not program or develop it well in an integrated manner. Programming a component and managing it well reduces the time-to-production to a greater degree.</p>\n<blockquote>\n<p><em>I am not a great programmer; I am just a good programmer with great habits.</em></p>\n<ul>\n<li>Martin Fowler</li>\n</ul>\n</blockquote>\n<p>While designing and developing complicated systems where microservices are involved, integration and debugging become cumbersome.</p>\n<p>To ease it up docker-compose acts a friend.</p>\n<p>For the example above we are going to write a docker-compose. Docker-Compose has got <em>powers</em> to</p>\n<ul>\n<li>Build images</li>\n<li>Bring up the whole application ecosystem</li>\n<li>Wipe it up from the memory in one command</li>\n</ul>\n<p>First things first, the Dockerfile.</p>\n<p>Starting from the API. The API needs a docker image to build. The following is the Dockerfile for the same.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">FROM node:alpine</span>\n<span class=\"grvsc-line\">WORKDIR &#39;/app&#39;</span>\n<span class=\"grvsc-line\">COPY ./package.json ./</span>\n<span class=\"grvsc-line\">RUN npm install </span>\n<span class=\"grvsc-line\">COPY . .</span>\n<span class=\"grvsc-line\">CMD [&quot;npm&quot;, &quot;run&quot;, &quot;start&quot;]</span></code></pre>\n<p>Since the other two components, listener and frontend are also written in JavaScript the Dockerfile does not change at all for them too, for this particular example.</p>\n<p>The following is a two-liner Dockerfile for gateway. The conf file targets apiserver and frontend. Please have a look at the configuration file in the repository itself.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">FROM nginx</span>\n<span class=\"grvsc-line\">COPY ./nginx.conf /etc/nginx/conf.d/default.conf</span></code></pre>\n<p>The other 2 components :</p>\n<ul>\n<li>Mongodb has its image. We will leverage that while writing the docker-compose.</li>\n<li>SQS is emulated using softwaremill/elasticmq image.</li>\n</ul>\n<h3 id=\"action\" style=\"position:relative;\"><a href=\"#action\" aria-label=\"action permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Action!</h3>\n<p>First things first, file version. Since it is all yaml out there, the file <code>version</code> tells docker-compose about the data structure. The data structure which is expected by docker \"compose\".</p>\n<p>so we start the docker-compose as</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">version: &#39;3&#39;</span></code></pre>\n<p>All the components in the docker-compose are known as <code>services</code>. Next, we are going to write some services. Yes, the services we have written for our business.</p>\n<p>Message Queue :</p>\n<p>The message queue shall use <code>softwaremill/elasticmq</code> image out of the box and the applications will access that on port 9324. The service description in docker-compose shall look like this.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">mqserver:</span>\n<span class=\"grvsc-line\">        image: softwaremill/elasticmq</span>\n<span class=\"grvsc-line\">        ports:</span>\n<span class=\"grvsc-line\">            - &#39;9324:9324&#39;</span></code></pre>\n<p>That is analogous to <code>docker run -it -p '9324:9324' softwaremill/elasticmq</code>.</p>\n<p>A bit more complicated service next, mongodb.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">mongodbdb: </span>\n<span class=\"grvsc-line\">        depends_on: </span>\n<span class=\"grvsc-line\">            - mqserver</span>\n<span class=\"grvsc-line\">        image: mongo</span>\n<span class=\"grvsc-line\">        container_name: mongo</span>\n<span class=\"grvsc-line\">        volumes:</span>\n<span class=\"grvsc-line\">            - /data/db:/mongodata</span>\n<span class=\"grvsc-line\">        ports:</span>\n<span class=\"grvsc-line\">            - &#39;27017:27017&#39;</span></code></pre>\n<p>There are a couple of things one may notice more here.</p>\n<p><code>depends_on</code> shall wait for the container of mqserver service to come up, before mongodbdb service goes on air.</p>\n<blockquote>\n<p>Docker is only liable to check the containers when we use depends_on, if you want to check whether your service (which you have embedded) is ready to use or not, use <code>healthcheck</code>and <code>link</code>.</p>\n</blockquote>\n<p>Apart from this, we are mounting a volume and exposing ports for an image mongo which gets pulled directly from the docker container registry. <code>container_name</code> will give the service a name, so that it can be discovered *in the network. *Kind of a domain name in the internal docker-compose network.</p>\n<p>Now the developer's proprietary API service:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">apiserver:</span>\n<span class=\"grvsc-line\">        restart: always</span>\n<span class=\"grvsc-line\">        depends_on: </span>\n<span class=\"grvsc-line\">            - mqserver</span>\n<span class=\"grvsc-line\">            - mongodbdb</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">        build:</span>\n<span class=\"grvsc-line\">            dockerfile: Dockerfile</span>\n<span class=\"grvsc-line\">            context: ../fs-express-api/.</span>\n<span class=\"grvsc-line\">        volumes:</span>\n<span class=\"grvsc-line\">            - /app/node_modules</span>\n<span class=\"grvsc-line\">        environment: </span>\n<span class=\"grvsc-line\">            - NODE_ENV=production</span>\n<span class=\"grvsc-line\">            - AWS_SQS_URL=http://mqserver:9324/</span>\n<span class=\"grvsc-line\">            - AWS_SQS_FQ_URL=http://mqserver:9324/queue/fsqueue</span>\n<span class=\"grvsc-line\">            - AWS_ACCESS_KEY=na</span>\n<span class=\"grvsc-line\">            - AWS_SECRET_ACCESS_KEY=na</span>\n<span class=\"grvsc-line\">            - AWS_REGION=REGION</span>\n<span class=\"grvsc-line\">            - QUEUE_NAME=fsqueue</span>\n<span class=\"grvsc-line\">            - MONGODB_CONNECTION=mongodb://mongo:27017/fsorder</span>\n<span class=\"grvsc-line\">            - API_APP_PORT=5000</span>\n<span class=\"grvsc-line\">        ports:</span>\n<span class=\"grvsc-line\">            - &#39;5000:5000&#39;</span></code></pre>\n<p>The <code>build</code>tag will be used by the <code>docker-compose build</code> command to build an image. The build is defined as Dockerfile and the context is docker context, the directory which you want to use as context. Equivalent to:  <code>docker build -f filename.</code></p>\n<p>The more you are seeing here is <em>environment</em> and <em>restart</em> options. Environment variables are used to set environment variables while running the image. This is another part where docker-compose comes handy. Think about setting all nine environment variables with <code>docker run</code>.</p>\n<p><code>restart</code> is a bit interesting. One may specify a restart policy if the application crashes, which leads to stopping the docker image itself. always specifies to restart the container if it exit.</p>\n<p>In the environment section, one can see mqserver and mongo, instead of the regular localhost and loopback address. This is because when we run docker-compose, it creates a DNS recordset of all the <code>services</code> mentioned. The services can be referred to by their names. A slight deviation here may happen when the container is explicitly named. Here, container_name = mongo is used for service mongodbdb. Hence, the other containers in the environment shall refer to it by mongo and not mongodbdb.</p>\n<p>The pollingmod and frontend services are quite the same.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">    pollingmod:</span>\n<span class=\"grvsc-line\">        restart: always</span>\n<span class=\"grvsc-line\">        depends_on: </span>\n<span class=\"grvsc-line\">            - mqserver</span>\n<span class=\"grvsc-line\">            - mongodbdb</span>\n<span class=\"grvsc-line\">        build:</span>\n<span class=\"grvsc-line\">            dockerfile: Dockerfile</span>\n<span class=\"grvsc-line\">            context: ../polling-mod/</span>\n<span class=\"grvsc-line\">        volumes:</span>\n<span class=\"grvsc-line\">            - /app/node_modules</span>\n<span class=\"grvsc-line\">        environment: </span>\n<span class=\"grvsc-line\">            - AWS_QUEUE_URL=http://mqserver:9324/queue/fsqueue</span>\n<span class=\"grvsc-line\">            - AWS_ACCESS_KEY=na</span>\n<span class=\"grvsc-line\">            - AWS_SECRET_ACCESS_KEY=na</span>\n<span class=\"grvsc-line\">            - AWS_REGION=REGION</span>\n<span class=\"grvsc-line\">            - MONGODB_CONNECTION=mongodb://mongo:27017/fsorder   </span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">    frontend:</span>\n<span class=\"grvsc-line\">        build:</span>\n<span class=\"grvsc-line\">            dockerfile: Dockerfile</span>\n<span class=\"grvsc-line\">            context: ../fs-frontend</span>\n<span class=\"grvsc-line\">        volumes:</span>\n<span class=\"grvsc-line\">            - /app/node_modules</span>\n<span class=\"grvsc-line\">            - ../fs-frontend:/app</span>\n<span class=\"grvsc-line\">        stdin_open: true</span>\n<span class=\"grvsc-line\">        ports:</span>\n<span class=\"grvsc-line\">            - &#39;3000:3000&#39;</span></code></pre>\n<p>Finally, the gateway. So, a gateway is created on the front using Nginx to make the development production-grade. If you go through the gateway code you will find that the services are accessed by their name <code>frontend</code> and <code>apiserver</code>.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">upstream frontend{</span>\n<span class=\"grvsc-line\">    server frontend:3000;</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">upstream apiserver{</span>\n<span class=\"grvsc-line\">    server apiserver:5000;</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n<p>The Nginx container opens port 80 to an external port 5500. The Nginx container keeps configuration where the user can see just one port 5500 from out of the system, everything else is gray.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 542px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 31.734317343173434%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAAsTAAALEwEAmpwYAAABiElEQVQY02WQzS8DYRDGh15cXInPAwd3icTFwaEOzhJ/BGfh6uDg1JIWkTqIkJA4IYQmu91+0O272+622m6/Euwq8VVtmpR2x2zTC97kl3kO8z4zz4AoyrDmXIVUSrMpatyGiFAqlcCq5XK5WUVRZIlEAuPxeJ3AP5jEt6qq6PVyDuA4YcSzvQHJVBoYk+H+rtCZTCanDcOw67pup+Ypas7mcjkkGvl8HlsaLU2YxLemaSgIQScsLi1PcJx/lAxWFDUxL0eVua+vGlYqFaxWq2iaDcxkMphOp81oNIqMMZQkCWOxWFMTJummIc8HnECvw+X2DIbD8sz5BT/J88HZl9e3zwfdMHTjsfj2/lGkjWv0oaEoal1RlDpt3IQG1MnMOkOtZeiAoeGxHutOEYobFiUoPr227e4dD1x6Q31X3uvedddOP5lkW/F+USgQLW2l8PtDbujqHm/f3Dpoo0jtwWDY5vPdABnC2bkAh0cnoOWeIRAI7TNJvo1EJEZI/2CyKEak7OnZ5cIP/vFp9zeD8fcAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"User to System\"\n        title=\"User to System\"\n        src=\"/static/75b7d55327e23abc1558b2172b80f0f0/c0388/UserToSystem.png\"\n        srcset=\"/static/75b7d55327e23abc1558b2172b80f0f0/c0388/UserToSystem.png 542w\"\n        sizes=\"(max-width: 542px) 100vw, 542px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>And this is, how it happens in the real world as well!</p>\n<p>Finally, we have docker-compose.yml. And following are simple commands which make life even simpler when we need to build and run &#x26; stop the entire ecosystem.</p>\n<p>To build</p>\n<p><code>docker-compose build</code></p>\n<p>To start</p>\n<p><code>docker-compose up</code></p>\n<p>To stop</p>\n<p><code>docker-compose down</code></p>\n<p>This scratches the surface of using docker-compose for a production-grade development environment.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 493px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 82.96146044624746%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAIAAABSJhvpAAAACXBIWXMAABJ0AAASdAHeZh94AAAD5klEQVQ4y2NgZmZesGBBfX19TU3NzJkzZ8yY0dLSAmS0trbGxcV1d3c3NjaWl5fX1tYC2UDBjo4OIHfatGkqKioMQABUlJiYGBYWVlpampKSAiSB0uHh4d7e3nl5eenp6QkJCf7+/kB2RkZGfn5+VlZWWlqakJAQSHNOTs78+fObm5snTJjQ0NAAdAWQGx0dDTQFaM+UKVP6+vqmT58OtADoqKKiosWLF2dnZzNAgJ2dLdBsNze3kJCQ9IwMF1eXqKgoNzdXX18foCWxsbFAa4F2AmW9vLxMTU0iIiK8vDwZGBgZMAETE0i0pqZu5oxZkyZO0tTQAAsyYVEqJsohKMzOI8jGxc/CKcjCJQgkWVWURNpba5oaq6urS3MKi9zc3ZzszX38/PSM9USl+EUkePlA6pkZvFwlTU0F1PQ5FfQ5pfXYJXRYxHW4nD01ZnTE71jRu3VR16GDW44f23Ll7JbHj68tXlQfEWmoYCAgp8OmoMfJ4G4vaGbEbmzEbmTKrW3MI6vNoWkkWpPmuqzcf1WJ6742v3mFnstndV68tG/hwqaSHENTSwEhOUYxBQZJdWYGNzsOVxsOL0d+Z0cBGztBPTP+tliV47Vmh3uD1tf6nOp2v9DlML8qorTcPyBMTMuIRVSBWUiKQd5M0CbVnMHHiT3Mkz/cVzTAT9TDUyQ6Qu9Iu/3+apW9rRbnZ0btKPFaGmC9vT2xMM9JxZRTWo1LWIZByUY8flJi3bYmhkAPnkh/4eggUX8f3uxsmwub2t/vr9vT4dgVpby6NKTQzLzW0XxuqXd+sp2kKju/OIOCtVja3MxJp6bnLy9iCAsQjAmTjI6Ubm8NOHJg0ePDM47PTLg9v2xdU05ndvyS1Mw6d6cFWalz6tJUDATlDISiJydOuzCn83CfS5YRQ1ykWFKMTGWV88UTy2+dWXd46+R1c8uPLOh7vHrTorbCSZURvWmuszKTd/Z07tiybNvh9Xsvb154eWnMlDAdKxaGlBjJ5GjpmiqPSW0BjWVOmQF8k1qCdm7oX1QZUZdm1V/jPLnCb2Vf3M6VTXt2Lzl3Zuutq6c3XtxoGSWnb8bKEBsilhAmFRssEerP5+bJ4uXB4WzLHuHHt2JG3o5lDUc39e5Y3T27LyMpkq+rO3Xv3nWTVzcnTo3Utec1cRJg8PUUCPASCPYVDPATiIxQSIpWN9RlcLLlqc8zW9Id3l5l3Zlv1NUS6ODJ7BrEl1hl33yg1zXLWNeGz9xDgsHWls/Gls3FmcvVjT0hRnlBY6y7s6iTBXeIG0+AP4u7B2NAIJt/HJODJ0dci2vLvp6cJbmmXsLm7hLW3tIAw+9kFKCGTbYAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"No Animals Harmed\"\n        title=\"No Animals Harmed\"\n        src=\"/static/ce6bb0b0f93199d6510e41916aebfbe2/f88d0/noanimalsharmed.png\"\n        srcset=\"/static/ce6bb0b0f93199d6510e41916aebfbe2/f88d0/noanimalsharmed.png 493w\"\n        sizes=\"(max-width: 493px) 100vw, 493px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>Thanks for reading the blog. For detailed information and execution example of this blog, please refer to the video below:</p>\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/G-s2GXGAjTk\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n</style>","frontmatter":{"date":"September 11, 2020","updated_date":null,"title":"Production Grade Development using Docker-Compose","tags":["Docker","Docker-compose"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.7699115044247788,"src":"/static/a4a816f26fe017e3244b736c0cbee474/ee604/index.png","srcSet":"/static/a4a816f26fe017e3244b736c0cbee474/69585/index.png 200w,\n/static/a4a816f26fe017e3244b736c0cbee474/497c6/index.png 400w,\n/static/a4a816f26fe017e3244b736c0cbee474/ee604/index.png 800w,\n/static/a4a816f26fe017e3244b736c0cbee474/f3583/index.png 1200w,\n/static/a4a816f26fe017e3244b736c0cbee474/5707d/index.png 1600w,\n/static/a4a816f26fe017e3244b736c0cbee474/eeb1b/index.png 1920w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Anurag Choudhary","github":"choudharyanurag","avatar":null}}}}]}},"pageContext":{"tag":"Docker-compose"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}