{"id":719,"date":"2021-03-20T08:41:31","date_gmt":"2021-03-20T08:41:31","guid":{"rendered":"https:\/\/shreyapohekar.com\/blogs\/?p=719"},"modified":"2021-03-20T09:37:00","modified_gmt":"2021-03-20T09:37:00","slug":"the-docker-cheatsheet-doing-things-the-docker-way","status":"publish","type":"post","link":"https:\/\/shreyapohekar.com\/blogs\/the-docker-cheatsheet-doing-things-the-docker-way\/","title":{"rendered":"The docker cheatsheet: Doing things the docker way"},"content":{"rendered":"\n<p class=\"has-drop-cap\">Docker technology can never replace the concept of virtualization but has got its own special benefits. The ability to run an application by consuming minimalistic resources is just mindboggling. The feature of complete isolation is an everyday requirement for most of us.<\/p>\n\n\n\n<p>Recently I was creating challenges for winjactf 2021. And all the challenges had to be dockerized. Since I was doing it for the first time, I faced several issues. I felt that any beginner would get into similar troubles so I thought of blogging out the scenario where I made some stupid mistakes, but yes learned a lot in solving them.<\/p>\n\n\n\n<p>With this post, I&#8217;ll be sharing some must-know commands in docker that will surely solve lot of your problems.<\/p>\n\n\n\n<p>So let&#8217;s jump in.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Basic commands<\/h2>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background\">docker container ls\ndocker image ls\ndocker ps\ndocker ps -a\ndocker run -it -p 8080:80 ubuntu:latest --name ubuntu-machine \/bin\/bash\ndocker exec -it ubuntu-machine \/bin\/bash<\/pre>\n\n\n\n<p>This is a probably the complete set of commands, that we use on daily basis.<\/p>\n\n\n\n<p>Let&#8217;s see a brief explaination for all of them.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>container ls<\/strong> :- lists all the running containers<\/li><li><strong>image ls<\/strong> :- lists all the images residing over the machine<\/li><li><strong>ps <\/strong>:- tells you about all the active processes<\/li><li><strong>ps -a<\/strong> :- Gives you additional information like details about the process that exited.<\/li><li><strong>run -it<\/strong> :- This command starts a container. If the specified image is not present, it will pull it from the official docker repository (docker hub). <ul><li><strong>-p<\/strong> :- it maps the internal port of the docker to the host. For example, -p 8080:80 will map the internal port 80 to the 8080 of the host machine. So when u write, http:\/\/localhost:8080, you are actually accessing the web service on container running on port 80.<\/li><li><strong>&#8211;name<\/strong> :- gives a name to your running container.<\/li><li><strong>-v<\/strong> :- It maps the volume on the host machine to the container. Meaning? You can think of it as a shared disk space. This flag is used when u have to persist the state of a container.<\/li><li><strong>\/bin\/bash<\/strong> :- Its the command that you want to run in the container. You can also write &#8220;whoami&#8221; to just print the current user, or directly get shell access with \/bin\/bash.<\/li><li><strong>-d<\/strong> :- Run the container in background<\/li><\/ul><\/li><li><strong>exec -it<\/strong> :- It executes commands in an already running container.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">But there&#8217;s more to it&#8230;.<\/h2>\n\n\n\n<p>The commands listed above might solve most of your purpose. But, the endless possibilities of docker got me into more of digging! While working, I came across a few interesting commands that I want to list.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background\">docker container stop 9c<\/pre>\n\n\n\n<p>You see something different? The 9c. Its the initials of the container id that might be something of the form :- 9c13df3fd. So instead of copy-pasting you can simply type the initials and your docker command will know which container is being referenced. Same thing works when you are removing the image.<\/p>\n\n\n\n<p>Want to start a stopped container? You can do it by<\/p>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background\"> docker start -a my-container-name <\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Running out of space because of containers?<\/h2>\n\n\n\n<p>When the purpose of the container is served, it&#8217;s better to remove it. Because a lot of 1 GB containers are gonna eat up huge space. Remove images too, that are not in use.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background\">docker container prune # Removes all the stopped containers\ndocker rm <code>docker ps -aq<\/code> # Removes all the stopped containers (alternative)\n<\/pre>\n\n\n\n<p>You can check the amount of space that can be reclaimed due to unused images, run <\/p>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background\">docker system df<\/pre>\n\n\n\n<p>Delete images with command<\/p>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background\">docker image rm 9c -f\ndocker rmi 9c # Removes and untags images from the host<\/pre>\n\n\n\n<p>Use -f if you want to force the delete operation. Here, the reason may be that multiple images are linked together.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Want to submit your container to docker hub?<\/h2>\n\n\n\n<p>You read that right! Anyone can submit their container to docker hub for free. It can be an easy way to share your work. Someone else can easily setup your environment with a docker pull.<\/p>\n\n\n\n<p>Sign-up with dockerhub and click to create a repository. You will get this page. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"436\" src=\"https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/03\/image-2-1024x436.png\" alt=\"\" class=\"wp-image-727\" srcset=\"https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/03\/image-2-1024x436.png 1024w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/03\/image-2-300x128.png 300w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/03\/image-2-768x327.png 768w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/03\/image-2-640x273.png 640w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/03\/image-2.png 1319w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>With the free version, only 1 repo can be created. But obviously, you can use multiple tags to different images that you want to upload.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">You dont want the hassle of uploading to dockerhub?<\/h2>\n\n\n\n<p>Lets say , You built a web application that you wanna share with your friends. When your container is up and running with all the desired stuff, you just need to save the state of your container. Wondering how to do that?! Its just a command away.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background\">docker commit &lt;running-container-id&gt; image-name:tag<\/pre>\n\n\n\n<p>This command will create a new image from the base image that you had chosen to build your application. <\/p>\n\n\n\n<p>Note: Everything in docker is layered. When a new image is committed, new layers are added to the existing ones.<\/p>\n\n\n\n<p>Now once you have the new image, you can directly push it to docker hub. <\/p>\n\n\n\n<p>You can also create a tag TARGET_IMAGE that refers to SOURCE_IMAGE<\/p>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background\">docker tag source_imag:tag target_img:tag<\/pre>\n\n\n\n<p>Now simply run a docker push command to push to docker registry.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background\">docker push target_img:tag<\/pre>\n\n\n\n<p>When you own a private repository, the hostname has to be preceded in the docker tag and docker push command. Example:- docker push example.com\/target_img:tag<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">From image to tar file<\/h2>\n\n\n\n<p>Do you know, you can also convert an image to a tar file and move it around like a normal file? The command below makes it possible<\/p>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background\">docker save myimage:latest &gt; myimage.tar<\/pre>\n\n\n\n<p>Similarly, you can load an image from the tar file using<\/p>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background\">docker load --input myimage.tar<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Dealing with dockerfiles and docker-compose.yaml?<\/h2>\n\n\n\n<p>Dockerfiles are just like the script files that will just run whole thing in a go. Anyone with a dockerfile can replicate your whole container. Much handy than the tar file right?!<\/p>\n\n\n\n<p>docker-compose file come into play when your environement requires more than one service (ie more than one container). In compose files, you basically specify the configurations corresponding to different containers that will be spawned up like env variables, port mappings, volume mappings. <\/p>\n\n\n\n<p>To build an image from dockerfile, run<\/p>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background\">docker build -t myimage .<\/pre>\n\n\n\n<p>The &#8220;dot&#8221; corresponds to the path of the dockerfile ie the current working directory.<\/p>\n\n\n\n<p>Then following commands are generally used with the docker-compose files<\/p>\n\n\n\n<pre class=\"wp-block-preformatted wpf-blue-background\">docker-compose build   # builds images from corresponding dockerfiles\ndocker-compose up   # Starts the comtainers\ndocker-compose down   # Stops the containers\ndocker-compose down --remove-orphans # Remove containers for services not defined in the compose file<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Mistakes I made while creating challenges.<\/h2>\n\n\n\n<p>Let&#8217;s suppose, you want to create a challenge that requires the use of ssh service.<\/p>\n\n\n\n<p>Initially, I made the mistake of choosing the standard images like ubuntu (for docker) and I used to install ssh using the package manager apt. If I had a requirement for another service like http, I used to install it again with apt on the same container of ubuntu and saved the state as the final image.<\/p>\n\n\n\n<p>Everything works fine in the above scenario, only if you have a shell inside the container. In the cases, when you are required to automate the whole process, this approach won&#8217;t really work. Automation as in that you have a dockerfile or a newly committed image and you should just be able to run the container without any additional docker exec commands. If your application requires you to execute commands after running the container from the image, that means that you did something wrong in the configuration. I&#8217;ll explain why these commands fail while automating stuff.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Reason<\/h3>\n\n\n\n<p>After the completion of the main process, the container exits. The scripts that are run in Dockerfile&#8217;s CMD are written such that it wont run forever. And a container requires some foreground process to be running continuously in order to be in a running state. There are a lot of fixes available <span class=\"has-inline-color has-vivid-cyan-blue-color\"><a aria-label=\"undefined (opens in a new tab)\" href=\"https:\/\/stackoverflow.com\/questions\/28212380\/why-docker-container-exits-immediately#:~:text=you%20are%20basically%20running%20the,container%20with%20the%20above%20command.\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a><\/span>, but I don&#8217;t find it to be the best way to do things.<\/p>\n\n\n\n<p>If you still want to enclose everything in a single container, follow up this post- https:\/\/docs.docker.com\/config\/containers\/multi-service_container\/<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The correct way<\/h2>\n\n\n\n<p>If your challenge involves multiple services, the correct wayout is to have a <strong>separate container for each service<\/strong>. The base images of these services on dockerhub are built such that on the creation of the container , corresponding services are automatically started.<\/p>\n\n\n\n<p>For web service we require httpd image from the dockerhub. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"711\" height=\"283\" src=\"https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/03\/image-1.png\" alt=\"\" class=\"wp-image-723\" srcset=\"https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/03\/image-1.png 711w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/03\/image-1-300x119.png 300w, https:\/\/shreyapohekar.com\/blogs\/wp-content\/uploads\/2021\/03\/image-1-640x255.png 640w\" sizes=\"(max-width: 711px) 100vw, 711px\" \/><\/figure>\n\n\n\n<p>You can choose from various tags are available for httpd that matches your  requirements. Always go through the documentation for any service image that you wanna pull. It gives a lot of information about the usage of the image!<\/p>\n\n\n\n<p>You can enable networking between all of your services using docker-compose files. It binds all the containers and gives you a single environment. I will cover the dockerfile and docker-compose file essentials in the follow-up post.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Images to use when you create your applications<\/h2>\n\n\n\n<p>I found that some of the popular dockerhub images were creating configurational problems while i was implementing them into challenges<\/p>\n\n\n\n<p>I want to collate a list of all the docker images that i used for different services.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Mysql<\/strong> : <a aria-label=\"undefined (opens in a new tab)\" href=\"https:\/\/hub.docker.com\/_\/mariadb\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/hub.docker.com\/_\/mariadb<\/a>  [The mysql dockerhub image has got some limitations like I faced troubles while setting up the root password for db]. Mariadb image is much stable in every situation.<\/li><li><strong>http <\/strong>: <a aria-label=\"undefined (opens in a new tab)\" href=\"https:\/\/hub.docker.com\/_\/httpd\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/hub.docker.com\/_\/httpd<\/a> [Choose from the enormous tag that is apt for your use-case]<\/li><li><strong>ssh <\/strong>: <a aria-label=\"undefined (opens in a new tab)\" href=\"https:\/\/hub.docker.com\/r\/rastasheep\/ubuntu-sshd\/dockerfile\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/hub.docker.com\/r\/rastasheep\/ubuntu-sshd\/dockerfile <\/a><ul><li>The default image (openssh-server) didn&#8217;t served my purpose. I had to create new users, set suid bit on a binary, and had to make sure that any file doesn&#8217;t get deleted (esp flag.txt).  <\/li><\/ul><\/li><li><strong>tomcat<\/strong>: <a aria-label=\"undefined (opens in a new tab)\" href=\"https:\/\/hub.docker.com\/_\/tomcat\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/hub.docker.com\/_\/tomcat<\/a> [Choose from the various tags that serves your purpose]<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">What not to use while building upon docker<\/h2>\n\n\n\n<p>Unless its too urgent, try avoiding the use of ftp docker image. Why? The way that service works in docker takes a lot of open ports as a pre-requisite.  And having a lot of open ports is a bad thing&#8230;.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Epilogue<\/h2>\n\n\n\n<p>I hope you learned something new today around docker and would have learned from my mistakes. I will continue to post my findings on docker. Comment, if you prefer to learn about any specific topic.<\/p>\n\n\n\n<p>Thats all for this blog post! Hit like button if you enjoyed reading the post!<\/p>\n\n\n\n<p>See you in the next one! Until then, happy learning!!!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Docker can never replace a VM but it has got its own special benefits. know more about the docker features<\/p>\n","protected":false},"author":1,"featured_media":729,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ocean_post_layout":"","ocean_both_sidebars_style":"","ocean_both_sidebars_content_width":0,"ocean_both_sidebars_sidebars_width":0,"ocean_sidebar":"","ocean_second_sidebar":"","ocean_disable_margins":"enable","ocean_add_body_class":"","ocean_shortcode_before_top_bar":"","ocean_shortcode_after_top_bar":"","ocean_shortcode_before_header":"","ocean_shortcode_after_header":"","ocean_has_shortcode":"","ocean_shortcode_after_title":"","ocean_shortcode_before_footer_widgets":"","ocean_shortcode_after_footer_widgets":"","ocean_shortcode_before_footer_bottom":"","ocean_shortcode_after_footer_bottom":"","ocean_display_top_bar":"default","ocean_display_header":"default","ocean_header_style":"","ocean_center_header_left_menu":"","ocean_custom_header_template":"","ocean_custom_logo":0,"ocean_custom_retina_logo":0,"ocean_custom_logo_max_width":0,"ocean_custom_logo_tablet_max_width":0,"ocean_custom_logo_mobile_max_width":0,"ocean_custom_logo_max_height":0,"ocean_custom_logo_tablet_max_height":0,"ocean_custom_logo_mobile_max_height":0,"ocean_header_custom_menu":"","ocean_menu_typo_font_family":"","ocean_menu_typo_font_subset":"","ocean_menu_typo_font_size":0,"ocean_menu_typo_font_size_tablet":0,"ocean_menu_typo_font_size_mobile":0,"ocean_menu_typo_font_size_unit":"px","ocean_menu_typo_font_weight":"","ocean_menu_typo_font_weight_tablet":"","ocean_menu_typo_font_weight_mobile":"","ocean_menu_typo_transform":"","ocean_menu_typo_transform_tablet":"","ocean_menu_typo_transform_mobile":"","ocean_menu_typo_line_height":0,"ocean_menu_typo_line_height_tablet":0,"ocean_menu_typo_line_height_mobile":0,"ocean_menu_typo_line_height_unit":"","ocean_menu_typo_spacing":0,"ocean_menu_typo_spacing_tablet":0,"ocean_menu_typo_spacing_mobile":0,"ocean_menu_typo_spacing_unit":"","ocean_menu_link_color":"","ocean_menu_link_color_hover":"","ocean_menu_link_color_active":"","ocean_menu_link_background":"","ocean_menu_link_hover_background":"","ocean_menu_link_active_background":"","ocean_menu_social_links_bg":"","ocean_menu_social_hover_links_bg":"","ocean_menu_social_links_color":"","ocean_menu_social_hover_links_color":"","ocean_disable_title":"default","ocean_disable_heading":"default","ocean_post_title":"","ocean_post_subheading":"","ocean_post_title_style":"","ocean_post_title_background_color":"","ocean_post_title_background":0,"ocean_post_title_bg_image_position":"","ocean_post_title_bg_image_attachment":"","ocean_post_title_bg_image_repeat":"","ocean_post_title_bg_image_size":"","ocean_post_title_height":0,"ocean_post_title_bg_overlay":0.5,"ocean_post_title_bg_overlay_color":"","ocean_disable_breadcrumbs":"default","ocean_breadcrumbs_color":"","ocean_breadcrumbs_separator_color":"","ocean_breadcrumbs_links_color":"","ocean_breadcrumbs_links_hover_color":"","ocean_display_footer_widgets":"default","ocean_display_footer_bottom":"default","ocean_custom_footer_template":"","ocean_post_oembed":"","ocean_post_self_hosted_media":"","ocean_post_video_embed":"","ocean_link_format":"","ocean_link_format_target":"self","ocean_quote_format":"","ocean_quote_format_link":"post","ocean_gallery_link_images":"on","ocean_gallery_id":[],"footnotes":""},"categories":[294,2],"tags":[204,67,300,304,302,301,303,305],"class_list":["post-719","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cloud","category-information-security","tag-containers","tag-docker","tag-docker-commands","tag-docker-image","tag-docker-compose","tag-dockerfile","tag-dockerhub","tag-play-with-docker","entry","has-media"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/shreyapohekar.com\/blogs\/wp-json\/wp\/v2\/posts\/719"}],"collection":[{"href":"https:\/\/shreyapohekar.com\/blogs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/shreyapohekar.com\/blogs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/shreyapohekar.com\/blogs\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/shreyapohekar.com\/blogs\/wp-json\/wp\/v2\/comments?post=719"}],"version-history":[{"count":6,"href":"https:\/\/shreyapohekar.com\/blogs\/wp-json\/wp\/v2\/posts\/719\/revisions"}],"predecessor-version":[{"id":730,"href":"https:\/\/shreyapohekar.com\/blogs\/wp-json\/wp\/v2\/posts\/719\/revisions\/730"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/shreyapohekar.com\/blogs\/wp-json\/wp\/v2\/media\/729"}],"wp:attachment":[{"href":"https:\/\/shreyapohekar.com\/blogs\/wp-json\/wp\/v2\/media?parent=719"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/shreyapohekar.com\/blogs\/wp-json\/wp\/v2\/categories?post=719"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/shreyapohekar.com\/blogs\/wp-json\/wp\/v2\/tags?post=719"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}