Using Fedora Atomic

The Hackerspace Eastermundigen is often my real-world playground for Home Assistant-related topics which sometimes more belong in the industrial automation area than in a home. Also, it gives me access to devices which I don’t have like 3D printers, laser cutters, connected power strips and a like. In the past the local Home Assistant instance there was running on an old CubieBoard2 with Fedora ARM. It was one of several systems which were running 24/7. To reduce the electricity costs we decided to consolidate the physical systems to only two. One for storage and one for all other services.

This blog post contains the details of the setup. They may be useful for others as well. Our new system is running Fedora 27 from Project Atomic. We will not cover the setup of an Atomic host and the details of Project Atomic itself. For more details, have a look at Benjamin Affolter’s blog post which also covers some of the basics.

The installation process of an Atomic host is pretty much the same as for Fedora Server or Fedora Workstation. Either create a Live USB device or use PXE to get the installation going. E.g., lauch iPXE and chainload netboot.yxz with chain --autofree https://boot.netboot.xyz. Then let anaconda guide you through the setup.

After the first boot, copy the SSH keys, use visudo to add users and perform the usual steps you do for a new system. We only allow SSH with keys, are enforcing the usage of sudo, need special network settings and a couple of other things. But those configuration settings are irrelevant for a setup in a local network.

If the system is up and running then check if you are using the latest release.

$ sudo atomic host status
State: idle; auto updates disabled
Deployments:
● ostree://fedora-atomic:fedora/27/x86_64/atomic-host
                   Version: 27.100 (2018-03-13 17:19:44)
                    Commit: 326f62b93a5cc836c97d31e73a71b6b6b6955c0f225f7651b52a693718e6aa91
              GPGSignature: Valid signature by 860E19B0AFA800A1751881A6F55E7430F5282EE4

The release is 27.100. The latest is 27.105. So, let’s update the host and reboot it.

$ sudo atomic host upgrade
$ sudo systemctl reboot

You can also see that Docker is already running. No installation needed.

$ sudo systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
   Active: active (running) since Thu 2018-03-28 15:44:04 CEST; 35min ago
...

Further we will cover how it works for Home Assistant and Mosquitto. For a small setup using kubernetes seems a bit overkill. Thus, we decided to stick to systemd.

Instead of docker we can use the command-line tool atomic to perform a lot of tasks. Download the images for the containers. We are pulling the images from Docker Hub.

$ sudo atomic install docker.io/​homeassistant/home-assistant
$ sudo atomic install docker.io/eclipse-mosquitto

Both containers need additional directories for persistent storage.

$ sudo mkdir -p /opt/home-assistant
$ sudo mkdir -p /opt/mosquitto/{config,data,log}

We need a copy of mosquitto.conf:

$ sudo curl -o /opt/mosquitto/config/mosquitto.conf \
  https://raw.githubusercontent.com/eclipse/mosquitto/master/mosquitto.conf

To handle the containers we created service unit files for the Home Assistant and the Mosquitto container. For Home Assistant the file can looks like the sample below. Further details about the ExecStart line can be found in the documentation about a Docker setup. For Home Assistant

$ su
# cat <<'EOF' >> /etc/systemd/system/home-assistant.service
[Unit]
Description=Home Assistant
Requires=docker.service
Wants=docker.service
After=docker.service
 
[Service]
Restart=on-failure
RestartSec=10
ExecStart=/usr/bin/docker run --rm --name %p -v /opt/home-assistant:/config:Z -v /etc/localtime:/etc/localtime:ro --network host homeassistant/home-assistant
ExecStop=-/usr/bin/docker stop -t 30 %p
 
[Install]
WantedBy=multi-user.target
EOF

and for Mosquitto.

# cat <<'EOF' >> /etc/systemd/system/mosquitto.service
[Unit]
Description=Mosquitto MQTT docker container
Requires=docker.service
Wants=docker.service
After=docker.service
[Service]
Restart=on-failure
RestartSec=10
ExecStart=/usr/bin/docker run --name %p -v mosquitto.conf:/opt/mosquitto/config/mosquitto.conf -v /opt/mosquitto/data:/opt/mosquitto/data -v /opt/mosquitto/log:/mosquitto/log -p 1883:1883 -p 9001:9001 eclipse-mosquitto
ExecStop=/usr/bin/docker stop -t 2 %p
ExecStopPost=/usr/bin/docker rm -f %p
[Install]
WantedBy=multi-user.target
EOF

Exit to be not longer root.

Reload systemd to make it aware of the new configurations.

$ sudo systemctl daemon-reload

Now, both container can be controlled by systemctl.

$ sudo systemctl enable home-assistant.service --now
$ sudo systemctl enable mosquitto.service --now

Check with $ sudo systemctl status [name].service if there are error or the services are running.

The deployment of NGINX as webserver for static content, grafana and InfluxBD works the same way as for Home Assistant and Mosquitto. To get a proper traefik setup additional reading and work is required.


This is a companion discussion topic for the original entry at https://www.home-assistant.io/blog/2018/03/29/fedora-atomic/

I have been motivated by your post to move mosquitto to docker in my (non-atomic) Fedora 27 setup and I think your docker invocation is wrong:

ExecStart=/usr/bin/docker run --name %p -v mosquitto.conf:/opt/mosquitto/config/mosquitto.conf -v /opt/mosquitto/data:/opt/mosquitto/data -v /opt/mosquitto/log:/mosquitto/log -p 1883:1883 -p 9001:9001 eclipse-mosquitto

This will mount a volume named mosquitto.conf to /opt/mosquitto/config/mosquitto.conf inside the container as well as mounting the data to /opt/mosquitto/data while to container defaults to /mosquitto/data.

I have come up with this:

/usr/bin/docker run --name %p -v /opt/mosquitto/config:/mosquitto/config -v /opt/mosquitto/data:/mosquitto/data -v /opt/mosquitto/log:/mosquitto/log -p 1883:1883 -p 9001:9001 eclipse-mosquitto

Note that your version will work as well because the dockerfile comes with a default config - but it will not follow changes to local config as well as not write logs anywhere.

The downside of this is that the “host”-Directories need to be writeable for UID:GID 100:101 because that is what the mosquitto-process inside the container runs as. So it is probably better to use volumes instead of mounted host-directories for all three directories …

Could be that I made a copy-&-paste error along the way :confused:

Hmmm, I’m unable to use -v /opt/mosquitto/config:/mosquitto/config. Pretty sure that the permissions are right.