<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://training-course-material.com/index.php?action=history&amp;feed=atom&amp;title=Building_Docker_Images</id>
	<title>Building Docker Images - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://training-course-material.com/index.php?action=history&amp;feed=atom&amp;title=Building_Docker_Images"/>
	<link rel="alternate" type="text/html" href="https://training-course-material.com/index.php?title=Building_Docker_Images&amp;action=history"/>
	<updated>2026-05-13T22:52:02Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://training-course-material.com/index.php?title=Building_Docker_Images&amp;diff=73540&amp;oldid=prev</id>
		<title>Kbaran: /* EXPOSE */</title>
		<link rel="alternate" type="text/html" href="https://training-course-material.com/index.php?title=Building_Docker_Images&amp;diff=73540&amp;oldid=prev"/>
		<updated>2019-09-10T14:53:29Z</updated>

		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;EXPOSE&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;[[Category:Docker]]&lt;br /&gt;
[[Category:course_code_dockcm]]&lt;br /&gt;
&lt;br /&gt;
{{Copyright Notice}}&lt;br /&gt;
&lt;br /&gt;
== Author ==&lt;br /&gt;
* [http://www.kamilbaran.pl Kamil Baran]&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Building images ==&lt;br /&gt;
There are two ways of building images:&lt;br /&gt;
* build an image based on existing container&lt;br /&gt;
* build an image from a Dockerfile&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Committing an existing container ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ docker container run -it --name mc_test ubuntu&lt;br /&gt;
# inside of the container run: apt-get update &amp;amp;&amp;amp; apt-get install mc&lt;br /&gt;
$ docker container diff mc_test&lt;br /&gt;
$ docker container commit -m &amp;quot;installed mc&amp;quot; mc_test training:mc1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Building an image from a Dockerfile ==&lt;br /&gt;
* Create a new directory and &amp;quot;Dockerfile&amp;quot; text file&lt;br /&gt;
* After that run the command below to build an image&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ docker image build [options] PATH | URL | -&lt;br /&gt;
$ docker image build -t training:mc2 .&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
* build context&lt;br /&gt;
** the &amp;#039;&amp;#039;&amp;#039;PATH&amp;#039;&amp;#039;&amp;#039; is a directory on your local filesystem.&lt;br /&gt;
** the &amp;#039;&amp;#039;&amp;#039;URL&amp;#039;&amp;#039;&amp;#039; is a the location of a Git repository.&lt;br /&gt;
* the build is run by the Docker daemon, not by the Client&lt;br /&gt;
** .dockerignore&lt;br /&gt;
* some selected options:&lt;br /&gt;
** &amp;#039;&amp;#039;&amp;#039;-t&amp;#039;&amp;#039;&amp;#039; - name and a tag in the repository/name:tag format &lt;br /&gt;
** &amp;#039;&amp;#039;&amp;#039;-f&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;--file&amp;#039;&amp;#039;&amp;#039; - name of the Dockerfile (default: PATH/Dockerfile)&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== FROM===&lt;br /&gt;
* sets the base image for subsequent instructions&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;from&amp;#039;&amp;#039;&amp;#039; must be the first instruction in Dockerfile&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
FROM &amp;lt;image&amp;gt;&lt;br /&gt;
FROM &amp;lt;image&amp;gt;:&amp;lt;tag&amp;gt;&lt;br /&gt;
FROM &amp;lt;image&amp;gt;@&amp;lt;digest&amp;gt;&lt;br /&gt;
FROM ubuntu:trusty&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== RUN ===&lt;br /&gt;
* RUN instruction will execute any commands in a new layer on top of the current image and commit the results&lt;br /&gt;
* newly created image will be used for the next step in the Dockerfile&lt;br /&gt;
* RUN has 2 forms:&lt;br /&gt;
** &amp;#039;&amp;#039;&amp;#039;exec form&amp;#039;&amp;#039;&amp;#039; makes it possible to run commands using a base image that does not contain /bin/sh&lt;br /&gt;
** makes it possible to avoid shell string munging&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
RUN [&amp;quot;executable&amp;quot;, &amp;quot;param1&amp;quot;, &amp;quot;param2&amp;quot;]&lt;br /&gt;
RUN [&amp;quot;apt-get&amp;quot;, &amp;quot;update&amp;quot;]&lt;br /&gt;
RUN [&amp;quot;apt-get&amp;quot;, &amp;quot;install&amp;quot;, &amp;quot;-y&amp;quot;, &amp;quot;mc&amp;quot;]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
** &amp;#039;&amp;#039;&amp;#039;shell form&amp;#039;&amp;#039;&amp;#039; - the command is run in a shell (/bin/sh -c)&lt;br /&gt;
** use a &amp;amp;&amp;amp; (double ampersand) to combine many commands in one layer&lt;br /&gt;
** use a \ (backslash) to continue a single run instruction onto the next line&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
RUN &amp;lt;command&amp;gt;&lt;br /&gt;
RUN apt-get update &lt;br /&gt;
RUN apt-get install -y mc&lt;br /&gt;
RUN apt-get update &amp;amp;&amp;amp; apt-get install -y mc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Layering RUN instructions and cache&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* one of the key concepts of Docker: &amp;#039;&amp;#039;&amp;#039;commits are cheap&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* containers can be created from any point in an image’s history (docker images -a)&lt;br /&gt;
* cache and commands like apt-get update&lt;br /&gt;
** &amp;#039;&amp;#039;&amp;#039;--no-cache&amp;#039;&amp;#039;&amp;#039; - do not use cache when building the image&lt;br /&gt;
** &amp;#039;&amp;#039;&amp;#039;--pull&amp;#039;&amp;#039;&amp;#039; - always attempt to pull a newer version of the base image &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== COPY ===&lt;br /&gt;
* the &amp;#039;&amp;#039;&amp;#039;COPY&amp;#039;&amp;#039;&amp;#039; instruction copies files or directories from &amp;lt;src&amp;gt; to the filesystem of the container at the path &amp;lt;dest&amp;gt;&lt;br /&gt;
* &amp;lt;src&amp;gt; path must be inside the context of the build&lt;br /&gt;
* if &amp;lt;src&amp;gt; is a directory, the entire contents of the directory are copied but the directory itself is not copied&lt;br /&gt;
* slash after the directory name is important&lt;br /&gt;
* if &amp;lt;dest&amp;gt; doesn’t exist, it is created along with all missing directories in its path&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;COPY&amp;#039;&amp;#039;&amp;#039; has two forms:&lt;br /&gt;
** second one is required for paths containing whitespace&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
COPY &amp;lt;src&amp;gt; &amp;lt;src2&amp;gt;... &amp;lt;dest&amp;gt;&lt;br /&gt;
COPY [&amp;quot;&amp;lt;src&amp;gt;&amp;quot;, &amp;quot;&amp;lt;src2&amp;gt;&amp;quot;,... &amp;quot;&amp;lt;dest&amp;gt;&amp;quot;]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
COPY file1 file1&lt;br /&gt;
COPY fil* /&lt;br /&gt;
COPY dir1/ /dest_dir/&lt;br /&gt;
COPY file1 dir1/ /dest_dir/&lt;br /&gt;
COPY [&amp;quot;file 1&amp;quot;, &amp;quot;dir 1&amp;quot;, &amp;quot;/dest/dir/&amp;quot;]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== ADD ===&lt;br /&gt;
* ADD instruction can copy local files like &amp;#039;&amp;#039;&amp;#039;COPY&amp;#039;&amp;#039;&amp;#039; but has two extra features:&lt;br /&gt;
** remote URL support&lt;br /&gt;
** local tar extraction (only local)&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== WORKDIR ===&lt;br /&gt;
* WORKDIR instruction sets the working directory for any RUN, CMD, ENTRYPOINT, COPY and ADD instructions that follow it in the Dockerfile&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CMD===&lt;br /&gt;
* the main purpose of a &amp;#039;&amp;#039;&amp;#039;CMD&amp;#039;&amp;#039;&amp;#039; is to provide defaults for an executing container&lt;br /&gt;
* for example &amp;#039;&amp;#039;/bin/bash&amp;#039;&amp;#039; is default CMD for Ubuntu official image&lt;br /&gt;
* only the last CMD will take effect&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;CMD&amp;#039;&amp;#039;&amp;#039; has two forms:&lt;br /&gt;
** &amp;#039;&amp;#039;&amp;#039;exec form&amp;#039;&amp;#039;&amp;#039;, this is the preferred form&lt;br /&gt;
** skip executable to define default parameters to ENTRYPOINT&lt;br /&gt;
** does not invoke a command shell, so the variable substitution is not going to happen&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
CMD [&amp;quot;executable&amp;quot;,&amp;quot;param1&amp;quot;,&amp;quot;param2&amp;quot;]&lt;br /&gt;
CMD [&amp;quot;ping&amp;quot;, &amp;quot;nobleprog.pl&amp;quot;, &amp;quot;-c&amp;quot;, &amp;quot;3&amp;quot;]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
CMD [&amp;quot;param1&amp;quot;,&amp;quot;param2&amp;quot;]&lt;br /&gt;
CMD [&amp;quot;nobleprog.pl&amp;quot;, &amp;quot;-c&amp;quot;, &amp;quot;3&amp;quot;] # will work if ENTRYPOINT is set to ping&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
** &amp;#039;&amp;#039;&amp;#039;shell form&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
** command is exectuted in &amp;#039;&amp;#039;/bin/sh -c&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
CMD command param1 param2&lt;br /&gt;
CMD ping nobleprog.pl -c 3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ENTRYPOINT ===&lt;br /&gt;
* allows you to configure a container that will run as an executable&lt;br /&gt;
* only the last ENTRYPOINT will take effect&lt;br /&gt;
* command line arguments to docker run will be appended after all elements in an exec form ENTRYPOINT, and will override all elements specified using CMD&lt;br /&gt;
* use docker run --entrypoint to override image ENTRYPOINT&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;ENTRYPOINT&amp;#039;&amp;#039;&amp;#039; has two forms:&lt;br /&gt;
** &amp;#039;&amp;#039;&amp;#039;exec form&amp;#039;&amp;#039;&amp;#039;, this is the preferred form&lt;br /&gt;
** this form allows to gracefully shut down using docker stop command&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ENTRYPOINT [&amp;quot;executable&amp;quot;, &amp;quot;param1&amp;quot;, &amp;quot;param2&amp;quot;]&lt;br /&gt;
ENTRYPOINT [&amp;quot;ping&amp;quot;, &amp;quot;-c&amp;quot;, &amp;quot;5&amp;quot;]&lt;br /&gt;
CMD [&amp;quot;localhost&amp;quot;]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
** &amp;#039;&amp;#039;&amp;#039;shell form&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
** shell form prevents any CMD or run command line arguments from being used&lt;br /&gt;
** ENTRYPOINT will be started as a subcommand of /bin/sh -c (which does not pass signals)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ENTRYPOINT command param1 param2&lt;br /&gt;
ENTRYPOINT ping -c 5 localhost&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;Exercises&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ENV===&lt;br /&gt;
* sets the environment variable &amp;lt;key&amp;gt; to the value &amp;lt;value&amp;gt;&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;ENV&amp;#039;&amp;#039;&amp;#039; has two forms:&lt;br /&gt;
** first form - entire string after the first space will be treated as the &amp;lt;value&amp;gt; (including characters such as spaces and quotes)&lt;br /&gt;
** second form (uses equal sign) - allows for multiple variables to be set at once (quotes and backslashes can be used)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ENV &amp;lt;key&amp;gt; &amp;lt;value&amp;gt;&lt;br /&gt;
ENV &amp;lt;key1&amp;gt;=&amp;lt;value1&amp;gt; &amp;lt;key2&amp;gt;=&amp;lt;value2&amp;gt; \&lt;br /&gt;
    &amp;lt;key3&amp;gt;=&amp;lt;value3&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ENV APACHE_LOCK_DIR=&amp;quot;/var/lock/apache2&amp;quot; \&lt;br /&gt;
    APACHE_PID_FILE=&amp;quot;/var/run/apache2/apache2.pid&amp;quot; \&lt;br /&gt;
    APACHE_RUN_USER=&amp;quot;www-data&amp;quot; \&lt;br /&gt;
    APACHE_RUN_GROUP=&amp;quot;www-data&amp;quot; \&lt;br /&gt;
    APACHE_LOG_DIR=&amp;quot;/var/log/apache2/&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== EXPOSE===&lt;br /&gt;
* informs Docker that the container listens on the specified network ports at runtime&lt;br /&gt;
* it does not make the ports of the container accessible to the host&lt;br /&gt;
** use run &amp;#039;&amp;#039;&amp;#039;-p&amp;#039;&amp;#039;&amp;#039; flag to publish a range of ports&lt;br /&gt;
** use run &amp;#039;&amp;#039;&amp;#039;-P&amp;#039;&amp;#039;&amp;#039; flag to publish all of the exposed ports&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
EXPOSE 80 443&lt;br /&gt;
docker run -P image_name&lt;br /&gt;
docker run -p 8080:80 -p 443:443 image_name&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;Exercises&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== USER ===&lt;br /&gt;
* sets the user name or UID to use when running the image &lt;br /&gt;
** and for any RUN, CMD and ENTRYPOINT instructions that follow it in the Dockerfile&lt;br /&gt;
* try to avoid installing or using sudo since it has unpredictable TTY and signal-forwarding behaviour&lt;br /&gt;
** if you need functionality similar to sudo you should use &amp;#039;&amp;#039;&amp;#039;gosu&amp;#039;&amp;#039;&amp;#039; (https://github.com/tianon/gosu)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
USER mongodb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== VOLUME ===&lt;br /&gt;
* creates a mount point with the specified name and marks it as holding externally mounted volumes from native host or other containers&lt;br /&gt;
* &amp;#039;&amp;#039;docker run&amp;#039;&amp;#039; command initializes the newly created volume with any data that exists at the specified location within the base image&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
VOLUME [&amp;quot;/data&amp;quot;]&lt;br /&gt;
VOLUME [&amp;quot;/var/log&amp;quot;]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;Exercises&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other commands ===&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;LABEL&amp;#039;&amp;#039;&amp;#039; - adds metadata to an image&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
LABEL &amp;lt;key&amp;gt;=&amp;lt;value&amp;gt; &amp;lt;key&amp;gt;=&amp;lt;value&amp;gt; &amp;lt;key&amp;gt;=&amp;lt;value&amp;gt; ...&lt;br /&gt;
LABEL version=&amp;quot;1.0&amp;quot; description=&amp;quot;Docker Training&amp;quot; maintainer=&amp;quot;Kamil Baran&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;ARG&amp;#039;&amp;#039;&amp;#039; - defines a variable that users can pass at build-time to the builder&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;ONBUILD&amp;#039;&amp;#039;&amp;#039; - adds to the image a trigger instruction to be executed at a later time, when the image is used as the base for another build&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;STOPSIGNAL&amp;#039;&amp;#039;&amp;#039; - sets the system call signal that will be sent to the container to exit.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Automated Docker builds ==&lt;br /&gt;
* https://github.com/KamilBaran/nobleprog_docker_training&lt;br /&gt;
* https://hub.docker.com/r/kamilbaran/nobleprog_training/&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== gosu helper tool ==&lt;br /&gt;
* Simple Go-based setuid+setgid+setgroups+exec&lt;br /&gt;
* https://github.com/tianon/gosu&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
RUN    apt-get update \&lt;br /&gt;
    &amp;amp;&amp;amp; apt-get install -y --no-install-recommends ca-certificates curl numactl \&lt;br /&gt;
    &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/* \&lt;br /&gt;
    &amp;amp;&amp;amp; gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \&lt;br /&gt;
    &amp;amp;&amp;amp; curl -o /usr/local/bin/gosu -SL &amp;quot;https://github.com/tianon/gosu/releases/download/1.6/gosu-$(dpkg --print-architecture)&amp;quot; \&lt;br /&gt;
    &amp;amp;&amp;amp; curl -o /usr/local/bin/gosu.asc -SL &amp;quot;https://github.com/tianon/gosu/releases/download/1.6/gosu-$(dpkg --print-architecture).asc&amp;quot; \&lt;br /&gt;
    &amp;amp;&amp;amp; gpg --verify /usr/local/bin/gosu.asc \&lt;br /&gt;
    &amp;amp;&amp;amp; rm /usr/local/bin/gosu.asc \&lt;br /&gt;
    &amp;amp;&amp;amp; chmod +x /usr/local/bin/gosu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# exit immediately if a command exits with a non-zero status.&lt;br /&gt;
set -e&lt;br /&gt;
&lt;br /&gt;
# if the first character in arguments is -&lt;br /&gt;
if [ &amp;quot;${1:0:1}&amp;quot; = &amp;#039;-&amp;#039; ]; then&lt;br /&gt;
  # set all arguments to mongod process&lt;br /&gt;
  set -- mongod &amp;quot;$@&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# if the cmd is mongod&lt;br /&gt;
if [ &amp;quot;$1&amp;quot; = &amp;#039;mongod&amp;#039; ]; then&lt;br /&gt;
  # disable numa&lt;br /&gt;
  numa=&amp;#039;numactl --interleave=all&amp;#039;&lt;br /&gt;
  if $numa true &amp;amp;&amp;gt; /dev/null; then&lt;br /&gt;
    set -- $numa &amp;quot;$@&amp;quot;&lt;br /&gt;
  fi&lt;br /&gt;
&lt;br /&gt;
  # run mongod as mongodb user&lt;br /&gt;
  exec gosu mongodb &amp;quot;$@&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# run any other than mongod process&lt;br /&gt;
exec &amp;quot;$@&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Running more than one process in a container ==&lt;br /&gt;
* http://docs.docker.com/engine/admin/using_supervisord/&lt;br /&gt;
* http://supervisord.org&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
FROM ubuntu:trusty&lt;br /&gt;
RUN    apt-get update \&lt;br /&gt;
    &amp;amp;&amp;amp; apt-get install -y openssh-server supervisor \&lt;br /&gt;
    &amp;amp;&amp;amp; apt-get clean \&lt;br /&gt;
    &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/* \&lt;br /&gt;
    &amp;amp;&amp;amp; mkdir -p /var/run/sshd /var/log/supervisor&lt;br /&gt;
&lt;br /&gt;
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf&lt;br /&gt;
EXPOSE 22&lt;br /&gt;
CMD [&amp;quot;/usr/bin/supervisord&amp;quot;]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
[supervisord]&lt;br /&gt;
nodaemon=true&lt;br /&gt;
&lt;br /&gt;
[program:ping1]&lt;br /&gt;
command=/bin/ping nobleprog.pl&lt;br /&gt;
[program:ping2]&lt;br /&gt;
command=/bin/ping nobleprog.co.uk&lt;br /&gt;
[program:ping3]&lt;br /&gt;
command=/bin/ping nobleprog.cn&lt;br /&gt;
&lt;br /&gt;
[program:sshd]&lt;br /&gt;
command=/usr/sbin/sshd -D&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;Exercises&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General guidelines and recommendations ==&lt;br /&gt;
* Containers should be ephemeral&lt;br /&gt;
* Use a .dockerignore file&lt;br /&gt;
* Avoid installing unnecessary packages&lt;br /&gt;
* Run only one process per container&lt;br /&gt;
* Minimize the number of layers&lt;br /&gt;
* Sort multi-line arguments&lt;br /&gt;
* Build cache&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;Exercises&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kbaran</name></author>
	</entry>
</feed>