Running Docker on 32-bit Hosts

    
2019-02-03

Docker is known to not to support 32-bit hosts. As per debian installation instructions: Docker CE is supported on x86_64 (or amd64), armhf, and arm64 architectures. 32-bit hosts are unlikely to become supported either – “let’s bring docker on 32-bit” issue was closed and locked back in 2014.

Nothing fundamentally prevents docker (including latest version of docker CE) from running on 32-bit platforms. I am currently running a slightly outdated version 18.03.0-ce on a 15 years old IBM xSeries 335 server with a whopping 2.8GHz Intel Xeon and 4GB of DDR RAM. It comfortably runs half a dozen containers (nginx proxies with simple API end points) and a bunch of scripts poking at various sensors.

width500px

The server only supports IDE drives and I had to use a floppy diskette to sideload firmware for the network card (USB port wasn’t recognized by debian installer). This particular server been in 24/7 operation since its birth, with a brief interruption for two years in 2013-2014, when its ownership has changed (I picked it from the scrap yard, along with two complete replacement spares). Check out this boot animation from early 2000’s:

width300px

There are obviously no official docker builds for 32-bit platforms, but this fork supports building i386 docker. It is slightly outdated (18.03.0-ce as of February 2019), albeit I can’t remember any sweet features released since then anyways.

The build scripts themselves require a 64-bit environment, so if you can build docker on a 64-bit platform first, the recipe should work as-is.

I decided to complicate things further and run the installation entirely on a 32-bit system, so there are few changes to the recipe.

Prerequisites

  • debian 9.5.0 32-bit installed
  • apt repositories configured with network mirrors
  • sudo, git and build-essential installed in addition to bare debian image

Installing docker-io

The above mentioned docker build scripts use an existing docker installation. So if we want to build docker for a 32-bit platform, we have to have docker installed for the build (WinRAR.rar, anyone?)

As hopeless as it sounds, there is a way out. Docker.io package from jessie-backports can run on 32-bit hosts, even though there is a big red flag in the description: Using docker.io on non-amd64 hosts is not supported at this time. Please be careful when using it on anything besides amd64. We won’t use it in production, and it works fine as a build environment.

Install the package:

  • add deb https://deb.debian.org/debian jessie-backports main to your apt sources in /etc/apt/sources.list
  • update the package index: sudo apt-get update
  • install the docker.io package: sudo apt-get -t jessie-backports install docker.io
  • check the version of docker binary: docker -v (outputs Docker version 1.6.2, build 7c8fca2)

Building 32-bit docker from sources

Now is the time to install a relatively fresh version of docker from this magic repo.

Clone the repo:

  • cd /tmp
  • git clone https://github.com/mforkel/docker-ce-i386
  • cd docker-ce-i386

Depending from the state of this repository, you might need to switch the branch, e.g. git checkout 18.03-i386, depending from what versions are currently available. I used the latest commit available as of February, 2019:

  • git checkout c68b084

The build script assumes that a relatively fresh version of docker is available. Our docker.io is from 2015, and it doesn’t support ARG Dockerfiles parameters. That’s an easy fix:

  • sed -i "s/ARG APT_MIRROR=deb.debian.org/# ARG APT_MIRROR=deb.debian.org/" ./components/engine/contrib/builder/deb/i386/debian-stretch/Dockerfile
  • sed -i "s/\$APT_MIRROR/deb.debian.org/" ./components/engine/contrib/builder/deb/i386/debian-stretch/Dockerfile
  • sed -i "s/ARG APT_MIRROR=deb.debian.org/# ARG APT_MIRROR=deb.debian.org/" ./components/packaging/deb/debian-stretch/Dockerfile.i386
  • sed -i "s/\$APT_MIRROR/deb.debian.org/g" ./components/packaging/deb/debian-stretch/Dockerfile.i386

The build script also uses an official alpine image from dockerhub, which is 64-bit. We need to replace it with i386/alpine:

  • sed -i "s/alpine/i386\/alpine/" ./components/packaging/deb/Makefile

Now is finally the time to run the build:

  • sudo ARCH=i386 DOCKER_BUILD_PKGS=debian-stretch make deb

Make sure that a newly built *.deb package is present:

  • ls ./components/packaging/deb/debbuild/debian-stretch/

Remove old docker installation:

  • sudo apt-get remove docker.io

Install the newly built *.deb package:

  • sudo dpkg -i ./components/packaging/deb/debbuild/debian-stretch/docker-ce_18.03.0~ce-0~debian_i386.deb
  • sudo apt-get install -f

We’re done:

  • docker -v outputs Docker version 18.03.0-ce, build c68b084381
  • sudo docker run hello-world successfully pulls and runs the test image

Getting 32-bit docker-compose

Thankfully, 32-bit package of docker-compose is available from this Ubuntu Xenial repository, so installation is as simple as:

  • cd /tmp
  • wget https://launchpadlibrarian.net/314562376/docker-compose_1.8.0-2~16.04.1_all.deb
  • sudo dpkg -i docker-compose_1.8.0-2~16.04.1_all.deb
  • sudo apt-get install -f
  • docker-compose --version outputs docker-compose version 1.8.0, build unknown

Living with docker on 32-bit hosts

Bear in mind, this isn’t the end of a weird journey. Overwhelming majority of images from dockerhub are built with 64-bit binaries (see the above mentioned official alpine image), so there will be complications. E.g., the very popular nginx-proxy image is built with 64-bit builds of both docker-gen and forego, and is based on official nginx:1.11.10 image which in turn is based on official 64-bit debian:jessie image. The following changes would make it usable on 32-bit hosts:

  • replace docker-gen binary (i386 builds are available from releases)
  • replace forego binary (i386 build can be found here)
  • bump nginx version to nginx:1.14 – it is based on 32-bit debian:stretch-slim

Another example – must-have sibling of nginx-proxy, letsencrypt-nginx-proxy-companion, is based on official 64-bit alpine image and uses docker-gen as well, therefore:

  • replace alpine with i386/alpine
  • replace docker-gen binary with i386 version

…and so on. Some images of course are simply not worth porting back to the 32-bit world, and docker on 32-bit platforms is only worth using for simple images, but hey, that’s 90% of my use-cases anyways :)


Tagged #docker , #docker-compose , #nginx-proxy , #letsencrypt , #32-bit , #64-bit , #x86 , #x86_64 , #i386 , #i686 , #amd64 , #alpine , #Debian , #Jessie , #Stretch , #Ubuntu , #Xenial
2019-02-03