mirror of
/repos/baseimage-docker.git
synced 2025-12-30 08:01:31 +01:00
158 lines
9.8 KiB
Markdown
158 lines
9.8 KiB
Markdown
# A minimal Ubuntu base image modified for Docker-friendliness
|
|
|
|
Baseimage-docker is a special [Docker](http://www.docker.io) image that is configured for correct use within Docker containers. It is Ubuntu, plus modifications for Docker-friendliness. You can use it as a base for your own Docker images.
|
|
|
|
Baseimage-docker is available for pulling from on [the Docker registry](https://index.docker.io/u/phusion/baseimage/)!
|
|
|
|
* **Github**: https://github.com/phusion/baseimage-docker
|
|
* **Discussion forum**: https://groups.google.com/d/forum/passenger-docker
|
|
* **Twitter**: https://twitter.com/phusion_nl
|
|
* **Blog**: http://blog.phusion.nl/
|
|
|
|
### What are the problems with the stock Ubuntu base image?
|
|
|
|
Ubuntu is not designed to be run inside docker. Its init system, Upstart, assumes that it's running on either real hardware or virtualized hardware, but not inside a Docker container. But inside a container you don't want a full system anyway, you want a minimal system. But configuring that minimal system for use within a container has many strange corner cases that are hard to get right if you are not intimately familiar with the Unix system model. This can cause a lot of strange problems.
|
|
|
|
There are also other problems, like `apt-get install` failing when Upstart is not running (which is the case when running `docker build`), or the fact that not having SSH access into your container makes it impossible to safely store persistent data in the container.
|
|
|
|
Baseimage-docker gets everything right. The "Contents" section describes all the things that it modifies.
|
|
|
|
### Why use baseimage-docker?
|
|
|
|
You can configure the stock `ubuntu` image yourself from your Dockerfile, so why bother using baseimage-docker?
|
|
|
|
* Configuring the base system for Docker-friendliness is no easy task. As stated before, there are many corner cases. By the time that you've gotten all that right, you've reinvented baseimage-docker. Using baseimage-docker will save you from this effort.
|
|
* It reduces the time needed to write a correct Dockerfile. You won't have to worry about the base system and can focus on your stack and your app.
|
|
* It reduces the time needed to run `docker build`, allowing you to iterate your Dockerfile more quickly.
|
|
* It reduces download time during redeploys. Docker only needs to download the base image once: during the first deploy. On every subsequent deploys, only the changes you make on top of the base image are downloaded.
|
|
|
|
## Contents
|
|
|
|
*Looking for a more complete base image, one that is ideal for Ruby, Python, Node.js and Meteor web apps? Take a look at [passenger-docker](https://github.com/phusion/passenger-docker).*
|
|
|
|
| Component | Why is it included? / Remarks |
|
|
| ---------------- | ------------------- |
|
|
| Ubuntu 12.04 LTS | The base system. |
|
|
| A **correct** init process | According to the Unix process model, [the init process](https://en.wikipedia.org/wiki/Init) -- PID 1 -- inherits all [orphaned child processes](https://en.wikipedia.org/wiki/Orphan_process) and must [reap them](https://en.wikipedia.org/wiki/Wait_(system_call). Most Docker containers do not have an init process that does this correctly, and as a result their containers become filled with [zombie processes](https://en.wikipedia.org/wiki/Zombie_process) over time. <br><br>Furthermore, `docker stop` sends SIGTERM to the init process, which is then supposed to stop all services. Unfortunately most init systems don't do this correctly within Docker since they're built for hardware shutdowns instead. This causes processes to be hard killed with SIGKILL, which doesn't give them a chance to correctly deinitialize things. This can cause file corruption. <br><br>Baseimage-docker comes with an init process `/sbin/my_init` that performs both of these tasks correctly. |
|
|
| Fixes APT incompatibilities with Docker | See https://github.com/dotcloud/docker/issues/1024. |
|
|
| syslog-ng | A syslog daemon is necessary so that many services - including the kernel itself - can correctly log to /var/log/syslog. If no syslog daemon is running, a lot of important messages are silently swallowed. <br><br>Only listens locally. |
|
|
| ssh server | Allows you to easily login to your container to inspect or administer things. If your container has persistent data (e.g. runs a database) then you **must** have SSH access, otherwise there is no way to dump or backup your data! This is because bind mounts in Docker cannot be changed after a container is launched. <br><br>Password and challenge-response authentication are disabled by default. Only key authentication is allowed.<br>It allows an predefined key by default to make debugging easy. You should replace this ASAP. See instructions. |
|
|
| cron | The cron daemon must be running for cron jobs to work. |
|
|
| [runit](http://smarden.org/runit/) | Replaces Ubuntu's Upstart. Used for service supervision and management. Much easier to use than SysV init and supports restarting daemons when they crash. Much easier to use and more lightweight than Upstart. |
|
|
| `setuser` | A tool for running a command as another user. Easier to use than `su`, has a smaller attack vector than `sudo`, and unlike `chpst` this tool sets `$HOME` correctly. Available as `/sbin/setuser`. |
|
|
|
|
Baseimage-docker is very lightweight: it only consumes 6 MB of memory.
|
|
|
|
### Wait, I thought Docker is about running a single process in a container?
|
|
|
|
Absolutely not true. Docker runs fine with multiple processes in a container. In fact, there is no technical reason why you should limit yourself to one process - it only makes things harder for you and breaks all kinds of essential system functionality, e.g. syslog.
|
|
|
|
Baseimage-docker *encourages* multiple processes through the use of runit.
|
|
|
|
## Inspecting baseimage-docker
|
|
|
|
To look around in the image, run:
|
|
|
|
docker run -rm -t -i phusion/baseimage bash -l
|
|
|
|
You don't have to download anything manually. The above command will automatically pull the baseimage-docker image from the Docker registry.
|
|
|
|
## Using baseimage-docker as base image
|
|
|
|
The image is called `phusion/baseimage`, and is available on the Docker registry.
|
|
|
|
By default, it allows SSH access for the key in `image/insecure_key`. This makes it easy for you to login to the container, but you should replace this key as soon as possible.
|
|
|
|
# Use phusion/baseimage as base image. To make your builds reproducible, make
|
|
# sure you lock down to a specific version, not to `latest`!
|
|
# See https://github.com/phusion/baseimage-docker/blob/master/Changelog.md for
|
|
# a list of version numbers.
|
|
FROM phusion/baseimage:<VERSION>
|
|
|
|
# Set correct environment variables.
|
|
ENV HOME /root
|
|
|
|
# Remove authentication rights for insecure_key.
|
|
RUN rm -f /root/.ssh/authorized_keys /home/*/.ssh/authorized_keys
|
|
|
|
# Use baseimage-docker's init process.
|
|
CMD ["/sbin/my_init"]
|
|
|
|
# ...put other build instructions here...
|
|
|
|
# Clean up APT when done.
|
|
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
|
|
|
### Adding additional daemons
|
|
|
|
You can add additional daemons to the image by creating runit entries. You only have to write a small shell script which runs your daemon, and runit will keep it up and running for you, restarting it when it crashes, etc.
|
|
|
|
The shell script must be called `run`, must be executable, and is to be placed in the directory `/etc/services/<NAME>`.
|
|
|
|
Here's an example showing you how to a memached server runit entry can be made.
|
|
|
|
### In memcached.sh (make sure this file is chmod +x):
|
|
#!/bin/sh
|
|
# `chpst` is part of running. `chpst -u memcache` runs the given command
|
|
# as the user `memcache`. If you omit this, the command will be run as root.
|
|
exec chpst -u memcache /usr/bin/memcached >>/var/log/memcached.log 2>&1
|
|
|
|
### In Dockerfile:
|
|
RUN mkdir /etc/services/memcached
|
|
ADD redis.sh /etc/services/memcached/run
|
|
|
|
Note that the shell script must run the daemon **without letting it daemonize/fork it**. Usually, daemons provide a command line flag or a config file option for that.
|
|
|
|
### Login in to the container
|
|
|
|
You can use SSH to login to any container that is based on baseimage-docker.
|
|
|
|
Start a container based on baseimage-docker (or a container based on an image based on baseimage-docker):
|
|
|
|
docker run phusion/baseimage
|
|
|
|
Find out the ID of the container that you just ran:
|
|
|
|
docker ps
|
|
|
|
Once you have the ID, look for its IP address with:
|
|
|
|
docker inspect <ID> | grep IPAddress
|
|
|
|
Now SSH into the container. In this example we're using [the default insecure key](https://github.com/phusion/baseimage-docker/blob/master/image/insecure_key), but if you're followed the instructions well then you've already replaced that with your own key. You did replace the key, didn't you?
|
|
|
|
ssh -i insecure_key root@<IP address>
|
|
|
|
## Building the image yourself
|
|
|
|
If for whatever reason you want to build the image yourself instead of downloading it from the Docker registry, follow these instructions.
|
|
|
|
Clone this repository:
|
|
|
|
git clone https://github.com/phusion/baseimage-docker.git
|
|
cd baseimage-docker
|
|
|
|
Start a virtual machine with Docker in it. You can use the Vagrantfile that we've already provided.
|
|
|
|
vagrant up
|
|
vagrant ssh
|
|
cd /vagrant
|
|
|
|
Build the image:
|
|
|
|
make build
|
|
|
|
If you want to call the resulting image something else, pass the NAME variable, like this:
|
|
|
|
make build NAME=joe/baseimage
|
|
|
|
## Conclusion
|
|
|
|
* Using baseimage-docker? [Tweet about us](https://twitter.com/share) or [follow us on Twitter](https://twitter.com/phusion_nl).
|
|
* Having problems? Want to participate in development? Please post a message at [the discussion forum](https://groups.google.com/d/forum/passenger-docker).
|
|
* Looking for a more complete base image, one that is ideal for Ruby, Python, Node.js and Meteor web apps? Take a look at [passenger-docker](https://github.com/phusion/passenger-docker).
|
|
|
|
[<img src="http://www.phusion.nl/assets/logo.png">](http://www.phusion.nl/)
|
|
|
|
Please enjoy baseimage-docker, a product by [Phusion](http://www.phusion.nl/). :-)
|