When Do You Need to Build?
Most popular images on Docker Hub have ARM variants. But sometimes you'll only find x86/amd64 builds, or the ARM image is outdated. In that case, build from source.
For this guide: MariaDB 10.3 was only available for AMD64. The Raspberry Pi runs arm32v7 / armhf, so a custom build was needed.
Starting point: github.com/docker-library/mariadb
Stack context: Once built, tag your image with
--tag yourname/imagename:tag and push it to Docker Hub. Your docker-compose.yml then references it by that tag. When docker stack deploy runs, the Swarm manager pulls the image from Docker Hub onto every worker node automatically.
Set Up a Build Directory
Create working directory
$ mkdir mariadb10.3
$ cd mariadb10.3
# Save your Dockerfile and docker-entrypoint.sh here
Build the Image
Run on MASTER — build from current directory
$ docker build --tag jorgenlarsen/mariadb10.3:rpi .
# Note the trailing "." — it means "use current directory as build context"
Example Dockerfile (MariaDB 10.3 for Debian/ARM)
Dockerfile
# vim:set ft=dockerfile:
FROM debian:latest
RUN groupadd -r mysql && useradd -r -g mysql mysql
ENV MARIADB_MAJOR 10.3
ENV MARIADB_VERSION 1:10.3.23-0+deb10u1
RUN set -ex; \
apt-get update; \
apt-get install -y --no-install-recommends \
pwgen tzdata xz-utils gnupg dirmngr ca-certificates wget; \
rm -rf /var/lib/apt/lists/*
# gosu for privilege dropping
ENV GOSU_VERSION 1.12
RUN set -eux; \
dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \
wget -O /usr/local/bin/gosu \
"https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \
chmod +x /usr/local/bin/gosu; \
gosu nobody true
RUN mkdir /docker-entrypoint-initdb.d
# Add MariaDB repo
RUN set -e; \
echo "deb http://ftp.osuosl.org/pub/mariadb/repo/$MARIADB_MAJOR/debian buster main" \
> /etc/apt/sources.list.d/mariadb.list
RUN set -ex; \
apt-get update; \
apt-get install -y mariadb-server="$MARIADB_VERSION" mariadb-backup socat; \
rm -rf /var/lib/mysql; \
mkdir -p /var/lib/mysql /var/run/mysqld; \
chown -R mysql:mysql /var/lib/mysql /var/run/mysqld; \
chmod 777 /var/run/mysqld; \
echo '[mysqld]\nskip-host-cache\nskip-name-resolve' \
> /etc/mysql/conf.d/docker.cnf
VOLUME /var/lib/mysql
COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
EXPOSE 3306
CMD ["mysqld"]
Verify the Build
List images to confirm the build succeeded
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
jorgenlarsen/mariadb10.3 rpi 09f38af10d8f 2 weeks ago 316 MB
portainer/portainer-ce latest 5526251cc61f 7 weeks ago 163 MB
Building images on a Raspberry Pi is slow. A complex image can take 30–60 minutes. Plan accordingly and don't abort partway through.
Official reference: docs.docker.com — docker build