<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>docker Archives - Tech Chronicles</title>
	<atom:link href="http://kostacipo.stream/tag/docker/feed/" rel="self" type="application/rss+xml" />
	<link>http://kostacipo.stream/tag/docker/</link>
	<description>Ramblings of a Tech Dude</description>
	<lastBuildDate>Mon, 23 Jan 2023 19:20:11 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.2</generator>

<image>
	<url>https://kostacipo.stream/wp-content/uploads/2019/12/cropped-profile-32x32.jpg</url>
	<title>docker Archives - Tech Chronicles</title>
	<link>http://kostacipo.stream/tag/docker/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Using Wazuh for Docker Container Monitoring</title>
		<link>http://kostacipo.stream/using-wazuh-for-docker-container-monitoring/</link>
					<comments>http://kostacipo.stream/using-wazuh-for-docker-container-monitoring/#respond</comments>
		
		<dc:creator><![CDATA[Majordomo]]></dc:creator>
		<pubDate>Mon, 23 Jan 2023 19:20:11 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[container monitoring]]></category>
		<category><![CDATA[docker]]></category>
		<guid isPermaLink="false">https://kostacipo.stream/?p=2142</guid>

					<description><![CDATA[<p>In the last few years, container utilization to build, share, and run applications has grown significantly. This growth comes from the fact that containers give developers the ability to package application code and all its dependencies. Also, with containers, users can gain an extra layer of security thanks to the isolation capabilities it provides. The [&#8230;]</p>
<p>The post <a href="http://kostacipo.stream/using-wazuh-for-docker-container-monitoring/">Using Wazuh for Docker Container Monitoring</a> appeared first on <a href="http://kostacipo.stream">Tech Chronicles</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In the last few years, container utilization to build, share, and run applications has grown significantly. This growth comes from the fact that containers give developers the ability to package application code and all its dependencies. Also, with containers, users can gain an extra layer of security thanks to the isolation capabilities it provides. The introduction of Docker containers has paved the way for many organizations to easily host applications within containers. Docker containers are standardized, lightweight, and secure runtime instances of a Docker image.</p>
<p>Containers out-of-the-box do not provide security monitoring. Therefore, it is important to have a comprehensive view of what is happening in runtime. This ensures that containers operate smoothly without security issues that can easily affect other containers and the entire infrastructure. Some security aspects to continuously watch out for when running Docker containers are:</p>
<ul>
<li aria-level="1"><b>Container management: </b>Docker container management involves supervising actions performed on a container to keep it running smoothly. Threat actors can get hold of containers and perform malicious activities such as viewing critical content, opening ports, creating, stopping or even destroying containers. Ability to distinguish unusual Docker events can be challenging. Observing these actions in near real-time as they occur can help organizations running Docker containers make better informed decisions.</li>
</ul>
<ul>
<li aria-level="1"><b>Container resource consumption: </b>Monitoring the performance of a container provides insight into its resource utilization. Some core resources include CPU, memory, disk, and network traffic. With resource monitoring, organizations can track container resource consumption and set measures to increase efficiency. These actions prevent imbalances of container resources in Dockerized infrastructures. Additionally, it allows better visibility of infrastructures in the event of a security incident.</li>
</ul>
<ul>
<li aria-level="1"><b>Container health: </b>Container health checks aid an organization in knowing its workload availability. The health status of a container is different from its actual state of operation. For example, a container can run while a web server running in the container may be down and unable to handle requests. This can be due to an attack that, if not monitored, can persist and cause damage to an organization. Monitoring the health status of a container helps to reduce an attack surface and prevent anomalies in the container.</li>
</ul>
<p>Organizations need to identify and resolve threats quickly and proactively to avoid risks of compromise. For this, keeping track of the above criteria is indispensable and can be accomplished through the use of security monitoring solutions.</p>
<h1>Using Wazuh for container monitoring</h1>
<p><a href="https://wazuh.com/" target="_blank" rel="noopener">Wazuh</a> is an open source security platform with unified XDR and SIEM capabilities. Its architecture comprises the Wazuh central components (server, indexer, and dashboard) and a universal agent. The solution provides protection for devices in clouds and on-premises infrastructures. Wazuh has many features ranging from container monitoring, file integrity monitoring, vulnerability detection, security configuration assessment, and more. Wazuh is multi-platform and expands its flexibility through integration with other security solutions.</p>
<p>Figure 1 below shows an example of real-time monitoring of Docker containers using Wazuh.</p>
<p style="text-align: center;"><a href="https://hakin9.org/wp-content/uploads/2022/11/Figure-1-1.png"><img fetchpriority="high" decoding="async" class="wp-image-245480 aligncenter" src="https://hakin9.org/wp-content/uploads/2022/11/Figure-1-1.png" sizes="(max-width: 991px) 100vw, 991px" srcset="https://hakin9.org/wp-content/uploads/2022/11/Figure-1-1.png 1257w, https://hakin9.org/wp-content/uploads/2022/11/Figure-1-1-460x295.png 460w, https://hakin9.org/wp-content/uploads/2022/11/Figure-1-1-1024x657.png 1024w, https://hakin9.org/wp-content/uploads/2022/11/Figure-1-1-768x493.png 768w, https://hakin9.org/wp-content/uploads/2022/11/Figure-1-1-500x321.png 500w, https://hakin9.org/wp-content/uploads/2022/11/Figure-1-1-200x128.png 200w, https://hakin9.org/wp-content/uploads/2022/11/Figure-1-1-378x243.png 378w, https://hakin9.org/wp-content/uploads/2022/11/Figure-1-1-565x363.png 565w, https://hakin9.org/wp-content/uploads/2022/11/Figure-1-1-120x77.png 120w, https://hakin9.org/wp-content/uploads/2022/11/Figure-1-1-310x199.png 310w" alt="" width="991" height="637" /></a><em>Figure 1: Real-time monitoring of Docker containers using Wazuh</em></p>
<p>For the use cases below, the Wazuh agent is installed on endpoints running Docker containers. The agent collects security and runtime data from the containers and forwards it to the Wazuh server for log analysis, correlation, and alerting.</p>
<h2>Monitoring container events</h2>
<p>Wazuh has a Docker module that communicates with the Docker Engine API to gather information on Docker containers. The only configuration necessary is to enable the Docker listener module to allow us to monitor Docker events. The Wazuh dashboard in Figure 2 below shows an example of detected container events in a Docker environment.</p>
<p style="text-align: center;"><a href="https://hakin9.org/wp-content/uploads/2022/11/Figure-2.jpg"><img decoding="async" class="wp-image-245477 aligncenter" src="https://hakin9.org/wp-content/uploads/2022/11/Figure-2.jpg" sizes="(max-width: 992px) 100vw, 992px" srcset="https://hakin9.org/wp-content/uploads/2022/11/Figure-2.jpg 1910w, https://hakin9.org/wp-content/uploads/2022/11/Figure-2-460x197-1.jpg 460w, https://hakin9.org/wp-content/uploads/2022/11/Figure-2-1024x440-1.jpg 1024w, https://hakin9.org/wp-content/uploads/2022/11/Figure-2-768x330.png 768w, https://hakin9.org/wp-content/uploads/2022/11/Figure-2-1536x659-1.jpg 1536w, https://hakin9.org/wp-content/uploads/2022/11/Figure-2-500x215-1.jpg 500w, https://hakin9.org/wp-content/uploads/2022/11/Figure-2-200x86-1.jpg 200w, https://hakin9.org/wp-content/uploads/2022/11/Figure-2-378x162.png 378w, https://hakin9.org/wp-content/uploads/2022/11/Figure-2-565x243.png 565w, https://hakin9.org/wp-content/uploads/2022/11/Figure-2-120x52-1.jpg 120w, https://hakin9.org/wp-content/uploads/2022/11/Figure-2-310x133-1.jpg 310w" alt="" width="992" height="426" /></a><em>Figure 2: Docker events detected in a Docker environment</em></p>
<h2>Monitoring container resource utilization</h2>
<p>Wazuh can be used to monitor the performance of Docker containers in an endpoint.  The Wazuh command monitoring module allows you to monitor the output of specific commands and trigger alerts accordingly. This gives organizations a clear view of the container for abnormal activities. The Wazuh dashboard in Figure 3 below shows the CPU, memory, and network traffic consumption of containers in an endpoint.</p>
<p style="text-align: center;"><a href="https://hakin9.org/wp-content/uploads/2022/11/Figure-3.png"><img decoding="async" class=" wp-image-245478 aligncenter" src="https://hakin9.org/wp-content/uploads/2022/11/Figure-3.png" sizes="(max-width: 991px) 100vw, 991px" srcset="https://hakin9.org/wp-content/uploads/2022/11/Figure-3.png 1904w, https://hakin9.org/wp-content/uploads/2022/11/Figure-3-460x150.png 460w, https://hakin9.org/wp-content/uploads/2022/11/Figure-3-1024x335.png 1024w, https://hakin9.org/wp-content/uploads/2022/11/Figure-3-768x251.png 768w, https://hakin9.org/wp-content/uploads/2022/11/Figure-3-1536x502.png 1536w, https://hakin9.org/wp-content/uploads/2022/11/Figure-3-500x163.png 500w, https://hakin9.org/wp-content/uploads/2022/11/Figure-3-200x65.png 200w, https://hakin9.org/wp-content/uploads/2022/11/Figure-3-378x123.png 378w, https://hakin9.org/wp-content/uploads/2022/11/Figure-3-565x185.png 565w, https://hakin9.org/wp-content/uploads/2022/11/Figure-3-120x39.png 120w, https://hakin9.org/wp-content/uploads/2022/11/Figure-3-310x101.png 310w" alt="" width="991" height="324" /></a><em>Figure 3: Resource consumption of containers in a Docker environment</em></p>
<h2>Monitoring container health</h2>
<p>The Wazuh command monitoring module is used to monitor the health status of containers in Dockerized environments. Figure 4 below shows the health status of containers running on an endpoint.</p>
<p style="text-align: center;"><a href="https://hakin9.org/wp-content/uploads/2022/11/Figure-4.png"><img loading="lazy" decoding="async" class=" wp-image-245479 aligncenter" src="https://hakin9.org/wp-content/uploads/2022/11/Figure-4.png" sizes="auto, (max-width: 992px) 100vw, 992px" srcset="https://hakin9.org/wp-content/uploads/2022/11/Figure-4.png 1910w, https://hakin9.org/wp-content/uploads/2022/11/Figure-4-460x154.png 460w, https://hakin9.org/wp-content/uploads/2022/11/Figure-4-1024x344.png 1024w, https://hakin9.org/wp-content/uploads/2022/11/Figure-4-768x258.png 768w, https://hakin9.org/wp-content/uploads/2022/11/Figure-4-1536x515.png 1536w, https://hakin9.org/wp-content/uploads/2022/11/Figure-4-500x168.png 500w, https://hakin9.org/wp-content/uploads/2022/11/Figure-4-200x67.png 200w, https://hakin9.org/wp-content/uploads/2022/11/Figure-4-378x127.png 378w, https://hakin9.org/wp-content/uploads/2022/11/Figure-4-565x190.png 565w, https://hakin9.org/wp-content/uploads/2022/11/Figure-4-120x40.png 120w, https://hakin9.org/wp-content/uploads/2022/11/Figure-4-310x104.png 310w" alt="" width="992" height="333" /></a><em>Figure 4: Health status of containers in a Docker environment</em></p>
<h1>Conclusion</h1>
<p>Robust monitoring and easy debugging are key factors for container security. This ensures complete coverage of metrics and the events happening in your Dockerized container infrastructures. We have seen how Wazuh facilitates and improves an organization&#8217;s visibility through its container security monitoring capabilities. Visit this <a href="https://documentation.wazuh.com/current/container-security/index.html" target="_blank" rel="noopener">documentation</a> to get a detailed explanation of how to perform container monitoring with Wazuh.</p>
<p>Wazuh is free to use, easy to deploy, and has a continuously growing <a href="https://wazuh.com/community/" target="_blank" rel="noopener">community</a> that supports thousands of users. To get started with Wazuh, visit the <a href="https://documentation.wazuh.com/current/quickstart.html" target="_blank" rel="noopener">Quickstart installation guide</a> and explore the features it provides.</p>
<p>The post <a href="http://kostacipo.stream/using-wazuh-for-docker-container-monitoring/">Using Wazuh for Docker Container Monitoring</a> appeared first on <a href="http://kostacipo.stream">Tech Chronicles</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://kostacipo.stream/using-wazuh-for-docker-container-monitoring/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to install Docker CE on RHEL 8 / CentOS 8</title>
		<link>http://kostacipo.stream/how-to-install-docker-ce-on-rhel-8-centos-8/</link>
					<comments>http://kostacipo.stream/how-to-install-docker-ce-on-rhel-8-centos-8/#respond</comments>
		
		<dc:creator><![CDATA[Majordomo]]></dc:creator>
		<pubDate>Mon, 29 Nov 2021 14:44:25 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[CentOS 8]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[RHEL 8]]></category>
		<guid isPermaLink="false">https://kostacipo.stream/?p=2118</guid>

					<description><![CDATA[<p>The latest release of the RHEL 8 / CentOS 8. Red Hat has built its own tools, buildah and podman, which aim to be compatible with existing docker images and work without relying on a daemon, allowing the creation of containers as normal users, without the need of special permissions (with some limitations: e.g. at [&#8230;]</p>
<p>The post <a href="http://kostacipo.stream/how-to-install-docker-ce-on-rhel-8-centos-8/">How to install Docker CE on RHEL 8 / CentOS 8</a> appeared first on <a href="http://kostacipo.stream">Tech Chronicles</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>The latest release of the RHEL 8 / CentOS 8. Red Hat has built its own tools, <code>buildah</code> and <code>podman</code>, which aim to be compatible with existing docker images and work without relying on a daemon, allowing the creation of containers as normal users, without the need of special permissions (with some limitations: e.g. at the moment of writing, it’s still not possible to map host ports to the container without privileges).</p>
<p>Some specific tools, however, are still missing: an equivalent of <code>docker-compose</code>, for example does not exists yet. In this tutorial we will see how to install and run the original Docker CE on Rhel8 by using the official Docker repository for CentOS7.</p>
<p><strong>In this tutorial you will learn:</strong></p>
<ul>
<li>How to enable the docker-ce repository on RHEL 8 / CentOS 8</li>
<li>How to install docker and docker-compose on RHEL 8 / CentOS 8</li>
</ul>
<h2>Software Requirements and Conventions Used</h2>
<table class="uk-table uk-table-striped uk-table-condensed">
<caption>Software Requirements and Linux Command Line Conventions</caption>
<thead>
<tr>
<th>Category</th>
<th>Requirements, Conventions or Software Version Used</th>
</tr>
</thead>
<tbody>
<tr>
<td class="uk-text-primary uk-text-bold">System</td>
<td>RHEL 8 / CentOS 8</td>
</tr>
<tr>
<td class="uk-text-primary uk-text-bold">Software</td>
<td>Docker version 18.09.2</td>
</tr>
<tr>
<td class="uk-text-primary uk-text-bold">Other</td>
<td>Permission to run command with root privileges.</td>
</tr>
<tr>
<td class="uk-text-primary uk-text-bold">Conventions</td>
<td><b>#</b> – requires given linux commands to be executed with root privileges either directly as a root user or by use of <code>sudo</code> command<br />
<b>$</b> – requires given linux commands to be executed as a regular non-privileged user</td>
</tr>
</tbody>
</table>
<h2>What is Docker?</h2>
<p>Docker is an open source project which allows the creation and distribution of applications inside <code>containers</code>, which are standardized environments that can be easily replicated, independently from the host system. While in Red Hat Enterprise Linux 7 Docker was officially supported, on the new release of this open source operating system, it has been replaced by a series of other tools developed by Red Hat itself: <code>buildah</code> and <code>podman</code>.</p>
<p>By the use of an external repository, however, it’s still possible to install Docker CE (Community Edition). In this tutorial we will see how to install this repository; notice however, that it was originally meant for <code>CentOS 7</code> (a RHEL clone), and the community version of Docker has no official support for Red Hat Enterprise Linux. Because of this, issues exist – we discuss them below.</p>
<h2>Adding the external repository</h2>
<p>Since Docker is not available on RHEL 8 / CentOS 8, we need to add an external repository to obtain the software. In this case we will use the official Docker CE CentOS repository: this is, at the moment of writing, the only way to install Docker CE on RHEL 8 / CentOS 8.</p>
<p>The <code>dnf config-manager</code> utility let us, among the other things, easily enable or disable a repository in our distribution. By default, only the <code>appstream</code> and <code>baseos</code> repositories are enabled on Rhel8; we need to add and enable also the <code>docker-ce</code> repo. All we need to do to accomplish this task, is to run the following command:</p>
<pre>$ sudo dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo</pre>
<p>We can verify that the repository has been enabled, by looking at the output of the following command:</p>
<pre>$ sudo dnf repolist -v</pre>
<p>The command above will return detailed information about all the enabled repositories. This is what you should see at this point:</p>
<pre>Repo-id      : docker-ce-stable
Repo-name    : Docker CE Stable - x86_64
Repo-revision: 1549905809
Repo-updated : Mon 11 Feb 2019 06:23:29 PM CET
Repo-pkgs    : 30
Repo-size    : 618 M
Repo-baseurl : https://download.docker.com/linux/centos/7/x86_64/stable
Repo-expire  : 172,800 second(s) (last: Mon 18 Feb 2019 10:23:54 AM CET)
Repo-filename: /etc/yum.repos.d/docker-ce.repo

Repo-id      : rhel-8-for-x86_64-appstream-rpms
Repo-name    : Red Hat Enterprise Linux 8 for x86_64 - AppStream Beta (RPMs)
Repo-revision: 1542158694
Repo-updated : Wed 14 Nov 2018 02:24:54 AM CET
Repo-pkgs    : 4,594
Repo-size    : 4.9 G
Repo-baseurl : https://cdn.redhat.com/content/beta/rhel8/8/x86_64/appstream/os
Repo-expire  : 86,400 second(s) (last: Mon 18 Feb 2019 10:23:55 AM CET)
Repo-filename: /etc/yum.repos.d/redhat.repo

Repo-id      : rhel-8-for-x86_64-baseos-rpms
Repo-name    : Red Hat Enterprise Linux 8 for x86_64 - BaseOS Beta (RPMs)
Repo-revision: 1542158719
Repo-updated : Wed 14 Nov 2018 02:25:19 AM CET
Repo-pkgs    : 1,686
Repo-size    : 925 M
Repo-baseurl : https://cdn.redhat.com/content/beta/rhel8/8/x86_64/baseos/os
Repo-expire  : 86,400 second(s) (last: Mon 18 Feb 2019 10:23:56 AM CET)
Repo-filename: /etc/yum.repos.d/redhat.repo
Total packages: 6,310
</pre>
<h3>Installing docker-ce</h3>
<p>The <code>docker-ce-stable</code> repository is now enabled on our system. The repository contains several versions of the <code>docker-ce</code> package, to display all of them, we can run:</p>
<pre>$ dnf list docker-ce --showduplicates | sort -r
docker-ce.x86_64            3:19.03.2-3.el7                     docker-ce-stable
docker-ce.x86_64            3:19.03.1-3.el7                     docker-ce-stable
docker-ce.x86_64            3:19.03.0-3.el7                     docker-ce-stable
docker-ce.x86_64            3:18.09.9-3.el7                     docker-ce-stable
docker-ce.x86_64            3:18.09.8-3.el7                     docker-ce-stable
docker-ce.x86_64            3:18.09.7-3.el7                     docker-ce-stable
docker-ce.x86_64            3:18.09.6-3.el7                     docker-ce-stable
docker-ce.x86_64            3:18.09.5-3.el7                     docker-ce-stable
docker-ce.x86_64            3:18.09.4-3.el7                     docker-ce-stable
docker-ce.x86_64            3:18.09.3-3.el7                     docker-ce-stable
docker-ce.x86_64            3:18.09.2-3.el7                     docker-ce-stable
docker-ce.x86_64            3:18.09.1-3.el7                     docker-ce-stable
docker-ce.x86_64            3:18.09.0-3.el7                     docker-ce-stable
docker-ce.x86_64            18.06.3.ce-3.el7                    docker-ce-stable
docker-ce.x86_64            18.06.2.ce-3.el7                    docker-ce-stable
docker-ce.x86_64            18.06.1.ce-3.el7                    docker-ce-stable
docker-ce.x86_64            18.06.0.ce-3.el7                    docker-ce-stable
docker-ce.x86_64            18.03.1.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            18.03.0.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.12.1.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.12.0.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.09.1.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.09.0.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.06.2.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.06.1.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.06.0.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.03.3.ce-1.el7                    docker-ce-stable
docker-ce.x86_64            17.03.2.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.03.1.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.03.0.ce-1.el7.centos             docker-ce-stable
</pre>
<p>What version to install? Well, Red Hat seems to have somehow blocked the installation of <code>containerd.io</code> &gt; <code>1.2.0-3.el7</code>, which is a dependency of <code>docker-ce</code>. Because of this, simply running the <code>sudo dnf install docker-ce</code> command, won’t work. As we will see in a minute, it’s still possibile to workaround this problem; once <code>docker-ce</code> is installed, however, another problem becomes evident: as long as <code>firewalld</code>, the system firewall manager is enabled, <code>DNS resolution</code> inside docker containers does not work.</p>
<p>This is, of course a critical problem. However, if you still want to proceed with the installation, here are the possible methods that can be used to avoid the dependencies issues:</p>
<ul>
<li>Install a specific version of <code>docker-ce</code> which requires an installable version of the <code>containerd.io</code> package;</li>
<li>Force the installation providing the <code>--nobest</code> option</li>
<li>Install the latest available <code>containerd.io</code> rpm manually;</li>
</ul>
<h4>Install a specific version of docker-ce</h4>
<p>To install a specific version, all we have to do is to provide the fully qualified package name, for example:</p>
<pre>$ sudo dnf install docker-ce-3:18.09.1-3.el7</pre>
<h4>Force the installation of docker-ce with the –nobest option</h4>
<p>Normally, when installing a package, the best available candidate is selected from a repository. In this case, for example, the installation of the latest version of <code>docker-ce</code> is attempted (and fails). By using the <code>--nobest</code> option, we can change this behavior so that the first version of <code>docker-ce</code> with satisfiable dependencies is selected as “fallback”, in this case <code>3:18.09.1-3.el7</code>.</p>
<pre>$ sudo dnf install --nobest docker-ce
Dependencies resolved.

Problem: package <b>docker-ce-3:19.03.2-3.el7.x86_64</b> requires containerd.io &gt;= 1.2.2-3, but none of the providers can be installed
  - cannot install the best candidate for the job
  - package containerd.io-1.2.2-3.3.el7.x86_64 is excluded
  - package containerd.io-1.2.2-3.el7.x86_64 is excluded
  - package containerd.io-1.2.4-3.1.el7.x86_64 is excluded
  - package containerd.io-1.2.5-3.1.el7.x86_64 is excluded
  - package containerd.io-1.2.6-3.3.el7.x86_64 is excluded
=======================================================================================================================================================
 Package                            Arch         Version                                                  Repository                              Size
=======================================================================================================================================================
Installing:
 docker-ce                          x86_64       <b>3:18.09.1-3.el7</b>                                          docker-ce-stable                        19 M
Installing dependencies:
 containerd.io                      x86_64       1.2.0-3.el7                                              docker-ce-stable                        22 M
 docker-ce-cli                      x86_64       1:19.03.2-3.el7                                          docker-ce-stable                        39 M
 container-selinux                  noarch       2:2.94-1.git1e99f1d.module+el8.0.0+4017+bbba319f         rhel-8-for-x86_64-appstream-rpms        43 k
 tar                                x86_64       2:1.30-4.el8                                             rhel-8-for-x86_64-baseos-rpms          838 k
 libcgroup                          x86_64       0.41-19.el8                                              rhel-8-for-x86_64-baseos-rpms           70 k
 python3-policycoreutils            noarch       2.8-16.1.el8                                             rhel-8-for-x86_64-baseos-rpms          2.2 M
 python3-libsemanage                x86_64       2.8-5.el8                                                rhel-8-for-x86_64-baseos-rpms          127 k
 python3-setools                    x86_64       4.2.0-2.el8                                              rhel-8-for-x86_64-baseos-rpms          598 k
 checkpolicy                        x86_64       2.8-2.el8                                                rhel-8-for-x86_64-baseos-rpms          338 k
 python3-audit                      x86_64       3.0-0.10.20180831git0047a6c.el8                          rhel-8-for-x86_64-baseos-rpms           85 k
 policycoreutils-python-utils       noarch       2.8-16.1.el8                                             rhel-8-for-x86_64-baseos-rpms          228 k
Skipping packages with broken dependencies:
 docker-ce                          x86_64       3:19.03.2-3.el7                                          docker-ce-stable                        24 M

Transaction Summary
=======================================================================================================================================================
Install  12 Packages
Skip      1 Package

Total download size: 85 M
Installed size: 351 M
Is this ok [y/N]:</pre>
<h4>Install the latest available containerd.io package manually</h4>
<p>If we stricly need to install the latest version of <code>docker-ce</code>, we can install the required version of <code>containerd.io</code> manually, by running:</p>
<pre>$ sudo dnf install https://download.docker.com/linux/centos/7/x86_64/stable/Packages/containerd.io-1.2.6-3.3.el7.x86_64.rpm</pre>
<p>After the package is installed, we can simply install the latest <code>docker-ce</code>:</p>
<pre>$ sudo dnf install docker-ce
Dependencies resolved.
=======================================================================================================================================================
  Package                          Arch                      Version                             Repository                                        Size
=======================================================================================================================================================
Installing:
  docker-ce                        x86_64                    <b>3:19.03.2-3.el7</b>                     docker-ce-stable                                  24 M
Installing dependencies:
  docker-ce-cli                    x86_64                    1:19.03.2-3.el7                     docker-ce-stable                                  39 M
  tar                              x86_64                    2:1.30-4.el8                        rhel-8-for-x86_64-baseos-rpms                    838 k
  libcgroup                        x86_64                    0.41-19.el8                         rhel-8-for-x86_64-baseos-rpms                     70 k

Transaction Summary
=======================================================================================================================================================
Install  4 Packages

Total download size: 65 M
Installed size: 275 M
Is this ok [y/N]:
</pre>
<p>This option is less convenient since the <code>containerd.io</code> package is not installed as a dependency of <code>docker-ce</code>, therefore it will not be removed automatically when the latter is uninstalled from the system.</p>
<p>Whatever method we use to install <code>docker-ce</code>, as said before, in order to make <code>DNS resolution</code> work inside Docker containers, we must disable firewalld (a system reboot may be also needed):</p>
<pre>$ sudo systemctl disable firewalld</pre>
<h2>Start and enable the docker daemon</h2>
<p>Once <code>docker-ce</code> is installed, we must start and enable the docker daemon, so that it will be also launched automatically at boot. The command we need to run is the following:</p>
<pre>$ sudo systemctl enable --now docker</pre>
<p>At this point, we can confirm that the daemon is active by running:</p>
<pre>$ systemctl is-active docker
active
</pre>
<p>Similarly, we can check that it is enabled at boot, by running:</p>
<pre>$ systemctl is-enabled docker
enabled
</pre>
<h2>Installing docker-compose</h2>
<p>Docker compose is a very useful package which let us manage multi-container applications, like for example those based on the LAMP stack, where each part of the environment (PHP, Apache, MariaDB) is provided by a dedicated container (if you are interested in the subject, take a look at our tutorial about creating a docker-based lamp stack). The package is not available on Rhel8, nor an equivalent exists to be used with the Rhel tools. It’s, however, possible to install it in many ways: just keep on reading and decide what suits you best.</p>
<h3>Global installation</h3>
<p>The way we should install <code>docker-compose</code> varies depending on whether we want to install it globally or just for a single user. At the moment of writing, the only way to install it globally is to download the binary from the github page of the project:</p>
<pre>$ curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o docker-compose</pre>
<p>Once the binary is downloaded, we move it into <code>/usr/local/bin</code> and we make it executable:</p>
<pre>$ sudo mv docker-compose /usr/local/bin &amp;&amp; sudo chmod +x /usr/local/bin/docker-compose</pre>
<p>The <code>/usr/local</code> hierarchy is not chosen randomly. This directory structure is made to be used for files installed by the local administrator manually (for software compiled from source, for example), in order to ensure separation from the software installed with the system package manager.</p>
<p>Although it’s possible for a normal user to run docker-related commands if he is part of the <code>docker</code> group (the group is automatically created when we install docker-ce), by default they must be executed with root privileges for security reasons. When we need to do the latter, since the <code>/usr/local/bin</code> directory is not in the root user’s <code>PATH</code>, we either need to call the binary specifying its location or add <code>/usr/local/bin</code> to the <code>PATH</code> itself. The first option is the one which I recommend in this case.</p>
<h3>Per-user installation</h3>
<p>If our user is part of the <code>docker</code> group, and thus it is allowed to run docker commands, and since <code>docker-compose</code> is available as a python package, we can also install it using <code>pip</code>, the python package manager. First, make sure pip itself is installed:</p>
<pre>$ sudo dnf install python3-pip</pre>
<p>To obtain docker-compose we run:</p>
<pre>$ pip3.6 install docker-compose --user</pre>
<p>Please notice that even if would be possible to run pip as root to install a package globally, this is not recommended and highly discouraged.</p>
<h2>Testing docker</h2>
<p>We installed docker and docker-compose, now to check that everything works as expected, we can try to build an image and run a container: in this case we will use the official <code>httpd</code> one. All we have to do is to launch the following command:</p>
<pre>sudo docker run --rm --name=linuxconfig-test -p 80:80 httpd</pre>
<p>Since the <code>httpd</code> image does not exists locally it will be automatically fetched and built. Finally, a container based on it will be launched in the foreground (it will be automatically removed when stopped). We should be able to see the <code>It works!</code> message when we reach our machine ip via browser.</p>
<h2>Conclusions</h2>
<p>Red Hat Enterprise Linux 8 does not support Docker: on this distribution it has been replaced by Red Hat own tools like <code>buildah</code> and <code>podman</code>, which are compatible with Docker but don’t need a server/client architecture to run. Using native tools, where possible, is always the recommended way to go, but for a reason or another you may still want to install the original Docker. In this tutorial, we saw how it is possible to install <code>Docker CE</code> on Rhel8, by using the official Docker repository for CentOS7, which is a 100% compatible clone.</p>
<p>This is not an ideal solution, and as we saw, at the moment, some workarounds are needed to make Docker work on RHEL8. If some new issues arises, or better solutions to the problems mentioned above are found, this article will be updated accordingly.</p>
<p>The post <a href="http://kostacipo.stream/how-to-install-docker-ce-on-rhel-8-centos-8/">How to install Docker CE on RHEL 8 / CentOS 8</a> appeared first on <a href="http://kostacipo.stream">Tech Chronicles</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://kostacipo.stream/how-to-install-docker-ce-on-rhel-8-centos-8/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How Docker containers work</title>
		<link>http://kostacipo.stream/how-docker-containers-work/</link>
					<comments>http://kostacipo.stream/how-docker-containers-work/#respond</comments>
		
		<dc:creator><![CDATA[Majordomo]]></dc:creator>
		<pubDate>Mon, 15 Feb 2021 10:28:52 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[containers]]></category>
		<category><![CDATA[docker]]></category>
		<guid isPermaLink="false">http://kostacipo.stream/?p=2040</guid>

					<description><![CDATA[<p>Here, we&#8217;ll look a bit at a Docker container&#8217;s lifecycle and how to manage containers. We&#8217;ll also look at how to think about configuring data storage and the network options for your containers. How to manage Docker containers A Docker container has a lifecycle that you can manage and track the state of the container. [&#8230;]</p>
<p>The post <a href="http://kostacipo.stream/how-docker-containers-work/">How Docker containers work</a> appeared first on <a href="http://kostacipo.stream">Tech Chronicles</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Here, we&#8217;ll look a bit at a Docker container&#8217;s lifecycle and how to manage containers. We&#8217;ll also look at how to think about configuring data storage and the network options for your containers.</p>
<h2 id="how-to-manage-docker-containers">How to manage Docker containers</h2>
<p>A Docker container has a lifecycle that you can manage and track the state of the container.</p>
<p><span class="mx-imgBorder"> <img decoding="async" src="https://docs.microsoft.com/en-us/learn/modules/intro-to-docker-containers/media/4-docker-container-lifecycle.svg" alt="Diagram that shows the lifecycle of a container and the transition between the lifecycle phases." data-linktype="relative-path" /> </span></p>
<p>To place a container in the run state, use the run command. You can also restart a container that is already running. When restarting a container, the container receives a termination signal to enable any running processes to shut down gracefully before the container&#8217;s kernel is terminated.</p>
<p>A container is considered in a running state until it&#8217;s either paused, stopped, or killed. A container, however, may also exit from the run state by itself. A container can self-exit when the running process completes, or if the process goes into a fault state.</p>
<p>To pause a running container, use the pause command. This command suspends all processes in the container.</p>
<p>To stop a running container, use the stop command. The stop command enables the working process to shut down gracefully by sending it a termination signal. The container&#8217;s kernel terminates after the process shuts down.</p>
<p>To send a kill signal if you need to terminate the container, use the kill command. The running process doesn&#8217;t capture the kill signal, only the container&#8217;s kernel. This command will forcefully terminate the working process in the container.</p>
<p>Lastly, to remove containers that are in a stopped state, use the remove command. After removing a container, all data stored in the container gets destroyed.</p>
<h2 id="how-to-view-available-containers">How to view available containers</h2>
<p>To list running containers, run the <code>docker ps</code> command. To see all containers in all states, pass the <code>-a</code> argument.</p>
<p>Here is an example.</p>
<div id="code-try-0" class="codeHeader" data-bi-name="code-header"><span class="language">Console</span></div>
<pre class="has-inner-focus" tabindex="0"><code class="lang-console" data-author-content="docker ps -a
">docker ps -a
</code></pre>
<p>Here is the output from that command.</p>
<div id="code-try-1" class="codeHeader" data-bi-name="code-header"><span class="language">Output</span></div>
<pre class="has-inner-focus" tabindex="0"><code class="lang-output" data-author-content="CONTAINER ID    IMAGE        COMMAND         CREATED       STATUS           PORTS        NAMES
d93d40cc1ce9    tmp-ubuntu:latest  &quot;dotnet website.dll …&quot;  6 seconds ago    Up 5 seconds        8080/tcp      happy_wilbur
33a6cf71f7c1    tmp-ubuntu:latest  &quot;dotnet website.dll …&quot;  2 hours ago     Exited (0) 9 seconds ago            adoring_borg
">CONTAINER ID    IMAGE        COMMAND         CREATED       STATUS           PORTS        NAMES
d93d40cc1ce9    tmp-ubuntu:latest  "dotnet website.dll …"  6 seconds ago    Up 5 seconds        8080/tcp      happy_wilbur
33a6cf71f7c1    tmp-ubuntu:latest  "dotnet website.dll …"  2 hours ago     Exited (0) 9 seconds ago            adoring_borg
</code></pre>
<p>There are three items to review in the previous output:</p>
<ul>
<li>The image name listed in the <em>IMAGE</em> column. In this example, <em>tmp-ubuntu: latest</em>. Notice how you&#8217;re allowed to create more than one container from the same image. This feature is a powerful management feature that you use to enable scaling in your solutions.</li>
<li>The status of the container listed in the <em>STATUS</em> column. In this example, you have one container that is running, and one container that has exited. The container&#8217;s status usually is your first indicator of the health of the container.</li>
<li>The name of the container listed in the <em>NAMES</em> column. Apart from the container ID in the first column, containers will also receive a name. In this example, you didn&#8217;t explicitly provide a name for each container, and as a result, Docker gave the container a random name. To give a container an explicit name using the <code>--name</code> flag, use the run command.</li>
</ul>
<h3 id="why-are-containers-given-a-name">Why are containers given a name?</h3>
<p>This feature enables you to run multiple container instances of the same image. Container names are unique, which means if you specify a name, that name can&#8217;t be reused to create a new container. The only way to reuse a specific name is to remove the previous container.</p>
<h2 id="how-to-run-a-container">How to run a container</h2>
<p>To start a container, run the <code>docker run</code> command. You only need to specify the image to run with its name or ID to launch the container from the image. A container launched in this manner provides an interactive experience.</p>
<p>Here, to run the container with our website in the background, add the <code>-d</code> flag.</p>
<div id="code-try-2" class="codeHeader" data-bi-name="code-header"><span class="language">Console</span></div>
<pre class="has-inner-focus" tabindex="0"><code class="lang-console" data-author-content="docker run -d tmp-ubuntu
">docker run -d tmp-ubuntu
</code></pre>
<p>The command, in this case, only returns the ID of the new container.</p>
<p>After an image is specified to run, Docker finds the image, loads container from the image, and executes the command specified as the entry point. It&#8217;s at this point that the container is available for management.</p>
<h2 id="how-to-pause-a-container">How to pause a container</h2>
<p>To pause a container, run the <code>docker pause</code> command. Here is an example.</p>
<div id="code-try-3" class="codeHeader" data-bi-name="code-header"><span class="language">Console</span></div>
<pre class="has-inner-focus" tabindex="0"><code class="lang-console" data-author-content="docker pause happy_wilbur
">docker pause happy_wilbur
</code></pre>
<p>Pausing a container will suspend all processes. This command enables the container to continue processes at a later stage. The <code>docker unpause</code> command unsuspends all processes.</p>
<h3 id="how-to-restart-a-container">How to restart a container</h3>
<p>To restart containers, run the <code>docker restart</code> command. Here is an example.</p>
<div id="code-try-4" class="codeHeader" data-bi-name="code-header"><span class="language">Console</span></div>
<pre class="has-inner-focus" tabindex="0"><code class="lang-console" data-author-content="docker restart happy_wilbur
">docker restart happy_wilbur
</code></pre>
<p>The container receives a stop command, followed by a start command. If the container doesn&#8217;t respond to the stop command, then a kill signal is sent.</p>
<h3 id="how-to-stop-a-container">How to stop a container</h3>
<p>To stop a running container, run the <code>docker stop</code> command. Here is an example.</p>
<div id="code-try-5" class="codeHeader" data-bi-name="code-header"><span class="language">Console</span></div>
<pre class="has-inner-focus" tabindex="0"><code class="lang-console" data-author-content="docker stop happy_wilbur
">docker stop happy_wilbur
</code></pre>
<p>The stop command sends a termination signal to the container and the process running in the container.</p>
<h3 id="how-to-remove-a-container">How to remove a container</h3>
<p>To remove a container, run the <code>docker rm</code> command. Here is an example.</p>
<div id="code-try-6" class="codeHeader" data-bi-name="code-header"><span class="language">Console</span></div>
<pre class="has-inner-focus" tabindex="0"><code class="lang-console" data-author-content="docker rm happy_wilbur
">docker rm happy_wilbur
</code></pre>
<p>After you remove the container, all data in the container is destroyed. It&#8217;s essential to always consider containers as temporary when thinking about storing data.</p>
<h2 id="docker-container-storage-configuration">Docker container storage configuration</h2>
<p>As described earlier, always consider containers as temporary when the app in a container needs to store data.</p>
<p>Let&#8217;s assume your tracking portal creates a log file in a subfolder to the root of the app; that is, directly to the file system of the container. When your app writes data to the log file, the system writes the data to the writable container layer.</p>
<p>Even though this approach works, it, unfortunately, has several drawbacks.</p>
<ul>
<li>Container storage is temporary
<p>Your log file won&#8217;t persist between container instances. For example, let&#8217;s assume that you stop and remove the container. When you launch a new container instance, the new instance bases itself on the image specified, and all your previous data will be missing. Remember, all data in a container is destroyed with the container when you remove a container.</li>
<li>Container storage is coupled to the underlying host machine
<p>Accessing or moving the log file from the container is difficult to do as the container is coupled to the underlying host machine. You&#8217;ll have to connect to the container instance to access the file.</li>
<li>Container storage drives are less performant
<p>Containers implement a storage driver to allow your apps to write data. This driver introduces an extra abstraction to communicate with the host OS kernel and is less performant than writing directly to a host filesystem.</li>
</ul>
<p>Containers can make use of two options to persist data. The first option is to make use of <em>volumes</em>, and the second is <em>bind mounts</em>.</p>
<h3 id="what-is-a-volume">What is a volume?</h3>
<p>A volume is stored on the host filesystem at a specific folder location. Choose a folder where you know the data isn&#8217;t going to be modified by non-Docker processes.</p>
<p>Docker creates and manages the new volume by running the <code>docker volume create</code> command. This command can form part of our Dockerfile definition, which means that you can create volumes as part of the container creation process. Docker will create the volume if it doesn&#8217;t exist when you try to mount the volume into a container the first time.</p>
<p>Volumes are stored within directories on the host filesystem. Docker will mount and manage the volumes in the container. After mounting, these volumes are isolated from the host machine.</p>
<p>Multiple containers can simultaneously use the same volumes. Volumes also don&#8217;t get removed automatically when a container stops using the volume.</p>
<p>In this example, you can create a directory on our container host, and mount this volume into the container when you create the tracking portal container. When your tracking portal logs data, you can access this information via the container host&#8217;s filesystem. You&#8217;ll have access to this log file even if your container is removed.</p>
<h3 id="what-is-a-bind-mount">What is a bind mount?</h3>
<p>A bind mount is conceptually the same as a volume, however, instead of using a specific folder, you can mount any file or folder on the host. You&#8217;re also expecting the host can change the contents of these mounts. Just like volumes, the bind mount is created if you mount it, and it doesn&#8217;t yet exist on the host.</p>
<p>Bind mounts have limited functionality compared to volumes, and even though they&#8217;re more performant, they depend on the host having a specific folder structure in place.</p>
<p>Volumes are considered the preferred data storage strategy to use with containers.</p>
<h2 id="docker-container-network-configuration">Docker container network configuration</h2>
<p>The default Docker network configuration allows for the isolation of containers on the Docker host. This feature enables you to build and configure apps that can communicate securely with each other.</p>
<p>Docker provides three pre-configured network configurations:</p>
<ul>
<li>Bridge</li>
<li>Host</li>
<li>none</li>
</ul>
<p>You choose which of these network configurations to apply to your container depending on its network requirements.</p>
<h3 id="what-is-the-bridge-network">What is the bridge network?</h3>
<p>The bridge network is the default configuration applied to containers when launched without specifying any additional network configuration. This network is an internal, private network used by the container, and isolates the container network from the Docker host network.</p>
<p>Each container in the bridge network is assigned an IP address and subnet mask with the hostname defaulting to the container name. Containers connected to the default bridge network are allowed to access other bridge connected containers by IP address. The bridge network doesn&#8217;t allow communication between containers using hostnames.</p>
<p>By default, Docker doesn&#8217;t publish any container ports. To enable port mapping between the container ports and the Docker host ports, use the Docker port <code>--publish</code> flag.</p>
<p>The publish flag effectively configures a firewall rule that maps the ports.</p>
<p>In this example, your tracking portal is accessible to clients browsing to port 80. You&#8217;ll have to map port 80 from the container to an available port on the host. You have port 8080 open on the host, which enables you to set the flag like this.</p>
<div id="code-try-7" class="codeHeader" data-bi-name="code-header"><span class="language">Console</span></div>
<pre class="has-inner-focus" tabindex="0"><code class="lang-console" data-author-content="--publish 8080:80
">--publish 8080:80
</code></pre>
<p>Any client browsing to the Docker host IP and port 8080 can access the tracking portal.</p>
<h3 id="what-is-the-host-network">What is the host network?</h3>
<p>The host network enables you to run the container on the host network directly. This configuration effectively removes the isolation between the host and the container at a network level.</p>
<p>In this example, let&#8217;s assume you decide to change the networking configuration to the host network option. Your tracking portal is still accessible using the host IP. You can now use the well known port 80 instead of a mapped port.</p>
<p>Keep in mind that the container can use only ports not already used by the host.</p>
<h3 id="what-is-the-none-network">What is the none network?</h3>
<p>To disable networking for containers, use the none network option.</p>
<h3 id="operating-system-considerations">Operating system considerations</h3>
<p>Keep in mind that there are differences between desktop operating systems for the Docker network configuration options. For example, the <em>Docker0</em> network interface isn&#8217;t available on macOS when using the bridge network, and using the host network configuration isn&#8217;t supported for both Windows and macOS desktops.</p>
<p>These differences might affect the way your developers configure their workflow to manage container development.</p>
<p>The post <a href="http://kostacipo.stream/how-docker-containers-work/">How Docker containers work</a> appeared first on <a href="http://kostacipo.stream">Tech Chronicles</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://kostacipo.stream/how-docker-containers-work/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Deploying Docker Securely</title>
		<link>http://kostacipo.stream/deploying-docker-securely/</link>
					<comments>http://kostacipo.stream/deploying-docker-securely/#respond</comments>
		
		<dc:creator><![CDATA[Majordomo]]></dc:creator>
		<pubDate>Sun, 07 Feb 2021 22:33:24 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[docker]]></category>
		<guid isPermaLink="false">http://kostacipo.stream/?p=2035</guid>

					<description><![CDATA[<p>Docker is a fantastic piece of technology for teams. I was asked recently about docker deployment security. I will outline steps you can take to securely deploy a docker environment. This assumes you are using Docker daemon on hardware running Linux that you administer. Our main goal is to prevent container escapes and multiple container [&#8230;]</p>
<p>The post <a href="http://kostacipo.stream/deploying-docker-securely/">Deploying Docker Securely</a> appeared first on <a href="http://kostacipo.stream">Tech Chronicles</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Docker is a fantastic piece of technology for teams. I was asked recently about docker deployment security. I will outline steps you can take to securely deploy a docker environment. This assumes you are using Docker daemon on hardware running Linux that you administer. Our main goal is to prevent container escapes and multiple container breaches in the event that a  single container is compromised.</p>
<h2 id="maintain-the-host-daemon-software">Maintain the Host &amp; Daemon Software</h2>
<p>It should go without saying, but protecting the host is as important as always. Docker regularly releases security patches for the daemon, so ensure you have a good strategy for updating and maintaining the environment.</p>
<ul>
<li>Regularly patch the docker software installed on the server.</li>
<li>Regularly update the underlying operating system and software</li>
<li>Harden your server and setup host based intrusion detection, with docker configurations.</li>
</ul>
<h2 id="don-t-run-in-privileged-mode">Don&#8217;t Run in Privileged Mode</h2>
<p>Privileged mode gives a container access to many capabilities reserved for root on the host machine, such as control of all devices, the ability to create and manage other containers, and exceptions to any resource limitations imposed by cgroups.</p>
<p>Device control can be used to do all sorts of unfriendly things, such as change the host partition table, mount and read or modify sensitive host file systems, etc.</p>
<p>If at all possible, don&#8217;t run containers in privileged mode. Some applications may require this and have a valid use case, such as fully managing other docker containers. If so, don&#8217;t place containers unrelated to the privileged one on the same host, to limit the damage if the privileged container is breached.</p>
<p>In general, it is better to selectively add capabilities to the container, rather than giving blanket privileged access. You can see all default and addable privileges in the <a href="https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities">runtime documentation</a>.</p>
<h2 id="remove-default-capabilities-add-back-what-is-needed">Remove Default Capabilities. Add back what is needed</h2>
<p>In the same vein as above (adding capabilities as needed instead of running privileged), I recommend removing all default capabilities and only adding what will be used &#8211; frequently no capabilities will be needed in production.</p>
<p>Docker containers run with the following capabilities by default:</p>
<table>
<thead>
<tr>
<th>Capability</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>SETPCAP</td>
<td>Allow a process to change it&#8217;s own capabilities set (within the set it is already allowed). Should not be dangerous in practice.</td>
</tr>
<tr>
<td>MKNOD</td>
<td>Allows creation of special devices. Almost all containers will receive the devices they need automatically, so this is almost never needed.</td>
</tr>
<tr>
<td>AUDIT_WRITE</td>
<td>Allow the container to write records to the underlying kernel auditing log. This is generally used for things like ssh login. It is a better practice to keep all container logs within the container and drain them, rather than allow the container to write to the host log files.</td>
</tr>
<tr>
<td>CHOWN</td>
<td>Allow the container process to change file permissions. This should generally never be needed in production.</td>
</tr>
<tr>
<td>NET_RAW</td>
<td>Allows RAW and PACKET sockets, which can be used to spy on networks or create nasty packets. Some applications may need this, but most won&#8217;t.</td>
</tr>
<tr>
<td>DAC_OVERRIDE</td>
<td>Allows the root user to bypass normal file permission checks. No container should ever need this.</td>
</tr>
<tr>
<td>FOWNER</td>
<td>Bypass permission checks on operations that normally require the UID of the process to match the UID of the file.</td>
</tr>
<tr>
<td>FSETID</td>
<td>Don’t clear set-user-ID and set-group-ID permission bits when a file is modified. This should only be needed by installations, so generally not in production. Allowing this can let a user modify privileged programs.</td>
</tr>
<tr>
<td>KILL</td>
<td>Allow the root user to send kill signals to non-root processes. Not generally needed if keeping one container per process, but not too dangerous in general.</td>
</tr>
<tr>
<td>SETUID</td>
<td>Allows running of setuid binaries, which allows a process to change it&#8217;s effective user id. This is required for some processes that require privileged ports (less than 1024) and by some processes like Apache to start. It should only be given to containers that need it.</td>
</tr>
<tr>
<td>SETGID</td>
<td>Just like setuid above, but for group ids.</td>
</tr>
<tr>
<td>NET_BIND_SERVICE</td>
<td>Bind to ports less than 1024. Enable this if your container runs a service that listens in the this port range only.</td>
</tr>
<tr>
<td>SYS_CHROOT</td>
<td>Allows use of the chroot command. Enable only if your process actively uses chroot to change the root directory.</td>
</tr>
<tr>
<td>SETFCAP</td>
<td>Allows the container to set file capabilities. Sometimes this is needed during a software install, but generally should not be needed by a running container in production.</td>
</tr>
</tbody>
</table>
<p>As mentioned, it&#8217;s best to drop all of these and only selectively add the specific capabilities needed. This takes a little more management overhead, because you may have to work with the application team to determine what is really needed.</p>
<p>Run a container with no capabilities:</p>
<pre class=" language-bash"><code class=" language-bash"><span class="token comment"># docker run --cap-drop=all my_container</span>
</code></pre>
<p>Add back in only net_bind_service and setuid capabilities:</p>
<pre class=" language-bash"><code class=" language-bash"><span class="token comment"># docker run --cap-drop=all --cap-add net_bind_service --add-cap setuid my_container</span>
</code></pre>
<h2 id="mount-storage-carefully">Mount Storage Carefully</h2>
<p>Some Docker guides will walk you through how to mount storage from various locations. This is generally fine when done correctly, but can lead to potential issues. A few things to be wary of:</p>
<ul>
<li><strong>Don&#8217;t mount the Docker socket file</strong> &#8211; any process with read/write access to the socket file also has admin rights over docker processes on the same host. This may be OK if the container mounting the socket is trusted and it&#8217;s purpose is to manage other containers on the same host.</li>
<li><strong>Don&#8217;t mount sensitive host file systems</strong> &#8211; It&#8217;s best to mount only a clean filesystem to the container, that is not shared with the host for any reason except being container storage.</li>
<li><strong>Don&#8217;t mount file systems to more than one container</strong> &#8211; It may be tempting to mount filesystems to multiple containers to share files, but do so with care, as files modified in one will also be modified in the other.</li>
</ul>
<h2 id="only-run-trusted-images">Only Run Trusted Images</h2>
<p>We want to avoid a scenario where an attacker could modify images hosted for deployment, or convince the host to startup a container an attacker specified from an untrusted source. The solution to this is Docker Trusted Images and image signing.</p>
<p>Setting up this process takes a little work &#8211; we will need to create offline master keys along with a key creation and rotation process for engineers who will be creating and uploading images, so it&#8217;s not for every organization.</p>
<p>The <a href="https://docs.docker.com/engine/security/trust/">Docker documentation</a> has an excellent walkthrough for setting up a trusted registry and the various keys and infrastructure required to do this. Beause of the added risk of losing a master key, this is something you should embark on with a good understanding of chain of trust and key management in your organization.</p>
<h2 id="be-aware-of-docker-networks">Be Aware of Docker Networks</h2>
<p>Tools such as docker compose can help glue containers together by creating docker specific networks. These networks can provide decent network segmentation out of the box when networks are created with care, but create a single large network by default.</p>
<p>Because the default configuration is one network for all containers, it is easy to create a container network that allows communication between any containers on any port, which is not monitored by traditional network tools. This is especially true with containers running on the same host, where no actual network traffic is generated, but container separation is depended upon.</p>
<p>To mitigate this, leverage orchestration tools that offer networking definition tools, or work with teams to ensure that networks are being well defined between various containers.</p>
<h2 id="final-words">Final Words</h2>
<p>I recommend you also check out the <a href="https://docs.docker.com/engine/security/">official docker security documentation</a>. It has a wealth of information and can expand on these topics including more information about the underlying mechanisms.</p>
<p>The post <a href="http://kostacipo.stream/deploying-docker-securely/">Deploying Docker Securely</a> appeared first on <a href="http://kostacipo.stream">Tech Chronicles</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://kostacipo.stream/deploying-docker-securely/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How Docker Images Work</title>
		<link>http://kostacipo.stream/how-docker-images-work/</link>
					<comments>http://kostacipo.stream/how-docker-images-work/#respond</comments>
		
		<dc:creator><![CDATA[Majordomo]]></dc:creator>
		<pubDate>Mon, 01 Feb 2021 21:38:12 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[images]]></category>
		<guid isPermaLink="false">http://kostacipo.stream/?p=2027</guid>

					<description><![CDATA[<p>As you may already know, the container image becomes the unit we use to distribute applications. The container is in a standardized format used by both the developer and operation teams. Here we&#8217;ll look at the differences between software, packages, and images as used in Docker. Knowing the differences between these concepts will help us [&#8230;]</p>
<p>The post <a href="http://kostacipo.stream/how-docker-images-work/">How Docker Images Work</a> appeared first on <a href="http://kostacipo.stream">Tech Chronicles</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>As you may already know, the container image becomes the unit we use to distribute applications. The container is in a standardized format used by both the developer and operation teams.</p>
<p>Here we&#8217;ll look at the differences between software, packages, and images as used in Docker. Knowing the differences between these concepts will help us better understand how Docker images work.</p>
<p>We&#8217;ll also briefly discuss the roles of the OS running on the host and the OS running in the container.</p>
<h2 id="software-packaged-into-a-container">Software packaged into a container</h2>
<p>The software packaged into a container isn&#8217;t limited to the applications our developers build. When we talk about software, we refer to application code, system packages, binaries, libraries, configuration files, and the operating system running in the container.</p>
<p>For example, assume we&#8217;re developing an order tracking portal that our company&#8217;s various outlets will use. We need to look at the complete stack of software that will run our web application. The application we&#8217;re building is a .NET Core MVC app, and we plan to deploy the application using Nginx as a reverse proxy server on Ubuntu Linux. All of these software components form part of the container image.</p>
<h2 id="what-is-a-container-image">What is a container image?</h2>
<p>A container image is a portable package that contains software. It&#8217;s this image that, when run, becomes our container. The container is the in-memory instance of an image.</p>
<p>A container image is immutable. Once you&#8217;ve built an image, the image can&#8217;t be changed. The only way to change an image is to create a new image. This feature is our guarantee that the image we use in production is the same image used in development and QA.</p>
<h2 id="what-is-the-host-os">What is the host OS?</h2>
<p>The host OS is the OS on which the Docker engine runs. Docker containers running on Linux share the host OS kernel and don&#8217;t require a container OS as long as the binary can access the OS kernel directly.</p>
<p><span class="mx-imgBorder"> <img decoding="async" src="https://docs.microsoft.com/en-us/learn/modules/intro-to-docker-containers/media/3-container-scratch-host-os.svg" alt="Diagram showing a Docker image with no base OS and the dependency on the host OS Kernel." data-linktype="relative-path"> </span></p>
<p>However, Windows containers need a container OS. The container depends on the OS kernel to manage services such as the file system, network management, process scheduling, and memory management.</p>
<h2 id="what-is-the-container-os">What is the container OS?</h2>
<p>The container OS is the OS that is part of the packaged image. We have the flexibility to include different versions of Linux or Windows OSs in a container. This flexibility allows us to access specific OS features or install additional software our applications may use.</p>
<p><span class="mx-imgBorder"> <img decoding="async" src="https://docs.microsoft.com/en-us/learn/modules/intro-to-docker-containers/media/3-container-ubuntu-host-os.svg" alt="Diagram showing a Docker image with an Ubuntu base OS and the dependency on the host OS Kernel." data-linktype="relative-path"> </span></p>
<p>The container OS is isolated from the host OS and is the environment in which we deploy and run our application. Combined with the image&#8217;s immutability, this isolation means the environment for our application running in development is the same as in production.</p>
<p>In our example, we&#8217;re using Ubuntu Linux as the container OS and this OS doesn&#8217;t change from development or production. The image we use is always the same.</p>
<h2 id="what-is-the-stackable-unification-file-system-unionfs">What is the Stackable Unification File System (<code>Unionfs</code>)?</h2>
<p><code>Unionfs</code> is used to create Docker images. <code>Unionfs</code> is a filesystem that allows you to stack several directories, called branches, in such a way that it appears as if the content is merged. However, the content is physically kept separate. <code>Unionfs</code> allows you to add and remove branches as you build out your file system.</p>
<p><span class="mx-imgBorder"> <img decoding="async" src="https://docs.microsoft.com/en-us/learn/modules/intro-to-docker-containers/media/3-unionfs-diagram.svg" alt="Diagram showing the stacking of layers in a Docker image created with unionfs." data-linktype="relative-path"> </span></p>
<p>For example, assume we&#8217;re building an image for our web application from earlier. We&#8217;ll layer the Ubuntu distribution as a base image on top of the boot file system. Next we&#8217;ll install Nginx and our web app. We&#8217;re effectively layering Nginx and the web app on top of the original Ubuntu image.</p>
<p>A final writeable layer is created once the container is run from the image. This layer however, does not persist when the container is destroyed.</p>
<h2 id="what-is-a-base-image">What is a base image?</h2>
<p>A base image is an image that uses the Docker <code>scratch</code> image. The <code>scratch</code> image is an empty container image that doesn&#8217;t create a filesystem layer. This image assumes that the application you&#8217;re going to run can directly use the host OS kernel.</p>
<h2 id="what-is-a-parent-image">What is a parent image?</h2>
<p>A parent image is a container image from which you create your images.</p>
<p>For example, instead of creating an image from <code>scratch</code> and then installing Ubuntu, we&#8217;ll rather use an image already based on Ubuntu. We can even use an image that already has Nginx installed. A parent image usually includes a container OS.</p>
<h2 id="what-is-the-main-difference-between-base-and-parent-images">What is the main difference between base and parent images?</h2>
<p>Both image types allow us to create a reusable image. However, base images allow us more control over the contents of the final image. Recall from earlier that an image is immutable, you can only add to an image and not subtract.</p>
<h2 id="what-is-a-dockerfile">What is a Dockerfile?</h2>
<p>A Dockerfile is a text file that contains the instructions we use to build and run a Docker image. The following aspects of the image are defined:</p>
<ul>
<li>The base or parent image we use to create the new image</li>
<li>Commands to update the base OS and install additional software</li>
<li>Build artifacts to include, such as a developed application</li>
<li>Services to expose, such a storage and network configuration</li>
<li>Command to run when the container is launched</li>
</ul>
<p>Let&#8217;s map these aspects to an example Dockerfile. Suppose we&#8217;re creating a Docker image for our ASP.NET Core website. The Dockerfile may look like the following example.</p>
<div id="code-try-0" class="codeHeader" data-bi-name="code-header"><span class="language">Bash</span></div>
<pre class="has-inner-focus" tabindex="0"><code class="lang-bash" data-author-content="# Step 1: Specify the parent image for the new image
FROM ubuntu:18.04

# Step 2: Update OS packages and install additional software
RUN apt -y update &amp;&amp;  apt install -y wget nginx software-properties-common apt-transport-https \
	&amp;&amp; wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb \
	&amp;&amp; dpkg -i packages-microsoft-prod.deb \
	&amp;&amp; add-apt-repository universe \
	&amp;&amp; apt -y update \
	&amp;&amp; apt install -y dotnet-sdk-3.0

# Step 3: Configure Nginx environment
CMD service nginx start

# Step 4: Configure Nginx environment
COPY ./default /etc/nginx/sites-available/default

# STEP 5: Configure work directory
WORKDIR /app

# STEP 6: Copy website code to container
COPY ./website/. .

# STEP 7: Configure network requirements
EXPOSE 80:8080

# STEP 8: Define the entry point of the process that runs in the container
ENTRYPOINT [&quot;dotnet&quot;, &quot;website.dll&quot;]
"><span class="hljs-comment"># Step 1: Specify the parent image for the new image</span>
FROM ubuntu:18.04

<span class="hljs-comment"># Step 2: Update OS packages and install additional software</span>
RUN apt -y update &amp;&amp;  apt install -y wget nginx software-properties-common apt-transport-https \
	&amp;&amp; wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb \
	&amp;&amp; dpkg -i packages-microsoft-prod.deb \
	&amp;&amp; add-apt-repository universe \
	&amp;&amp; apt -y update \
	&amp;&amp; apt install -y dotnet-sdk-3.0

<span class="hljs-comment"># Step 3: Configure Nginx environment</span>
CMD service nginx start

<span class="hljs-comment"># Step 4: Configure Nginx environment</span>
COPY ./default /etc/nginx/sites-available/default

<span class="hljs-comment"># STEP 5: Configure work directory</span>
WORKDIR /app

<span class="hljs-comment"># STEP 6: Copy website code to container</span>
COPY ./website/. .

<span class="hljs-comment"># STEP 7: Configure network requirements</span>
EXPOSE 80:8080

<span class="hljs-comment"># STEP 8: Define the entry point of the process that runs in the container</span>
ENTRYPOINT [<span class="hljs-string">"dotnet"</span>, <span class="hljs-string">"website.dll"</span>]
</code></pre>
<p>We&#8217;re not going to cover the Dockerfile file specification here or the detail of each command in our above example. However, notice that there are several commands in this file that allow us to manipulate the structure of the image.</p>
<p>Recall, we mentioned earlier that Docker images make use of <em>unionfs</em>. Each of these steps creates a cached container image as we build the final container image. These temporary images are layered on top of the previous and presented as single image once all steps complete.</p>
<p>Finally, notice the last step, step 8. The <code>ENTRYPOINT</code> in the file indicates which process will execute once we run a container from an image.</p>
<h2 id="how-to-manage-docker-images">How to manage Docker images</h2>
<p>Docker images are large files that initially get stored on your PC and we need tools to manage these files.</p>
<p>The Docker CLI allows us to manage images by building, listing, removing, and running them. We manage Docker images by using the <code>docker</code> client. The client doesn&#8217;t execute the commands directly and sends all queries to the <code>dockerd</code> daemon.</p>
<p>We aren&#8217;t going to cover all the client commands and command flags here, but we&#8217;ll look at some of the most used commands. The <em>learn more</em> section of this module includes links to Docker documentation, which covers all commands and command flags in detail.</p>
<h2 id="how-to-build-an-image">How to build an image</h2>
<p>We use the <code>docker build</code> command to build Docker images. Let&#8217;s assume we use the Dockerfile definition from earlier to build an image. Here is an example that shows the build command.</p>
<div id="code-try-1" class="codeHeader" data-bi-name="code-header"><span class="language">Bash</span></div>
<pre class="has-inner-focus" tabindex="0"><code class="lang-bash" data-author-content="docker build -t temp-ubuntu .
">docker build -t temp-ubuntu .
</code></pre>
<p>Here is the output generated from the build command:</p>
<div id="code-try-2" class="codeHeader" data-bi-name="code-header"><span class="language">Output</span></div>
<pre class="has-inner-focus" tabindex="0"><code class="lang-output" data-author-content="Sending build context to Docker daemon  4.69MB
Step 1/8 : FROM ubuntu:18.04
 ---> a2a15febcdf3
Step 2/8 : RUN apt -y update &amp;&amp; apt install -y wget nginx software-properties-common apt-transport-https &amp;&amp; wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb &amp;&amp; dpkg -i packages-microsoft-prod.deb &amp;&amp; add-apt-repository universe &amp;&amp; apt -y update &amp;&amp; apt install -y dotnet-sdk-3.0
 ---> Using cache
 ---> feb452bac55a
Step 3/8 : CMD service nginx start
 ---> Using cache
 ---> ce3fd40bd13c
Step 4/8 : COPY ./default /etc/nginx/sites-available/default
 ---> 97ff0c042b03
Step 5/8 : WORKDIR /app
 ---> Running in 883f8dc5dcce
Removing intermediate container 883f8dc5dcce
 ---> 6e36758d40b1
Step 6/8 : COPY ./website/. .
 ---> bfe84cc406a4
Step 7/8 : EXPOSE 80:8080
 ---> Running in b611a87425f2
Removing intermediate container b611a87425f2
 ---> 209b54a9567f
Step 8/8 : ENTRYPOINT [&quot;dotnet&quot;, &quot;website.dll&quot;]
 ---> Running in ea2efbc6c375
Removing intermediate container ea2efbc6c375
 ---> f982892ea056
Successfully built f982892ea056
Successfully tagged temp-ubuntu:latest
">Sending build context to Docker daemon  4.69MB
Step 1/8 : FROM ubuntu:18.04
 ---&gt; a2a15febcdf3
Step 2/8 : RUN apt -y update &amp;&amp; apt install -y wget nginx software-properties-common apt-transport-https &amp;&amp; wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb &amp;&amp; dpkg -i packages-microsoft-prod.deb &amp;&amp; add-apt-repository universe &amp;&amp; apt -y update &amp;&amp; apt install -y dotnet-sdk-3.0
 ---&gt; Using cache
 ---&gt; feb452bac55a
Step 3/8 : CMD service nginx start
 ---&gt; Using cache
 ---&gt; ce3fd40bd13c
Step 4/8 : COPY ./default /etc/nginx/sites-available/default
 ---&gt; 97ff0c042b03
Step 5/8 : WORKDIR /app
 ---&gt; Running in 883f8dc5dcce
Removing intermediate container 883f8dc5dcce
 ---&gt; 6e36758d40b1
Step 6/8 : COPY ./website/. .
 ---&gt; bfe84cc406a4
Step 7/8 : EXPOSE 80:8080
 ---&gt; Running in b611a87425f2
Removing intermediate container b611a87425f2
 ---&gt; 209b54a9567f
Step 8/8 : ENTRYPOINT ["dotnet", "website.dll"]
 ---&gt; Running in ea2efbc6c375
Removing intermediate container ea2efbc6c375
 ---&gt; f982892ea056
Successfully built f982892ea056
Successfully tagged temp-ubuntu:latest
</code></pre>
<p>Don&#8217;t worry if you don&#8217;t understand the above output. However, notice the steps listed in the output. When each step executes, a new layer gets added to the image we&#8217;re building.</p>
<p>Also, notice that we execute a number of commands to install software and manage configuration. For example, in step 2, we run the <code>apt -y update</code> and <code>apt install -y</code> commands to update the OS. These commands execute in a running container that is created for that step. Once the command has run, the intermediate container is removed. The underlying cached image is kept on the build host and not automatically deleted. This optimization ensures that later builds reuse these images to speed up build times.</p>
<h3 id="what-is-an-image-tag">What is an image tag?</h3>
<p>An image tag is a text string that is used to version an image.</p>
<p>In the example build from earlier, notice the last build message that reads &#8220;Successfully tagged <em>temp-ubuntu: latest</em>&#8220;. When building an image, we name and optionally tag the image using the <code>-t</code> command flag. In our example, we named the image using <code>-t temp-ubuntu</code>, while the resulting image name was tagged <em>temp-ubuntu: latest</em>. An image is labeled with the <code>latest</code> tag if you don&#8217;t specify a tag.</p>
<p>A single image can have multiple tags assigned to it. By convention, the most recent version of an image is assigned the <em>latest</em> tag and a tag that describes the image version number. When you release a new version of an image, you can reassign the latest tag to reference the new image.</p>
<p>Here is another example. Suppose you want to use the .NET Core samples Docker images. Here we have four platforms versions that we can choose from:</p>
<ul>
<li><code>mcr.microsoft.com/dotnet/core/samples:dotnetapp</code></li>
<li><code>mcr.microsoft.com/dotnet/core/samples:aspnetapp</code></li>
<li><code>mcr.microsoft.com/dotnet/core/samples:wcfservice</code></li>
<li><code>mcr.microsoft.com/dotnet/core/samples:wcfclient</code></li>
</ul>
<h2 id="how-to-list-images">How to list images</h2>
<p>The Docker software automatically configures a local image registry on your machine. You can view the images in this registry with the <code>docker images</code> command.</p>
<div id="code-try-3" class="codeHeader" data-bi-name="code-header"><span class="language">Console</span></div>
<pre class="has-inner-focus" tabindex="0"><code class="lang-console" data-author-content="docker images
">docker images
</code></pre>
<p>The output looks like the example below.</p>
<div id="code-try-4" class="codeHeader" data-bi-name="code-header"><span class="language">Output</span></div>
<pre class="has-inner-focus" tabindex="0"><code class="lang-output" data-author-content="REPOSITORY          TAG                     IMAGE ID            CREATED                     SIZE
tmp-ubuntu          latest             f89469694960        14 minutes ago         1.69GB
tmp-ubuntu          version-1.0        f89469694960        14 minutes ago         1.69GB
ubuntu              18.04                   a2a15febcdf3        5 weeks ago            64.2MB
">REPOSITORY          TAG                     IMAGE ID            CREATED                     SIZE
tmp-ubuntu          latest             f89469694960        14 minutes ago         1.69GB
tmp-ubuntu          version-1.0        f89469694960        14 minutes ago         1.69GB
ubuntu              18.04                   a2a15febcdf3        5 weeks ago            64.2MB
</code></pre>
<p>Notice how the image is listed with its <em>Name</em>, <em>Tag</em>, and an <em>Image ID</em>. Recall that we can apply multiple labels to an image. Here is such an example. Even though the image names are different, we can see the IDs are the same.</p>
<p>The image ID is a useful way to identify and manage images where the name or tag of an image might be ambiguous.</p>
<h2 id="how-to-remove-an-image">How to remove an image</h2>
<p>You can remove an image from the local docker registry with the <code>docker rmi</code> command. Specify the name or ID of the image to remove. This example removes the image for the sample web app using the image name:</p>
<div id="code-try-5" class="codeHeader" data-bi-name="code-header"><span class="language">code</span></div>
<pre class="has-inner-focus" tabindex="0"><code class="lang-code" data-author-content="docker rmi temp-ubuntu:version-1.0
">docker rmi temp-ubuntu:version-1.0
</code></pre>
<p>You can&#8217;t remove an image if the image is still in use by a container. The <code>docker rmi </code> command returns an error message, which lists the container relying on the image.</p>
<p>We&#8217;ve explored the basics of Docker images, how to manage these images and how to run a container from an image.</p>
<p>The post <a href="http://kostacipo.stream/how-docker-images-work/">How Docker Images Work</a> appeared first on <a href="http://kostacipo.stream">Tech Chronicles</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://kostacipo.stream/how-docker-images-work/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Containers vs Virtual Machines (VMs): What&#8217;s the Difference?</title>
		<link>http://kostacipo.stream/containers-vs-virtual-machines-vms-whats-the-difference/</link>
					<comments>http://kostacipo.stream/containers-vs-virtual-machines-vms-whats-the-difference/#respond</comments>
		
		<dc:creator><![CDATA[Majordomo]]></dc:creator>
		<pubDate>Mon, 20 Apr 2020 13:11:46 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[containers]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[virtual machines]]></category>
		<guid isPermaLink="false">http://www.kostacipo.stream/?p=1786</guid>

					<description><![CDATA[<p>&#160; Both virtual machines and containers are used to created isolated virtual environments for developing and testing applications or software. The question is how they differ. This article examines the two concepts to help understand the difference between a container and a VM. It defines containers and virtual machines separately, as well as side-by-side, to [&#8230;]</p>
<p>The post <a href="http://kostacipo.stream/containers-vs-virtual-machines-vms-whats-the-difference/">Containers vs Virtual Machines (VMs): What&#8217;s the Difference?</a> appeared first on <a href="http://kostacipo.stream">Tech Chronicles</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>&nbsp;</p>
<div class="uncode_text_column">
<p>Both <strong>virtual machines</strong> and <strong>containers</strong> are used to created isolated virtual environments for developing and testing applications or software. The question is how they differ.</p>
<p>This article examines the two concepts to help understand the difference between a container and a VM. It defines containers and virtual machines separately, as well as side-by-side, to see what makes one distinct from the other.</p>
</div>
<div class="heading-text el-text">
<h2 class="h3"><span id="htoc-what-are-virtual-machines-vms">What are Virtual Machines (VMs)?</span></h2>
</div>
<div class="clear">&nbsp;</div>
<div class="uncode_text_column">
<p>A<strong> virtual machine (VM)</strong> is an operating system that shares the physical resources of one server. It is a guest on the host’s hardware, which is why it is also called a <strong>guest machine</strong>.</p>
<p>There are several layers that make up a virtual machine. The layer that enables virtualization is the <strong>hypervisor</strong>. A hypervisor is a software that virtualizes the server.</p>
</div>
<div class="heading-text el-text">
<h2 class="h3"><span id="htoc-how-a-virtual-machine-works">How a Virtual Machine Works</span></h2>
</div>
<div class="clear">&nbsp;</div>
<div class="uncode_text_column">
<p>Everything necessary to run an app is contained within the virtual machine – the virtualized hardware, an OS, and any required binaries and libraries. Therefore, virtual machines have their own infrastructure and are self-contained.</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-84024 size-full lazyloaded" src="https://phoenixnap.com/kb/wp-content/uploads/2019/04/hypervisor-host-os-of-a-virtual-machine.png" alt="hypervisor host os of a virtual machine diagram " data-lazy-src="https://phoenixnap.com/kb/wp-content/uploads/2019/04/hypervisor-host-os-of-a-virtual-machine.png" data-was-processed="true" width="506" height="508"></p>
<p>Each VM is completely isolated from the host operating system. Also, it requires its own OS, which can be different from the host’s OS. Each has its own binaries, libraries, and applications.</p>
</div>
<div class="divider-wrapper ">
<hr class="border-accent-color separator-no-padding"></div>
<div class="icon-box icon-box-left">
<div class="icon-box-content">
<p><strong>Virtual machine monitor (VMM)</strong>: another name for the hypervisor</p>
<p><strong>Host machine</strong>: the hardware on which the VM is installed</p>
<p><strong>Guest&nbsp;</strong><strong>machine</strong>: another name for the VM</p>
</div>
</div>
<div class="divider-wrapper ">
<hr class="border-accent-color separator-no-padding">
<h3 class="h3"><span id="htoc-virtual-machine-pros">Virtual Machine: PROS</span></h3>
</div>
<div class="clear">&nbsp;</div>
<div class="uncode_text_column">
<p>VMs <strong>reduce expenses</strong>. Instead of running an application on a single server, a virtual machine enables utilizing one physical resource to do the job of many. Therefore, you do not have to buy, maintain and store enumerable stacks of servers.</p>
<p>Because there is one host machine, it allows you to <strong>efficiently manage</strong> all the virtual environments with the centralized power of the hypervisor. These systems are entirely separate from each other meaning you can install <strong>multiple system environments</strong>.</p>
<p>Most importantly, a virtual machine is isolated from the host OS and is a <strong>safe</strong> place for experimenting and developing applications.</p>
</div>
<div class="heading-text el-text">
<h3 class="h3"><span id="htoc-virtual-machine-cons">Virtual Machine: CONS</span></h3>
</div>
<div class="clear">&nbsp;</div>
<div class="uncode_text_column">
<p><strong>Virtual machines may take up a lot of system resources&nbsp;</strong>of the host machine, being many GBs in size. Running a single app on a virtual server means running a copy of an operating system as well as a virtual copy of all the hardware required for the system to run. This quickly adds up to a lot of RAM and CPU cycles.</p>
<p>The process of&nbsp;<strong>relocating an app running on a virtual machine can also be complicated&nbsp;</strong>as it is always attached to the operating system. Hence, you have to migrate the app as well as the OS with it. Also, when creating a virtual machine, the hypervisor allocates hardware resources dedicated to the VM.</p>
<p>A virtual machine rarely uses all the resources available which can&nbsp;<strong>make the planning and distribution difficult.&nbsp;</strong>That’s still economical compared to running separate actual computers.</p>
</div>
<div class="heading-text el-text">
<h3 class="h3"><span id="htoc-popular-vm-providers">Popular VM providers:</span></h3>
</div>
<div class="clear">&nbsp;</div>
<div class="uncode_text_column">
<ul>
<li>VMware vSphere</li>
<li>VirtualBox</li>
<li>Zen</li>
<li>Hyper-V</li>
<li>KVM</li>
</ul>
<p>&nbsp;</p>
<h2><span id="htoc-what-is-a-container">What is a Container?</span></h2>
</div>
<div class="clear">&nbsp;</div>
<div class="uncode_text_column">
<p>A container is an environment that runs an application that is not dependent on the operating system. It isolates the app from the host by virtualizing it. This allows users to created multiple workloads on a single OS instance.</p>
<p>The kernel of the host operating system serves the needs of running different functions of an app, separated into containers. Each container runs isolated tasks. It cannot harm the host machine nor come in conflict with other apps running in separate containers.</p>
</div>
<div class="heading-text el-text">
<h2 class="h3"><span id="htoc-how-do-containers-work">How do Containers Work?</span></h2>
</div>
<div class="clear">&nbsp;</div>
<div class="uncode_text_column">
<p>When working inside a container, you can create a template of an environment you need. The container essentially runs a snapshot of the system at a particular time, providing consistency in the behavior of an app.</p>
<p>The container shares the host’s kernel to run all the individual apps within the container. The only elements that each container requires are bins, libraries and other runtime components.</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-84025 size-full lazyloaded" src="https://phoenixnap.com/kb/wp-content/uploads/2019/04/container-elements.png" alt="container elements diagram" data-lazy-src="https://phoenixnap.com/kb/wp-content/uploads/2019/04/container-elements.png" data-was-processed="true" width="580" height="323"></p>
</div>
<div class="heading-text el-text">
<h3 class="h3"><span id="htoc-container-pros">Container: PROS</span></h3>
</div>
<div class="clear">&nbsp;</div>
<div class="uncode_text_column">
<p>Containers can be as small as 10MB. This makes containers remarkably <strong>lightweight</strong> and <strong>fast to launch</strong> as opposed to deploying virtual machines, where the entire operating system needs to be deployed.<br />Because of their size, you can quickly <strong>scale</strong> in and out of containers and add identical containers.</p>
<p>Also, containers are excellent for <strong>Continuous Integration and Continuous Deployment</strong> (CI/CD) implementation. They foster collaborative development by distributing and merging images among developers.</p>
</div>
<div class="heading-text el-text">
<h3 class="h3"><span id="htoc-container-cons">Container: CONS</span></h3>
</div>
<div class="clear">&nbsp;</div>
<div class="uncode_text_column">
<p>A container uses the kernel of the host OS and has operating system dependencies. Therefore, containers can differ from the underlying OS by dependency, but not by type. The host’s kernel <strong>limits the use of other operating systems</strong>.</p>
<p>Containers still do not offer the same <strong>security and stability</strong> that VMs can. Since they share the host’s kernel, they cannot be as isolated as a virtual machine. Consequently, containers are process-level isolated and one container can affect others by compromising the stability of the kernel.</p>
<p>Moreover, once a container performs its task, it shuts down, deleting all the data inside of it. If you want the data to remain on the host server, you have to save it using Data Volumes. This requires <strong>manual configuration and provisioning</strong> on the host.</p>
</div>
<div class="heading-text el-text">
<h3 class="h3"><span id="htoc-popular-container-providers">Popular Container Providers:</span></h3>
</div>
<div class="uncode_text_column">
<ul>
<li style="list-style-type: none;">
<ul>
<li style="list-style-type: none;">
<ul style="list-style-type: square;">
<li>Docker</li>
<li>AWS</li>
<li>LXD</li>
<li>Java Containers</li>
<li>Hyper-V Containers</li>
<li>Windows Server Containers</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<div class="heading-text el-text">
<h2>&nbsp;</h2>
<h2 class="h3"><span id="htoc-how-to-choose-vms-vs-containers">How to Choose VMs vs Containers</span></h2>
</div>
<div class="clear">&nbsp;</div>
<div class="uncode_text_column">
<p>Deciding whether to go for virtual machines or containers depends on the work you want your virtual environment to carry out.</p>
</div>
<div class="heading-text el-text">
<h3 class="h3"><span id="htoc-how-to-choose-vms-vs-containers">Virtual machines&nbsp;are a better solution if you need to:</span></h3>
</div>
<div class="uncode_text_column">
<ol>
<li>Manage a variety of operating systems</li>
<li>Manage multiple apps on a single server</li>
<li>Run an app that requires all the resources and functionalities of an OS</li>
<li>Ensure full isolation and security</li>
</ol>
</div>
<div class="uncode_text_column">&nbsp;</div>
<div class="heading-text el-text">
<h3 class="h3"><span id="htoc-how-to-choose-vms-vs-containers">Containers are suitable if you need to:</span></h3>
</div>
<div class="uncode_text_column">
<ol>
<li>Maximize the number of apps running on a server</li>
<li>Deploy multiple instances of a single application</li>
<li>Have a lightweight system that quickly starts</li>
<li>Develop an application that runs on any underlying infrastructure</li>
</ol>
</div>
<div class="divider-wrapper ">
<hr class="border-accent-color separator-no-padding"></div>
<div class="icon-box icon-box-left">
<div class="icon-box-icon fa-container">&nbsp;</div>
<div class="icon-box-content">
<p><strong>Note:&nbsp;</strong>VMs and containers should not necessarily be seen as rivals. Rather, you can use both to balance the workload between the two.</p>
</div>
</div>
<div class="divider-wrapper ">
<hr class="border-accent-color separator-no-padding"></div>
<div class="uncode_text_column">
<p><strong>Virtual machines are commonly used for&nbsp;</strong>demanding applications, network infrastructure, and apps that will consume most of the resources of the VM.</p>
</div>
<div class="uncode_text_column">
<p><strong>Containers are commonly used for&nbsp;</strong>web, applications and caching services, network daemons, and small databases.</p>
</div>
<div class="heading-text el-text">
<h3 class="h3"><span id="htoc-drawbacks-of-containers">Conclusion</span></h3>
</div>
<div class="clear">&nbsp;</div>
<div class="uncode_text_column">
<p>Before committing to VMs or containers, make sure to consider all the factors that will influence efficiency. Take into account the kind of tasks they will have to perform as well as the resources you have available.</p>
</div>
<p>The post <a href="http://kostacipo.stream/containers-vs-virtual-machines-vms-whats-the-difference/">Containers vs Virtual Machines (VMs): What&#8217;s the Difference?</a> appeared first on <a href="http://kostacipo.stream">Tech Chronicles</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://kostacipo.stream/containers-vs-virtual-machines-vms-whats-the-difference/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Docker Image Vs Container: The Major Differences</title>
		<link>http://kostacipo.stream/docker-image-vs-container-the-major-differences/</link>
					<comments>http://kostacipo.stream/docker-image-vs-container-the-major-differences/#respond</comments>
		
		<dc:creator><![CDATA[Majordomo]]></dc:creator>
		<pubDate>Mon, 20 Apr 2020 12:56:45 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[docker]]></category>
		<guid isPermaLink="false">http://www.kostacipo.stream/?p=1783</guid>

					<description><![CDATA[<p>&#160; Introduction Docker&#160;is an open-source software designed to facilitate and simplify application development. It is a set of platform-as-a-service products that create isolated virtualized environments for building, deploying, and testing applications. Although the software is relatively simple to master, there are some Docker-specific terms that new users may find confusing. Dockerfiles, images, containers, volumes, and [&#8230;]</p>
<p>The post <a href="http://kostacipo.stream/docker-image-vs-container-the-major-differences/">Docker Image Vs Container: The Major Differences</a> appeared first on <a href="http://kostacipo.stream">Tech Chronicles</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>&nbsp;</p>
<div class="heading-text el-text">
<h1 class="h3">Introduction</h1>
</div>
<div class="uncode_text_column">
<p><strong>Docker</strong>&nbsp;is an open-source software designed to facilitate and simplify application development. It is a set of platform-as-a-service products that create isolated virtualized environments for building, deploying, and testing applications.</p>
<p>Although the software is relatively simple to master, there are some Docker-specific terms that new users may find confusing. Dockerfiles, images, containers, volumes, and other terminology will need to be mastered and should become second nature over time.</p>
<p>It is a good idea to try to comprehend the basic roles of these elements. It will speed up learning on how to work with them. One of the questions many users ask is:</p>
</div>
<div class="heading-text el-text">
<h2 class="h2"><span id="htoc-what-is-a-docker-image">What is a Docker Image?</span></h2>
</div>
<div class="uncode_text_column">
<p>A <strong>Docker image</strong>&nbsp;is an immutable (unchangeable) file that contains the source code, libraries, dependencies, tools, and other files needed for an application to run.</p>
<p>Due to their&nbsp;<strong>read-only</strong>&nbsp;quality, these images are sometimes referred to as snapshots. They represent an application and its virtual environment at a specific point in time. This consistency is one of the great features of Docker. It allows developers to test and experiment software in stable, uniform conditions.</p>
<p>Since images are, in a way, just&nbsp;<strong>templates</strong>, you cannot start or run them. What you can do is use that template as a base to build a container. A container is, ultimately, just a running image. Once you create a container, it adds a writable layer on top of the immutable image, meaning you can now modify it.</p>
<p>The image-based on which you create a container exists separately and cannot be altered. When you run a&nbsp;containerized environment, you essentially create a&nbsp;<strong>read-write copy</strong>&nbsp;of that filesystem (docker image) inside the container. This adds a&nbsp;<strong>container layer&nbsp;</strong>which allows modifications of the entire copy of the image.</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-85144 size-full lazyloaded" src="https://phoenixnap.com/kb/wp-content/uploads/2019/10/container-layers.png" alt="Brief explanation of Container Layer and Image layer" data-lazy-src="https://phoenixnap.com/kb/wp-content/uploads/2019/10/container-layers.png" data-was-processed="true" width="511" height="338"></p>
<p>You can create an unlimited number of Docker images from one&nbsp;<strong>image base</strong>. Each time you change the initial state of an image and save the existing state, you create a new template with an additional layer on top of it.</p>
<p>Docker images can, therefore, consist of a&nbsp;<strong>series of layers</strong>, each differing but also originating from the previous one. Image layers represent read-only files to which a container layer is added once you use it to start up a virtual environment.</p>
</div>
<div class="heading-text el-text">
<h2 class="h2"><span id="htoc-what-is-a-docker-container">What is a Docker Container?</span></h2>
</div>
<div class="uncode_text_column">
<p>A <strong>Docker container</strong>&nbsp;is a virtualized run-time environment where users can isolate applications from the underlying system. These containers are compact, portable units in which you can start up an application quickly and easily.</p>
<p>A valuable feature is the&nbsp;<strong>standardization</strong>&nbsp;of the computing environment running inside the container. Not only does it ensure your application is working in identical circumstances, but it also simplifies sharing with other teammates.</p>
<p>As containers are autonomous, they provide strong isolation, ensuring they do not interrupt other running containers, as well as the server that supports them. Docker claims that these units “provide the strongest isolation capabilities in the industry”. Therefore, you won’t have to worry about keeping your machine&nbsp;<strong>secure</strong>&nbsp;while developing an application.</p>
<p>Unlike virtual machines (VMs) where virtualization happens at the hardware level, containers virtualize at the app layer. They can utilize one machine, share its kernel, and virtualize the operating system to run isolated processes. This makes containers extremely&nbsp;<strong>lightweight</strong>, allowing you to retain valuable resources.</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-85142 size-full lazyloaded" src="https://phoenixnap.com/kb/wp-content/uploads/2019/10/container-vs-virtual-machine.png" alt="The difference in structure between containers and virtual machines" data-lazy-src="https://phoenixnap.com/kb/wp-content/uploads/2019/10/container-vs-virtual-machine.png" data-was-processed="true" width="562" height="392"></p>
</div>
<div class="divider-wrapper ">&nbsp;</div>
<div class="divider-wrapper ">
<h2 class="h2"><span id="htoc-docker-images-vs-containers">Docker Images vs Containers</span></h2>
</div>
<div class="clear">&nbsp;</div>
<div class="uncode_text_column">
<p>When discussing the difference between images and containers, it isn’t fair to contrast them as opposing entities. Both elements are closely&nbsp;<strong>related and are part of a system</strong>&nbsp;defined by the Docker platform.</p>
<p>If you have read the previous two sections that define docker images and docker containers, you may already have some understanding as to how the two establish a relationship.</p>
<p>Images can exist without containers, whereas a container needs to run an image to exist. Therefore, containers are dependent on images and use them to construct a run-time environment and run an application.</p>
<p>The two concepts exist as essential components (or rather phases) in the process of running a Docker container. Having a running container is the final “phase” of that process, indicating it is dependent on previous steps and components. That is why docker images essentially govern and shape containers.</p>
</div>
<div class="heading-text el-text">
<h3 class="h3"><span id="htoc-from-dockerfile-to-image-to-container">From Dockerfile to Image to Container</span></h3>
</div>
<div class="uncode_text_column">
<p>It all starts with a script of instructions that define how to build a specific Docker image. This script is called a Dockerfile. The file automatically executes the outlined commands and creates a&nbsp;<strong>Docker image</strong>.</p>
<p>The command for creating an image from a Dockerfile is&nbsp;<strong><code>docker build</code></strong>.</p>
<p>The image is then used as a template (or base), which a developer can copy and use it to run an application. The application needs an isolated environment in which to run – a&nbsp;<strong>container</strong>.</p>
<p>This environment is not just a virtual “space”. It entirely relies on the image that created it. The source code, files, dependencies, and binary libraries, which are all found in the Docker image, are the ones that make up a container.</p>
<p>To create a container layer from an image, use the command&nbsp;<strong><code>docker create</code></strong>.</p>
<p>Finally, after you have launched a container from an existing image, you start its service and run&nbsp;the application.</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-85187 aligncenter lazyloaded" src="https://phoenixnap.com/kb/wp-content/uploads/2019/10/crating-a-docker-container.png" alt="how a docker container is created" data-lazy-src="https://phoenixnap.com/kb/wp-content/uploads/2019/10/crating-a-docker-container.png" data-was-processed="true" width="741" height="167"></p>
</div>
<div class="divider-wrapper ">
<hr class="border-accent-color separator-no-padding"></div>
<div class="icon-box icon-box-left">
<div class="icon-box-icon fa-container">&nbsp;</div>
<div class="icon-box-content">
<p><strong>Creating a Docker Image from a Container.</strong></p>
<p>If you make changes to the initial image and you want to preserve it for future work, you can save the modified image by taking a screenshot of the current state of the container. By doing so, you&nbsp;attach a container&nbsp;layer on top of the image, ultimately building a new immutable image. As a result, you end up with two Docker images derived from the same filesystem.</p>
</div>
</div>
<hr class="border-accent-color separator-no-padding">
<h3 class="divider-wrapper ">Conclusion</h3>
<div class="uncode_text_column">
<p>Once you understand the process of creating a container, you will easily recognize how different images and containers are. After reading this article, you should now have a good understanding of what a Docker image is, what a container is, and how they are connected.</p>
</div>
<p>The post <a href="http://kostacipo.stream/docker-image-vs-container-the-major-differences/">Docker Image Vs Container: The Major Differences</a> appeared first on <a href="http://kostacipo.stream">Tech Chronicles</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://kostacipo.stream/docker-image-vs-container-the-major-differences/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Docker Cheat Sheet</title>
		<link>http://kostacipo.stream/docker-cheat-sheet/</link>
					<comments>http://kostacipo.stream/docker-cheat-sheet/#respond</comments>
		
		<dc:creator><![CDATA[Majordomo]]></dc:creator>
		<pubDate>Wed, 26 Feb 2020 10:42:28 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[docker]]></category>
		<guid isPermaLink="false">http://www.kostacipo.stream/?p=1762</guid>

					<description><![CDATA[<p>&#160; 1. Fundamentals 1.1. Concepts Union file system (UFS): allows to overlay multiple file systems appearing as a single system whereby equal folders are merged and equally named files hide their previous versions Image: a portable read-only file system layer optionally stacked on a parent image Dockerfile: used to&#160;build&#160;an image and declare the command executed [&#8230;]</p>
<p>The post <a href="http://kostacipo.stream/docker-cheat-sheet/">Docker Cheat Sheet</a> appeared first on <a href="http://kostacipo.stream">Tech Chronicles</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>&nbsp;</p>
<h1 id="fundamentals">1. Fundamentals</h1>
<h2 id="concepts">1.1. Concepts</h2>
<ul>
<li><strong>Union file system (UFS)</strong>: allows to overlay multiple file systems appearing as a single system whereby equal folders are merged and equally named files hide their previous versions</li>
<li><strong>Image</strong>: a portable read-only file system layer optionally stacked on a parent image</li>
<li><strong>Dockerfile</strong>: used to&nbsp;<code class="highlighter-rouge">build</code>&nbsp;an image and declare the command executed in the container</li>
<li><strong>Registry</strong>: is the place where to&nbsp;<code class="highlighter-rouge">push</code>&nbsp;and&nbsp;<code class="highlighter-rouge">pull</code>&nbsp;from named / tagged images</li>
<li><strong>Container</strong>: an instance of an image with a writable file system layer on top, virtual networking, ready to execute a single application</li>
<li><strong>Volume</strong>: a directory outside the UFS that can be mounted inside containers for persistent and shared data</li>
<li><strong>Network</strong>: acts as a namespace for containers</li>
<li><strong>Service</strong>: a flexible number of container replicas running on a cluster of multiple hosts</li>
</ul>
<h2 id="lifecycle">1.2. Lifecycle</h2>
<p><em>A typical&nbsp;<code class="highlighter-rouge">docker</code>&nbsp;workflow:</em></p>
<ul>
<li><code class="highlighter-rouge">build</code>&nbsp;an image based on a&nbsp;<code class="highlighter-rouge">Dockerfile</code></li>
<li><code class="highlighter-rouge">tag</code>&nbsp;and&nbsp;<code class="highlighter-rouge">push</code>&nbsp;the image to a&nbsp;<em>registry</em></li>
<li><code class="highlighter-rouge">login</code>&nbsp;to the registry from the runtime environment to&nbsp;<code class="highlighter-rouge">pull</code>&nbsp;the image</li>
<li>optionally&nbsp;<code class="highlighter-rouge">create</code>&nbsp;a&nbsp;<code class="highlighter-rouge">volume</code>&nbsp;or two to provide configuration files and hold data that needs to be persisted</li>
<li><code class="highlighter-rouge">run</code>&nbsp;a container based on the image</li>
<li><code class="highlighter-rouge">stop</code>&nbsp;and&nbsp;<code class="highlighter-rouge">start</code>&nbsp;the container if necessary</li>
<li><code class="highlighter-rouge">commit</code>&nbsp;the container to turn it into an image (note: makes the image harder to reproduce)</li>
<li>in exceptional situations,&nbsp;<code class="highlighter-rouge">exec</code>&nbsp;additional commands inside the container</li>
<li>to replace a container with an updated version:
<ul>
<li><code class="highlighter-rouge">pull</code>&nbsp;the new image from the registry</li>
<li><code class="highlighter-rouge">stop</code>&nbsp;the running container</li>
<li>backup your volumes to be prepared for a potential rollback</li>
<li><code class="highlighter-rouge">run</code>&nbsp;the newer one by specifying a temporary name</li>
<li>if successful,&nbsp;<code class="highlighter-rouge">remove</code>&nbsp;the old container and&nbsp;<code class="highlighter-rouge">rename</code>&nbsp;the new one accordingly</li>
</ul>
</li>
</ul>
<h1 id="recipes">2. Recipes</h1>
<h2 id="docker-engine">2.1. Docker Engine</h2>
<h4 id="show-docker-disk-usage">Show docker disk usage</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker system df
</code></pre>
</div>
<h4 id="remove-unused-data">Remove unused data</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker system prune
</code></pre>
</div>
<p class="note">This prompts for confirmation and will remove: all stopped containers, all volumes not used by at least one container, all networks not used by at least one container and all dangling images</p>
<h3 id="building-images">2.1.1. Building Images</h3>
<h4 id="debug-image-build">Debug image build</h4>
<ul>
<li><code class="highlighter-rouge">docker image build</code>&nbsp;shows the IDs of all temporary containers and intermediate images</li>
<li>use&nbsp;<code class="highlighter-rouge">docker container run -it IMAGE_ID</code>&nbsp;with the ID of the image resulting from the last successful build step and try the next command manually</li>
</ul>
<h4 id="list-all-local-tags-for-the-same-image">List all local tags for the same image</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>
docker image ls --no-trunc | grep <span class="k">$(</span>docker image inspect -f <span class="o">{{</span>.Id<span class="o">}}</span> IMAGE:TAG<span class="k">)</span>

</code></pre>
</div>
<h3 id="running-containers">2.1.2. Running Containers</h3>
<h4 id="start-container-and-run-command-inside">Start container and run command inside</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker container run -it ubuntu:14.04 /bin/bash
</code></pre>
</div>
<h4 id="start-a-shell-in-a-running-container">Start a shell in a running container</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker container <span class="nb">exec</span> -it CONTAINER /bin/bash
</code></pre>
</div>
<h4 id="start-a-container-as-another-user">Start a container as another user</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker container run -u root IMAGE
</code></pre>
</div>
<h4 id="list-all-existing-containers">List all existing containers</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker container ls -a
</code></pre>
</div>
<h4 id="list-running-processes-inside-a-container">List running processes inside a container</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker container top CONTAINER
</code></pre>
</div>
<h4 id="follow-the-logs">Follow the logs</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker container logs -f --tail<span class="o">=</span>1000 CONTAINER
</code></pre>
</div>
<h4 id="stop-all-running-containers">Stop all running containers</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker container stop <span class="k">$(</span>docker container ls -q<span class="k">)</span>
</code></pre>
</div>
<h4 id="remove-all-stopped-containers-except-those-suffixed--data">Remove all stopped containers, except those suffixed ‘-data’:</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker container ls -a -f <span class="nv">status</span><span class="o">=</span>exited | grep -v <span class="s1">'\-data *$'</span>| awk <span class="s1">'{if(NR&gt;1) print $1}'</span> | xargs -r docker container rm
</code></pre>
</div>
<h4 id="remove-all-stopped-containers-warning-removes-data-only-containers-too">Remove all stopped containers (warning: removes data-only containers too)</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker container prune
</code></pre>
</div>
<h4 id="list-all-images">List all images</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker image ls -a
</code></pre>
</div>
<h4 id="remove-all-unused-images">Remove all unused images</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker image prune
</code></pre>
</div>
<h4 id="show-image-history-of-container">Show image history of container</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>
docker image <span class="nb">history</span> --no-trunc<span class="o">=</span><span class="nb">true</span> <span class="k">$(</span>docker container inspect -f <span class="s1">'{{.Image}}'</span> CONTAINER<span class="k">)</span>

</code></pre>
</div>
<h4 id="show-file-system-changes-compared-to-the-original-image">Show file system changes compared to the original image</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker container diff CONTAINER
</code></pre>
</div>
<h4 id="backup-directory-content-from-container-to-host-directory">Backup directory content from container to host directory</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker container run --rm --volumes-from SOURCE_CONTAINER:ro -v <span class="k">$(</span><span class="nb">pwd</span><span class="k">)</span>:/backup alpine <span class="se">\</span>
 tar cvf /backup/backup_<span class="k">$(</span>date +%Y-%m-%d_%H-%M<span class="k">)</span>.tar /data
</code></pre>
</div>
<h4 id="restore-directory-content-to-container-from-host-directory">Restore directory content to container from host directory</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker container run --rm --volumes-from TARGET_CONTAINER:ro -v <span class="k">$(</span><span class="nb">pwd</span><span class="k">)</span>:/backup alpine <span class="se">\</span>
 tar xvf /backup/backup.tar
</code></pre>
</div>
<h4 id="show-names-of-volumes-used-by-a-container">Show names of volumes used by a container</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>
docker container inspect -f <span class="s1">'{{ range .Mounts }}{{ .Name }} {{ end }}'</span> CONTAINER

</code></pre>
</div>
<h4 id="show-names-and-mount-point-destinations-of-volumes-used-by-a-container">Show names and mount point destinations of volumes used by a container</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>
docker container inspect -f <span class="s1">'{{ range .Mounts }}{{ .Name }}:{{ .Destination }} {{ end }}'</span> CONTAINER

</code></pre>
</div>
<h4 id="start-all-paused--stopped-containers">Start all paused / stopped containers</h4>
<ul>
<li>does not work together with container dependencies</li>
</ul>
<h4 id="edit-and-update-a-file-in-a-container">Edit and update a file in a container</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker container cp CONTAINER:FILE /tmp/ <span class="o">&amp;&amp;</span> docker container run --name<span class="o">=</span>nano -it --rm -v /tmp:/tmp <span class="se">\</span>
 piegsaj/nano nano /tmp/FILE ; <span class="se">\</span>
cat /tmp/FILE | docker container <span class="nb">exec</span> -i CONTAINER sh -c <span class="s1">'cat &gt; FILE'</span> ; <span class="se">\</span>
rm /tmp/FILE
</code></pre>
</div>
<h4 id="deploy-war-file-to-apache-tomcat-server-instantly">Deploy war file to Apache Tomcat server instantly</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker container run -i -t -p 80:8080 -e <span class="nv">WAR_URL</span><span class="o">=</span>“&lt;http://web-actions.googlecode.com/files/helloworld.war&gt;” <span class="se">\</span>
 bbytes/tomcat7
</code></pre>
</div>
<h4 id="dump-a-postgres-database-into-current-directory-on-the-host">Dump a Postgres database into current directory on the host</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code><span class="nb">echo</span> <span class="s2">"postgres_password"</span> | sudo docker container run -i --rm --link db:db -v <span class="nv">$PWD</span>:/tmp postgres:8 sh -c <span class="s1">' \
 pg_dump -h ocdb -p $OCDB_PORT_5432_TCP_PORT -U postgres -F tar -v openclinica \
 &gt; /tmp/ocdb_pg_dump_$(date +%Y-%m-%d_%H-%M-%S).tar'</span>
</code></pre>
</div>
<h4 id="backup-data-folder">Backup data folder</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker container run --rm --volumes-from oc-data -v <span class="nv">$PWD</span>:/tmp piegsaj/openclinica <span class="se">\</span>
 tar cvf /tmp/oc_data_backup_<span class="k">$(</span>date +%Y-%m-%d_%H-%M-%S<span class="k">)</span>.tar /tomcat/openclinica.data
</code></pre>
</div>
<h4 id="restore-volume-from-data-only-container">Restore volume from data-only container</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker container run --rm --volumes-from oc-data2 -v <span class="nv">$pwd</span>:/tmp piegsaj/openclinica <span class="se">\</span>
 tar xvf /tmp/oc_data_backup_<span class="k">*</span>.tar
</code></pre>
</div>
<h4 id="get-the-ip-address-of-a-container">Get the IP address of a container</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>
docker container inspect -f <span class="s1">'{{ .NetworkSettings.IPAddress }}'</span> CONTAINER

</code></pre>
</div>
<h3 id="using-volumes">2.1.3. Using Volumes</h3>
<h4 id="declare-a-volume-via-dockerfile">Declare a volume via Dockerfile</h4>
<div class="highlighter-rouge">
<pre class="highlight"><code>RUN mkdir /data &amp;&amp; echo "some content" &gt; /data/file &amp;&amp; chown -R daemon:daemon /data
VOLUME /data
</code></pre>
</div>
<p class="note">after the&nbsp;<code class="highlighter-rouge">VOLUME</code>&nbsp;directive, its content can not be changed within the Dockerfile</p>
<h4 id="create-an-anonymous-volume-at-runtime">Create an anonymous volume at runtime</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker container run -it -v /data debian /bin/bash
</code></pre>
</div>
<h4 id="create-a-volume-at-runtime-that-is-bound-to-a-host-directory">Create a volume at runtime that is bound to a host directory</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker container run --rm -v /tmp:/data debian ls -RAlph /data
</code></pre>
</div>
<h4 id="create-a-named-volume-and-use-it">Create a named volume and use it</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker volume create --name<span class="o">=</span><span class="nb">test
</span>docker container run --rm -v <span class="nb">test</span>:/data alpine sh -c <span class="s1">'echo "Hello named volumes" &gt; /data/hello.txt'</span>
docker container run --rm -v <span class="nb">test</span>:/data alpine sh -c <span class="s1">'cat /data/hello.txt'</span>
</code></pre>
</div>
<h4 id="list-the-content-of-a-volume">List the content of a volume</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker container run --rm -v data:/data alpine ls -RAlph /data
</code></pre>
</div>
<h4 id="copy-a-file-from-host-to-named-volume">Copy a file from host to named volume</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code><span class="nb">echo</span> <span class="s2">"debug=true"</span> &gt; test.cnf <span class="o">&amp;&amp;</span> <span class="se">\</span>
docker volume create --name<span class="o">=</span>conf <span class="o">&amp;&amp;</span> <span class="se">\</span>
docker container run --rm -it -v <span class="k">$(</span><span class="nb">pwd</span><span class="k">)</span>:/src -v conf:/dest alpine cp /src/test.cnf /dest/ <span class="o">&amp;&amp;</span> <span class="se">\</span>
rm -f test.cnf <span class="o">&amp;&amp;</span> <span class="se">\</span>
docker container run --rm -it -v conf:/data alpine cat /data/test.cnf
</code></pre>
</div>
<h4 id="copy-content-of-existing-volume-to-a-new-named-volume">Copy content of existing volume to a new named volume</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker volume create --name VOL_B
</code></pre>
</div>
<ul>
<li>than:</li>
</ul>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker container run --rm -v VOL_A:/source/folder:ro -v VOL_B:/target/folder <span class="se">\</span>
 alpine cp -r /source/folder /target
</code></pre>
</div>
<p>or without the need for an intermediate directory (<code class="highlighter-rouge">cp</code>&nbsp;implementations differ):</p>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code> docker container run --rm -v VOL_A:/source:ro -v VOL_B:/target debian cp -TR /source /target
</code></pre>
</div>
<h4 id="list-all-orphaned-volumes">List all orphaned volumes</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker volume ls -qf <span class="nv">dangling</span><span class="o">=</span><span class="nb">true</span>
</code></pre>
</div>
<h4 id="remove-all-orphaned-volumes">Remove all orphaned volumes</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker volume rm <span class="k">$(</span>docker volume ls -qf <span class="nv">dangling</span><span class="o">=</span><span class="nb">true</span><span class="k">)</span>
</code></pre>
</div>
<p class="note">Caution, this also removes&nbsp;<em>named volumes</em>&nbsp;that are currently not mounted by any container!</p>
<h2 id="docker-machine">2.2. Docker Machine</h2>
<h3 id="on-a-local-vm">On a local VM</h3>
<h4 id="get-the-ip-address-of-the-virtual-machine-for-access-from-host">Get the IP address of the virtual machine for access from host</h4>
<div class="highlighter-rouge">
<pre class="highlight"><code>docker-machine ip default
</code></pre>
</div>
<h4 id="add-persistent-environment-variable-to-boot2docker">Add persistent environment variable to boot2docker</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code><span class="nb">echo</span> <span class="s1">'echo '</span><span class="se">\'</span><span class="s1">'export ENVTEST="Hello Env!"'</span><span class="se">\'</span><span class="s1">' &gt; /etc/profile.d/custom.sh'</span> | <span class="se">\</span>
sudo tee -a /var/lib/boot2docker/profile &gt; /dev/null
</code></pre>
</div>
<p>and restart with&nbsp;<code class="highlighter-rouge">docker-machine restart default</code></p>
<h4 id="install-additional-linux-packages-in-boot2docker">Install additional linux packages in boot2docker</h4>
<ul>
<li>create the file&nbsp;<code class="highlighter-rouge">/var/lib/boot2docker/bootsync.sh</code>&nbsp;with a content like:</li>
</ul>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code><span class="c">#!/bin/sh</span>
sudo /bin/su - docker -c <span class="s1">'tce-load -wi nano'</span>
</code></pre>
</div>
<h4 id="recreate-any-folders-and-files-on-boot2docker-startup">Recreate any folders and files on boot2docker startup</h4>
<ul>
<li>store folders / files in&nbsp;<code class="highlighter-rouge">/var/lib/boot2docker/restore-on-boot</code>&nbsp;and</li>
<li>create the file&nbsp;<code class="highlighter-rouge">/var/lib/boot2docker/bootsync.sh</code>&nbsp;with a content like:</li>
</ul>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code><span class="c">#!/bin/sh</span>
sudo mkdir -p /var/lib/boot2docker/restore-on-boot <span class="o">&amp;&amp;</span> <span class="se">\</span>
sudo rsync -a /var/lib/boot2docker/restore-on-boot/ /
</code></pre>
</div>
<h2 id="dockerfile">2.3. Dockerfile</h2>
<h4 id="add-a-periodic-health-check">Add a periodic health check</h4>
<div class="highlighter-rouge">
<pre class="highlight"><code>HEALTHCHECK --interval=1m --timeout=3s --retries=5 \
 CMD curl -f &lt;http://localhost/&gt; || exit 1
</code></pre>
</div>
<ul>
<li>see also:&nbsp;<a href="https://docs.docker.com/engine/reference/builder/#/healthcheck">HEALTHCHECK</a></li>
</ul>
<h2 id="logging">2.4. Logging</h2>
<h3 id="enable-log-rotation-for-docker">Enable log rotation for Docker</h3>
<ul>
<li>create the file&nbsp;<code class="highlighter-rouge">/etc/logrotate.d/docker</code>&nbsp;and insert:</li>
</ul>
<div class="highlighter-rouge">
<pre class="highlight"><code>/var/lib/docker/containers/*/*.log {
  daily
  rotate 14
  compress
  delaycompress
  missingok
  copytruncate
}
</code></pre>
</div>
<ul>
<li>check&nbsp;<code class="highlighter-rouge">/etc/cron.daily/logrotate</code>&nbsp;and&nbsp;<code class="highlighter-rouge">/etc/crontab</code>&nbsp;for general logrotate configuration.</li>
</ul>
<p class="note">This example will keep all container logs for 14 days.</p>
<h1 id="showcases">3. Showcases</h1>
<h2 id="private-docker-registry">3.1. Private Docker Registry</h2>
<h4 id="setup-with-boot2docker-or-natively-on-linux">Setup with boot2docker or natively on Linux</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code><span class="nb">printf</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">Pulling registry image ...</span><span class="se">\n</span><span class="s2">"</span> <span class="o">&amp;&amp;</span> <span class="se">\</span>
docker image pull registry ; <span class="se">\</span>

<span class="nb">printf</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">Preparing registry-cert volume ...</span><span class="se">\n</span><span class="s2">"</span> <span class="o">&amp;&amp;</span> <span class="se">\</span>
docker volume create --name<span class="o">=</span>registry-cert <span class="o">&amp;&amp;</span> <span class="se">\</span>
<span class="nb">cd</span> /tmp <span class="o">&amp;&amp;</span> <span class="se">\</span>
openssl genrsa -out registry.key 4096 <span class="o">&amp;&amp;</span> <span class="se">\</span>
openssl req -new -nodes -sha256 -subj <span class="s1">'/CN=localhost'</span> -key /tmp/registry.key -out /tmp/registry.csr <span class="o">&amp;&amp;</span> <span class="se">\</span>
openssl x509 -req -days 3650 -signkey /tmp/registry.key -in /tmp/registry.csr -out /tmp/registry.pem <span class="o">&amp;&amp;</span> <span class="se">\</span>
docker container run --rm -it -v /tmp:/from -v registry-cert:/to --entrypoint sh registry <span class="se">\</span>
 -c <span class="s1">'cp /from/registry.key /to &amp;&amp; cp /from/registry.pem /to'</span> <span class="o">&amp;&amp;</span> <span class="se">\</span>

<span class="nb">printf</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">Letting docker client trust certificate ...</span><span class="se">\n</span><span class="s2">"</span> <span class="o">&amp;&amp;</span> <span class="se">\</span>
<span class="k">if</span> <span class="o">[</span> -d /var/lib/boot2docker <span class="o">]</span> ;
<span class="k">then
    </span>sudo mkdir -p /var/lib/boot2docker/certs <span class="o">&amp;&amp;</span> <span class="se">\</span>
    sudo cp /tmp/registry.pem /var/lib/boot2docker/certs
<span class="k">else
    </span>sudo mkdir -p /etc/docker/certs.d/localhost <span class="o">&amp;&amp;</span> <span class="se">\</span>
    sudo cp /tmp/registry.pem /etc/docker/certs.d/localhost
<span class="k">fi</span> <span class="o">&amp;&amp;</span> <span class="se">\</span>

<span class="nb">printf</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">Preparing registry-auth volume (please change 'reg_user' and 'reg_password') ...</span><span class="se">\n</span><span class="s2">"</span> <span class="o">&amp;&amp;</span> <span class="se">\</span>
docker volume create --name<span class="o">=</span>registry-auth <span class="o">&amp;&amp;</span> <span class="se">\</span>
docker container run --rm --entrypoint /bin/sh -v registry-auth:/auth registry <span class="se">\</span>
 -c <span class="s1">'htpasswd -Bbn reg_user reg_password &gt; /auth/htpasswd'</span> <span class="o">&amp;&amp;</span> <span class="se">\</span>

<span class="nb">printf</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">Preparing registry-data volume ...</span><span class="se">\n</span><span class="s2">"</span> <span class="o">&amp;&amp;</span> <span class="se">\</span>
docker volume create --name<span class="o">=</span>registry-data <span class="o">&amp;&amp;</span> <span class="se">\</span>

<span class="nb">printf</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">Running registry container ...</span><span class="se">\n</span><span class="s2">"</span> <span class="o">&amp;&amp;</span> <span class="se">\</span>
docker container run --name registry -h registry -d <span class="se">\</span>
-v registry-data:/var/lib/registry <span class="se">\</span>
-v registry-auth:/auth:ro <span class="se">\</span>
-v registry-cert:/certs:ro <span class="se">\</span>
--restart<span class="o">=</span>always <span class="se">\</span>
-p 5000:5000 <span class="se">\</span>
-e <span class="nv">REGISTRY_HTTP_TLS_KEY</span><span class="o">=</span>/certs/registry.key <span class="se">\</span>
-e <span class="nv">REGISTRY_HTTP_TLS_CERTIFICATE</span><span class="o">=</span>/certs/registry.pem <span class="se">\</span>
-e <span class="nv">REGISTRY_AUTH</span><span class="o">=</span>htpasswd <span class="se">\</span>
-e <span class="s2">"REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm"</span> <span class="se">\</span>
-e <span class="nv">REGISTRY_AUTH_HTPASSWD_PATH</span><span class="o">=</span>/auth/htpasswd <span class="se">\</span>
-e <span class="nv">REGISTRY_STORAGE_DELETE_ENABLED</span><span class="o">=</span><span class="nb">true</span> <span class="se">\</span>
registry</code></pre>
</div>
<h4 id="usage-example">Usage example</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker image pull alpine:latest <span class="o">&amp;&amp;</span> <span class="se">\</span>
docker login -u reg_user -p reg_password localhost:5000 <span class="o">&amp;&amp;</span> <span class="se">\</span>
docker image tag alpine:latest localhost:5000/alpine:private <span class="o">&amp;&amp;</span> <span class="se">\</span>
docker image rm alpine:latest <span class="o">&amp;&amp;</span> <span class="se">\</span>
docker image push localhost:5000/alpine:private <span class="o">&amp;&amp;</span> <span class="se">\</span>
docker image rm -f localhost:5000/alpine:private <span class="o">&amp;&amp;</span> <span class="se">\</span>
docker image pull localhost:5000/alpine:private <span class="o">&amp;&amp;</span> <span class="se">\</span>
docker <span class="nb">logout </span>localhost:5000 <span class="o">&amp;&amp;</span> <span class="se">\</span>
docker image ls | grep alpine <span class="o">&amp;&amp;</span> <span class="se">\</span>
<span class="nb">printf</span> <span class="s2">"Deleting image from registry ...</span><span class="se">\n</span><span class="s2">"</span> <span class="o">&amp;&amp;</span> <span class="se">\</span>
curl -X DELETE -u reg_user:reg_password --insecure <span class="se">\</span>
https://localhost:5000/v2/alpine/manifests/<span class="k">$(</span>docker image ls --digests | grep localhost:5000/alpine | awk <span class="s1">'{print $3}'</span><span class="k">)</span>
</code></pre>
</div>
<h4 id="removal">Removal</h4>
<div class="language-sh highlighter-rouge">
<pre class="highlight"><code>docker container rm -f registry <span class="o">&amp;&amp;</span> <span class="se">\</span>
docker volume rm registry-data registry-cert registry-auth
</code></pre>
</div>
<h4 id="further-reading">Further Reading</h4>
<ul>
<li>advanced authentication:&nbsp;<a href="https://github.com/cesanta/docker_auth">Docker Registry 2 authentication server</a></li>
<li>developer notes about&nbsp;<a href="https://github.com/docker/distribution/blob/master/ROADMAP.md#deletes">deleting images from the registry</a></li>
</ul>
<h2>&nbsp;</h2>
<h2 id="continuous-integration-tool-stack">3.2. Continuous Integration Tool Stack</h2>
<h4 id="setup-with-docker-machine--boot2docker">Setup with docker-machine / boot2docker</h4>
<ul>
<li>
<p>make a directory called&nbsp;<code class="highlighter-rouge">ci</code>&nbsp;in your home directory on your host system and change into it</p>
</li>
<li>
<p>create a file named&nbsp;<code class="highlighter-rouge">docker-compose.yml</code>&nbsp;with the following content:</p>
</li>
</ul>
<div class="language-yaml highlighter-rouge">
<pre class="highlight"><code><span class="s">version</span><span class="pi">:</span> <span class="s2">"</span><span class="s">2"</span>

<span class="s">services</span><span class="pi">:</span>

  <span class="s">jenkins</span><span class="pi">:</span>
    <span class="s">image</span><span class="pi">:</span> <span class="s">jenkins</span>
    <span class="s">ports</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s2">"</span><span class="s">8082:8082"</span>
      <span class="pi">-</span> <span class="s2">"</span><span class="s">50000:50000"</span>
    <span class="s">restart</span><span class="pi">:</span> <span class="s">always</span>
    <span class="s">env_file</span><span class="pi">:</span> <span class="s">.env</span>
    <span class="s">environment</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s2">"</span><span class="s">JAVA_OPTS=-Dmail.smtp.starttls.enable=true</span> <span class="s">-Dorg.apache.commons.jelly.tags.fmt.timeZone=Europe/Berlin"</span>
      <span class="pi">-</span> <span class="s2">"</span><span class="s">JENKINS_OPTS=--httpPort=8082"</span>
    <span class="s">volumes</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">jenkins_home:/var/jenkins_home</span>
    
  <span class="s">nexus</span><span class="pi">:</span>
    <span class="s">image</span><span class="pi">:</span> <span class="s">sonatype/nexus3</span>
    <span class="s">ports</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s2">"</span><span class="s">8081:8081"</span>
    <span class="s">restart</span><span class="pi">:</span> <span class="s">always</span>
    <span class="s">env_file</span><span class="pi">:</span> <span class="s">.env</span>
    <span class="s">volumes</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">nexus-data:/nexus-data</span>
    
  <span class="s">sonarqube</span><span class="pi">:</span>
    <span class="s">image</span><span class="pi">:</span> <span class="s">sonarqube</span>
    <span class="s">ports</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s2">"</span><span class="s">9000:9000"</span>
    <span class="s">restart</span><span class="pi">:</span> <span class="s">always</span>
    <span class="s">env_file</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">.env</span>
      <span class="pi">-</span> <span class="s">sonarqube.env</span>
    <span class="s">environment</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">SONARQUBE_JDBC_URL=jdbc:postgresql://postgres:5432/sonar</span>
      <span class="pi">-</span> <span class="s">SONARQUBE_JDBC_USERNAME=sonar</span>
    <span class="s">volumes</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">sonarqube_conf:/opt/sonarqube/conf</span>
      <span class="pi">-</span> <span class="s">sonarqube_data:/opt/sonarqube/data</span>
      <span class="pi">-</span> <span class="s">sonarqube_extensions:/opt/sonarqube/extensions</span>
      <span class="pi">-</span> <span class="s">sonarqube_bundled-plugins:/opt/sonarqube/lib/bundled-plugins</span>
    <span class="s">links</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">postgres</span>

  <span class="s">postgres</span><span class="pi">:</span>
    <span class="s">image</span><span class="pi">:</span> <span class="s">postgres</span>
    <span class="s">ports</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s2">"</span><span class="s">5432:5432"</span>
    <span class="s">restart</span><span class="pi">:</span> <span class="s">always</span>
    <span class="s">env_file</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">.env</span>
      <span class="pi">-</span> <span class="s">sonarqube.env</span>
    <span class="s">environment</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">POSTGRES_USER=sonar</span>
    <span class="s">volumes</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">postgresql:/var/lib/postgresql</span>
      <span class="pi">-</span> <span class="s">postgresql_data:/var/lib/postgresql/data</span>

<span class="s">volumes</span><span class="pi">:</span>
  <span class="s">jenkins_home</span><span class="pi">:</span>
  <span class="s">nexus-data</span><span class="pi">:</span>
  <span class="s">sonarqube_conf</span><span class="pi">:</span>
  <span class="s">sonarqube_data</span><span class="pi">:</span>
  <span class="s">sonarqube_extensions</span><span class="pi">:</span>
  <span class="s">sonarqube_bundled-plugins</span><span class="pi">:</span>
  <span class="s">postgresql</span><span class="pi">:</span>
  <span class="s">postgresql_data</span><span class="pi">:</span>
</code></pre>
</div>
<ul>
<li>create a second file named&nbsp;<code class="highlighter-rouge">.env</code>&nbsp;that defines a timezone:</li>
</ul>
<div class="highlighter-rouge">
<pre class="highlight"><code>TZ=Europe/Berlin
</code></pre>
</div>
<ul>
<li>create a third file named&nbsp;<code class="highlighter-rouge">sonarqube.env</code>&nbsp;that holds the database passwords:</li>
</ul>
<div class="highlighter-rouge">
<pre class="highlight"><code>SONARQUBE_JDBC_PASSWORD=sonar
POSTGRES_PASSWORD=sonar
</code></pre>
</div>
<h4 id="usage">Usage</h4>
<ul>
<li>startup all containers:</li>
</ul>
<div class="highlighter-rouge">
<pre class="highlight"><code>docker-compose up -d
</code></pre>
</div>
<ul>
<li>
<p>watch the logs, type&nbsp;<code class="highlighter-rouge">docker-compose logs</code>&nbsp;or&nbsp;<code class="highlighter-rouge">docker logs -f ci_jenkins_1</code></p>
</li>
<li>
<p>access the web applications:</p>
<ul>
<li>Jenkins on port 8082</li>
<li>Sonatype Nexus on port 8081 and</li>
<li>SonarQube on port 9000</li>
</ul>
</li>
</ul>
<h4 id="removal-1">Removal</h4>
<ul>
<li>to remove the tool stack (incl. data), use:</li>
</ul>
<div class="highlighter-rouge">
<pre class="highlight"><code>docker-compose down -v
</code></pre>
</div>
<h1 id="best-practices">4. Best Practices</h1>
<h2 id="docker-engine-1">Docker Engine</h2>
<ul>
<li><code class="highlighter-rouge">docker exec</code>&nbsp;is your friend in development, but should be avoided in a production setup</li>
</ul>
<h2 id="volumes">Volumes</h2>
<ul>
<li>use&nbsp;<em>named volumes</em>&nbsp;to simplify maintenance by separating persistent data from the container and communicating the structure of a project in a more transparent manner</li>
</ul>
<h2 id="dockerfile-1">Dockerfile</h2>
<ul>
<li>always keep environment configuration and secrets out of deployments and images, for example by using environment variables (<code class="highlighter-rouge">-e</code>,&nbsp;<code class="highlighter-rouge">--env-file</code>)</li>
<li>always set the&nbsp;<code class="highlighter-rouge">USER</code>&nbsp;statement, otherwise the container will run as&nbsp;<code class="highlighter-rouge">root</code>&nbsp;user by default, which maps to the&nbsp;<code class="highlighter-rouge">root</code>&nbsp;user of the host machine</li>
<li>use&nbsp;<code class="highlighter-rouge">ENTRYPOINT</code>&nbsp;and&nbsp;<code class="highlighter-rouge">CMD</code>&nbsp;directives together to make container usage more convenient</li>
<li>coalesce consecutive&nbsp;<code class="highlighter-rouge">RUN</code>&nbsp;directives with&nbsp;<code class="highlighter-rouge">&amp;&amp;</code>&nbsp;to reduce the costs of a build and to avoid caching of instructions like&nbsp;<code class="highlighter-rouge">apt-get update</code></li>
<li>to reduce the size of an image, remove temporary resources in the same&nbsp;<code class="highlighter-rouge">RUN</code>&nbsp;statement that produces them (otherwise they are still present in an intermediate layer)</li>
<li>use&nbsp;<code class="highlighter-rouge">EXPOSE</code>&nbsp;to document all needed ports</li>
<li>introduce an additional build Dockerfile for your app, if you have a large set of compile-time dependencies (<a href="http://blog.terranillius.com/post/docker_builder_pattern/">build container pattern</a>)</li>
</ul>
<h1 id="additional-material">5. Additional Material</h1>
<ul>
<li><a href="http://shop.oreilly.com/product/0636920035671.do">Mouat, A. (2015).&nbsp;<em>Using Docker: Developing and Deploying Software with Containers.</em>&nbsp;O’Reilly Media.</a>&nbsp;(<a href="https://www.dpunkt.de/buecher/12553/9783864903847-docker.html">German Edition:&nbsp;<em>Docker. Software entwickeln und deployen mit Containern.</em>&nbsp;dpunkt.verlag</a>)</li>
<li><a href="https://www.dockerbook.com/">Turnbull, J. (2016).&nbsp;<em>The Docker Book. Containerization is the new Virtualization.</em></a></li>
<li><a href="http://blog.arungupta.me/docker-container-anti-patterns/">Gupta, A. (2016).&nbsp;<em>Docker Container Anti Patterns.</em></a></li>
<li><a href="http://www.tmf-ev.de/Desktopmodules/Bring2Mind/DMX/Download.aspx?EntryId=29283&amp;PortalId=0">Piegsa, J. (2016). Dockerbank 2 Workshop.&nbsp;<em>Szenarien des Routinebetriebs.</em>&nbsp;(German Slides)</a></li>
<li><a href="https://docs.docker.com/">Official Docker Documentation</a></li>
<li><a href="http://stackoverflow.com/documentation/docker/topics">StackOverflow Documentation</a></li>
<li><a href="https://veggiemonk.github.io/awesome-docker/">Awesome Docker</a></li>
<li><a href="https://github.com/docker/labs">Docker Labs</a></li>
<li><a href="http://view.dckr.info/DockerIntro.pdf">Docker Introduction</a></li>
<li><a href="http://play-with-docker.com/">play-with-docker.com</a></li>
</ul>
<p>The post <a href="http://kostacipo.stream/docker-cheat-sheet/">Docker Cheat Sheet</a> appeared first on <a href="http://kostacipo.stream">Tech Chronicles</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://kostacipo.stream/docker-cheat-sheet/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to purge Docker images, containers, networks or volumes</title>
		<link>http://kostacipo.stream/how-to-purge-docker-images-containers-networks-or-volumes/</link>
					<comments>http://kostacipo.stream/how-to-purge-docker-images-containers-networks-or-volumes/#respond</comments>
		
		<dc:creator><![CDATA[Majordomo]]></dc:creator>
		<pubDate>Fri, 31 Jan 2020 10:50:22 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[docker]]></category>
		<guid isPermaLink="false">http://www.kostacipo.stream/?p=1726</guid>

					<description><![CDATA[<p>&#160; Purpose The purpose of this post is to learn how to easily delete images, containers, networks and volumes from an existing&#160;Docker&#160;local (or remote) Docker installation using its CLI. A Docker installation is required to follow this tutorial. Docker version used to prepare this article:&#160;18.04.0-ce. Note that other Docker version commands can vary. Delete Docker [&#8230;]</p>
<p>The post <a href="http://kostacipo.stream/how-to-purge-docker-images-containers-networks-or-volumes/">How to purge Docker images, containers, networks or volumes</a> appeared first on <a href="http://kostacipo.stream">Tech Chronicles</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>&nbsp;</p>
<div class="post-content">
<h3 id="purpose">Purpose</h3>
<p>The purpose of this post is to learn how to easily delete images, containers, networks and volumes from an existing&nbsp;Docker&nbsp;local (or remote) Docker installation using its CLI. A Docker installation is required to follow this tutorial. Docker version used to prepare this article:&nbsp;<code class="language-bash highlighter-rouge">18.04.0-ce</code>. Note that other Docker version commands can vary.</p>
<h3 id="delete-docker-containers">Delete Docker containers</h3>
<p>Whether you need to Docker container because there is a new image version in the pipeline or it is just a test in a dev environment you can use this command to remove a specific container:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker container <span class="nb">rm</span> <span class="o">[</span>container_name / container_id]
<span class="c"># deleting multiple containers</span>
<span class="nv">$ </span>docker container <span class="nb">rm</span> <span class="o">[</span>container_1] <span class="o">[</span>container_2] ... <span class="o">[</span>container_N]
</code></pre>
</div>
</div>
<p>If the container o containers that you should delete are running you could stop or delete them first or use the parameter&nbsp;<em>f</em>&nbsp;as follows to force their deletion:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker container <span class="nb">rm</span> <span class="nt">-f</span> <span class="o">[</span>container_name / container_id]
</code></pre>
</div>
</div>
<p>Specially in development environments you could end up with dozens of stopped containers and obviously always come in handy to delete them and free disk space: Docker command to purge all stopped containers:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker container prune
</code></pre>
</div>
</div>
<p>Finally, you can delete all stopped containers based on a filter:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker container prune <span class="nt">--filter</span> <span class="s1">'NAME=VALUE'</span>

<span class="c"># Example: Deletes stopped containers created until 1 minute ago.</span>
<span class="nv">$ </span>docker container prune <span class="nt">--filter</span> <span class="s1">'until=1m'</span>
</code></pre>
</div>
</div>
<h3 id="delete-docker-images">Delete Docker images</h3>
<h4 id="delete-docker-images-by-nametag-or-id">Delete Docker images by name/tag or ID</h4>
<p>To delete a Docker image you first need to know the image name and tag or the image ID. You can use the following command to list all current images:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker image <span class="nb">ls</span>
<span class="c"># or</span>
<span class="nv">$ </span>docker images
</code></pre>
</div>
</div>
<p>Once you know the name of the image name + tag or the image ID you can use this command to remove a specific Docker image:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>docker image <span class="nb">rm</span> <span class="o">[</span>image_name:tag / image_id]
<span class="c"># or</span>
docker rmi <span class="o">[</span>image_name:tag / image_id]
</code></pre>
</div>
</div>
<blockquote class="note">
<p>If you remove a Docker image using its name like&nbsp;<code class="language-bash highlighter-rouge"><span class="nv">$&nbsp;</span>docker rmi image_name</code>&nbsp;without specifying an image tag, Docker will use&nbsp;<code class="language-bash highlighter-rouge">latest</code>&nbsp;as a default tag like&nbsp;<code class="language-bash highlighter-rouge"><span class="nv">$&nbsp;</span>docker rmi image_name:latest</code>.</p>
<p>If you remove a Docker image using its ID, it is not necessary to specify the full string. Example: To delete the Docker image with ID&nbsp;<em>d3d96b1e5d48</em>&nbsp;you could run&nbsp;<code class="language-bash highlighter-rouge"><span class="nv">$&nbsp;</span>docker rmi image_name d3d96b</code>&nbsp;or&nbsp;<code class="language-bash highlighter-rouge"><span class="nv">$&nbsp;</span>docker rmi image_name d3d</code>. If you are using very few characters make sure you are not deleting other images as well.</p>
</blockquote>
<h4 id="delete-docker-dangling-images">Delete Docker dangling images</h4>
<p>In addition to tagged or named Docker images, there are dangling images. These images don’t have any relationship to any current image and there aren’t used anymore. Because of that, it is a good practise to delete them and keeping more space in the disk. This is the Docker command to prune dangling images:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker image prune
<span class="c"># or</span>
<span class="nv">$ </span>docker rmi <span class="k">$(</span>docker images <span class="nt">-qf</span> <span class="s2">"dangling=true"</span><span class="k">)</span>
</code></pre>
</div>
</div>
<h4 id="delete-docker-unused-images">Delete Docker unused images</h4>
<p>Finally, part of the current tagged images could be not used. Docker provides a command to purge these unused images as well (previous dangling images included):</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker image prune <span class="nt">-a</span>
</code></pre>
</div>
</div>
<h3 id="delete-docker-networks">Delete Docker networks</h3>
<h4 id="delete-docker-networks-by-name-or-id">Delete Docker networks by name or id</h4>
<p>To delete a Docker network it’s very useful to get a list of the current networks:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker network <span class="nb">ls
</span>NETWORK ID          NAME                          DRIVER              SCOPE
387cccf19c98        custom_net                    bridge              <span class="nb">local
</span>bf5345d30d7f        bridge                        bridge              <span class="nb">local
</span>1ae6aef09e5c        host                          host                <span class="nb">local</span>
...
</code></pre>
</div>
</div>
<p>Once you’ve identified the Docker network to be deleted you can run this command to remove it:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker network <span class="nb">rm</span> <span class="o">[</span>network_name / network_id]
<span class="c"># or</span>
<span class="nv">$ </span>docker network remove <span class="o">[</span>network_name / network_id]

<span class="c"># example</span>
<span class="nv">$ </span>docker network <span class="nb">rm </span>custom_net
<span class="c"># or</span>
<span class="nv">$ </span>docker network <span class="nb">rm </span>387cccf19c98
<span class="c"># or</span>
<span class="nv">$ </span>docker network remove 387cc
</code></pre>
</div>
</div>
<h4 id="delete-docker-unused-networks">Delete Docker unused networks</h4>
<p>If you want to tidy up a little bit the Docker networks you could delete the unused networks:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker network prune

<span class="c"># using --filter you can filter which unused networks you want to delete as we did before with stopped containers</span>
<span class="nv">$ </span>docker container prune <span class="nt">--filter</span> <span class="s1">'NAME=VALUE'</span>
</code></pre>
</div>
</div>
<h4 id="delete-docker-networks-with-active-endpoints">Delete Docker networks with active endpoints</h4>
<p>If you try to delete a busy newtork you’ll get the following error:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker network <span class="nb">rm </span>custom_net
Error response from daemon: error <span class="k">while </span>removing network: network bi_private <span class="nb">id</span> &lt;ID&gt; has active endpoints.
</code></pre>
</div>
</div>
<p>Probably this is because there are containers using this network and make sense to review this scenario o delete all the containers first. But if this is not the case and you really need to delete the Docker network you can run the following command and write down all the containers in the Docker net:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker network inspect custom_net
...
<span class="s2">"Containers"</span>: <span class="o">[</span>..]
...
</code></pre>
</div>
</div>
<p>Once you have the list of Docker containers you can disconnect the network from them:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker network disconnect <span class="nt">-f</span> custom_net container_1
<span class="nv">$ </span>docker network disconnect <span class="nt">-f</span> custom_net container_2
...
<span class="nv">$ </span>docker network disconnect <span class="nt">-f</span> custom_net container_N
</code></pre>
</div>
</div>
<p>And finally delete the network:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker network <span class="nb">rm </span>custom_net
</code></pre>
</div>
</div>
<h3 id="delete-docker-volumes">Delete Docker volumes</h3>
<p>Docker volumes are used to provide or keep container’s configuration or to persist data from it. Either you need to remove unused volumes, the persisted data from a running container or its configuration, you can use the following commands to remove a Docker volume:</p>
<p>First of all you should list all current volumes:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker volume <span class="nb">ls
</span>DRIVER              VOLUME NAME
<span class="nb">local               </span>named_volume
<span class="nb">local               </span>0a0bce5c74f249a9954120ce3d6cbc5fb388d1fadc27fd55c2a008d2c1bd8d1a
<span class="nb">local               </span>1e3f5e108a2e2542f018d0302f3d598bb90ded4cd604fed352c9530d30d35a56
...
</code></pre>
</div>
</div>
<p>Named volumes are defined by the user and there is no issue to identify them. Things change a little bit for auto-generated volumes. These volumes can be tricky to be identified and if you need to delete one of them from a known container you should try to locate it:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker inspect containerid
...
<span class="s2">"Mounts"</span>: <span class="o">[{</span>volume 6d29ac8a196.. <span class="o">}{</span> ... <span class="o">}]</span>
</code></pre>
</div>
</div>
<p>The volume name to be deleted is 6d29ac8a196..</p>
<h4 id="delete-a-specific-docker-volume">Delete a specific Docker volume</h4>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker volume <span class="nb">rm</span> <span class="o">[</span>volume_name]
</code></pre>
</div>
</div>
<h4 id="delete-all-docker-unused-volumes">Delete all Docker unused volumes</h4>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker volume prune

<span class="c"># using --filter you can filter which unused volumes you want to delete as we did before with stopped containers and networks.</span>
<span class="nv">$ </span>docker volume prune <span class="nt">--filter</span> <span class="s1">'NAME=VALUE'</span>
</code></pre>
</div>
</div>
<h3 id="deleting-docker-containers-images-nets-and-volumes">Deleting Docker containers, images, nets and volumes</h3>
<p>Specially in dev environments sometimes you need to delete the full Docker installation. This command could help you to delete stopped containers, dangling images, networks and build cache at the same time:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker system prune
</code></pre>
</div>
</div>
<p>Using&nbsp;<em>-a</em>&nbsp;at the end of the command will delete all unused images:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker system prune <span class="nt">-a</span>
</code></pre>
</div>
</div>
<p>Finally, adding&nbsp;<em>–volumes</em>&nbsp;will delete unused volumes as well:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker system prune <span class="nt">-a</span> <span class="nt">--volumes</span>
</code></pre>
</div>
</div>
<blockquote class="note">
<p>Previous commands will request [y/N] to confirm or not the deletion. You can add the&nbsp;<code class="language-bash highlighter-rouge"><span class="nt">-f</span>&nbsp;or&nbsp;<span class="nt">--force</span></code>&nbsp;parameter to avoid prompt and perform the action right away.</p>
</blockquote>
</div>
<p>The post <a href="http://kostacipo.stream/how-to-purge-docker-images-containers-networks-or-volumes/">How to purge Docker images, containers, networks or volumes</a> appeared first on <a href="http://kostacipo.stream">Tech Chronicles</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://kostacipo.stream/how-to-purge-docker-images-containers-networks-or-volumes/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to backup a PostgreSQL database using Docker</title>
		<link>http://kostacipo.stream/how-to-backup-a-postgresql-database-using-docker/</link>
					<comments>http://kostacipo.stream/how-to-backup-a-postgresql-database-using-docker/#respond</comments>
		
		<dc:creator><![CDATA[Majordomo]]></dc:creator>
		<pubDate>Fri, 31 Jan 2020 10:46:11 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[postgresql]]></category>
		<guid isPermaLink="false">http://www.kostacipo.stream/?p=1723</guid>

					<description><![CDATA[<p>&#160; Before you begin In this tutorial, we’ll learn how to&#160;backup&#160;a&#160;PostgreSQL&#160;database. A Linux machine and&#160;Docker&#160;will be required to follow this tutorial. Backup a PostgreSQL local or remote database Command to backup a local or remote PostgreSQL database using Docker: $ docker run -i postgres /usr/bin/pg_dump \ -h [POSTGRESQL_HOST] \ -U [POSTGRESQL_USER] [POSTGRESQL_DATABASE] &#62; backup.sql Command [&#8230;]</p>
<p>The post <a href="http://kostacipo.stream/how-to-backup-a-postgresql-database-using-docker/">How to backup a PostgreSQL database using Docker</a> appeared first on <a href="http://kostacipo.stream">Tech Chronicles</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>&nbsp;</p>
<h3 id="before-you-begin">Before you begin</h3>
<p>In this tutorial, we’ll learn how to&nbsp;backup&nbsp;a&nbsp;PostgreSQL&nbsp;database. A Linux machine and&nbsp;Docker&nbsp;will be required to follow this tutorial.</p>
<h3 id="backup-a-postgresql-local-or-remote-database">Backup a PostgreSQL local or remote database</h3>
<p>Command to backup a local or remote PostgreSQL database using Docker:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker run <span class="nt">-i</span> postgres /usr/bin/pg_dump <span class="se">\</span>
  <span class="nt">-h</span> <span class="o">[</span>POSTGRESQL_HOST] <span class="se">\</span>
  <span class="nt">-U</span> <span class="o">[</span>POSTGRESQL_USER] <span class="o">[</span>POSTGRESQL_DATABASE] <span class="o">&gt;</span> backup.sql
</code></pre>
</div>
</div>
<p>Command to backup multiple PostgreSQL databases using Docker:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker run <span class="nt">-i</span> postgres /usr/bin/pg_dumpall <span class="se">\</span>
  <span class="nt">-h</span> <span class="o">[</span>POSTGRESQL_HOST] <span class="se">\</span>
  <span class="nt">-U</span> <span class="o">[</span>POSTGRESQL_USER] <span class="o">&gt;</span> backup.sql
</code></pre>
</div>
</div>
<p>Command to backup a local or remote PostgreSQL database using Docker with compression (using gzip):</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker run <span class="nt">-i</span> postgres /usr/bin/pg_dump <span class="se">\</span>
  <span class="nt">-h</span> <span class="o">[</span>POSTGRESQL_HOST] <span class="se">\</span>
  <span class="nt">-U</span> <span class="o">[</span>POSTGRESQL_USER] <span class="o">[</span>POSTGRESQL_DATABASE] | <span class="nb">gzip</span> <span class="nt">-9</span> <span class="o">&gt;</span> backup.sql.gz
</code></pre>
</div>
</div>
<p>Same command below but providing PostgreSQL password as environment variable:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker run <span class="nt">-i</span> <span class="nt">-e</span> <span class="nv">PGPASSWORD</span><span class="o">=[</span>POSTGRESQL_PASSWORD] postgres /usr/bin/pg_dump <span class="se">\</span>
  <span class="nt">-h</span> <span class="o">[</span>POSTGRESQL_HOST] <span class="se">\</span>
  <span class="nt">-U</span> <span class="o">[</span>POSTGRESQL_USER] <span class="o">[</span>POSTGRESQL_DATABASE] | <span class="nb">gzip</span> <span class="nt">-9</span> <span class="o">&gt;</span> backup.sql.gz
</code></pre>
</div>
</div>
<h3 id="backup-a-containerized-postgresql-database">Backup a containerized PostgreSQL database</h3>
<p>Command to backup a containerized PostgreSQL database creating a compressed file using Docker and gzip:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker <span class="nb">exec</span> <span class="o">[</span>POSTGRESQL_CONTAINER] /usr/bin/pg_dump <span class="se">\</span>
  <span class="nt">-U</span> <span class="o">[</span>POSTGRESQL_USER] <span class="o">[</span>POSTGRESQL_DATABASE] | <span class="nb">gzip</span> <span class="nt">-9</span> <span class="o">&gt;</span> backup.sql.gz
</code></pre>
</div>
</div>
<p>Same command below but setting PostgreSQL password environment variable to existing container:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker <span class="nb">exec</span> <span class="o">[</span>POSTGRESQL_CONTAINER] /bin/bash <span class="se">\</span>
  <span class="nt">-c</span> <span class="s2">"export PGPASSWORD=[POSTGRESQL_PASSWORD] </span><span class="se">\</span><span class="s2">
      &amp;&amp; /usr/bin/pg_dump -U [POSTGRESQL_USER] [POSTGRESQL_DATABASE]"</span> <span class="se">\</span>
  | <span class="nb">gzip</span> <span class="nt">-9</span> <span class="o">&gt;</span> backup.sql.gz
</code></pre>
</div>
</div>
<h3 id="bonus-track-how-to-dump-a-portion-of-a-table">Bonus track: How to dump a portion of a table?</h3>
<p>Using Postgres functions you can dump all databases, a database, a schema, only schema data or even a single table dataset. These are some of the available options:</p>
<p><code class="language-bash highlighter-rouge">pg_dumpall</code>: Retrieves all databases.</p>
<p><code class="language-bash highlighter-rouge">pg_dump</code>: Retrieves specific database.</p>
<p><code class="language-bash highlighter-rouge">pg_dump&nbsp;<span class="nt">--schema-only</span>&nbsp;DATABASE_NAME</code>: Retrieves only schema/structure of a database.</p>
<p><code class="language-bash highlighter-rouge">pg_dump&nbsp;<span class="nt">--table</span>&nbsp;TABLE_NAME</code>: Dumps the content of the table TABLE_A.</p>
<p><code class="language-bash highlighter-rouge">COPY</code>: Retrieves data from a table and outputs it to a file or stdout. E.g.:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker <span class="nb">exec</span> <span class="nt">-i</span> <span class="o">[</span>POSTGRESQL_CONTAINER] /usr/bin/psql <span class="nt">-U</span> <span class="se">\</span>
  <span class="o">[</span>POSTGRESQL_USER] <span class="o">[</span>POSTGRESQL_DATABASE] <span class="se">\</span>
  <span class="nt">-c</span> <span class="s2">"COPY (SELECT * FROM [TABLE_NAME] order by time desc limit 1000)
  TO 'dest/folder/filename.txt';"</span>
</code></pre>
</div>
</div>
<p>In previous example we are retrieving last 1000 records from a table&nbsp;<em>TABLE_NAME</em>&nbsp;sorted by&nbsp;<em>time</em>&nbsp;and saving it to a text file&nbsp;<em>dest/folder/filename.txt</em>.</p>
<p>Lately this data file can be restored using the same command&nbsp;<code class="language-bash highlighter-rouge">COPY</code>&nbsp;as the following example does:</p>
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><span class="nv">$ </span>docker <span class="nb">exec</span> <span class="nt">-i</span> <span class="o">[</span>POSTGRESQL_CONTAINER] /usr/bin/psql <span class="nt">-U</span> <span class="se">\</span>
  <span class="o">[</span>POSTGRESQL_USER] <span class="o">[</span>POSTGRESQL_DATABASE] <span class="se">\</span>
  <span class="nt">-c</span> <span class="s2">"COPY [TABLE_NAME] from 'dest/folder/filename.txt' WITH (FORMAT text);"</span>
</code></pre>
</div>
</div>
<p>More info about&nbsp;<code class="language-bash highlighter-rouge">COPY</code>&nbsp;here:&nbsp;<a href="https://www.postgresql.org/docs/10/static/sql-copy.html" target="_blank" rel="noopener noreferrer">https://www.postgresql.org/docs/10/static/sql-copy.html</a></p>
<p>The post <a href="http://kostacipo.stream/how-to-backup-a-postgresql-database-using-docker/">How to backup a PostgreSQL database using Docker</a> appeared first on <a href="http://kostacipo.stream">Tech Chronicles</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://kostacipo.stream/how-to-backup-a-postgresql-database-using-docker/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
