{"id":1888,"date":"2017-04-02T16:37:35","date_gmt":"2017-04-02T11:07:35","guid":{"rendered":"http:\/\/ramkulkarni.com\/blog\/?p=1888"},"modified":"2018-01-13T11:55:39","modified_gmt":"2018-01-13T06:25:39","slug":"docker-notes","status":"publish","type":"post","link":"http:\/\/ramkulkarni.com\/blog\/docker-notes\/","title":{"rendered":"Docker Notes"},"content":{"rendered":"<p>I recently started using Docker and am very impressed with how easily you can set up environment to develop, test and deploy applications. It provides a virtualization environment, but unlike some of the other virtualization solution, Docker container\u00a0\u00a0(runtime environment for your application) \u00a0is a process instead of a\u00a0complete OS. It runs natively on Linux and uses a single virtual machine on Windows and Mac in which Docker containers run.<\/p>\n<p>Using Docker you can easily create containers required for your application to run, for example containers for database, application server etc and easily deploy them to test or production environment. You can create images of your set-up and re-create the same setup constantly from those images. When you create a Docker image, it has to be based on some variant of Linux base image.\u00a0You can browse Docker images at\u00a0<a href=\"https:\/\/hub.docker.com\/\">Docker Hub<\/a>.<\/p>\n<p>This post is not meant to be tutorial or\u00a0detailed information about Docker. You can refer\u00a0to <a href=\"https:\/\/www.docker.com\/\">Docker web site<\/a> for that. As many of my other posts, this post is meant to be reference for me &#8211; about\u00a0some of the Docker commands I have used so far.<!--more--><\/p>\n<h1>How to get Docker<\/h1>\n<ul>\n<li>Download <a href=\"https:\/\/docs.docker.com\/docker-for-mac\/install\/\">Docker for Mac<\/a><\/li>\n<li>Dowlnoad <a href=\"https:\/\/docs.docker.com\/docker-for-windows\/install\/\">Docker for Windows<\/a><\/li>\n<li><a href=\"https:\/\/docs.docker.com\/engine\/installation\/\">Docker for Linux<\/a><\/li>\n<\/ul>\n<h1>Dockerfile<\/h1>\n<p>You create Dockerfile to create a new docker container. Some of the commands used in the Dockerfile are (also see complete <a href=\"https:\/\/docs.docker.com\/engine\/reference\/builder\">official reference docs<\/a>) \u00a0&#8211;<\/p>\n<p><strong>FROM<\/strong> &#8211; Specify base image for your docker image. For example &#8211;\u00a0FROM ubuntu<\/p>\n<p><strong>ADD<\/strong> &#8211; Add file(s) from the host machine to a docker container. For example, to copy setup.sh file, from the directory from where docker commands are run, to my container &#8211; ADD .\/setup.sh \/setup.sh<\/p>\n<p><strong>RUN<\/strong> &#8211; Runs a command in the container. For example to make setup.sh file executable after copying to the container &#8211; RUN chmod +x \/setup.sh<\/p>\n<div>\n<div><strong>ENTRYPOINT<\/strong>&#8211; Docker containers are meant to have one main application, which when stops running, the container stops. That main program is specified \u00a0using this directive. For example to run Apache server after it is installed (using possibly RUN command ) &#8211; ENTRYPOINT apachectl start<\/div>\n<p>&nbsp;<\/p>\n<div><strong>CMD<\/strong>\u00a0&#8211; This is a little confusing directive in Dockerfile. There can be only one command specified in a Dockerfile. In the absence of ENTRYPOINT, if you specify CMD, with is executable, then that becomes the main application for the container. If you do not specify\u00a0executable application command in CMD, then arguments to it are passed to the command\u00a0specified in\u00a0ENTRYPOINT.<\/div>\n<\/div>\n<div><\/div>\n<div><strong>EXPOSE<\/strong> &#8211;\u00a0This is another one of confusing directives. You would think this commands exposes port from the container to the outside world. But that is not what it does. It simply tell Docker that the container listens on specified port(s) at runtime. For example if Apache server is listening on port 80 in a\u00a0container, \u00a0then you would specify &#8211; EXPOSE 80 in the docker file<\/div>\n<div><\/div>\n<div><strong>ENV<\/strong> &#8211; Set environment variable(s) in the container. For example, ENV PATH=\/some\/path:$PATH<\/div>\n<div><\/div>\n<div><strong>VOLUME<\/strong> &#8211; Creates mountable point for a volume. Volume is just like folder, or virtual folder. From within the container, it can be accessed as any other folder. \u00a0Volumes can be used to share folders across different running containers. One container can import volumes from another container.<\/div>\n<div><\/div>\n<div>There am many other directives those can be used in a Dockerfile, but above are the ones I have used frequently, well other than cmd.<\/div>\n<div><\/div>\n<h1>Creating Docker images and containers<\/h1>\n<div>You can create a docker container either completely from command line options or passing location of Dockerfile.<\/div>\n<h2>Create docker container with command line options<\/h2>\n<p>(See <a href=\"https:\/\/docs.docker.com\/engine\/reference\/commandline\/docker\/\">complete reference<\/a>)<\/p>\n<h3>Create a container from ubuntu image<\/h3>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker run <span style=\"color: #308080;\">-<\/span>name my<span style=\"color: #308080;\">-<\/span>ubuntu <span style=\"color: #308080;\">-<\/span>it ubuntu bash\r\n<\/pre>\n<p>The above command will create a docker container from base ubuntu image, name it my-ubuntu, run bash command (open bash shell) and keep standard input open (-i) and text input console open (-t, together -it). It will open a bash shell in the container, where\u00a0you can execute any command.<\/p>\n<h3>Create an image from Dockerfile<\/h3>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker build -t image_name .\r\n<\/pre>\n<p>Run above command from the directory where Dockerfile is present. -t option specifies name of the image in : format. See <a href=\"https:\/\/docs.docker.com\/engine\/reference\/commandline\/build\/\" target=\"_blank\" rel=\"noopener\">build command reference\u00a0<\/a>for details.<\/p>\n<h2>See currently running containers<\/h2>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker ps\r\n<\/pre>\n<p>If you run this command from another terminal on the host computer\u00a0(from where you are running docker commands), you will see my-ubuntu container created above. If you did not exit the bash shell opened in that container (exit command), then you should see my-ubuntu container listed. If you exit the shell, the container stops (because bash was the main command and it terminated). To see all containers, including stopped ones, use -a flag<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker ps <span style=\"color: #308080;\">-<\/span>a\r\n<\/pre>\n<p>ps command shows lot of information. However you can filter and format the output. Format should be a Go template string. For example to see only names of \u00a0container use following command &#8211;<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker ps <span style=\"color: #308080;\">-<\/span><span style=\"color: #308080;\">-<\/span>format <span style=\"color: #800000;\">\"<\/span><span style=\"color: #1060b6;\">{{.Names}}<\/span><span style=\"color: #800000;\">\"<\/span>\r\n<\/pre>\n<p>See <a href=\"https:\/\/docs.docker.com\/engine\/reference\/commandline\/ps\/#formatting\">docs<\/a>\u00a0for more formatting options.<\/p>\n<h3>Start Container<\/h3>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker start my<span style=\"color: #308080;\">-<\/span>ubuntu\r\n<\/pre>\n<p>Above command will start my-ubuntu container, if it was stopped. It will use the same entrypoint command that was specified when the container was created. In this case it will open bash shell, but will terminate immediately. So the container would also stop. Specifying -i option will keep stdin open and will allow you to run commands in the container.<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker start <span style=\"color: #308080;\">-<\/span>i my<span style=\"color: #308080;\">-<\/span>ubuntu\r\n<\/pre>\n<p>use stop command\u00a0to stop the container, e.g. docker stop my-ubuntu1<\/p>\n<p>To remove a container , use rm command\u00a0(you can specify multiple containers names) &#8211;<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker rm my<span style=\"color: #308080;\">-<\/span>ubuntu1 my-ubuntu\r\n<\/pre>\n<p>If you want to remove running container, use -f option, e.g. docker rm -f my-ubuntu1. Instead of container names, you can use container ids also.<\/p>\n<p>Attaching to running container<\/p>\n<p>Let&#8217;s create a container in detached mode.<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker run <span style=\"color: #308080;\">-<\/span>d -it <span style=\"color: #308080;\">-<\/span><span style=\"color: #308080;\">-<\/span>name my<span style=\"color: #308080;\">-<\/span>ubuntu ubuntu\r\n<\/pre>\n<p>-d option runs docker container in background (detached mode). You will immediately return to command prompt after executing the above command.<\/p>\n<p>To attach to the \u00a0the above container and the process that started it (in this case \/bin\/bash) &#8211;<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker attach my<span style=\"color: #308080;\">-<\/span>ubuntu\r\n<\/pre>\n<p>This will allow you to execute commands in bash shell that was started in the container when container was run. Existing the shell (exit command) will also terminate the container.<\/p>\n<p>If you do not want to terminate the container upon existing the bash shell, you can use exec command. It can be used to run any command, not just bash shell.<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker exec <span style=\"color: #308080;\">-<\/span>it my<span style=\"color: #308080;\">-<\/span>ubuntu bash\r\n<\/pre>\n<p>This will open a new bash shell. Exiting that shell will not terminate the container because it was not the command that started the container.<\/p>\n<h2>Listing images<\/h2>\n<p>To list all images &#8211;<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker images\r\n<\/pre>\n<h2>Deleting Image<\/h2>\n<p>To remove images, use rmi command. Note that there should be no container based on the images you want to delete. If there are containers using images to be deleted, then remove those containers first using rm command mentioned above.<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker rmi my<span style=\"color: #308080;\">-<\/span>image1 my<span style=\"color: #308080;\">-<\/span>image2\r\n<\/pre>\n<p>Instead of names you can also use image ids.<\/p>\n<h2>Delete all\u00a0Containers<\/h2>\n<p>Following command will delete ALL containers, so be careful<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker rm $<span style=\"color: #308080;\">(<\/span>docker ps <span style=\"color: #308080;\">-<\/span>a <span style=\"color: #308080;\">-<\/span>q<span style=\"color: #308080;\">)<\/span>\r\n<\/pre>\n<p>-q option tells ps command to return only ids, which are then fed to rm command.<\/p>\n<p>Here is an example of using filters to remove containers (this example removes all containers starting with my-ubuntu)<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker rm $<span style=\"color: #308080;\">(<\/span>docker ps <span style=\"color: #308080;\">-<\/span><span style=\"color: #308080;\">-<\/span>filter name<span style=\"color: #308080;\">=<\/span>my<span style=\"color: #308080;\">-<\/span>ubuntu<span style=\"color: #308080;\">*<\/span> <span style=\"color: #308080;\">-<\/span>q<span style=\"color: #308080;\">)<\/span>\r\n<\/pre>\n<h2>Delete all Images<\/h2>\n<p>Following command deletes all images, so again be careful &#8211;<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker rmi $<span style=\"color: #308080;\">(<\/span>docker images <span style=\"color: #308080;\">-<\/span>q<span style=\"color: #308080;\">)<\/span>\r\n<\/pre>\n<p>To delete by filtering on image name &#8211;<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker rmi <span style=\"color: #308080;\">(<\/span>$docker images <span style=\"color: #308080;\">*<\/span>my<span style=\"color: #308080;\">-<\/span>ubuntu<span style=\"color: #308080;\">*<\/span><span style=\"color: #308080;\">)<\/span>\r\n<\/pre>\n<h2>Using Volumes<\/h2>\n<p>As mentioned earlier, volumes can be used to share data between host and container and also amongst containers. Let&#8217;s create a container, call it container1, with volume v-container1.<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker run <span style=\"color: #308080;\">-<\/span>dt <span style=\"color: #308080;\">-<\/span><span style=\"color: #308080;\">-<\/span>name container1 <span style=\"color: #308080;\">-<\/span>v <span style=\"color: #308080;\">\/<\/span>v<span style=\"color: #308080;\">-<\/span>container1 ubuntu\r\n<\/pre>\n<p>You can open a bash shell in container and verify that \/v-container1 folder is available. Create a file in this folder.<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker exec <span style=\"color: #308080;\">-<\/span>it container1 bash\r\n$ touch v<span style=\"color: #308080;\">-<\/span>container1<span style=\"color: #308080;\">\/<\/span>file<span style=\"color: #308080;\">-<\/span>in<span style=\"color: #308080;\">-<\/span>container1\r\n<\/pre>\n<p>Now create a container, container2, that uses volumes from container1.<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker run <span style=\"color: #308080;\">-<\/span><span style=\"color: #308080;\">-<\/span>rm <span style=\"color: #308080;\">-<\/span>it <span style=\"color: #308080;\">-<\/span><span style=\"color: #308080;\">-<\/span>name container2 <span style=\"color: #308080;\">-<\/span><span style=\"color: #308080;\">-<\/span>volumes<span style=\"color: #308080;\">-<\/span>from container1 ubuntu\r\n<\/pre>\n<p>Note that the above command uses &#8211;rm to create a temporary container. Once the main application started in the container (in this case bash shell) stops, the container will be terminated and it won&#8217;t appear in &#8216;docker ps -a&#8217; command too.<\/p>\n<p>Once the shell opens in container2, you can ensure that \/v-container1 is available and the file we created exists in the folder.<\/p>\n<h2>Mapping folder from host to container<\/h2>\n<p>To share folder from the host to a container, use the same -v option, but specify &lt;host-folder-name&gt;:&lt;path-in-container&gt; argument. For example if you want make, say \/project1\/src folder from host map to \/src folder in the container &#8211;<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker run <span style=\"color: #308080;\">-<\/span><span style=\"color: #308080;\">-<\/span>rm <span style=\"color: #308080;\">-<\/span>it <span style=\"color: #308080;\">-<\/span>v $<span style=\"color: #406080;\">{<\/span>PWD<span style=\"color: #406080;\">}<\/span><span style=\"color: #406080;\">:<\/span><span style=\"color: #308080;\">\/<\/span>src ubuntu\r\n<\/pre>\n<p>${PWD} tells docker to map present working directory. We could have entered the entire path too &#8211; docker run &#8211;rm -it -v \/project1\/src:\/src ubuntu<\/p>\n<p>If your host is Mac or Windows, make sure \/project1\/src folder is shared in Docker preferences, else docker will throw error.<\/p>\n<h2>Using volumes for backup and restore<\/h2>\n<p>I found docker volumes very useful when backing up data from one container and restoring it in another. For example, if you had created a container from mysql image and populated a database, you could easily create a tar file of that data from the host machine and then restore it when you create a new instance of the container, or restore the data in the original db container. However you will need to know volumes used by the container &#8211; \u00a0in this case the container using mysql base image. You can find that easily by running this command &#8211;<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker inspect my-db\r\n<\/pre>\n<p>Note that the the output is JSON. Look for &#8220;Mounts&#8221; key and &#8220;destination&#8221; sub-key in that.\u00a0In case of mysql container, this value is &#8220;\/var\/lib\/mysql&#8221;. This is where the data is stored in mysql container. So we can use -volumes-from option we saw above to use this volume in another container and then run tar command on it and save it in the volume mapped on the host machine.<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\"><span style=\"color: #000020;\">$ docker run <\/span><span style=\"color: #308080;\">-<\/span><span style=\"color: #308080;\">-<\/span><span style=\"color: #000020;\">rm <\/span><span style=\"color: #308080;\">-<\/span><span style=\"color: #308080;\">-<\/span><span style=\"color: #000020;\">volumes<\/span><span style=\"color: #308080;\">-<\/span><span style=\"color: #000020;\">from my<\/span><span style=\"color: #308080;\">-<\/span><span style=\"color: #000020;\">db <\/span><span style=\"color: #308080;\">-<\/span><span style=\"color: #000020;\">v $<\/span><span style=\"color: #406080;\">{<\/span><span style=\"color: #000020;\">pwd<\/span><span style=\"color: #406080;\">}<\/span><span style=\"color: #308080;\">\/<\/span><span style=\"color: #000020;\">backup<\/span><span style=\"color: #308080;\">-<\/span><span style=\"color: #000020;\">data<\/span><span style=\"color: #406080;\">:<\/span><span style=\"color: #308080;\">\/<\/span><span style=\"color: #000020;\">backup<\/span><span style=\"color: #308080;\">-<\/span><span style=\"color: #000020;\">data ubuntu tar cvf <\/span><span style=\"color: #308080;\">\/<\/span><span style=\"color: #000020;\">backup<\/span><span style=\"color: #308080;\">-<\/span><span style=\"color: #000020;\">data<\/span><span style=\"color: #308080;\">\/<\/span><span style=\"color: #000020;\">my<\/span><span style=\"color: #308080;\">-<\/span><span style=\"color: #000020;\">db<\/span><span style=\"color: #308080;\">-<\/span><span style=\"color: #000020;\">volume<\/span><span style=\"color: #308080;\">.<\/span><span style=\"color: #000020;\">tar <\/span><span style=\"color: #308080;\">\/<\/span><span style=\"color: #000020;\">var<\/span><span style=\"color: #308080;\">\/<\/span><span style=\"color: #000020;\">lib<\/span><span style=\"color: #308080;\">\/<\/span><span style=\"color: #000020;\">mysql\r\n<\/span><\/pre>\n<p>We are using &#8211;rm because we want to create a temporary container. The container will be terminated after the command is finished. We are using volumes from my-db container, which is based on mysql image. This makes \/var\/lib\/mysql folder available to this (temporary) container. Then we are mapping backup-data folder in the present folder (on host machine) to \/backup-data in the container. So now the temporary container has access to \/var\/lib\/mysql (from my-db container) and backup-data folder on the host machine. Then we execute tar command to create my-db-volume.tar in \/backup-data, which in effect creates in the same named folder in the host machine. And it tars data from \/var\/lib\/mysql, which is contains data from my-db container.<\/p>\n<p>To restore the data &#8211;<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker run <span style=\"color: #308080;\">-<\/span><span style=\"color: #308080;\">-<\/span>rm <span style=\"color: #308080;\">-<\/span><span style=\"color: #308080;\">-<\/span>volumes<span style=\"color: #308080;\">-<\/span>from my<span style=\"color: #308080;\">-<\/span>new<span style=\"color: #308080;\">-<\/span>db <span style=\"color: #308080;\">-<\/span>v $<span style=\"color: #308080;\">(<\/span>pwd<span style=\"color: #308080;\">)<\/span><span style=\"color: #308080;\">\/<\/span>data<span style=\"color: #308080;\">-<\/span>backup<span style=\"color: #406080;\">:<\/span><span style=\"color: #308080;\">\/<\/span>backup<span style=\"color: #308080;\">-<\/span>data ubuntu bash <span style=\"color: #308080;\">-<\/span>c <span style=\"color: #800000;\">\"<\/span><span style=\"color: #1060b6;\">cd \/ &amp;&amp; tar xvf \/backup-data\/my-db-data.tar<\/span><span style=\"color: #800000;\">\"<\/span>\r\n<\/pre>\n<p>Here we are restoring the data into newly created my-new-db container (created with mysql base image). We are using volumes from the new db container, so \/var\/lib\/mysql folder is available to the temporary container. We map the same folder from host to the temp container and then run tar command to untar\u00a0\/backup-data\/my-db-data.tar (which in untars the same named file from the host machine) into root. So data from \/var\/lib\/mysql in the tar file will be written to \/var\/lib\/mysql in the temp container. And since this volume is coming from my-new-db (the container into which we want to restore the data), we get data saved in that container.<\/p>\n<h2>Creating image from container<\/h2>\n<p>Let say you create a container from some base image, you installed more applications in that container. Now you want to save the container as an image so that next time you could create a container from that image and don&#8217;t have to repeat installation of all the additional applications. You can do that with export command &#8211;<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker <span style=\"color: #200080; font-weight: bold;\">export<\/span> <span style=\"color: #308080;\">-<\/span>o <span style=\"color: #308080;\">\/<\/span>my<span style=\"color: #308080;\">-<\/span>images<span style=\"color: #308080;\">\/<\/span>container1<span style=\"color: #308080;\">-<\/span>image.tar container1\r\n<\/pre>\n<p>Specify output file path using -o option. The last argument is name of the container from which you want to create an image.<\/p>\n<p>To create image\u00a0from the exported file, use import command &#8211;<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker <span style=\"color: #200080; font-weight: bold;\">import<\/span> <span style=\"color: #308080;\">\/<\/span>my<span style=\"color: #308080;\">-<\/span>images<span style=\"color: #308080;\">\/<\/span>container1<span style=\"color: #308080;\">-<\/span>image<span style=\"color: #308080;\">.<\/span>tar container1<span style=\"color: #308080;\">-<\/span>image\r\n<\/pre>\n<p>The above command will create image named container1-image from container1-image.tar file.<\/p>\n<p>I know the post is getting really long, but I wanted to put some of the most useful commands, according to me, \u00a0of Docker in this post. I would wrap up the post by briefly list some of the useful commands in docker-compose<\/p>\n<h2>Docker-Compose<\/h2>\n<p><a href=\"https:\/\/docs.docker.com\/compose\/overview\/\">Docker-compose <\/a>can be used to configure multiple docker containers in the same file and also to specify dependencies between them. There is a docker-compose command which executes commands from <a href=\"https:\/\/docs.docker.com\/compose\/compose-file\/compose-file-v2\/\">docker-compose-yml <\/a>(though you can override file name in docker-compose command).<\/p>\n<p>Structure of docker-compose.yml is simple &#8211; It has version umber at the top (the latest version is 3, but I have mostly worked with version 2), and then there is services section which lists container definitions. Here an example of docker-compose.yml<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">version: \"2\"\r\n\r\nservices: \r\n  my-db:\r\n    image: mysql\r\n    environment:\r\n      MYSQL_DATABASE: my-db\r\n    container_name: my-db\r\n    ports:\r\n      - '3307:3306'\r\n\r\n  my-app-server:\r\n    build: ..\/my-app-server\r\n    container_name: my-app-server\r\n    stdin_open: true\r\n    tty: true\r\n    ports:\r\n      - '8082:8080'\r\n      - '9001:9001' # Open port for debuggin\r\n    volumes: \r\n      - ..\/src\/app1:\/src\/app1\r\n      - ..\/logs:\/logs\r\n    depends_on: \r\n      - my-db\r\n<\/pre>\n<p>Many of the options we have already seen in this post so far, so I though I would just show and example of docker-compose.yml. The file contains definition of one db container that specifies image directly in the docker-compose.yml and one app server container that builds the container from dockerfile in ..\/my-app-server folder. Note the dependency of app server on db server, specified in\u00a0&#8216;depends_on&#8217; \u00a0section in the app server<\/p>\n<p>To bring up both the container, run<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker-compose up\r\n<\/pre>\n<p>To run docker-compose in detached mode, use -d option. However you may want to use non-detached mode to see output messages.<\/p>\n<p>To stop all containers started in docker-compose.yml, press CTRL+C if it is running in foreground, or you can run<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\">$ docker-compose down\r\n<\/pre>\n<p>-Ram Kulkarni<\/p>\n<p><strong>Update:<\/strong> \u00a0I had run into a networking issue in docker containers on Linux. The containers created did not have access to internet. After struggling to find a solution for this issue, I realized that the issue could be with DNS lookup. I am not sure if this is a generic problem, but in my setup DNS were not set properly in the containers. So I had to specify DNS (find DNS from host network settings) when creating containers, either in docker-compose.yml (see <a href=\"https:\/\/docs.docker.com\/compose\/compose-file\/compose-file-v2\/#dns\">this<\/a>) or when executing &#8216;docker run&#8217; command (see <a href=\"https:\/\/docs.docker.com\/engine\/reference\/run\/#network-settings\">this<\/a>).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I recently started using Docker and am very impressed with how easily you can set up environment to develop, test and deploy applications. It provides a virtualization environment, but unlike some of the other virtualization solution, Docker container\u00a0\u00a0(runtime environment for your application) \u00a0is a process instead of a\u00a0complete OS. It runs natively on Linux and &hellip; <\/p>\n<p class=\"link-more\"><a href=\"http:\/\/ramkulkarni.com\/blog\/docker-notes\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Docker Notes&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":true,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[135],"tags":[133,134],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p2g9O8-us","jetpack-related-posts":[],"_links":{"self":[{"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/posts\/1888"}],"collection":[{"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/comments?post=1888"}],"version-history":[{"count":11,"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/posts\/1888\/revisions"}],"predecessor-version":[{"id":2180,"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/posts\/1888\/revisions\/2180"}],"wp:attachment":[{"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/media?parent=1888"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/categories?post=1888"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/tags?post=1888"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}