diff --git a/.dockerignore b/.dockerignore
index 535e9f6bd62aa0154dd8ec069aee9681767881ec..a9ed50c1dd280a68ba50ea2ba7de6bb8c252f9b4 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -4,4 +4,6 @@
 .vscode
 docker/Dockerfile
 docker-compose.yml
-target
+arm-build/
+build/
+**/target/
diff --git a/.gitignore b/.gitignore
index fc0f4a9dd0e36fd02310b2919a833fee72efec49..335209047639312b59f349481921ed2f119b32f7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,7 +15,8 @@
 # node modules
 **/node_modules/**
 
-# build folder
+# build folders
+arm-build
 build
 
 # Temporary files
diff --git a/docker/cross-arm.Dockerfile b/docker/cross-arm.Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..930c58d40ebee3626a169b7928faf5fe01800738
--- /dev/null
+++ b/docker/cross-arm.Dockerfile
@@ -0,0 +1,45 @@
+FROM rust:latest
+
+RUN dpkg --add-architecture armhf && \
+  apt-get update && apt-get upgrade -y && \
+  apt-get install -y aptitude && \
+  aptitude install -y \
+  gcc-arm-linux-gnueabihf \
+  g++-arm-linux-gnueabihf \
+  pkg-config \
+  cmake \
+  libssl-dev \
+  git \
+  clang \
+  libclang-dev \
+  libssl-dev:armhf
+
+# Install nightly with armv7 and  w32-u-u
+RUN rustup install nightly-2021-11-12-x86_64-unknown-linux-gnu && \
+  rustup target add armv7-unknown-linux-gnueabihf --toolchain \
+  nightly-2021-11-12-x86_64-unknown-linux-gnu && \
+  rustup target add wasm32-unknown-unknown --toolchain \
+  nightly-2021-11-12-x86_64-unknown-linux-gnu && \
+  cargo +nightly-2021-11-12-x86_64-unknown-linux-gnu install --git \
+  https://github.com/alexcrichton/wasm-gc --force
+
+ENV CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER arm-linux-gnueabihf-gcc
+ENV PKG_CONFIG_ALLOW_CROSS 1
+ENV PKG_CONFIG_PATH /usr/lib/arm-linux-gnueabihf/pkgconfig/
+
+
+# Disallow the `pkg-config` crate to look for the config for zlib, because build.rs of `libz-sys`
+# gets confused and pulls the system-wide library (i.e. of the host) instead of the target when
+# cross-compiling. This essentially leads to static linking of zlib.
+#
+# Alternatively, we can supply LIBZ_SYS_STATIC=1. Weirdly enough, installing libgtk-3-dev:armhf
+# also solves the problem somehow.
+#
+# Here is the related issue: https://github.com/rust-lang/libz-sys/issues/49
+ENV ZLIB_NO_PKG_CONFIG 1
+
+# This is for compiling GUI apps.
+# RUN aptitude install -y libasound2-dev:armhf libgtk-3-dev:armhf libsdl2-dev:armhf
+
+RUN useradd rust --user-group --create-home --shell /bin/bash --groups sudo
+WORKDIR /home/rust/src
diff --git a/docs/user/build-for-arm.md b/docs/user/build-for-arm.md
new file mode 100644
index 0000000000000000000000000000000000000000..90ab18f38d23e179f9861b404f20363c9e8ae878
--- /dev/null
+++ b/docs/user/build-for-arm.md
@@ -0,0 +1,15 @@
+# How to build duniter-v2s for arm
+
+1. Create a docker image that contains the build environment
+
+```bash
+docker build -t duniter-v2s-arm-builder -f docker/cross-arm.Dockerfile .
+```
+
+2. Use this docker image to cross-compile duniter-v2s for armv7
+
+```bash
+./scripts/cross-build-arm.sh
+```
+
+then, get the final binary at `target/armv7-unknown-linux-gnueabihf/release/duniter`.
diff --git a/scripts/cross-build-arm.sh b/scripts/cross-build-arm.sh
new file mode 100755
index 0000000000000000000000000000000000000000..23119cc9def7d2ff94a89702fe1576756be4255e
--- /dev/null
+++ b/scripts/cross-build-arm.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+docker run --rm -it \
+	--env BINDGEN_EXTRA_CLANG_ARGS="--sysroot=/usr/arm-linux-gnueabihf -D__ARM_PCS_VFP -mfpu=vfp -mfloat-abi=hard" \
+	--env CARGO_HOME=/home/rust/src/arm-build \
+	-v "$(pwd)":/home/rust/src duniter-v2s-arm-builder \
+	cargo build --target=armv7-unknown-linux-gnueabihf --release