I am trying to build rtlamr and rtlamr-collect in Docker and then using a multi-stage build copy the outputs to reduce file sizes. I am trying to target a Raspberry Pi 1 B+ which is a low powered ARMv6 SBC.
dockerfile:
FROM golang:latest AS build
RUN CGO_ENABLED=0 GOOS=linux go install github.com/bemasher/rtlamr-collect@latest
RUN CGO_ENABLED=0 GOOS=linux go install github.com/bemasher/rtlamr@latest
# Use a multi-stage build to reduce our image size
FROM alpine:latest AS runtime
COPY --from=build /go/bin/rtlamr /usr/bin/rtlamr
COPY --from=build /go/bin/rtlamr-collect /usr/bin/rtlamr-collect
# Fully qualify the paths to the binaries
ENTRYPOINT ["/bin/sh", "-c", "/usr/bin/rtlamr | /usr/bin/rtlamr-collect"]
Attempts to perform this operation solely on the Pi have failed, I believe it runs out of memory as it results in a lock for 30+ minutes, sometimes it will come back but most times I end up rebooting the machine.
I believe the solution is to attempt to create a multi-platform docker image and then perform the build on my much more powerful ubuntu machine (linux/amd64).
I have attempted the following without luck.
dockerfile:
FROM --platform=linux/arm/v6 golang:latest AS build
RUN CGO_ENABLED=0 GOOS=linux GOARM=6 GOARCH=arm go install github.com/bemasher/rtlamr-collect@latest
RUN CGO_ENABLED=0 GOOS=linux GOARM=6 GOARCH=arm go install github.com/bemasher/rtlamr@latest
# Use a multi-stage build to reduce our image size
FROM --platform=linux/arm/v6 alpine:latest AS runtime
COPY --from=build /go/bin/linux_arm/rtlamr /usr/bin/rtlamr
COPY --from=build /go/bin/linux_arm/rtlamr-collect /usr/bin/rtlamr-collect
# Fully qualify the paths to the binaries
ENTRYPOINT ["/bin/sh", "-c", "/usr/bin/rtlamr | /usr/bin/rtlamr-collect"]
Command:
sudo docker build . --platform=linux/arm/v6
This did not work, it results in this output/error message:
ubuntu:~/docker-rtlamr$ sudo docker build . --platform=linux/arm/v6
Sending build context to Docker daemon 11.77MB
Step 1/7 : FROM --platform=linux/arm/v6 golang:latest AS build
---> 8827cedaa309
Step 2/7 : RUN CGO_ENABLED=0 GOOS=linux GOARM=6 GOARCH=arm go install github.com/bemasher/rtlamr-collect@latest
---> Running in a8fdb644bf6c
go: downloading github.com/bemasher/rtlamr-collect v1.0.3
go: downloading github.com/influxdata/influxdb-client-go/v2 v2.2.0
go: downloading github.com/pkg/errors v0.9.1
go: downloading github.com/sirupsen/logrus v1.7.0
go: downloading github.com/vmihailenco/msgpack v4.0.4+incompatible
go: downloading go.etcd.io/bbolt v1.3.5
go: downloading golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
go: downloading github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839
go: downloading golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5
go: downloading golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553
go: downloading github.com/deepmap/oapi-codegen v1.3.13
go: downloading gopkg.in/yaml.v2 v2.3.0
Removing intermediate container a8fdb644bf6c
---> 0c430490c31d
Step 3/7 : RUN CGO_ENABLED=0 GOOS=linux GOARM=6 GOARCH=arm go install github.com/bemasher/rtlamr@latest
---> Running in b0178fa9cb57
go: downloading github.com/bemasher/rtlamr v0.9.3
go: downloading github.com/bemasher/rtltcp v0.0.0-20151011062038-3aed81c166c5
go: downloading github.com/pkg/errors v0.8.1
go: downloading golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898
Removing intermediate container b0178fa9cb57
---> 43596fbe42b9
Step 4/7 : FROM --platform=linux/arm/v6 alpine:latest AS runtime
---> 9c6f07244728
Step 5/7 : COPY --from=build /go/bin/linux_arm/rtlamr /usr/bin/rtlamr
invalid from flag value build: image with reference sha256:43596fbe42b9350e34855cf4954baf56e619f567de12201e4224f73b36669311 was found but does not match the specified platform: wanted linux/arm/v6, actual: linux/amd64
The "work around" I've come up with is to have two separate dockerfiles and perform a dance with both machines:
- On the "ubuntu powerhouse" machine build rtlamr binaries like so (
dockerfile-build
):
FROM golang:latest AS build
RUN CGO_ENABLED=0 GOOS=linux GOARM=6 GOARCH=arm go install github.com/bemasher/rtlamr-collect@latest
RUN CGO_ENABLED=0 GOOS=linux GOARM=6 GOARCH=arm go install github.com/bemasher/rtlamr@latest
Command:
sudo docker build --file dockerfile-build --tag rtlamr-rpbi1build:latest .
- The binaries are copied out of the image using the following commands to create a throw away container:
sudo docker create --name rtlamrrbpi1build rtlamr-rpbi1build:latest
sudo docker cp rtlamrrbpi1build:/go/bin/linux_arm/rtlamr rtlamr
sudo docker cp rtlamrrbpi1build:/go/bin/linux_arm/rtlamr-collect rtlamr-collect
sudo docker rm -f rtlamrrbpi1build
- The items are then copied to the Raspberry Pi via SCP:
scp rtlamr [email protected]:~/docker-rtlamr
scp rtlamr-collect [email protected]:~/docker-rtlamr
- On the Raspberry Pi:
dockerfile-run
# Assumes that the binaries have already been built and are at this location
FROM alpine:latest AS runtime
COPY rtlamr /usr/bin/rtlamr
COPY rtlamr-collect /usr/bin/rtlamr-collect
# Fully qualify the paths to the binaries
ENTRYPOINT ["/bin/sh", "-c", "/usr/bin/rtlamr | /usr/bin/rtlamr-collect"]
Command:
sudo docker build --tag rtlamr:armv6 --file dockerfile-run .
This is error prone and requires several steps along with access to both machines. Is there a way to perform this operation solely on the "ubuntu power house" and have the image be usable on the Raspberry Pi? (obviously after pushing it to a Docker Container Registry).