remove rst/sphinx documentation
Docker-DCO-1.1-Signed-off-by: Sven Dowideit <SvenDowideit@fosiki.com> (github: SvenDowideit) Upstream-commit: adf04681b4bd7293675b77b2397d87a5361b383b Component: engine
This commit is contained in:
@ -1,102 +0,0 @@
|
||||
:title: Running an apt-cacher-ng service
|
||||
:description: Installing and running an apt-cacher-ng service
|
||||
:keywords: docker, example, package installation, networking, debian, ubuntu
|
||||
|
||||
.. _running_apt-cacher-ng_service:
|
||||
|
||||
Apt-Cacher-ng Service
|
||||
=====================
|
||||
|
||||
.. include:: example_header.inc
|
||||
|
||||
|
||||
When you have multiple Docker servers, or build unrelated Docker containers
|
||||
which can't make use of the Docker build cache, it can be useful to have a
|
||||
caching proxy for your packages. This container makes the second download of
|
||||
any package almost instant.
|
||||
|
||||
Use the following Dockerfile:
|
||||
|
||||
.. literalinclude:: apt-cacher-ng.Dockerfile
|
||||
|
||||
To build the image using:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo docker build -t eg_apt_cacher_ng .
|
||||
|
||||
Then run it, mapping the exposed port to one on the host
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo docker run -d -p 3142:3142 --name test_apt_cacher_ng eg_apt_cacher_ng
|
||||
|
||||
To see the logfiles that are 'tailed' in the default command, you can use:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo docker logs -f test_apt_cacher_ng
|
||||
|
||||
To get your Debian-based containers to use the proxy, you can do one of three things
|
||||
|
||||
1. Add an apt Proxy setting ``echo 'Acquire::http { Proxy "http://dockerhost:3142"; };' >> /etc/apt/conf.d/01proxy``
|
||||
2. Set an environment variable: ``http_proxy=http://dockerhost:3142/``
|
||||
3. Change your ``sources.list`` entries to start with ``http://dockerhost:3142/``
|
||||
|
||||
**Option 1** injects the settings safely into your apt configuration in a local
|
||||
version of a common base:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
FROM ubuntu
|
||||
RUN echo 'Acquire::http { Proxy "http://dockerhost:3142"; };' >> /etc/apt/apt.conf.d/01proxy
|
||||
RUN apt-get update ; apt-get install vim git
|
||||
|
||||
# docker build -t my_ubuntu .
|
||||
|
||||
**Option 2** is good for testing, but will
|
||||
break other HTTP clients which obey ``http_proxy``, such as ``curl``, ``wget`` and others:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo docker run --rm -t -i -e http_proxy=http://dockerhost:3142/ debian bash
|
||||
|
||||
**Option 3** is the least portable, but there will be times when you might need to
|
||||
do it and you can do it from your ``Dockerfile`` too.
|
||||
|
||||
Apt-cacher-ng has some tools that allow you to manage the repository, and they
|
||||
can be used by leveraging the ``VOLUME`` instruction, and the image we built to run the
|
||||
service:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo docker run --rm -t -i --volumes-from test_apt_cacher_ng eg_apt_cacher_ng bash
|
||||
|
||||
$$ /usr/lib/apt-cacher-ng/distkill.pl
|
||||
Scanning /var/cache/apt-cacher-ng, please wait...
|
||||
Found distributions:
|
||||
bla, taggedcount: 0
|
||||
1. precise-security (36 index files)
|
||||
2. wheezy (25 index files)
|
||||
3. precise-updates (36 index files)
|
||||
4. precise (36 index files)
|
||||
5. wheezy-updates (18 index files)
|
||||
|
||||
Found architectures:
|
||||
6. amd64 (36 index files)
|
||||
7. i386 (24 index files)
|
||||
|
||||
WARNING: The removal action may wipe out whole directories containing
|
||||
index files. Select d to see detailed list.
|
||||
|
||||
(Number nn: tag distribution or architecture nn; 0: exit; d: show details; r: remove tagged; q: quit): q
|
||||
|
||||
|
||||
Finally, clean up after your test by stopping and removing the container, and
|
||||
then removing the image.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo docker stop test_apt_cacher_ng
|
||||
$ sudo docker rm test_apt_cacher_ng
|
||||
$ sudo docker rmi eg_apt_cacher_ng
|
||||
@ -1,137 +0,0 @@
|
||||
:title: Process Management with CFEngine
|
||||
:description: Managing containerized processes with CFEngine
|
||||
:keywords: cfengine, process, management, usage, docker, documentation
|
||||
|
||||
Process Management with CFEngine
|
||||
================================
|
||||
|
||||
Create Docker containers with managed processes.
|
||||
|
||||
Docker monitors one process in each running container and the container lives or dies with that process.
|
||||
By introducing CFEngine inside Docker containers, we can alleviate a few of the issues that may arise:
|
||||
|
||||
* It is possible to easily start multiple processes within a container, all of which will be managed automatically, with the normal ``docker run`` command.
|
||||
* If a managed process dies or crashes, CFEngine will start it again within 1 minute.
|
||||
* The container itself will live as long as the CFEngine scheduling daemon (cf-execd) lives. With CFEngine, we are able to decouple the life of the container from the uptime of the service it provides.
|
||||
|
||||
|
||||
How it works
|
||||
------------
|
||||
|
||||
CFEngine, together with the cfe-docker integration policies, are installed as part of the Dockerfile. This builds CFEngine into our Docker image.
|
||||
|
||||
The Dockerfile's ``ENTRYPOINT`` takes an arbitrary amount of commands (with any desired arguments) as parameters.
|
||||
When we run the Docker container these parameters get written to CFEngine policies and CFEngine takes over to ensure that the desired processes are running in the container.
|
||||
|
||||
CFEngine scans the process table for the ``basename`` of the commands given to the ``ENTRYPOINT`` and runs the command to start the process if the ``basename`` is not found.
|
||||
For example, if we start the container with ``docker run "/path/to/my/application parameters"``, CFEngine will look for a process named ``application`` and run the command.
|
||||
If an entry for ``application`` is not found in the process table at any point in time, CFEngine will execute ``/path/to/my/application parameters`` to start the application once again.
|
||||
The check on the process table happens every minute.
|
||||
|
||||
Note that it is therefore important that the command to start your application leaves a process with the basename of the command.
|
||||
This can be made more flexible by making some minor adjustments to the CFEngine policies, if desired.
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
This example assumes you have Docker installed and working.
|
||||
We will install and manage ``apache2`` and ``sshd`` in a single container.
|
||||
|
||||
There are three steps:
|
||||
|
||||
1. Install CFEngine into the container.
|
||||
2. Copy the CFEngine Docker process management policy into the containerized CFEngine installation.
|
||||
3. Start your application processes as part of the ``docker run`` command.
|
||||
|
||||
|
||||
Building the container image
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The first two steps can be done as part of a Dockerfile, as follows.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
FROM ubuntu
|
||||
MAINTAINER Eystein Måløy Stenberg <eytein.stenberg@gmail.com>
|
||||
|
||||
RUN apt-get -y install wget lsb-release unzip ca-certificates
|
||||
|
||||
# install latest CFEngine
|
||||
RUN wget -qO- http://cfengine.com/pub/gpg.key | apt-key add -
|
||||
RUN echo "deb http://cfengine.com/pub/apt $(lsb_release -cs) main" > /etc/apt/sources.list.d/cfengine-community.list
|
||||
RUN apt-get update
|
||||
RUN apt-get install cfengine-community
|
||||
|
||||
# install cfe-docker process management policy
|
||||
RUN wget https://github.com/estenberg/cfe-docker/archive/master.zip -P /tmp/ && unzip /tmp/master.zip -d /tmp/
|
||||
RUN cp /tmp/cfe-docker-master/cfengine/bin/* /var/cfengine/bin/
|
||||
RUN cp /tmp/cfe-docker-master/cfengine/inputs/* /var/cfengine/inputs/
|
||||
RUN rm -rf /tmp/cfe-docker-master /tmp/master.zip
|
||||
|
||||
# apache2 and openssh are just for testing purposes, install your own apps here
|
||||
RUN apt-get -y install openssh-server apache2
|
||||
RUN mkdir -p /var/run/sshd
|
||||
RUN echo "root:password" | chpasswd # need a password for ssh
|
||||
|
||||
ENTRYPOINT ["/var/cfengine/bin/docker_processes_run.sh"]
|
||||
|
||||
|
||||
By saving this file as ``Dockerfile`` to a working directory, you can then build your container with the docker build command,
|
||||
e.g. ``docker build -t managed_image``.
|
||||
|
||||
Testing the container
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Start the container with ``apache2`` and ``sshd`` running and managed, forwarding a port to our SSH instance:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker run -p 127.0.0.1:222:22 -d managed_image "/usr/sbin/sshd" "/etc/init.d/apache2 start"
|
||||
|
||||
We now clearly see one of the benefits of the cfe-docker integration: it allows to start several processes
|
||||
as part of a normal ``docker run`` command.
|
||||
|
||||
We can now log in to our new container and see that both ``apache2`` and ``sshd`` are running. We have set the root password to
|
||||
"password" in the Dockerfile above and can use that to log in with ssh:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
ssh -p222 root@127.0.0.1
|
||||
|
||||
ps -ef
|
||||
UID PID PPID C STIME TTY TIME CMD
|
||||
root 1 0 0 07:48 ? 00:00:00 /bin/bash /var/cfengine/bin/docker_processes_run.sh /usr/sbin/sshd /etc/init.d/apache2 start
|
||||
root 18 1 0 07:48 ? 00:00:00 /var/cfengine/bin/cf-execd -F
|
||||
root 20 1 0 07:48 ? 00:00:00 /usr/sbin/sshd
|
||||
root 32 1 0 07:48 ? 00:00:00 /usr/sbin/apache2 -k start
|
||||
www-data 34 32 0 07:48 ? 00:00:00 /usr/sbin/apache2 -k start
|
||||
www-data 35 32 0 07:48 ? 00:00:00 /usr/sbin/apache2 -k start
|
||||
www-data 36 32 0 07:48 ? 00:00:00 /usr/sbin/apache2 -k start
|
||||
root 93 20 0 07:48 ? 00:00:00 sshd: root@pts/0
|
||||
root 105 93 0 07:48 pts/0 00:00:00 -bash
|
||||
root 112 105 0 07:49 pts/0 00:00:00 ps -ef
|
||||
|
||||
|
||||
If we stop apache2, it will be started again within a minute by CFEngine.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
service apache2 status
|
||||
Apache2 is running (pid 32).
|
||||
service apache2 stop
|
||||
* Stopping web server apache2 ... waiting [ OK ]
|
||||
service apache2 status
|
||||
Apache2 is NOT running.
|
||||
# ... wait up to 1 minute...
|
||||
service apache2 status
|
||||
Apache2 is running (pid 173).
|
||||
|
||||
|
||||
Adapting to your applications
|
||||
-----------------------------
|
||||
|
||||
To make sure your applications get managed in the same manner, there are just two things you need to adjust from the above example:
|
||||
|
||||
* In the Dockerfile used above, install your applications instead of ``apache2`` and ``sshd``.
|
||||
* When you start the container with ``docker run``, specify the command line arguments to your applications rather than ``apache2`` and ``sshd``.
|
||||
@ -1,56 +0,0 @@
|
||||
:title: Sharing data between 2 couchdb databases
|
||||
:description: Sharing data between 2 couchdb databases
|
||||
:keywords: docker, example, package installation, networking, couchdb, data volumes
|
||||
|
||||
.. _running_couchdb_service:
|
||||
|
||||
CouchDB Service
|
||||
===============
|
||||
|
||||
.. include:: example_header.inc
|
||||
|
||||
Here's an example of using data volumes to share the same data between
|
||||
two CouchDB containers. This could be used for hot upgrades, testing
|
||||
different versions of CouchDB on the same data, etc.
|
||||
|
||||
Create first database
|
||||
---------------------
|
||||
|
||||
Note that we're marking ``/var/lib/couchdb`` as a data volume.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
COUCH1=$(sudo docker run -d -p 5984 -v /var/lib/couchdb shykes/couchdb:2013-05-03)
|
||||
|
||||
Add data to the first database
|
||||
------------------------------
|
||||
|
||||
We're assuming your Docker host is reachable at ``localhost``. If not,
|
||||
replace ``localhost`` with the public IP of your Docker host.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
HOST=localhost
|
||||
URL="http://$HOST:$(sudo docker port $COUCH1 5984 | grep -Po '\d+$')/_utils/"
|
||||
echo "Navigate to $URL in your browser, and use the couch interface to add data"
|
||||
|
||||
Create second database
|
||||
----------------------
|
||||
|
||||
This time, we're requesting shared access to ``$COUCH1``'s volumes.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
COUCH2=$(sudo docker run -d -p 5984 --volumes-from $COUCH1 shykes/couchdb:2013-05-03)
|
||||
|
||||
Browse data on the second database
|
||||
----------------------------------
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
HOST=localhost
|
||||
URL="http://$HOST:$(sudo docker port $COUCH2 5984 | grep -Po '\d+$')/_utils/"
|
||||
echo "Navigate to $URL in your browser. You should see the same data as in the first database"'!'
|
||||
|
||||
Congratulations, you are now running two Couchdb containers, completely
|
||||
isolated from each other *except* for their data.
|
||||
@ -1,181 +0,0 @@
|
||||
:title: Hello world example
|
||||
:description: A simple hello world example with Docker
|
||||
:keywords: docker, example, hello world
|
||||
|
||||
.. _running_examples:
|
||||
|
||||
Check your Docker install
|
||||
-------------------------
|
||||
|
||||
This guide assumes you have a working installation of Docker. To check
|
||||
your Docker install, run the following command:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Check that you have a working install
|
||||
$ sudo docker info
|
||||
|
||||
If you get ``docker: command not found`` or something like
|
||||
``/var/lib/docker/repositories: permission denied`` you may have an incomplete
|
||||
Docker installation or insufficient privileges to access docker on your machine.
|
||||
|
||||
Please refer to :ref:`installation_list` for installation instructions.
|
||||
|
||||
|
||||
.. _hello_world:
|
||||
|
||||
Hello World
|
||||
-----------
|
||||
|
||||
.. include:: example_header.inc
|
||||
|
||||
This is the most basic example available for using Docker.
|
||||
|
||||
Download the small base image named ``busybox``:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Download a busybox image
|
||||
$ sudo docker pull busybox
|
||||
|
||||
The ``busybox`` image is a minimal Linux system. You can do the same
|
||||
with any number of other images, such as ``debian``, ``ubuntu`` or ``centos``.
|
||||
The images can be found and retrieved using the `Docker index`_.
|
||||
|
||||
.. _Docker index: http://index.docker.io
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo docker run busybox /bin/echo hello world
|
||||
|
||||
This command will run a simple ``echo`` command, that will echo ``hello world`` back to the console over standard out.
|
||||
|
||||
**Explanation:**
|
||||
|
||||
- **"sudo"** execute the following commands as user *root*
|
||||
- **"docker run"** run a command in a new container
|
||||
- **"busybox"** is the image we are running the command in.
|
||||
- **"/bin/echo"** is the command we want to run in the container
|
||||
- **"hello world"** is the input for the echo command
|
||||
|
||||
|
||||
|
||||
**Video:**
|
||||
|
||||
See the example in action
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<iframe width="560" height="400" frameborder="0"
|
||||
sandbox="allow-same-origin allow-scripts"
|
||||
srcdoc="<body><script type="text/javascript"
|
||||
src="https://asciinema.org/a/7658.js"
|
||||
id="asciicast-7658" async></script></body>">
|
||||
</iframe>
|
||||
|
||||
----
|
||||
|
||||
.. _hello_world_daemon:
|
||||
|
||||
Hello World Daemon
|
||||
------------------
|
||||
|
||||
.. include:: example_header.inc
|
||||
|
||||
And now for the most boring daemon ever written!
|
||||
|
||||
We will use the Ubuntu image to run a simple hello world daemon that will just print hello
|
||||
world to standard out every second. It will continue to do this until
|
||||
we stop it.
|
||||
|
||||
**Steps:**
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
container_id=$(sudo docker run -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done")
|
||||
|
||||
We are going to run a simple hello world daemon in a new container
|
||||
made from the ``ubuntu`` image.
|
||||
|
||||
- **"sudo docker run -d "** run a command in a new container. We pass "-d"
|
||||
so it runs as a daemon.
|
||||
- **"ubuntu"** is the image we want to run the command inside of.
|
||||
- **"/bin/sh -c"** is the command we want to run in the container
|
||||
- **"while true; do echo hello world; sleep 1; done"** is the mini
|
||||
script we want to run, that will just print hello world once a
|
||||
second until we stop it.
|
||||
- **$container_id** the output of the run command will return a
|
||||
container id, we can use in future commands to see what is going on
|
||||
with this process.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo docker logs $container_id
|
||||
|
||||
Check the logs make sure it is working correctly.
|
||||
|
||||
- **"docker logs**" This will return the logs for a container
|
||||
- **$container_id** The Id of the container we want the logs for.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo docker attach --sig-proxy=false $container_id
|
||||
|
||||
Attach to the container to see the results in real-time.
|
||||
|
||||
- **"docker attach**" This will allow us to attach to a background
|
||||
process to see what is going on.
|
||||
- **"--sig-proxy=false"** Do not forward signals to the container; allows
|
||||
us to exit the attachment using Control-C without stopping the container.
|
||||
- **$container_id** The Id of the container we want to attach to.
|
||||
|
||||
Exit from the container attachment by pressing Control-C.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo docker ps
|
||||
|
||||
Check the process list to make sure it is running.
|
||||
|
||||
- **"docker ps"** this shows all running process managed by docker
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo docker stop $container_id
|
||||
|
||||
Stop the container, since we don't need it anymore.
|
||||
|
||||
- **"docker stop"** This stops a container
|
||||
- **$container_id** The Id of the container we want to stop.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo docker ps
|
||||
|
||||
Make sure it is really stopped.
|
||||
|
||||
|
||||
**Video:**
|
||||
|
||||
See the example in action
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<iframe width="560" height="400" frameborder="0"
|
||||
sandbox="allow-same-origin allow-scripts"
|
||||
srcdoc="<body><script type="text/javascript"
|
||||
src="https://asciinema.org/a/2562.js"
|
||||
id="asciicast-2562" async></script></body>">
|
||||
</iframe>
|
||||
|
||||
The next example in the series is a :ref:`nodejs_web_app` example, or
|
||||
you could skip to any of the other examples:
|
||||
|
||||
|
||||
* :ref:`nodejs_web_app`
|
||||
* :ref:`running_redis_service`
|
||||
* :ref:`running_ssh_service`
|
||||
* :ref:`running_couchdb_service`
|
||||
* :ref:`postgresql_service`
|
||||
* :ref:`mongodb_image`
|
||||
* :ref:`python_web_app`
|
||||
@ -1,126 +0,0 @@
|
||||
:title: Docker HTTPS Setup
|
||||
:description: How to setup docker with https
|
||||
:keywords: docker, example, https, daemon
|
||||
|
||||
.. _running_docker_https:
|
||||
|
||||
Running Docker with https
|
||||
=========================
|
||||
|
||||
By default, Docker runs via a non-networked Unix socket. It can also optionally
|
||||
communicate using a HTTP socket.
|
||||
|
||||
If you need Docker reachable via the network in a safe manner, you can enable
|
||||
TLS by specifying the `tlsverify` flag and pointing Docker's `tlscacert` flag to a
|
||||
trusted CA certificate.
|
||||
|
||||
In daemon mode, it will only allow connections from clients authenticated by a
|
||||
certificate signed by that CA. In client mode, it will only connect to servers
|
||||
with a certificate signed by that CA.
|
||||
|
||||
.. warning::
|
||||
|
||||
Using TLS and managing a CA is an advanced topic. Please make you self familiar
|
||||
with openssl, x509 and tls before using it in production.
|
||||
|
||||
Create a CA, server and client keys with OpenSSL
|
||||
------------------------------------------------
|
||||
|
||||
First, initialize the CA serial file and generate CA private and public keys:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ echo 01 > ca.srl
|
||||
$ openssl genrsa -des3 -out ca-key.pem
|
||||
$ openssl req -new -x509 -days 365 -key ca-key.pem -out ca.pem
|
||||
|
||||
Now that we have a CA, you can create a server key and certificate signing request.
|
||||
Make sure that `"Common Name (e.g. server FQDN or YOUR name)"` matches the hostname you will use
|
||||
to connect to Docker or just use '*' for a certificate valid for any hostname:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ openssl genrsa -des3 -out server-key.pem
|
||||
$ openssl req -new -key server-key.pem -out server.csr
|
||||
|
||||
Next we're going to sign the key with our CA:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ openssl x509 -req -days 365 -in server.csr -CA ca.pem -CAkey ca-key.pem \
|
||||
-out server-cert.pem
|
||||
|
||||
For client authentication, create a client key and certificate signing request:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ openssl genrsa -des3 -out client-key.pem
|
||||
$ openssl req -new -key client-key.pem -out client.csr
|
||||
|
||||
|
||||
To make the key suitable for client authentication, create a extensions config file:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ echo extendedKeyUsage = clientAuth > extfile.cnf
|
||||
|
||||
Now sign the key:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ openssl x509 -req -days 365 -in client.csr -CA ca.pem -CAkey ca-key.pem \
|
||||
-out client-cert.pem -extfile extfile.cnf
|
||||
|
||||
Finally you need to remove the passphrase from the client and server key:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ openssl rsa -in server-key.pem -out server-key.pem
|
||||
$ openssl rsa -in client-key.pem -out client-key.pem
|
||||
|
||||
Now you can make the Docker daemon only accept connections from clients providing
|
||||
a certificate trusted by our CA:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo docker -d --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem \
|
||||
-H=0.0.0.0:4243
|
||||
|
||||
To be able to connect to Docker and validate its certificate, you now need to provide your client keys,
|
||||
certificates and trusted CA:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ docker --tlsverify --tlscacert=ca.pem --tlscert=client-cert.pem --tlskey=client-key.pem \
|
||||
-H=dns-name-of-docker-host:4243
|
||||
|
||||
.. warning::
|
||||
|
||||
As shown in the example above, you don't have to run the ``docker``
|
||||
client with ``sudo`` or the ``docker`` group when you use
|
||||
certificate authentication. That means anyone with the keys can
|
||||
give any instructions to your Docker daemon, giving them root
|
||||
access to the machine hosting the daemon. Guard these keys as you
|
||||
would a root password!
|
||||
|
||||
Other modes
|
||||
-----------
|
||||
If you don't want to have complete two-way authentication, you can run Docker in
|
||||
various other modes by mixing the flags.
|
||||
|
||||
Daemon modes
|
||||
~~~~~~~~~~~~
|
||||
- tlsverify, tlscacert, tlscert, tlskey set: Authenticate clients
|
||||
- tls, tlscert, tlskey: Do not authenticate clients
|
||||
|
||||
Client modes
|
||||
~~~~~~~~~~~~
|
||||
- tls: Authenticate server based on public/default CA pool
|
||||
- tlsverify, tlscacert: Authenticate server based on given CA
|
||||
- tls, tlscert, tlskey: Authenticate with client certificate, do not authenticate
|
||||
server based on given CA
|
||||
- tlsverify, tlscacert, tlscert, tlskey: Authenticate with client certificate,
|
||||
authenticate server based on given CA
|
||||
|
||||
The client will send its client certificate if found, so you just need to drop
|
||||
your keys into `~/.docker/<ca, cert or key>.pem`
|
||||
@ -1,30 +0,0 @@
|
||||
:title: Docker Examples
|
||||
:description: Examples on how to use Docker
|
||||
:keywords: docker, hello world, node, nodejs, python, couch, couchdb, redis, ssh, sshd, examples, postgresql, link
|
||||
|
||||
|
||||
.. _example_list:
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
Here are some examples of how to use Docker to create running
|
||||
processes, starting from a very simple *Hello World* and progressing
|
||||
to more substantial services like those which you might find in production.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
hello_world
|
||||
nodejs_web_app
|
||||
running_redis_service
|
||||
running_ssh_service
|
||||
couchdb_data_volumes
|
||||
postgresql_service
|
||||
mongodb
|
||||
running_riak_service
|
||||
using_supervisord
|
||||
cfengine_process_management
|
||||
python_web_app
|
||||
apt-cacher-ng
|
||||
https
|
||||
@ -1,100 +0,0 @@
|
||||
:title: Building a Docker Image with MongoDB
|
||||
:description: How to build a Docker image with MongoDB pre-installed
|
||||
:keywords: docker, example, package installation, networking, mongodb
|
||||
|
||||
.. _mongodb_image:
|
||||
|
||||
Building an Image with MongoDB
|
||||
==============================
|
||||
|
||||
.. include:: example_header.inc
|
||||
|
||||
The goal of this example is to show how you can build your own
|
||||
Docker images with MongoDB pre-installed. We will do that by
|
||||
constructing a ``Dockerfile`` that downloads a base image, adds an
|
||||
apt source and installs the database software on Ubuntu.
|
||||
|
||||
Creating a ``Dockerfile``
|
||||
+++++++++++++++++++++++++
|
||||
|
||||
Create an empty file called ``Dockerfile``:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
touch Dockerfile
|
||||
|
||||
Next, define the parent image you want to use to build your own image on top of.
|
||||
Here, we’ll use `Ubuntu <https://index.docker.io/_/ubuntu/>`_ (tag: ``latest``)
|
||||
available on the `docker index <http://index.docker.io>`_:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
FROM ubuntu:latest
|
||||
|
||||
Since we want to be running the latest version of MongoDB we'll need to add the
|
||||
10gen repo to our apt sources list.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Add 10gen official apt source to the sources list
|
||||
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10
|
||||
RUN echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | tee /etc/apt/sources.list.d/10gen.list
|
||||
|
||||
Then, we don't want Ubuntu to complain about init not being available so we'll
|
||||
divert ``/sbin/initctl`` to ``/bin/true`` so it thinks everything is working.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Hack for initctl not being available in Ubuntu
|
||||
RUN dpkg-divert --local --rename --add /sbin/initctl
|
||||
RUN ln -sf /bin/true /sbin/initctl
|
||||
|
||||
Afterwards we'll be able to update our apt repositories and install MongoDB
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Install MongoDB
|
||||
RUN apt-get update
|
||||
RUN apt-get install mongodb-10gen
|
||||
|
||||
To run MongoDB we'll have to create the default data directory (because we want it to
|
||||
run without needing to provide a special configuration file)
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Create the MongoDB data directory
|
||||
RUN mkdir -p /data/db
|
||||
|
||||
Finally, we'll expose the standard port that MongoDB runs on, 27107, as well as
|
||||
define an ``ENTRYPOINT`` instruction for the container.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
EXPOSE 27017
|
||||
ENTRYPOINT ["usr/bin/mongod"]
|
||||
|
||||
Now, lets build the image which will go through the ``Dockerfile`` we made and
|
||||
run all of the commands.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo docker build -t <yourname>/mongodb .
|
||||
|
||||
Now you should be able to run ``mongod`` as a daemon and be able to connect on
|
||||
the local port!
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Regular style
|
||||
MONGO_ID=$(sudo docker run -P -d <yourname>/mongodb)
|
||||
|
||||
# Lean and mean
|
||||
MONGO_ID=$(sudo docker run -P -d <yourname>/mongodb --noprealloc --smallfiles)
|
||||
|
||||
# Check the logs out
|
||||
sudo docker logs $MONGO_ID
|
||||
|
||||
# Connect and play around
|
||||
mongo --port <port you get from `docker ps`>
|
||||
|
||||
Sweet!
|
||||
@ -1,239 +0,0 @@
|
||||
:title: Running a Node.js app on CentOS
|
||||
:description: Installing and running a Node.js app on CentOS
|
||||
:keywords: docker, example, package installation, node, centos
|
||||
|
||||
.. _nodejs_web_app:
|
||||
|
||||
Node.js Web App
|
||||
===============
|
||||
|
||||
.. include:: example_header.inc
|
||||
|
||||
The goal of this example is to show you how you can build your own
|
||||
Docker images from a parent image using a ``Dockerfile`` . We will do
|
||||
that by making a simple Node.js hello world web application running on
|
||||
CentOS. You can get the full source code at
|
||||
https://github.com/gasi/docker-node-hello.
|
||||
|
||||
Create Node.js app
|
||||
++++++++++++++++++
|
||||
|
||||
First, create a directory ``src`` where all the files would live. Then create a ``package.json`` file that describes your app and its
|
||||
dependencies:
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"name": "docker-centos-hello",
|
||||
"private": true,
|
||||
"version": "0.0.1",
|
||||
"description": "Node.js Hello World app on CentOS using docker",
|
||||
"author": "Daniel Gasienica <daniel@gasienica.ch>",
|
||||
"dependencies": {
|
||||
"express": "3.2.4"
|
||||
}
|
||||
}
|
||||
|
||||
Then, create an ``index.js`` file that defines a web app using the
|
||||
`Express.js <http://expressjs.com/>`_ framework:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
var express = require('express');
|
||||
|
||||
// Constants
|
||||
var PORT = 8080;
|
||||
|
||||
// App
|
||||
var app = express();
|
||||
app.get('/', function (req, res) {
|
||||
res.send('Hello World\n');
|
||||
});
|
||||
|
||||
app.listen(PORT);
|
||||
console.log('Running on http://localhost:' + PORT);
|
||||
|
||||
|
||||
In the next steps, we’ll look at how you can run this app inside a CentOS
|
||||
container using Docker. First, you’ll need to build a Docker image of your app.
|
||||
|
||||
Creating a ``Dockerfile``
|
||||
+++++++++++++++++++++++++
|
||||
|
||||
Create an empty file called ``Dockerfile``:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
touch Dockerfile
|
||||
|
||||
Open the ``Dockerfile`` in your favorite text editor and add the following line
|
||||
that defines the version of Docker the image requires to build
|
||||
(this example uses Docker 0.3.4):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# DOCKER-VERSION 0.3.4
|
||||
|
||||
Next, define the parent image you want to use to build your own image on top of.
|
||||
Here, we’ll use `CentOS <https://index.docker.io/_/centos/>`_ (tag: ``6.4``)
|
||||
available on the `Docker index`_:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
FROM centos:6.4
|
||||
|
||||
Since we’re building a Node.js app, you’ll have to install Node.js as well as
|
||||
npm on your CentOS image. Node.js is required to run your app and npm to install
|
||||
your app’s dependencies defined in ``package.json``.
|
||||
To install the right package for CentOS, we’ll use the instructions from the
|
||||
`Node.js wiki`_:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Enable EPEL for Node.js
|
||||
RUN rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
|
||||
# Install Node.js and npm
|
||||
RUN yum install -y npm
|
||||
|
||||
To bundle your app’s source code inside the Docker image, use the ``ADD``
|
||||
instruction:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Bundle app source
|
||||
ADD . /src
|
||||
|
||||
Install your app dependencies using the ``npm`` binary:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Install app dependencies
|
||||
RUN cd /src; npm install
|
||||
|
||||
Your app binds to port ``8080`` so you’ll use the ``EXPOSE`` instruction
|
||||
to have it mapped by the ``docker`` daemon:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
Last but not least, define the command to run your app using ``CMD``
|
||||
which defines your runtime, i.e. ``node``, and the path to our app,
|
||||
i.e. ``src/index.js`` (see the step where we added the source to the
|
||||
container):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
CMD ["node", "/src/index.js"]
|
||||
|
||||
Your ``Dockerfile`` should now look like this:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
|
||||
# DOCKER-VERSION 0.3.4
|
||||
FROM centos:6.4
|
||||
|
||||
# Enable EPEL for Node.js
|
||||
RUN rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
|
||||
# Install Node.js and npm
|
||||
RUN yum install -y npm
|
||||
|
||||
# Bundle app source
|
||||
ADD . /src
|
||||
# Install app dependencies
|
||||
RUN cd /src; npm install
|
||||
|
||||
EXPOSE 8080
|
||||
CMD ["node", "/src/index.js"]
|
||||
|
||||
|
||||
Building your image
|
||||
+++++++++++++++++++
|
||||
|
||||
Go to the directory that has your ``Dockerfile`` and run the following
|
||||
command to build a Docker image. The ``-t`` flag let’s you tag your
|
||||
image so it’s easier to find later using the ``docker images``
|
||||
command:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo docker build -t <your username>/centos-node-hello .
|
||||
|
||||
Your image will now be listed by Docker:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo docker images
|
||||
|
||||
> # Example
|
||||
> REPOSITORY TAG ID CREATED
|
||||
> centos 6.4 539c0211cd76 8 weeks ago
|
||||
> gasi/centos-node-hello latest d64d3505b0d2 2 hours ago
|
||||
|
||||
|
||||
Run the image
|
||||
+++++++++++++
|
||||
|
||||
Running your image with ``-d`` runs the container in detached mode, leaving the
|
||||
container running in the background. The ``-p`` flag redirects a public port to a private port in the container. Run the image you previously built:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo docker run -p 49160:8080 -d <your username>/centos-node-hello
|
||||
|
||||
Print the output of your app:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Get container ID
|
||||
sudo docker ps
|
||||
|
||||
# Print app output
|
||||
sudo docker logs <container id>
|
||||
|
||||
> # Example
|
||||
> Running on http://localhost:8080
|
||||
|
||||
|
||||
Test
|
||||
++++
|
||||
|
||||
To test your app, get the the port of your app that Docker mapped:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo docker ps
|
||||
|
||||
> # Example
|
||||
> ID IMAGE COMMAND ... PORTS
|
||||
> ecce33b30ebf gasi/centos-node-hello:latest node /src/index.js 49160->8080
|
||||
|
||||
In the example above, Docker mapped the ``8080`` port of the container to
|
||||
``49160``.
|
||||
|
||||
Now you can call your app using ``curl`` (install if needed via:
|
||||
``sudo apt-get install curl``):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
curl -i localhost:49160
|
||||
|
||||
> HTTP/1.1 200 OK
|
||||
> X-Powered-By: Express
|
||||
> Content-Type: text/html; charset=utf-8
|
||||
> Content-Length: 12
|
||||
> Date: Sun, 02 Jun 2013 03:53:22 GMT
|
||||
> Connection: keep-alive
|
||||
>
|
||||
> Hello World
|
||||
|
||||
We hope this tutorial helped you get up and running with Node.js and
|
||||
CentOS on Docker. You can get the full source code at
|
||||
https://github.com/gasi/docker-node-hello.
|
||||
|
||||
Continue to :ref:`running_redis_service`.
|
||||
|
||||
|
||||
.. _Node.js wiki: https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#rhelcentosscientific-linux-6
|
||||
.. _docker index: https://index.docker.io/
|
||||
@ -1,117 +0,0 @@
|
||||
:title: PostgreSQL service How-To
|
||||
:description: Running and installing a PostgreSQL service
|
||||
:keywords: docker, example, package installation, postgresql
|
||||
|
||||
.. _postgresql_service:
|
||||
|
||||
PostgreSQL Service
|
||||
==================
|
||||
|
||||
.. include:: example_header.inc
|
||||
|
||||
Installing PostgreSQL on Docker
|
||||
-------------------------------
|
||||
|
||||
Assuming there is no Docker image that suits your needs in `the index`_, you
|
||||
can create one yourself.
|
||||
|
||||
.. _the index: http://index.docker.io
|
||||
|
||||
Start by creating a new Dockerfile:
|
||||
|
||||
.. note::
|
||||
|
||||
This PostgreSQL setup is for development only purposes. Refer
|
||||
to the PostgreSQL documentation to fine-tune these settings so that it
|
||||
is suitably secure.
|
||||
|
||||
.. literalinclude:: postgresql_service.Dockerfile
|
||||
|
||||
Build an image from the Dockerfile assign it a name.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo docker build -t eg_postgresql .
|
||||
|
||||
And run the PostgreSQL server container (in the foreground):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo docker run --rm -P --name pg_test eg_postgresql
|
||||
|
||||
There are 2 ways to connect to the PostgreSQL server. We can use
|
||||
:ref:`working_with_links_names`, or we can access it from our host (or the network).
|
||||
|
||||
.. note:: The ``--rm`` removes the container and its image when the container
|
||||
exists successfully.
|
||||
|
||||
Using container linking
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Containers can be linked to another container's ports directly using
|
||||
``--link remote_name:local_alias`` in the client's ``docker run``. This will
|
||||
set a number of environment variables that can then be used to connect:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo docker run --rm -t -i --link pg_test:pg eg_postgresql bash
|
||||
|
||||
postgres@7ef98b1b7243:/$ psql -h $PG_PORT_5432_TCP_ADDR -p $PG_PORT_5432_TCP_PORT -d docker -U docker --password
|
||||
|
||||
Connecting from your host system
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Assuming you have the postgresql-client installed, you can use the host-mapped port
|
||||
to test as well. You need to use ``docker ps`` to find out what local host port the
|
||||
container is mapped to first:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ docker ps
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
5e24362f27f6 eg_postgresql:latest /usr/lib/postgresql/ About an hour ago Up About an hour 0.0.0.0:49153->5432/tcp pg_test
|
||||
$ psql -h localhost -p 49153 -d docker -U docker --password
|
||||
|
||||
Testing the database
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Once you have authenticated and have a ``docker =#`` prompt, you can
|
||||
create a table and populate it.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
psql (9.3.1)
|
||||
Type "help" for help.
|
||||
|
||||
docker=# CREATE TABLE cities (
|
||||
docker(# name varchar(80),
|
||||
docker(# location point
|
||||
docker(# );
|
||||
CREATE TABLE
|
||||
docker=# INSERT INTO cities VALUES ('San Francisco', '(-194.0, 53.0)');
|
||||
INSERT 0 1
|
||||
docker=# select * from cities;
|
||||
name | location
|
||||
---------------+-----------
|
||||
San Francisco | (-194,53)
|
||||
(1 row)
|
||||
|
||||
Using the container volumes
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
You can use the defined volumes to inspect the PostgreSQL log files and to backup your
|
||||
configuration and data:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker run --rm --volumes-from pg_test -t -i busybox sh
|
||||
|
||||
/ # ls
|
||||
bin etc lib linuxrc mnt proc run sys usr
|
||||
dev home lib64 media opt root sbin tmp var
|
||||
/ # ls /etc/postgresql/9.3/main/
|
||||
environment pg_hba.conf postgresql.conf
|
||||
pg_ctl.conf pg_ident.conf start.conf
|
||||
/tmp # ls /var/log
|
||||
ldconfig postgresql
|
||||
|
||||
@ -1,145 +0,0 @@
|
||||
:title: Python Web app example
|
||||
:description: Building your own python web app using docker
|
||||
:keywords: docker, example, python, web app
|
||||
|
||||
.. _python_web_app:
|
||||
|
||||
Python Web App
|
||||
==============
|
||||
|
||||
.. include:: example_header.inc
|
||||
|
||||
While using Dockerfiles is the preferred way to create maintainable
|
||||
and repeatable images, its useful to know how you can try things out
|
||||
and then commit your live changes to an image.
|
||||
|
||||
The goal of this example is to show you how you can modify your own
|
||||
Docker images by making changes to a running
|
||||
container, and then saving the results as a new image. We will do
|
||||
that by making a simple 'hello world' Flask web application image.
|
||||
|
||||
Download the initial image
|
||||
--------------------------
|
||||
|
||||
Download the ``shykes/pybuilder`` Docker image from the ``http://index.docker.io``
|
||||
registry.
|
||||
|
||||
This image contains a ``buildapp`` script to download the web app and then ``pip install``
|
||||
any required modules, and a ``runapp`` script that finds the ``app.py`` and runs it.
|
||||
|
||||
.. _`shykes/pybuilder`: https://github.com/shykes/pybuilder
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo docker pull shykes/pybuilder
|
||||
|
||||
.. note:: This container was built with a very old version of docker
|
||||
(May 2013 - see `shykes/pybuilder`_ ), when the ``Dockerfile`` format was different,
|
||||
but the image can still be used now.
|
||||
|
||||
Interactively make some modifications
|
||||
-------------------------------------
|
||||
|
||||
We then start a new container running interactively using the image.
|
||||
First, we set a ``URL`` variable that points to a tarball of a simple
|
||||
helloflask web app, and then we run a command contained in the image called
|
||||
``buildapp``, passing it the ``$URL`` variable. The container is
|
||||
given a name ``pybuilder_run`` which we will use in the next steps.
|
||||
|
||||
While this example is simple, you could run any number of interactive commands,
|
||||
try things out, and then exit when you're done.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo docker run -i -t --name pybuilder_run shykes/pybuilder bash
|
||||
|
||||
$$ URL=http://github.com/shykes/helloflask/archive/master.tar.gz
|
||||
$$ /usr/local/bin/buildapp $URL
|
||||
[...]
|
||||
$$ exit
|
||||
|
||||
Commit the container to create a new image
|
||||
------------------------------------------
|
||||
|
||||
Save the changes we just made in the container to a new image called
|
||||
``/builds/github.com/shykes/helloflask/master``. You now have 3 different
|
||||
ways to refer to the container: name ``pybuilder_run``, short-id ``c8b2e8228f11``, or
|
||||
long-id ``c8b2e8228f11b8b3e492cbf9a49923ae66496230056d61e07880dc74c5f495f9``.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo docker commit pybuilder_run /builds/github.com/shykes/helloflask/master
|
||||
c8b2e8228f11b8b3e492cbf9a49923ae66496230056d61e07880dc74c5f495f9
|
||||
|
||||
|
||||
Run the new image to start the web worker
|
||||
-----------------------------------------
|
||||
|
||||
Use the new image to create a new container with
|
||||
network port 5000 mapped to a local port
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo docker run -d -p 5000 --name web_worker /builds/github.com/shykes/helloflask/master /usr/local/bin/runapp
|
||||
|
||||
|
||||
- **"docker run -d "** run a command in a new container. We pass "-d"
|
||||
so it runs as a daemon.
|
||||
- **"-p 5000"** the web app is going to listen on this port, so it
|
||||
must be mapped from the container to the host system.
|
||||
- **/usr/local/bin/runapp** is the command which starts the web app.
|
||||
|
||||
|
||||
View the container logs
|
||||
-----------------------
|
||||
|
||||
View the logs for the new ``web_worker`` container and
|
||||
if everything worked as planned you should see the line ``Running on
|
||||
http://0.0.0.0:5000/`` in the log output.
|
||||
|
||||
To exit the view without stopping the container, hit Ctrl-C, or open another
|
||||
terminal and continue with the example while watching the result in the logs.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo docker logs -f web_worker
|
||||
* Running on http://0.0.0.0:5000/
|
||||
|
||||
|
||||
See the webapp output
|
||||
---------------------
|
||||
|
||||
Look up the public-facing port which is NAT-ed. Find the private port
|
||||
used by the container and store it inside of the ``WEB_PORT`` variable.
|
||||
|
||||
Access the web app using the ``curl`` binary. If everything worked as planned you
|
||||
should see the line ``Hello world!`` inside of your console.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ WEB_PORT=$(sudo docker port web_worker 5000 | awk -F: '{ print $2 }')
|
||||
|
||||
# install curl if necessary, then ...
|
||||
$ curl http://127.0.0.1:$WEB_PORT
|
||||
Hello world!
|
||||
|
||||
|
||||
Clean up example containers and images
|
||||
--------------------------------------
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo docker ps --all
|
||||
|
||||
List ``--all`` the Docker containers. If this container had already finished
|
||||
running, it will still be listed here with a status of 'Exit 0'.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo docker stop web_worker
|
||||
$ sudo docker rm web_worker pybuilder_run
|
||||
$ sudo docker rmi /builds/github.com/shykes/helloflask/master shykes/pybuilder:latest
|
||||
|
||||
And now stop the running web worker, and delete the containers, so that we can
|
||||
then delete the images that we used.
|
||||
|
||||
@ -1,101 +0,0 @@
|
||||
:title: Running a Redis service
|
||||
:description: Installing and running an redis service
|
||||
:keywords: docker, example, package installation, networking, redis
|
||||
|
||||
.. _running_redis_service:
|
||||
|
||||
Redis Service
|
||||
=============
|
||||
|
||||
.. include:: example_header.inc
|
||||
|
||||
Very simple, no frills, Redis service attached to a web application using a link.
|
||||
|
||||
Create a docker container for Redis
|
||||
-----------------------------------
|
||||
|
||||
Firstly, we create a ``Dockerfile`` for our new Redis image.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
FROM debian:jessie
|
||||
RUN apt-get update && apt-get install -y redis-server
|
||||
EXPOSE 6379
|
||||
ENTRYPOINT ["/usr/bin/redis-server"]
|
||||
CMD ["--bind", "0.0.0.0"]
|
||||
|
||||
Next we build an image from our ``Dockerfile``. Replace ``<your username>``
|
||||
with your own user name.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo docker build -t <your username>/redis .
|
||||
|
||||
Run the service
|
||||
---------------
|
||||
|
||||
Use the image we've just created and name your container ``redis``.
|
||||
|
||||
Running the service with ``-d`` runs the container in detached mode, leaving the
|
||||
container running in the background.
|
||||
|
||||
Importantly, we're not exposing any ports on our container. Instead we're going to
|
||||
use a container link to provide access to our Redis database.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo docker run --name redis -d <your username>/redis
|
||||
|
||||
Create your web application container
|
||||
-------------------------------------
|
||||
|
||||
Next we can create a container for our application. We're going to use the ``--link``
|
||||
flag to create a link to the ``redis`` container we've just created with an alias of
|
||||
``db``. This will create a secure tunnel to the ``redis`` container and expose the
|
||||
Redis instance running inside that container to only this container.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo docker run --link redis:db -i -t ubuntu:12.10 /bin/bash
|
||||
|
||||
Once inside our freshly created container we need to install Redis to get the
|
||||
``redis-cli`` binary to test our connection.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
apt-get update
|
||||
apt-get -y install redis-server
|
||||
service redis-server stop
|
||||
|
||||
As we've used the ``--link redis:db`` option, Docker has created some environment
|
||||
variables in our web application container.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
env | grep DB_
|
||||
|
||||
# Should return something similar to this with your values
|
||||
DB_NAME=/violet_wolf/db
|
||||
DB_PORT_6379_TCP_PORT=6379
|
||||
DB_PORT=tcp://172.17.0.33:6379
|
||||
DB_PORT_6379_TCP=tcp://172.17.0.33:6379
|
||||
DB_PORT_6379_TCP_ADDR=172.17.0.33
|
||||
DB_PORT_6379_TCP_PROTO=tcp
|
||||
|
||||
We can see that we've got a small list of environment variables prefixed with ``DB``.
|
||||
The ``DB`` comes from the link alias specified when we launched the container. Let's use
|
||||
the ``DB_PORT_6379_TCP_ADDR`` variable to connect to our Redis container.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
redis-cli -h $DB_PORT_6379_TCP_ADDR
|
||||
redis 172.17.0.33:6379>
|
||||
redis 172.17.0.33:6379> set docker awesome
|
||||
OK
|
||||
redis 172.17.0.33:6379> get docker
|
||||
"awesome"
|
||||
redis 172.17.0.33:6379> exit
|
||||
|
||||
We could easily use this or other environment variables in our web application to make a
|
||||
connection to our ``redis`` container.
|
||||
|
||||
@ -1,151 +0,0 @@
|
||||
:title: Running a Riak service
|
||||
:description: Build a Docker image with Riak pre-installed
|
||||
:keywords: docker, example, package installation, networking, riak
|
||||
|
||||
Riak Service
|
||||
==============================
|
||||
|
||||
.. include:: example_header.inc
|
||||
|
||||
The goal of this example is to show you how to build a Docker image with Riak
|
||||
pre-installed.
|
||||
|
||||
Creating a ``Dockerfile``
|
||||
+++++++++++++++++++++++++
|
||||
|
||||
Create an empty file called ``Dockerfile``:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
touch Dockerfile
|
||||
|
||||
Next, define the parent image you want to use to build your image on top of.
|
||||
We’ll use `Ubuntu <https://index.docker.io/_/ubuntu/>`_ (tag: ``latest``),
|
||||
which is available on the `docker index <http://index.docker.io>`_:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Riak
|
||||
#
|
||||
# VERSION 0.1.0
|
||||
|
||||
# Use the Ubuntu base image provided by dotCloud
|
||||
FROM ubuntu:latest
|
||||
MAINTAINER Hector Castro hector@basho.com
|
||||
|
||||
Next, we update the APT cache and apply any updates:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Update the APT cache
|
||||
RUN sed -i.bak 's/main$/main universe/' /etc/apt/sources.list
|
||||
RUN apt-get update
|
||||
RUN apt-get upgrade -y
|
||||
|
||||
After that, we install and setup a few dependencies:
|
||||
|
||||
- ``curl`` is used to download Basho's APT repository key
|
||||
- ``lsb-release`` helps us derive the Ubuntu release codename
|
||||
- ``openssh-server`` allows us to login to containers remotely and join Riak
|
||||
nodes to form a cluster
|
||||
- ``supervisor`` is used manage the OpenSSH and Riak processes
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Install and setup project dependencies
|
||||
RUN apt-get install -y curl lsb-release supervisor openssh-server
|
||||
|
||||
RUN mkdir -p /var/run/sshd
|
||||
RUN mkdir -p /var/log/supervisor
|
||||
|
||||
RUN locale-gen en_US en_US.UTF-8
|
||||
|
||||
ADD supervisord.conf /etc/supervisor/conf.d/supervisord.conf
|
||||
|
||||
RUN echo 'root:basho' | chpasswd
|
||||
|
||||
Next, we add Basho's APT repository:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
RUN curl -s http://apt.basho.com/gpg/basho.apt.key | apt-key add --
|
||||
RUN echo "deb http://apt.basho.com $(lsb_release -cs) main" > /etc/apt/sources.list.d/basho.list
|
||||
RUN apt-get update
|
||||
|
||||
After that, we install Riak and alter a few defaults:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Install Riak and prepare it to run
|
||||
RUN apt-get install -y riak
|
||||
RUN sed -i.bak 's/127.0.0.1/0.0.0.0/' /etc/riak/app.config
|
||||
RUN echo "ulimit -n 4096" >> /etc/default/riak
|
||||
|
||||
Almost there. Next, we add a hack to get us by the lack of ``initctl``:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Hack for initctl
|
||||
# See: https://github.com/dotcloud/docker/issues/1024
|
||||
RUN dpkg-divert --local --rename --add /sbin/initctl
|
||||
RUN ln -sf /bin/true /sbin/initctl
|
||||
|
||||
Then, we expose the Riak Protocol Buffers and HTTP interfaces, along with SSH:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Expose Riak Protocol Buffers and HTTP interfaces, along with SSH
|
||||
EXPOSE 8087 8098 22
|
||||
|
||||
Finally, run ``supervisord`` so that Riak and OpenSSH are started:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
CMD ["/usr/bin/supervisord"]
|
||||
|
||||
Create a ``supervisord`` configuration file
|
||||
+++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Create an empty file called ``supervisord.conf``. Make sure it's at the same
|
||||
directory level as your ``Dockerfile``:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
touch supervisord.conf
|
||||
|
||||
Populate it with the following program definitions:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
[supervisord]
|
||||
nodaemon=true
|
||||
|
||||
[program:sshd]
|
||||
command=/usr/sbin/sshd -D
|
||||
stdout_logfile=/var/log/supervisor/%(program_name)s.log
|
||||
stderr_logfile=/var/log/supervisor/%(program_name)s.log
|
||||
autorestart=true
|
||||
|
||||
[program:riak]
|
||||
command=bash -c ". /etc/default/riak && /usr/sbin/riak console"
|
||||
pidfile=/var/log/riak/riak.pid
|
||||
stdout_logfile=/var/log/supervisor/%(program_name)s.log
|
||||
stderr_logfile=/var/log/supervisor/%(program_name)s.log
|
||||
|
||||
Build the Docker image for Riak
|
||||
+++++++++++++++++++++++++++++++
|
||||
|
||||
Now you should be able to build a Docker image for Riak:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker build -t "<yourname>/riak" .
|
||||
|
||||
Next steps
|
||||
++++++++++
|
||||
|
||||
Riak is a distributed database. Many production deployments consist of `at
|
||||
least five nodes <http://basho.com/why-your-riak-cluster-should-have-at-least-
|
||||
five-nodes/>`_. See the `docker-riak <https://github.com/hectcastro /docker-
|
||||
riak>`_ project details on how to deploy a Riak cluster using Docker and
|
||||
Pipework.
|
||||
@ -1,49 +0,0 @@
|
||||
:title: Running an SSH service
|
||||
:description: Installing and running an sshd service
|
||||
:keywords: docker, example, package installation, networking
|
||||
|
||||
.. _running_ssh_service:
|
||||
|
||||
SSH Daemon Service
|
||||
==================
|
||||
|
||||
.. include:: example_header.inc
|
||||
|
||||
The following Dockerfile sets up an sshd service in a container that you can use
|
||||
to connect to and inspect other container's volumes, or to get quick access to a
|
||||
test container.
|
||||
|
||||
.. literalinclude:: running_ssh_service.Dockerfile
|
||||
|
||||
Build the image using:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo docker build -t eg_sshd .
|
||||
|
||||
Then run it. You can then use ``docker port`` to find out what host port the container's
|
||||
port 22 is mapped to:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo docker run -d -P --name test_sshd eg_sshd
|
||||
$ sudo docker port test_sshd 22
|
||||
0.0.0.0:49154
|
||||
|
||||
And now you can ssh to port ``49154`` on the Docker daemon's host IP address
|
||||
(``ip address`` or ``ifconfig`` can tell you that):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ ssh root@192.168.1.2 -p 49154
|
||||
# The password is ``screencast``.
|
||||
$$
|
||||
|
||||
Finally, clean up after your test by stopping and removing the container, and
|
||||
then removing the image.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo docker stop test_sshd
|
||||
$ sudo docker rm test_sshd
|
||||
$ sudo docker rmi eg_sshd
|
||||
@ -1,128 +0,0 @@
|
||||
:title: Using Supervisor with Docker
|
||||
:description: How to use Supervisor process management with Docker
|
||||
:keywords: docker, supervisor, process management
|
||||
|
||||
.. _using_supervisord:
|
||||
|
||||
Using Supervisor with Docker
|
||||
============================
|
||||
|
||||
.. include:: example_header.inc
|
||||
|
||||
Traditionally a Docker container runs a single process when it is launched, for
|
||||
example an Apache daemon or a SSH server daemon. Often though you want to run
|
||||
more than one process in a container. There are a number of ways you can
|
||||
achieve this ranging from using a simple Bash script as the value of your
|
||||
container's ``CMD`` instruction to installing a process management tool.
|
||||
|
||||
In this example we're going to make use of the process management tool,
|
||||
`Supervisor <http://supervisord.org/>`_, to manage multiple processes in our
|
||||
container. Using Supervisor allows us to better control, manage, and restart the
|
||||
processes we want to run. To demonstrate this we're going to install and manage both an
|
||||
SSH daemon and an Apache daemon.
|
||||
|
||||
Creating a Dockerfile
|
||||
---------------------
|
||||
|
||||
Let's start by creating a basic ``Dockerfile`` for our new image.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
FROM ubuntu:latest
|
||||
MAINTAINER examples@docker.io
|
||||
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
|
||||
RUN apt-get update
|
||||
RUN apt-get upgrade -y
|
||||
|
||||
Installing Supervisor
|
||||
---------------------
|
||||
|
||||
We can now install our SSH and Apache daemons as well as Supervisor in our container.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
RUN apt-get install -y openssh-server apache2 supervisor
|
||||
RUN mkdir -p /var/run/sshd
|
||||
RUN mkdir -p /var/log/supervisor
|
||||
|
||||
Here we're installing the ``openssh-server``, ``apache2`` and ``supervisor``
|
||||
(which provides the Supervisor daemon) packages. We're also creating two new
|
||||
directories that are needed to run our SSH daemon and Supervisor.
|
||||
|
||||
Adding Supervisor's configuration file
|
||||
--------------------------------------
|
||||
|
||||
Now let's add a configuration file for Supervisor. The default file is called
|
||||
``supervisord.conf`` and is located in ``/etc/supervisor/conf.d/``.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
ADD supervisord.conf /etc/supervisor/conf.d/supervisord.conf
|
||||
|
||||
Let's see what is inside our ``supervisord.conf`` file.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
[supervisord]
|
||||
nodaemon=true
|
||||
|
||||
[program:sshd]
|
||||
command=/usr/sbin/sshd -D
|
||||
|
||||
[program:apache2]
|
||||
command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2 -DFOREGROUND"
|
||||
|
||||
The ``supervisord.conf`` configuration file contains directives that configure
|
||||
Supervisor and the processes it manages. The first block ``[supervisord]``
|
||||
provides configuration for Supervisor itself. We're using one directive,
|
||||
``nodaemon`` which tells Supervisor to run interactively rather than daemonize.
|
||||
|
||||
The next two blocks manage the services we wish to control. Each block controls
|
||||
a separate process. The blocks contain a single directive, ``command``, which
|
||||
specifies what command to run to start each process.
|
||||
|
||||
Exposing ports and running Supervisor
|
||||
-------------------------------------
|
||||
|
||||
Now let's finish our ``Dockerfile`` by exposing some required ports and
|
||||
specifying the ``CMD`` instruction to start Supervisor when our container
|
||||
launches.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
EXPOSE 22 80
|
||||
CMD ["/usr/bin/supervisord"]
|
||||
|
||||
Here we've exposed ports 22 and 80 on the container and we're running the
|
||||
``/usr/bin/supervisord`` binary when the container launches.
|
||||
|
||||
Building our container
|
||||
----------------------
|
||||
|
||||
We can now build our new container.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo docker build -t <yourname>/supervisord .
|
||||
|
||||
Running our Supervisor container
|
||||
--------------------------------
|
||||
|
||||
Once we've got a built image we can launch a container from it.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo docker run -p 22 -p 80 -t -i <yourname>/supervisord
|
||||
2013-11-25 18:53:22,312 CRIT Supervisor running as root (no user in config file)
|
||||
2013-11-25 18:53:22,312 WARN Included extra file "/etc/supervisor/conf.d/supervisord.conf" during parsing
|
||||
2013-11-25 18:53:22,342 INFO supervisord started with pid 1
|
||||
2013-11-25 18:53:23,346 INFO spawned: 'sshd' with pid 6
|
||||
2013-11-25 18:53:23,349 INFO spawned: 'apache2' with pid 7
|
||||
. . .
|
||||
|
||||
We've launched a new container interactively using the ``docker run`` command.
|
||||
That container has run Supervisor and launched the SSH and Apache daemons with
|
||||
it. We've specified the ``-p`` flag to expose ports 22 and 80. From here we can
|
||||
now identify the exposed ports and connect to one or both of the SSH and Apache
|
||||
daemons.
|
||||
|
||||
Reference in New Issue
Block a user