<commit_before># A minimal Ubuntu base image that is Predictable and stays Up To Date

_ubuntu-baseimage_ is docker base image based on the work of [phusion/baseimage-docker](https://github.com/phusion/baseimage-docker) and inherits the following features:

  * [A correct Init system solving the PID 1 problem](https://blog.phusion.nl/2015/01/20/docker-and-the-pid-1-zombie-reaping-problem/).
  * Scripts in `/etc/my_init.d/` are started in lexical order.
  * `rc.local` is executed after the _Init Scripts_.
  * Fixes APT incompatibilities with Docker See https://github.com/dotcloud/docker/issues/1024.
  * A mechansim to simplify work with _Environment Variables_.
  * Provides a `cron` and `syslog-ng` with `logotate` daemon per default.
  * Ability to define additonal daemons in `/etc/service`.
  * Lightweight sudo alternative at `/sbin/setuser`

Moreover _ubuntu-baseimage_ brings the following improvements:

 * Provides an [Automated Build](https://hub.docker.com/r/wingedkiwi/ubuntu-baseimage/) that stays up to date and
 eleminates the need to run `apt-get upgrade`. (See [dockerfile best-practices](https://docs.docker.com/articles/dockerfile_best-practices/#run))
 * Services are started in lexical order.
 * Services are terminated in reverse lexical order.
 * User command is executed after all services has been started.
 * If a `check` script for a service is provided, the init daemon will wait until service is fully started.
 * `/sbin/my_init` in `Dockerfile` is defined as `ENTRYPOINT` instead as `CMD`.

Changes due to personal choice:

 * Removes sshd service as it is not essential (see [nsenter](https://blog.docker.com/tag/nsenter/)).

_ubuntu-baseimage_ introduces backward-incompatible changes to [phusion/baseimage-docker](https://github.com/phusion/baseimage-docker).

## The problems _ubuntu-baseimage_ tries to solve

Even though [phusion/baseimage-docker](https://github.com/phusion/baseimage-docker) claims that it _does everything right_, it still leaves us with some unsolved problems:

  * The image is not updated regularly (Last push was 2 months ago, whereas _Ubuntu_ base Image was pushed 8 days ago. Status from 10th Sep 2015). Moreover it advocates the use of `apt-get upgrade` which is contrary to [dockerfile best-practices](https://docs.docker.com/articles/dockerfile_best-practices/#run))
  * Naturally services/daemons depend on each other. _phusion/baseimage-docker_ starts and stops all daemons at the same time causing unpredictable behavior and failure.
  * _phusion/baseimage-docker_ executes the user provided command without knowing if the required services/daemons are up and running.

_ubuntu-baseimage_ solves the above problems using an [Automated Build](https://hub.docker.com/r/wingedkiwi/ubuntu-baseimage/) and a predictable boot and shutdown mechanism.

## Using _ubuntu-baseimage_ as base image

 * [Getting started](#getting_started)
 * [Adding additional daemons](#adding_additional_daemons)
    * [Starting order](#starting_order)
    * [Wait until daemon is fully up](#wait_until)
 * [Running scripts during container startup](#running_startup_scripts)
 * [Environment variables](#environment_variables)
    * [Centrally defining your own environment variables](#envvar_central_definition)
        * [Environment variable dumps](#envvar_dumps)
        * [Modifying environment variables](#modifying_envvars)
        * [Security](#envvar_security)
 * [Upgrading the operating system inside the container](#upgrading_os)

<a name="getting_started"></a>
### Getting started

The image is called `wingedkiwi/ubuntu-baseimage`, and is available on the Docker registry.

    # Use wingedkiwi/ubuntu-baseimage as base image.
    FROM wingedkiwi/ubuntu-baseimage:<VERSION>

    # Put your own build instructions here.

    # Clean up APT when done.
    RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

    # Run your command or leave empty if only the daemons should be started.
    CMD ["your_command"]

<a name="adding_additional_daemons"></a>
### Adding additional daemons

You can add additional daemons (e.g. your own app) 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/service/<NAME>`.

Here's an example showing you how a memcached server runit entry can be made.

In `memcached.sh` (make sure this file is chmod +x):

    #!/bin/sh
    # `/sbin/setuser memcache` runs the given command as the user `memcache`.
    # If you omit that part, the command will be run as root.
    exec /sbin/setuser memcache /usr/bin/memcached >>/var/log/memcached.log 2>&1

In `Dockerfile`:

    RUN mkdir /etc/service/30-memcached
    ADD memcached.sh /etc/service/30-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.

<a name="starting_order"></a>
#### Starting order
Daemons are started in lexical order. System services are defined as `10-syslog-ng`, `10-syslog-forwarder` and `20-cron`, so you can define your daemons e.g. starting with 30 to start your daemon after the system services.

<a name="wait_until"></a>
#### Wait until daemon is fully up
You can add a `check` script to make the _Init System_ wait until daemon is fully up.

Example `memcached-check.sh` file:

    #!/bin/bash
    if [ $memcached_is_up = true ]; then
        exit 0
    fi
    exit 1

And in `Dockerfile`:

    ADD memcached-check.sh /etc/service/30-memcached/check<commit_msg>Add info about disabling daemons<commit_after># A minimal Ubuntu base image that is Predictable and stays Up To Date

_ubuntu-baseimage_ is docker base image based on the work of [phusion/baseimage-docker](https://github.com/phusion/baseimage-docker) and inherits the following features:

  * [A correct Init system solving the PID 1 problem](https://blog.phusion.nl/2015/01/20/docker-and-the-pid-1-zombie-reaping-problem/).
  * Scripts in `/etc/my_init.d/` are started in lexical order.
  * `rc.local` is executed after the _Init Scripts_.
  * Fixes APT incompatibilities with Docker See https://github.com/dotcloud/docker/issues/1024.
  * A mechansim to simplify work with _Environment Variables_.
  * Provides a `cron` and `syslog-ng` with `logotate` daemon per default.
  * Ability to define additonal daemons in `/etc/service`.
  * Lightweight sudo alternative at `/sbin/setuser`

Moreover _ubuntu-baseimage_ brings the following improvements:

 * Provides an [Automated Build](https://hub.docker.com/r/wingedkiwi/ubuntu-baseimage/) that stays up to date and
 eleminates the need to run `apt-get upgrade`. (See [dockerfile best-practices](https://docs.docker.com/articles/dockerfile_best-practices/#run))
 * Services are started in lexical order.
 * Services are terminated in reverse lexical order.
 * User command is executed after all services has been started.
 * If a `check` script for a service is provided, the init daemon will wait until service is fully started.
 * `/sbin/my_init` in `Dockerfile` is defined as `ENTRYPOINT` instead as `CMD`.

Changes due to personal choice:

 * Removes sshd service as it is not essential (see [nsenter](https://blog.docker.com/tag/nsenter/)).

_ubuntu-baseimage_ introduces backward-incompatible changes to [phusion/baseimage-docker](https://github.com/phusion/baseimage-docker).

## The problems _ubuntu-baseimage_ tries to solve

Even though [phusion/baseimage-docker](https://github.com/phusion/baseimage-docker) claims that it _does everything right_, it still leaves us with some unsolved problems:

  * The image is not updated regularly (Last push was 2 months ago, whereas _Ubuntu_ base Image was pushed 8 days ago. Status from 10th Sep 2015). Moreover it advocates the use of `apt-get upgrade` which is contrary to [dockerfile best-practices](https://docs.docker.com/articles/dockerfile_best-practices/#run))
  * Naturally services/daemons depend on each other. _phusion/baseimage-docker_ starts and stops all daemons at the same time causing unpredictable behavior and failure.
  * _phusion/baseimage-docker_ executes the user provided command without knowing if the required services/daemons are up and running.

_ubuntu-baseimage_ solves the above problems using an [Automated Build](https://hub.docker.com/r/wingedkiwi/ubuntu-baseimage/) and a predictable boot and shutdown mechanism.

## Using _ubuntu-baseimage_ as base image

 * [Getting started](#getting_started)
 * [Adding additional daemons](#adding_additional_daemons)
    * [Starting order](#starting_order)
    * [Wait until daemon is fully up](#wait_until)
 * [Disable daemons](#disable_daemons)
 * [Running scripts during container startup](#running_startup_scripts)
 * [Environment variables](#environment_variables)
    * [Centrally defining your own environment variables](#envvar_central_definition)
        * [Environment variable dumps](#envvar_dumps)
        * [Modifying environment variables](#modifying_envvars)
        * [Security](#envvar_security)
 * [Upgrading the operating system inside the container](#upgrading_os)

<a name="getting_started"></a>
### Getting started

The image is called `wingedkiwi/ubuntu-baseimage`, and is available on the Docker registry.

    # Use wingedkiwi/ubuntu-baseimage as base image.
    FROM wingedkiwi/ubuntu-baseimage:<VERSION>

    # Put your own build instructions here.

    # Clean up APT when done.
    RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

    # Run your command or leave empty if only the daemons should be started.
    CMD ["your_command"]

<a name="adding_additional_daemons"></a>
### Adding additional daemons

You can add additional daemons (e.g. your own app) 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/service/<NAME>`.

Here's an example showing you how a memcached server runit entry can be made.

In `memcached.sh` (make sure this file is chmod +x):

    #!/bin/sh
    # `/sbin/setuser memcache` runs the given command as the user `memcache`.
    # If you omit that part, the command will be run as root.
    exec /sbin/setuser memcache /usr/bin/memcached >>/var/log/memcached.log 2>&1

In `Dockerfile`:

    RUN mkdir /etc/service/30-memcached
    ADD memcached.sh /etc/service/30-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.

<a name="starting_order"></a>
#### Starting order
Daemons are started in lexical order. System services are defined as `10-syslog-ng`, `10-syslog-forwarder` and `20-cron`, so you can define your daemons e.g. starting with 30 to start your daemon after the system services.

<a name="wait_until"></a>
#### Wait until daemon is fully up
You can add a `check` script to make the _Init System_ wait until daemon is fully up.

Example `memcached-check.sh` file:

    #!/bin/bash
    if [ $memcached_is_up = true ]; then
        exit 0
    fi
    exit 1

And in `Dockerfile`:

    ADD memcached-check.sh /etc/service/30-memcached/check

<a name="disable_daemons"></a>
### Disable Daemons
Any daemon can be disabled by adding a `disabled` file to the corresponding service folder.

    RUN touch /etc/service/30-memcached/disabled
{'fraction_non_alphanumeric': 0.09312885538039753, 'fraction_numerical': 0.00702535983550377, 'mean_word_length': 4.2041908158716, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 31, 'https://': 20, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6376954', 'n_tokens_mistral': 3644, 'n_tokens_neox': 3344, 'n_words': 1319}