Docker is the most popular among a collection of tools that provide containerization.
Containerization allows one to run a server in its own isolated environment without the overhead of running a full virtual machine.
There are several reasons one would want to run openHAB in a Docker container.
These include:
* easily test out different versions
* run multiple instances side by side
* easily map the OH ports to other ports without modifying configs
* isolate OH from the rest of your server environment (e.g. configure the container's networking so the only way it can be accessed is through a reverse proxy)
* orchestration and automated deployment of OH and related servers
However, this flexibility comes at a cost.
For example, because openHAB is running in its own container with only enough installed to run openHAB, the Exec binding is very likely to be useless to you because the container will not have access to the programs and files you need.
# About the openHAB installed in the Image
Inside the Docker Image, openHAB is installed to `/openhab`.
The install is a manual installation so all of the files are located here.
This is also set as the home directory of the `openhab` user.
The Image has a very minimal installation of Linux with no services running and just enough installed to allow openHAB to run.
At the time of this writing, the official image uses the latest snapshot version of openHAB 2.
Where `<uid>` is the user ID number for the `openhab` user which you can obtain using the command `id openhab` and `<arch>` is the architecture of your system.
It is important that ID number is passed in as the ID for the `openhab` user inside the container will not match the id of the user on your host system and file permissions may be a bit odd (e.g. why does www-data own my openHAB config files?)
To change the runtime parameters stop the container then execute the long command above with the new parameters.
## Running the Container as a Service Controlled by Systemd
If running on a Systemd based Linux distro (Ubuntu 16.1 to be specific).
The following openhab2.service file will start a new openHAB 2 container every time it starts the service and destroy that container when the service stops.
What that means is any data that you want to preserve between restarts of openHAB 2 (e.g. configuration, databases, etc.) must be mounted from your host file system into the container.
Creating a new container on every run greatly simplifies the upgrade and update process.
It also ensures that you start with a fresh install every time you run which can avoid some problems.
```bash
[Unit]
Description=openHAB 2
Requires=docker.service
After=docker.service
[Service]
Restart=always
ExecStart=/usr/bin/docker run --name=%n --net=host \
Where `<uid>` is the user ID number for the `openhab` user which you can obtain using the command `id openhab` and `<arch>` is the architecture of your system.
It is important that ID number is passed in as the ID for the `openhab` user inside the container will not match the id of the user on your host system and file permissions may be a bit odd (e.g. why does www-data own my openHAB config files?)
Then run `sudo systemctl enable openhab2.service`.
Finally run `sudo systemctl start openhab2.service` to start openHAB running.
# Explanation of Arguments Passed to Docker
*`/usr/bin/docker run` : create a new container from the passed in Image (last argument)
*`--name=openhab` : give the container a human remember able name
*`--net=host` : by default Docker will place a container into its own network stack. However, openHAB 2 requires UPnP discovery so this parameter makes the Docker container use the host's network stack.
*`-v /etc/localtime:/etc/localtime:ro` : ties the time of the container to the host's time, read only so the container cannot change the host's time
*`-v /etc/timezone:/etc/timezone:ro ` : ties the timezone of the container to the host's time zone, read only so the container cannot change the host's time zone
*`-v /opt/openhab/conf:/openhab/conf` : location of the conf folder for openHAB configurations (NOTE: you must create these folders on the host before running the container)
*`-v /opt/openhab/userdata:/openhab/userdata` : location for logs, cache, persistence databases, etc.
*`-v /opt/openhab/addons:/openhab/addons` : only needed if installing addons unavailable via PaperUI or the Karaf Console
*`-v /opt/openhab/.java:/openhab/.java` : needed by the Nest binding (and others?), location of the security token
*`--user=<uid>` : sets the user that runs the processes inside the container to match the uid passed, makes sure the `openhab` user can read and write to all needed files
*`--device=/dev/ttyUSB0` : location of my zwave controller, change and/or add more --device tags to pass all your devices needed by openHAB to the container
*`--restart=always` : if the container crashes or the syetem reboots the container is restarted
*`openhab/openhab:amd64` : name of the Docker Image
*`debug` : You can start the container with the command ``docker run -it openhab/openhab debug`` to get into the debug shell. You might need to mount additional volumes and parameters as described above.