[{"data":1,"prerenderedAt":40},["ShallowReactive",2],{"article-docker-for-local-development-6ak":3},{"type_of":4,"id":5,"title":6,"description":7,"readable_publish_date":8,"slug":9,"path":10,"url":11,"comments_count":12,"public_reactions_count":13,"collection_id":14,"published_timestamp":15,"language":16,"subforem_id":17,"positive_reactions_count":13,"cover_image":18,"social_image":19,"canonical_url":11,"created_at":15,"edited_at":20,"crossposted_at":14,"published_at":15,"last_comment_at":21,"reading_time_minutes":22,"tag_list":23,"tags":24,"body_html":29,"body_markdown":30,"user":31},"article",236783,"Docker for Local Development","This will teach you how to containerize your application\u002Fservices and setup a development environment.","Jan 12 '20","docker-for-local-development-6ak","\u002Fashraful\u002Fdocker-for-local-development-6ak","https:\u002F\u002Fdev.to\u002Fashraful\u002Fdocker-for-local-development-6ak",6,171,null,"2020-01-12T17:23:09Z","en",1,"https:\u002F\u002Fmedia2.dev.to\u002Fdynamic\u002Fimage\u002Fwidth=1000,height=420,fit=cover,gravity=auto,format=auto\u002Fhttps%3A%2F%2Fblog.ashraful.dev%2Fimages%2Fdocker-compose.png","https:\u002F\u002Fmedia2.dev.to\u002Fdynamic\u002Fimage\u002Fwidth=1000,height=500,fit=cover,gravity=auto,format=auto\u002Fhttps%3A%2F%2Fblog.ashraful.dev%2Fimages%2Fdocker-compose.png","2026-07-21T06:33:02Z","2020-01-30T08:33:27Z",4,"docker, dockercompose, devops, beginners",[25,26,27,28],"docker","dockercompose","devops","beginners","\u003Cblockquote>\n\u003Cp>Are we already know about \u003Ca href=\"https:\u002F\u002Fwww.docker.com\u002F\" target=\"_blank\" rel=\"noopener noreferrer\">Docker\u003C\u002Fa>? If not please read this (\u003Ca href=\"https:\u002F\u002Fashraful.dev\u002Fposts\u002Fintroduction-to-docker.html\" target=\"_blank\" rel=\"noopener noreferrer\">Docker Into\u003C\u002Fa>) first.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\n\u003Ch2>\n  \u003Ca name=\"question-why-should-i-use-docker-in-local-development\" href=\"#question-why-should-i-use-docker-in-local-development\">\n  \u003C\u002Fa>\n  ❓ Why should I use Docker in local development?\n\u003C\u002Fh2>\n\n\u003Cp>Do you like to spend more time to setup your environment? If yes? just close the window. Maybe you are not in the right place. Okay no more gossiping. Let me tell you a real story.  \u003C\u002Fp>\n\n\u003Cp>Recently I have bought a MacBook for my personal development. I was exited to write code on it. But before that I must setup my development environment to start with it. So, without delaying I started cloning repositories from Github and then installing their dev dependencies. Seriously at the end of the day I was damn tired of doing this. One of my pet project was using Node(v8.10.*), MongoDB and React. Another projects have latest version of Node and other dependencies. So I was on trouble setting up my environment as I was new at Mac OS. So, finally I had decided to write \u003Ccode>Dockerfile\u003C\u002Fcode> at all my services and \u003Ccode>Docker Compose\u003C\u002Fcode> to run them together.\u003C\u002Fp>\n\n\u003Ch2>\n  \u003Ca name=\"question-what-is-docker-compose\" href=\"#question-what-is-docker-compose\">\n  \u003C\u002Fa>\n  ❓ What is Docker Compose?\n\u003C\u002Fh2>\n\n\u003Cp>Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. More details \u003Ca href=\"https:\u002F\u002Fdocs.docker.com\u002Fcompose\u002F\" target=\"_blank\" rel=\"noopener noreferrer\">here\u003C\u002Fa>.\u003C\u002Fp>\n\n\u003Ch2>\n  \u003Ca name=\"dizzy-an-example-architecture\" href=\"#dizzy-an-example-architecture\">\n  \u003C\u002Fa>\n  💫 An Example Architecture\n\u003C\u002Fh2>\n\n\u003Cp>Suppose, we have two different services and one database service. \u003C\u002Fp>\n\n\u003Col>\n\u003Cli>NodeJS app (port: 5000)\u003C\u002Fli>\n\u003Cli>React app (port: 5001)\u003C\u002Fli>\n\u003Cli>MongoDB (port: 27017)\u003C\u002Fli>\n\u003C\u002Fol>\n\n\u003Cp>We are going to write \u003Ccode>docker-compose.yml\u003C\u002Fcode> file and run them with single command anytime and anywhere. As I am not going to explain the code part rather than \u003Ccode>docker\u003C\u002Fcode> and \u003Ccode>docker-compose\u003C\u002Fcode>, So, I already have an app with this architecture. Fork and clone the app from \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fiashraful\u002Fgraphql-mongo-todo\" target=\"_blank\" rel=\"noopener noreferrer\">github\u003C\u002Fa> and change on your own.\u003C\u002Fp>\n\n\u003Cp>As you already have seen we are going to run all these services\u002Fapplications in different ports, So, we need to allow these ports in the container and physical machine(your machine). For example, If you already mongo installed on your computer then you may not use \u003Ccode>27017\u003C\u002Fcode> port for new mongo container. So, what we can do, we can forward the port from the docker container to the physical machine. It's simple as you think.\u003C\u002Fp>\n\n\u003Ch2>\n  \u003Ca name=\"rocket-lets-setting-it-up\" href=\"#rocket-lets-setting-it-up\">\n  \u003C\u002Fa>\n  🚀 Let's setting it up\n\u003C\u002Fh2>\n\n\u003Cul>\n\u003Cli>Clone the repo, \u003Ccode>git clone https:\u002F\u002Fgithub.com\u002Fiashraful\u002Fgraphql-mongo-todo.git\u003C\u002Fcode>\n\u003C\u002Fli>\n\u003Cli>\u003Ccode>cd graphql-mongo-todo\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>Open \u003Ccode>docker-compose.yml\u003C\u002Fcode> with your favorite editor. (Don;t worry I'll explain. 😎). You'll see similar like following.\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Ch4>\n  \u003Ca name=\"-raw-dockercomposeyml-endraw-\" href=\"#-raw-dockercomposeyml-endraw-\">\n  \u003C\u002Fa>\n  \u003Ccode>docker-compose.yml\u003C\u002Fcode>\n\u003C\u002Fh4>\n\n\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight yaml\">\u003Ccode>\u003Cspan class=\"na\">version\u003C\u002Fspan>\u003Cspan class=\"pi\">:\u003C\u002Fspan> \u003Cspan class=\"s1\">'\u003C\u002Fspan>\u003Cspan class=\"s\">3.5'\u003C\u002Fspan>\n\u003Cspan class=\"na\">services\u003C\u002Fspan>\u003Cspan class=\"pi\">:\u003C\u002Fspan> \n  \u003Cspan class=\"na\">react_client\u003C\u002Fspan>\u003Cspan class=\"pi\">:\u003C\u002Fspan>\n    \u003Cspan class=\"na\">build\u003C\u002Fspan>\u003Cspan class=\"pi\">:\u003C\u002Fspan> \u003Cspan class=\"s\">.\u002Fclient\u003C\u002Fspan>\n    \u003Cspan class=\"na\">command\u003C\u002Fspan>\u003Cspan class=\"pi\">:\u003C\u002Fspan> \u003Cspan class=\"s\">sh -c \"yarn install &amp;&amp; yarn start\"\u003C\u002Fspan>\n    \u003Cspan class=\"na\">environment\u003C\u002Fspan>\u003Cspan class=\"pi\">:\u003C\u002Fspan> \n      \u003Cspan class=\"pi\">-\u003C\u002Fspan> \u003Cspan class=\"s\">NODE_ENV=development\u003C\u002Fspan>\n      \u003Cspan class=\"pi\">-\u003C\u002Fspan> \u003Cspan class=\"s\">PORT=5001\u003C\u002Fspan>\n    \u003Cspan class=\"na\">ports\u003C\u002Fspan>\u003Cspan class=\"pi\">:\u003C\u002Fspan>\n      \u003Cspan class=\"pi\">-\u003C\u002Fspan> \u003Cspan class=\"s1\">'\u003C\u002Fspan>\u003Cspan class=\"s\">5001:5001'\u003C\u002Fspan>\n    \u003Cspan class=\"na\">working_dir\u003C\u002Fspan>\u003Cspan class=\"pi\">:\u003C\u002Fspan> \u003Cspan class=\"s\">\u002Fapp\u002Fclient\u003C\u002Fspan>\n    \u003Cspan class=\"na\">volumes\u003C\u002Fspan>\u003Cspan class=\"pi\">:\u003C\u002Fspan>\n      \u003Cspan class=\"pi\">-\u003C\u002Fspan> \u003Cspan class=\"s\">.\u002Fclient:\u002Fapp\u002Fclient:cached\u003C\u002Fspan>\n\n  \u003Cspan class=\"na\">node_server\u003C\u002Fspan>\u003Cspan class=\"pi\">:\u003C\u002Fspan>\n    \u003Cspan class=\"na\">build\u003C\u002Fspan>\u003Cspan class=\"pi\">:\u003C\u002Fspan> \u003Cspan class=\"s\">.\u002Fserver\u003C\u002Fspan>\n    \u003Cspan class=\"na\">command\u003C\u002Fspan>\u003Cspan class=\"pi\">:\u003C\u002Fspan> \u003Cspan class=\"s\">sh -c \"yarn install &amp;&amp; yarn dev\"\u003C\u002Fspan>\n    \u003Cspan class=\"na\">environment\u003C\u002Fspan>\u003Cspan class=\"pi\">:\u003C\u002Fspan> \n      \u003Cspan class=\"pi\">-\u003C\u002Fspan> \u003Cspan class=\"s\">NODE_ENV=development\u003C\u002Fspan>\n      \u003Cspan class=\"pi\">-\u003C\u002Fspan> \u003Cspan class=\"s\">PORT=5000\u003C\u002Fspan>\n    \u003Cspan class=\"na\">ports\u003C\u002Fspan>\u003Cspan class=\"pi\">:\u003C\u002Fspan>\n      \u003Cspan class=\"pi\">-\u003C\u002Fspan> \u003Cspan class=\"s1\">'\u003C\u002Fspan>\u003Cspan class=\"s\">5000:5000'\u003C\u002Fspan>\n    \u003Cspan class=\"na\">working_dir\u003C\u002Fspan>\u003Cspan class=\"pi\">:\u003C\u002Fspan> \u003Cspan class=\"s\">\u002Fapp\u002Fserver\u003C\u002Fspan>\n    \u003Cspan class=\"na\">volumes\u003C\u002Fspan>\u003Cspan class=\"pi\">:\u003C\u002Fspan>\n      \u003Cspan class=\"pi\">-\u003C\u002Fspan> \u003Cspan class=\"s\">.\u002Fserver:\u002Fapp\u002Fserver:cached\u003C\u002Fspan>\n    \u003Cspan class=\"na\">depends_on\u003C\u002Fspan>\u003Cspan class=\"pi\">:\u003C\u002Fspan> \n      \u003Cspan class=\"pi\">-\u003C\u002Fspan> \u003Cspan class=\"s\">mongodb\u003C\u002Fspan>\n\n  \u003Cspan class=\"na\">mongodb\u003C\u002Fspan>\u003Cspan class=\"pi\">:\u003C\u002Fspan>\n    \u003Cspan class=\"na\">image\u003C\u002Fspan>\u003Cspan class=\"pi\">:\u003C\u002Fspan> \u003Cspan class=\"s\">mongo\u003C\u002Fspan>\n    \u003Cspan class=\"na\">expose\u003C\u002Fspan>\u003Cspan class=\"pi\">:\u003C\u002Fspan>\n      \u003Cspan class=\"pi\">-\u003C\u002Fspan> \u003Cspan class=\"s1\">'\u003C\u002Fspan>\u003Cspan class=\"s\">27017'\u003C\u002Fspan>\n    \u003Cspan class=\"na\">environment\u003C\u002Fspan>\u003Cspan class=\"pi\">:\u003C\u002Fspan> \n      \u003Cspan class=\"pi\">-\u003C\u002Fspan> \u003Cspan class=\"s\">MONGO_INIT_DB_DATABASE_NAME='graphql-todo'\u003C\u002Fspan>\n    \u003Cspan class=\"na\">volumes\u003C\u002Fspan>\u003Cspan class=\"pi\">:\u003C\u002Fspan> \n      \u003Cspan class=\"pi\">-\u003C\u002Fspan> \u003Cspan class=\"s\">.\u002Fdb:\u002Fdata\u002Fdb\u003C\u002Fspan>\n    \u003Cspan class=\"na\">ports\u003C\u002Fspan>\u003Cspan class=\"pi\">:\u003C\u002Fspan>\n      \u003Cspan class=\"pi\">-\u003C\u002Fspan> \u003Cspan class=\"s1\">'\u003C\u002Fspan>\u003Cspan class=\"s\">27019:27017'\u003C\u002Fspan>\n\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n    \u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C\u002Ftitle>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C\u002Fpath>\n\u003C\u002Fsvg>\n\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\n\n\n\u003Ch4>\n  \u003Ca name=\"version-35\" href=\"#version-35\">\n  \u003C\u002Fa>\n  version: '3.5'\n\u003C\u002Fh4>\n\n\u003Cp>This version indicates that, which docker engine version you are using. In my case I am using most recent docker engine 19.*.*. So, I am using version 3.7. See \u003Ca href=\"https:\u002F\u002Fdocs.docker.com\u002Fcompose\u002Fcompose-file\u002Fcompose-versioning\u002F\" target=\"_blank\" rel=\"noopener noreferrer\">full versioning guide\u003C\u002Fa>\u003C\u002Fp>\n\n\u003Ch4>\n  \u003Ca name=\"services\" href=\"#services\">\n  \u003C\u002Fa>\n  services\n\u003C\u002Fh4>\n\n\u003Cp>It's plain and simple. How many services you want to run using this compose file. Mine is three. Node, React, Mongo.\u003C\u002Fp>\n\n\u003Ch4>\n  \u003Ca name=\"reactclient-nodeserver-mongodb\" href=\"#reactclient-nodeserver-mongodb\">\n  \u003C\u002Fa>\n  react_client, node_server, mongodb\n\u003C\u002Fh4>\n\n\u003Cp>Name of each service. Under each service you need to specify the configuration.\u003C\u002Fp>\n\n\u003Ch4>\n  \u003Ca name=\"build-directory-path\" href=\"#build-directory-path\">\n  \u003C\u002Fa>\n  build: [directory path]\n\u003C\u002Fh4>\n\n\u003Cp>Which directory you are going to use for the particular services. You can specify the relative path here.\u003C\u002Fp>\n\n\u003Ch4>\n  \u003Ca name=\"command-any-shell-command\" href=\"#command-any-shell-command\">\n  \u003C\u002Fa>\n  command: [Any shell command]\n\u003C\u002Fh4>\n\n\u003Cp>Command is fully depends on the image that you have chosen. If you pick an image that is based on linux then you know the bash is default shell. So, without any worrying you can use bash command. \u003Cstrong>If you are confused about the image that I've chosen here? Don't worry I'll talk about it.\u003C\u002Fstrong>\u003C\u002Fp>\n\n\u003Ch4>\n  \u003Ca name=\"environment\" href=\"#environment\">\n  \u003C\u002Fa>\n  environment\n\u003C\u002Fh4>\n\n\u003Cp>Any kind of environment variable you can pass through the \u003Ccode>environment\u003C\u002Fcode>.\u003C\u002Fp>\n\n\u003Ch4>\n  \u003Ca name=\"ports\" href=\"#ports\">\n  \u003C\u002Fa>\n  ports\n\u003C\u002Fh4>\n\n\u003Cp>This is important to know how to enable port for container and map the physical machine port. Here \u003Ccode>5000:5000\u003C\u002Fcode> means \u003Ccode>Container port:Physical machine port\u003C\u002Fcode>.\u003C\u002Fp>\n\n\u003Ch4>\n  \u003Ca name=\"workingdir\" href=\"#workingdir\">\n  \u003C\u002Fa>\n  working_dir\n\u003C\u002Fh4>\n\n\u003Cp>It's a straightforward path of the container where your code will be copied.\u003C\u002Fp>\n\n\u003Ch4>\n  \u003Ca name=\"volumes\" href=\"#volumes\">\n  \u003C\u002Fa>\n  volumes\n\u003C\u002Fh4>\n\n\u003Cp>Volumes is most important to know when you are on local development. Because you don't like to re-build and run the container after every change. So, It creates a mapping between physical machine code vs container working directory codes.\u003C\u002Fp>\n\n\u003Ch4>\n  \u003Ca name=\"dependson\" href=\"#dependson\">\n  \u003C\u002Fa>\n  depends_on\n\u003C\u002Fh4>\n\n\u003Cp>It's an awesome feature we have. Suppose you have five services and one service depends on other. Like our nodejs service depends on mongodb. So, I put \u003Ccode>depends_on: mongodb\u003C\u002Fcode>\u003C\u002Fp>\n\n\u003Ch4>\n  \u003Ca name=\"image\" href=\"#image\">\n  \u003C\u002Fa>\n  image\n\u003C\u002Fh4>\n\n\u003Cp>Image is the docker image that we are using as a base image. As we already know from our \u003Ca href=\"https:\u002F\u002Fashraful.dev\u002Fposts\u002Fintroduction-to-docker.html\" target=\"_blank\" rel=\"noopener noreferrer\">previous post\u003C\u002Fa> that, \u003Cstrong>Every docker must have a base image.\u003C\u002Fstrong>. This is the image tag we can use for defining the image. If you look closely, I didn't define image at \u003Ccode>react_client\u003C\u002Fcode> and \u003Ccode>node_server\u003C\u002Fcode>. But on mongo I defined \u003Ccode>image: mongo\u003C\u002Fcode>. Do you know why?? Let's see why.\u003C\u002Fp>\n\n\u003Ch2>\n  \u003Ca name=\"question-cant-we-use-raw-dockerfile-endraw-\" href=\"#question-cant-we-use-raw-dockerfile-endraw-\">\n  \u003C\u002Fa>\n  ❓ Can't we use \u003Ccode>Dockerfile\u003C\u002Fcode>?\n\u003C\u002Fh2>\n\n\u003Cp>\u003Cstrong>Yes we can.\u003C\u002Fstrong> Open client and server directory, you'll see Dockerfile is there. Even when you command your computer to runt the docker compose file then, your computer find the build directory and find a dockerfile inside it. Then execute as it is.\u003C\u002Fp>\n\n\u003Ch2>\n  \u003Ca name=\"dog-oh-enough-bomb-lets-run-the-project\" href=\"#dog-oh-enough-bomb-lets-run-the-project\">\n  \u003C\u002Fa>\n  🐶 Oh Enough 💣 Let's run the project.\n\u003C\u002Fh2>\n\n\u003Cul>\n\u003Cli>Open up your terminal\u002Fconsole.\u003C\u002Fli>\n\u003Cli>\u003Ccode>$ docker-compose up\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>Wait few moments and enjoy.\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Ch2>\n  \u003Ca name=\"snowman-basic-raw-dockercompose-endraw-commands\" href=\"#snowman-basic-raw-dockercompose-endraw-commands\">\n  \u003C\u002Fa>\n  ⛄ Basic \u003Ccode>docker-compose\u003C\u002Fcode> commands.\n\u003C\u002Fh2>\n\n\u003Cul>\n\u003Cli>\n\u003Ccode>docker-compose up\u003C\u002Fcode> ➡️ Run the docker compose file.\u003C\u002Fli>\n\u003Cli>\n\u003Ccode>docker-compose up --build\u003C\u002Fcode> ➡️ Re build and run the docker compose file.\u003C\u002Fli>\n\u003Cli>\n\u003Ccode>docker-compose up &lt;service name&gt;\u003C\u002Fcode> ➡️ Up and running a specific services.\u003C\u002Fli>\n\u003Cli>\n\u003Ccode>docker-compose start\u003C\u002Fcode> ➡️ Start the last built containers.\u003C\u002Fli>\n\u003Cli>\n\u003Ccode>docker-compose stop\u003C\u002Fcode> ➡️ Stop the last running containers.\u003C\u002Fli>\n\u003Cli>\n\u003Ccode>docker-compose restart\u003C\u002Fcode> ➡️ Restart the last running containers.\u003C\u002Fli>\n\u003Cli>\n\u003Ccode>docker-compose logs -f &lt;service name&gt;\u003C\u002Fcode> ➡️ Log from a specific service.\u003C\u002Fli>\n\u003Cli>\n\u003Ccode>docker-compose exec &lt;service name&gt; bash\u003C\u002Fcode> ➡️ SSH into a particular container bash.\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>🚩 That's all. Thanks for reading! 😆\u003C\u002Fp>\n\n","---\ntitle: Docker for Local Development\npublished: true\ndescription: This will teach you how to containerize your application\u002Fservices and setup a development environment.\ncover_image: https:\u002F\u002Fblog.ashraful.dev\u002Fimages\u002Fdocker-compose.png\ntags: Docker, DockerCompose, DevOps, beginners\n---\n\n> Are we already know about [Docker](https:\u002F\u002Fwww.docker.com\u002F)? If not please read this ([Docker Into](https:\u002F\u002Fashraful.dev\u002Fposts\u002Fintroduction-to-docker.html)) first.\n\n## :question: Why should I use Docker in local development?\n\nDo you like to spend more time to setup your environment? If yes? just close the window. Maybe you are not in the right place. Okay no more gossiping. Let me tell you a real story.  \n\nRecently I have bought a MacBook for my personal development. I was exited to write code on it. But before that I must setup my development environment to start with it. So, without delaying I started cloning repositories from Github and then installing their dev dependencies. Seriously at the end of the day I was damn tired of doing this. One of my pet project was using Node(v8.10.*), MongoDB and React. Another projects have latest version of Node and other dependencies. So I was on trouble setting up my environment as I was new at Mac OS. So, finally I had decided to write `Dockerfile` at all my services and `Docker Compose` to run them together.\n\n## :question: What is Docker Compose?\n\nCompose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. More details [here](https:\u002F\u002Fdocs.docker.com\u002Fcompose\u002F).\n\n## :dizzy: An Example Architecture\n\nSuppose, we have two different services and one database service. \n1. NodeJS app (port: 5000)\n2. React app (port: 5001)\n3. MongoDB (port: 27017)\n\nWe are going to write `docker-compose.yml` file and run them with single command anytime and anywhere. As I am not going to explain the code part rather than `docker` and `docker-compose`, So, I already have an app with this architecture. Fork and clone the app from [github](https:\u002F\u002Fgithub.com\u002Fiashraful\u002Fgraphql-mongo-todo) and change on your own.\n\nAs you already have seen we are going to run all these services\u002Fapplications in different ports, So, we need to allow these ports in the container and physical machine(your machine). For example, If you already mongo installed on your computer then you may not use `27017` port for new mongo container. So, what we can do, we can forward the port from the docker container to the physical machine. It's simple as you think.\n\n## :rocket: Let's setting it up\n\n* Clone the repo, `git clone https:\u002F\u002Fgithub.com\u002Fiashraful\u002Fgraphql-mongo-todo.git`\n* `cd graphql-mongo-todo`\n* Open `docker-compose.yml` with your favorite editor. (Don;t worry I'll explain. :sunglasses:). You'll see similar like following.\n\n#### `docker-compose.yml`\n```yml\nversion: '3.5'\nservices: \n  react_client:\n    build: .\u002Fclient\n    command: sh -c \"yarn install && yarn start\"\n    environment: \n      - NODE_ENV=development\n      - PORT=5001\n    ports:\n      - '5001:5001'\n    working_dir: \u002Fapp\u002Fclient\n    volumes:\n      - .\u002Fclient:\u002Fapp\u002Fclient:cached\n\n  node_server:\n    build: .\u002Fserver\n    command: sh -c \"yarn install && yarn dev\"\n    environment: \n      - NODE_ENV=development\n      - PORT=5000\n    ports:\n      - '5000:5000'\n    working_dir: \u002Fapp\u002Fserver\n    volumes:\n      - .\u002Fserver:\u002Fapp\u002Fserver:cached\n    depends_on: \n      - mongodb\n\n  mongodb:\n    image: mongo\n    expose:\n      - '27017'\n    environment: \n      - MONGO_INIT_DB_DATABASE_NAME='graphql-todo'\n    volumes: \n      - .\u002Fdb:\u002Fdata\u002Fdb\n    ports:\n      - '27019:27017'\n\n```\n\n#### version: '3.5'\nThis version indicates that, which docker engine version you are using. In my case I am using most recent docker engine 19.\\*.\\*. So, I am using version 3.7. See [full versioning guide](https:\u002F\u002Fdocs.docker.com\u002Fcompose\u002Fcompose-file\u002Fcompose-versioning\u002F)\n\n#### services\nIt's plain and simple. How many services you want to run using this compose file. Mine is three. Node, React, Mongo.\n\n#### react_client, node_server, mongodb\nName of each service. Under each service you need to specify the configuration.\n\n#### build: [directory path]\nWhich directory you are going to use for the particular services. You can specify the relative path here.\n\n#### command: [Any shell command]\nCommand is fully depends on the image that you have chosen. If you pick an image that is based on linux then you know the bash is default shell. So, without any worrying you can use bash command. **If you are confused about the image that I've chosen here? Don't worry I'll talk about it.**\n\n#### environment\nAny kind of environment variable you can pass through the `environment`.\n\n#### ports\nThis is important to know how to enable port for container and map the physical machine port. Here `5000:5000` means `Container port:Physical machine port`.\n\n#### working_dir\nIt's a straightforward path of the container where your code will be copied.\n\n#### volumes\nVolumes is most important to know when you are on local development. Because you don't like to re-build and run the container after every change. So, It creates a mapping between physical machine code vs container working directory codes.\n\n#### depends_on\nIt's an awesome feature we have. Suppose you have five services and one service depends on other. Like our nodejs service depends on mongodb. So, I put `depends_on: mongodb`\n\n#### image\nImage is the docker image that we are using as a base image. As we already know from our [previous post](https:\u002F\u002Fashraful.dev\u002Fposts\u002Fintroduction-to-docker.html) that, **Every docker must have a base image.**. This is the image tag we can use for defining the image. If you look closely, I didn't define image at `react_client` and `node_server`. But on mongo I defined `image: mongo`. Do you know why?? Let's see why.\n\n## :question: Can't we use `Dockerfile`?\n**Yes we can.** Open client and server directory, you'll see Dockerfile is there. Even when you command your computer to runt the docker compose file then, your computer find the build directory and find a dockerfile inside it. Then execute as it is.\n\n## :dog: Oh Enough :bomb: Let's run the project.\n* Open up your terminal\u002Fconsole.\n* `$ docker-compose up`\n* Wait few moments and enjoy.\n\n## :snowman: Basic `docker-compose` commands.\n* `docker-compose up` :arrow_right: Run the docker compose file.\n* `docker-compose up --build` :arrow_right: Re build and run the docker compose file.\n* `docker-compose up \u003Cservice name>` :arrow_right: Up and running a specific services.\n* `docker-compose start` :arrow_right: Start the last built containers.\n* `docker-compose stop` :arrow_right: Stop the last running containers.\n* `docker-compose restart` :arrow_right: Restart the last running containers.\n* `docker-compose logs -f \u003Cservice name>` :arrow_right: Log from a specific service.\n* `docker-compose exec \u003Cservice name> bash` :arrow_right: SSH into a particular container bash.\n\n:triangular_flag_on_post: That's all. Thanks for reading! :laughing:",{"name":32,"username":33,"twitter_username":34,"github_username":35,"user_id":36,"website_url":37,"profile_image":38,"profile_image_90":39},"Mohamad Ashraful Islam","ashraful","_ashraful","iashraful",30490,"https:\u002F\u002Fashraful.dev","https:\u002F\u002Fmedia2.dev.to\u002Fdynamic\u002Fimage\u002Fwidth=640,height=640,fit=cover,gravity=auto,format=auto\u002Fhttps%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F30490%2F9dc1ef64-0233-43b5-9127-79affd83cc43.jpg","https:\u002F\u002Fmedia2.dev.to\u002Fdynamic\u002Fimage\u002Fwidth=90,height=90,fit=cover,gravity=auto,format=auto\u002Fhttps%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F30490%2F9dc1ef64-0233-43b5-9127-79affd83cc43.jpg",1784633124160]