{"id":3871,"date":"2023-09-01T19:59:12","date_gmt":"2023-09-01T19:59:12","guid":{"rendered":"https:\/\/geekmungus.co.uk\/?p=3871"},"modified":"2023-09-01T19:59:13","modified_gmt":"2023-09-01T19:59:13","slug":"docker-basics","status":"publish","type":"post","link":"https:\/\/geekmungus.co.uk\/?p=3871","title":{"rendered":"Docker Basics"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Containerisation is an increasingly popular method to deploy and run applications on both your computer but also for enterprise applications. Containerisation essentially bundles an application&#8217;s code with all the files and libraries it needs to run.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Having a layer of abstraction like this means that as long as you are running the same Operating System, then everything else is essentially taken care of, meaning you don&#8217;t need to worry about matching loads of different dependencies, packages and libraries within the environment that your application runs, that is all taken care of by the container.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In my previous article: <a href=\"https:\/\/geekmungus.co.uk\/?p=3851\" data-type=\"link\" data-id=\"https:\/\/geekmungus.co.uk\/?p=3851\">Docker Install on Ubuntu 22.04.2 LTS<\/a> we went through the installation of Docker on a Linux machine, in this article we&#8217;ll go into more depth <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Running a Docker Container<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s start with a simple example. We first need to create the container, to do this we&#8217;ll run the following command to create the hello-world container. Note that this does not run the container, it just retrieves it from the image registry (more on this later) and readies it to be run.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker container create hello-world:linux<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">All being well you should see an alphanumeric string showing that it has been downloaded and saved successfully.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s run the following, it will normally show running containers, in our case we&#8217;ve not started any; but we&#8217;ve added the &#8220;-a&#8221; so it will show all containers running or otherwise.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker ps -a<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And in the output we can see:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ubuntu@development:~$ docker ps -a\nCONTAINER ID   IMAGE                 COMMAND                  CREATED              STATUS                     PORTS     NAMES\n5625528d15d8   hello-world:linux     \"\/hello\"                 About a minute ago   Created                              romantic_snyder\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Cool, that&#8217;s showing its created and ready, so lets run our container now. There&#8217;s three things you can do here, you can start the container with the terminal attached, or you can start the container without the terminal attached, but that means you need to examine the logs to see the output. Or you can use Docker Run to create the container, run it and attach to the terminal.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Option 1 &#8211; Run Container without Terminal Attached<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">From the previous output take the Container ID, and run the following:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker container start 5625528d15d8<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Assuming it runs okay, all you&#8217;ll get is that Container ID echoed back to you. To see what actually happened we then need to examine the logs with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker logs 5625528d15d8<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And we get the output as follows:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"590\" height=\"343\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/08\/image-1.png\" alt=\"\" class=\"wp-image-3876\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/08\/image-1.png 590w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/08\/image-1-300x174.png 300w\" sizes=\"auto, (max-width: 590px) 100vw, 590px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Option 2 &#8211; Run Container with Terminal Attached<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The other approach is to run the container with the terminal attached as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker container start --attach 5625528d15d8<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"576\" height=\"343\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/08\/image-2.png\" alt=\"\" class=\"wp-image-3878\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/08\/image-2.png 576w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/08\/image-2-300x179.png 300w\" sizes=\"auto, (max-width: 576px) 100vw, 576px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">As you can see in this case the output is put straight to the screen, which option you choose, well, that is down to what your application needs.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Option 3 &#8211; Use Docker Run<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>docker run hello-world:linux<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">As you&#8217;ll see with this you&#8217;ll get the result printed to the terminal. You&#8217;ll also notice that you didn&#8217;t need to refer to the Container ID, but what &#8220;Docker Run&#8221; does is to create the container and run it, which means you&#8217;ll end up with a number of containers created which you can see with &#8220;docker ps -a&#8221;, for example:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"88\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/08\/image-3-1024x88.png\" alt=\"\" class=\"wp-image-3880\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/08\/image-3-1024x88.png 1024w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/08\/image-3-300x26.png 300w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/08\/image-3-768x66.png 768w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/08\/image-3.png 1044w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Running a Container in the Background<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To run a container in the background use the below, referring to the Container ID from the examples above.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker run -d 5625528d15d8<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Viewing Running Containers<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To see containers as they are running you can use &#8220;docker ps&#8221;, this shows you containers that are currently running.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker ps<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Cleaning-Up Old Containers<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Okay, so we&#8217;ve run a few containers and there&#8217;s a few of them starting to build up, we want to clear these away now, as they aren&#8217;t needed anymore.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So first run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker ps -a<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then get the Container ID of the container you wish to delete, the container needs to be stop to run this.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker rm &lt;Container ID&gt;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">(Add a &#8220;-f&#8221;, so &#8220;docker rm -f &lt;Container ID&gt;&#8221; to remove a running container.)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Stopping a Container<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To stop a running container, you first obtain the Container ID, then run the following to stop the container from running.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker stop &lt;Container ID&gt;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">(Add a &#8220;-t&#8221; to force stop the container)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Creating Your Own Docker Container<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s create a simple web-server container, so we can use it across the network in the following section. We&#8217;re not running Apache or the like, instead we&#8217;ll just use netcat to return a page to illustrate the point.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Creating a Docker container, requires that you create a Dockerfile that specifies what the container will look like, i.e. what packages are needed and so forth in the form of an image. You then also need a specify the &#8220;Entrypoint&#8221; which is what is started when the container starts (in simple terms).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>nc-web-server.Dockerfile<\/em><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>FROM ubuntu\n\nUSER root\nCOPY .\/nc-web-server.bash \/\n\nRUN chmod 755 \/nc-web-server.bash\nRUN apt -y update\nRUN apt -y install bash netcat\n\nUSER nobody\n\nENTRYPOINT &#91; \"\/nc-web-server.bash\" ]<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Once created we now need to create the bash file that essentially behaves like a web server by responding to a request using netcat (nc) and gives a simple HTML page in response.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>nc-web-server.bash<\/em><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/usr\/bin\/env bash\n\nwebserver() {\n  echo \"Netcat Web Server ready, access: http:\/\/localhost:5000 or http:\/\/&lt;Server IP&gt;:5000\"\n  \n  serveroutput=$(echo \"&lt;html&gt;&lt;body&gt;&lt;p&gt;Web Site Output: $(date)&lt;\/p&gt;&lt;\/body&gt;&lt;\/html&gt;\")\n  \n  length=$(wc -c &lt;&lt;&lt; \"$serveroutput\")\n  \n  content=\"\\\nHTTP\/1.1 200 OK\nContent-Length: $((length-1))\n\n$serveroutput\"\n  \n  while true\n  do echo -ne \"$content\" | nc -l -p 5000\n  done\n}\n\nwebserver<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now we can build the Docker container image with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker build -t nc-web-server -f nc-web-server.Dockerfile .<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s quickly explore this. So the &#8220;-t&#8221; names the image, the &#8220;-f&#8221; specifies the Dockerfile with the instructions to build the image, the full stop afterwards specifies the working directory of the build command, in this case the current directory (i.e. &#8220;.&#8221;) where it will be able to find the nc-web-server.bash file which is needed for the build.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Once completed run the following to show the list of images:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker images<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And there you can see the image has been created successfully and is ready to be run.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"549\" height=\"50\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/08\/image-4.png\" alt=\"\" class=\"wp-image-3888\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/08\/image-4.png 549w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/08\/image-4-300x27.png 300w\" sizes=\"auto, (max-width: 549px) 100vw, 549px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Running a Docker Container and Accessing Across the Network<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In this example, we have a web server container called &#8220;nc-web-server&#8221;, the container is configured to listen on port 5000\/TCP, however we need to expose it to the outside world, i.e. expose it to your local network and to do that on another port. So when we run it we need to specify the ports with &#8220;-p&#8221;, so the format is <em>Outside Port:Inside Port<\/em> and in this case: 8080:5000.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker run -d -p 8080:5000 nc-web-server<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Once run, we should find that the web server is now listening on port 8080 on your machine&#8217;s IP address, in my case my machine&#8217;s IP address is 192.168.1.6, but in the below you can see its listening on 0.0.0.0:8080, what this means is any IP address on your machine.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"49\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/08\/image-5-1024x49.png\" alt=\"\" class=\"wp-image-3892\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/08\/image-5-1024x49.png 1024w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/08\/image-5-300x14.png 300w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/08\/image-5-768x36.png 768w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/08\/image-5.png 1054w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Now let&#8217;s access the web server with a web browser&#8230;..and bingo, we&#8217;re in.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"437\" height=\"153\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/08\/image-6.png\" alt=\"\" class=\"wp-image-3893\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/08\/image-6.png 437w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/08\/image-6-300x105.png 300w\" sizes=\"auto, (max-width: 437px) 100vw, 437px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">We now have our simple web server running in a docker container on our machine. Of course this is just an example, but you can see how this could be very useful. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Imagine you have your web application within a Docker container, its currently running v1.0, you want to upgrade to v1.1, all you need to do is prepare a new container, test it, and when you&#8217;re ready swap the containers over; if you find a problem, just swap it back again!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Persistence<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">So having a Docker container that you can just run and stop is fine, but what if you need data (files) to persist between you stopping and starting a container. Perhaps you want the container to pull in files as it starts, or you want it to perform an action and write a result for some future container to be able to use. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">No problem, that&#8217;s where persistence comes in. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There are two ways to do this which we&#8217;ll explore in this section.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Mount a Local Directory<\/li>\n\n\n\n<li>Using Docker Volumes<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Option 1 &#8211; Mount a Local Directory<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s run a basic Ubuntu container in this way and get it to echo some data to a file, which we&#8217;ll want to  persist after the container has finished running. Now, in your home directory on your machine, let&#8217;s create a directory which we&#8217;ll present within our container when it runs.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir ~\/cont-data\ncd ~\/cont-data\n\ndocker run --rm --entrypoint sh -v \/home\/ubuntu\/cont-data:\/tmp ubuntu -c \"echo 'Persistent data' &gt; \/tmp\/persist &amp;&amp; cat \/tmp\/persist\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Okay so let&#8217;s examine the command above. The main part is the <em>&#8220;-v \/home\/ubuntu\/cont-data:\/tmp&#8221; <\/em>argument, what this means is that the directory on our machine i.e. the <strong>\/home\/ubuntu\/cont-data<\/strong> is being mapped to the <strong>\/tmp <\/strong>directory within the container.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And what we can find is that there is a file within our home directory <strong>\/home\/ubuntu\/cont-data<\/strong> called &#8220;persist&#8221; which has the &#8220;Persistent data&#8221; text string within it. And this persists after the container finishes running.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It&#8217;s also worth noting that this is a 2 way synchronised directory. i.e. the file changed on the host is changed within what the container can see and vice versa.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Option 2 &#8211; Using Docker Volumes<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Another way to do this is to use a Docker Volume, this is similar to the previous method except you&#8217;re created an abstracted volume rather than just presenting a directory (into the container), thus allowing more separation from the host&#8217;s specifics (which may or may not exist). <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The Docker Volume is also isolated from the host&#8217;s storage. If you need a persistent place to store data going to and from your container, but without needing to be seen or changed by your host system, this is an approach you can use.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker volume create mydockervol<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then run the container and this time rather than specifying a path (after the -v) you specify the name of the Docker volume, as so:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">docker run &#8211;rm &#8211;entrypoint sh -v mydockervol:\/tmp ubuntu -c &#8220;echo &#8216;Persistent data&#8217; &gt; \/tmp\/persist &amp;&amp; cat \/tmp\/persist&#8221;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s see what it did:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker volume ls<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And there you can see the Docker volume has been created:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ubuntu@development:~\/cont-data$ docker volume ls\nDRIVER    VOLUME NAME\nlocal     mydockervol\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If we wanted to see the actual data, we first need to find where the data really is with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ubuntu@development:~\/cont-data$ docker volume inspect mydockervol\n&#91;\n    {\n        \"CreatedAt\": \"2023-08-31T21:12:24+01:00\",\n        \"Driver\": \"local\",\n        \"Labels\": null,\n        \"Mountpoint\": \"\/var\/lib\/docker\/volumes\/mydockervol\/_data\",\n        \"Name\": \"mydockervol\",\n        \"Options\": null,\n        \"Scope\": \"local\"\n    }\n]\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then with sudo we can actually show the directory and inspect the file within.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ sudo -s\n# cd \/var\/lib\/docker\/volumes\/mydockervol\/_data\n# ls -la\ntotal 12\ndrwxrwxrwt 2 root root 4096 Aug 31 21:12 .\ndrwx-----x 3 root root 4096 Aug 31 21:12 ..\n-rw-r--r-- 1 root root   16 Aug 31 21:12 persist<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To delete the Docker volume all you need to run is a cheeky:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker volume rm mydockervol<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Docker Container Registry<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A container image registry is a service that allows you to store images that you can then call upon and run the container at a later date. The Container image tags consists of its name, a colon and then its version (and it defaults to &#8220;latest&#8221; if no version number is provided.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Docker Hub is a registry you can use with the Docker. I&#8217;m going to assume that you&#8217;ve already setup a Docker Hub account, so if you&#8217;ve not done that go and do that now.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Login to Docker from Docker CLI<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">To login run the following, enter your Docker Hub username and password:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker login<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The credentials are saved into your home directory for future use.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Push an Image to the Registry<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">We&#8217;ll take the image and then rename it, then we can upload it to the Docker Hub registry.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker tag nc-web-server geekmungus\/nc-web-server:1.0.0\n\ndocker push geekmungus\/nc-web-server:1.0.0<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You&#8217;ll now see it start to upload:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ubuntu@development:~$ docker tag nc-web-server geekmungus\/nc-web-server:1.0.0\r\nubuntu@development:~$ docker push geekmungus\/nc-web-server:1.0.0\r\nThe push refers to repository &#91;docker.io\/geekmungus\/nc-web-server]\r\n5ebe31cc7a4e: Pushed\r\nd96d02bfe339: Pushing &#91;===============>                                   ]  12.71MB\/40.25MB\r\n5634744e4c7d: Pushed\r\n2182c773bb4b: Pushed\r\n1b9698f962dc: Mounted from library\/ubuntu\r<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">When completed, we can then see it in the registry, ready for use.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"693\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/09\/image-1024x693.png\" alt=\"\" class=\"wp-image-3898\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/09\/image-1024x693.png 1024w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/09\/image-300x203.png 300w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/09\/image-768x520.png 768w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/09\/image-305x207.png 305w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/09\/image-622x420.png 622w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/09\/image.png 1107w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">If you want to upload a new version, just tag the image with an updated version number and then upload, for example <strong>geekmungus\/nc-web-server:1.0.1<\/strong> in my case.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Pull an Image from the Registry<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In this final task, we&#8217;ll pull an image from the registry. To ensure the (nc-web-server) image is not present in the local cache, we&#8217;ll delete it, we may need to stop the running container first, but then we&#8217;ll be able to pull down a new copy.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Firstly run &#8220;docker ps&#8221; and get the Container ID of any container that is using the nc-web-server image, then run the following command to stop it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker stop &lt;Container ID><\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now delete the image:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker images\ndocker rmi &lt;Image Name><\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><em>(e.g. &#8220;docker rmi nc-web-server&#8221; or &#8220;docker rmi geekmungus\/nc-web-server&#8221;)<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Right now we can pull down the image, let&#8217;s pull down the latest nc-web-server image we pushed up, so the image: <strong>geekmungus\/nc-web-server:1.0.1<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ubuntu@development:~$ docker pull geekmungus\/nc-web-server:1.0.1\r\n1.0.1: Pulling from geekmungus\/nc-web-server\r\ndb76c1f8aa17: Already exists\r\n978d20ea8b1d: Already exists\r\n639eb43d03dd: Already exists\r\n4f45d942f960: Already exists\r\n92c89c6f91e2: Already exists\r\nDigest: sha256:aaa4c84cf3273203a1e9acc96342bc437d200d63b482395f5c852f941bd9ba4a\r\nStatus: Downloaded newer image for geekmungus\/nc-web-server:1.0.1\r\ndocker.io\/geekmungus\/nc-web-server:1.0.1\n\r\nubuntu@development:~$ docker images\r\nREPOSITORY                    TAG       IMAGE ID       CREATED        SIZE\r\ngeekmungus\/nc-web-server      1.0.1     0f51daf29ec1   3 days ago     111MB\r\nubuntu                        latest    a2f229f811bf   4 weeks ago    69.2MB\r<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And there you go its been downloaded, and is available, for a quick test, lets fire up that container again:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker run -d -p 8080:5000 geekmungus\/nc-web-server:1.0.1<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check it is running:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ubuntu@development:~$ docker ps\r\nCONTAINER ID   IMAGE                            COMMAND                 CREATED         STATUS         PORTS                                       NAMES\r\n47e9b96e1b17   geekmungus\/nc-web-server:1.0.1   \"\/nc-web-server.bash\"   5 seconds ago   Up 4 seconds   0.0.0.0:8080->5000\/tcp, :::8080->5000\/tcp   kind_almeida\r<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And we can access the website:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"392\" height=\"134\" src=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/09\/image-1.png\" alt=\"\" class=\"wp-image-3900\" srcset=\"https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/09\/image-1.png 392w, https:\/\/geekmungus.co.uk\/wp-content\/uploads\/2023\/09\/image-1-300x103.png 300w\" sizes=\"auto, (max-width: 392px) 100vw, 392px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">We&#8217;ve seen how to run some Docker containers to use functions of these applications, wrapping your application up in its own container can be very helpful in terms of deployment (you don&#8217;t have to worry about building the exact environment for the application to run in), but also in terms of its support and operation in the long term. For example, if you&#8217;re running your version 1.0 and want to upgrade to version 1.2, previously this would require a re-installation of the application, if anything went wrong rolling back the change may be very difficult; however with a container, you just stop the version 1.2 container and start the version 1.0 container again.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When you&#8217;re running at enterprise scale you&#8217;ll be using something like Docker Swarm or Kubernetes to manage the orchestration of containers and running them in a manageable way.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Stay tuned for further containerisation articles in future.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/unsplash.com\/@live_for_photo\" data-type=\"link\" data-id=\"https:\/\/unsplash.com\/@live_for_photo\">Image Attribution<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Containerisation is an increasingly popular method to deploy and run applications on both your computer but also for enterprise applications. Containerisation essentially bundles an application&#8217;s code with all the files and libraries it needs to run. Having a layer of abstraction like this means that as long as you are running the same Operating System, &#8230; <a title=\"Docker Basics\" class=\"read-more\" href=\"https:\/\/geekmungus.co.uk\/?p=3871\" aria-label=\"Read more about Docker Basics\">Read more<\/a><\/p>\n","protected":false},"author":4,"featured_media":3873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[46],"tags":[],"class_list":["post-3871","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-docker"],"_links":{"self":[{"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/3871","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3871"}],"version-history":[{"count":21,"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/3871\/revisions"}],"predecessor-version":[{"id":3901,"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/3871\/revisions\/3901"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=\/wp\/v2\/media\/3873"}],"wp:attachment":[{"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3871"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3871"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/geekmungus.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3871"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}