msrd0 / docker-element

Docker image serving element, a matrix client.
11 stars 2 forks source link

Add ARM build? #17

Open bertybuttface opened 1 year ago

bertybuttface commented 1 year ago

Hello,

Is it fairly straightforward to make this also build an ARM64 image?

Cheers

msrd0 commented 1 year ago

I have never built docker images for arm, but PRs welcome. @luckyturtledev has done this before I think.

bertybuttface commented 1 year ago

I've got it building locally:

FROM rust:alpine AS element
SHELL ["/bin/ash", "-uo", "pipefail", "-c"]
RUN apk add --update --no-cache gpg gpg-agent wget build-base
RUN cargo install miniserve oxipng --locked
ARG BUILD_ARCH
ENV TARGET "${BUILD_ARCH}-unknown-linux-musl"
ENV ELEMENT_VERSION 1.11.37
RUN mkdir /src
WORKDIR /src
COPY ./web .
RUN if [ "$BUILD_ARCH" = "amd64" ]; then \
    export TARGET="x86_64-unknown-linux-musl"; \
    fi \
    && rustup target add "$TARGET" \
    && cargo build --release --target "$TARGET" \
    && mv "target/$TARGET/release/element" . \
    && strip element
WORKDIR /
COPY ./web/E95B7699E80B68A9EAD9A19A2BAA9B8552BD9047.key .
RUN wget -qO element.tar.gz "https://github.com/vector-im/element-web/releases/download/v$ELEMENT_VERSION/element-v$ELEMENT_VERSION.tar.gz" \
    && wget -qO element.tar.gz.asc "https://github.com/vector-im/element-web/releases/download/v$ELEMENT_VERSION/element-v$ELEMENT_VERSION.tar.gz.asc" \
    && gpg --batch --import E95B7699E80B68A9EAD9A19A2BAA9B8552BD9047.key \
    && gpg --batch --verify element.tar.gz.asc element.tar.gz \
    && mkdir -p /opt/element \
    && tar xfz element.tar.gz --strip-components=1 -C /opt/element \
    && rm /opt/element/config.sample.json; \
    find /opt/element -name '*.png' | while read file; do oxipng -o6 "$file"; done; \
    find /opt/element -name '*.html' -or -name '*.js' -or -name '*.css' -or -name '*.html' -or -name '*.svg' -or -name '*.json' | while read file; do gzip -k9 "$file"; done

That's a bit of a hack though (there is probably a better environment variable set that we don't have to modify too) so I was hoping we could just turn on a setting on Github CI and have it spit out an ARM build.

LuckyTurtleDev commented 1 year ago

@msrd0 you can use buildx for this. But this is only usable if you do not compile anything (otherwise it will take forever)

see https://github.com/LuckyTurtleDev/easy-docker-action/blob/01416c97666feb5a08c8d40b8e06a4a03356e733/action.yml

If you compile rust you can use cargo cross for compiling at copy the binary to docker. see https://github.com/LuckyTurtleDev/crab-hole/blob/d76ffc9e33bcc0a662bd363875dd8939a2e9e49b/.github/workflows/rust.yml#L49-L122 (ignore the apple job)

bertybuttface commented 1 year ago

Thanks @LuckyTurtleDev , I think we do compile rust as part of this project so might have to go the cross route.

bertybuttface commented 1 year ago

Wow buildx qemu is super slow. 38 minute build time:

https://github.com/bertybuttface/docker-element/actions/runs/5850239047/job/15859402598

I'll take a look at the cargo cross approach next.

LuckyTurtleDev commented 1 year ago

Wow buildx qemu is super slow. 38 minute build time

Wow that is fast (for buildx). So we might can do this easy and stick with buildx. This is much easier and faster to setup at github actions.

As long we need only an additional architektur.

msrd0 commented 1 year ago

Did you speed check the non-alpine version of the rust docker image as well? Last I checked, the official musl toolchain (the one from the rust:alpine docker image, not the one built by alpine linux, that one is fine) is very restricted in an unnecessary way when it comes to proc macros, and all musl versions (rustup and alpine linux) performed slower than when using gnu libc.

LuckyTurtleDev commented 1 year ago
RUN if [ "$BUILD_ARCH" = "amd64" ]; then \
        export TARGET="x86_64-unknown-linux-musl"; \
    fi \

Do we need this? Does rustup not choose the architektur of the os as default?

bertybuttface commented 1 year ago

Did you speed check the non-alpine version of the rust docker image as well? Last I checked, the official musl toolchain (the one from the rust:alpine docker image, not the one built by alpine linux, that one is fine) is very restricted in an unnecessary way when it comes to proc macros, and all musl versions (rustup and alpine linux) performed slower than when using gnu libc.

I haven't yet but I will do that today, Didn't realise it was so limited.

bertybuttface commented 1 year ago

Builds a lot faster using rustup (2 minutes 30 seconds with no cache):

https://github.com/bertybuttface/docker-element/actions/runs/5851214672

bertybuttface commented 1 year ago

@msrd0 This build is back to the rust-slim image: https://github.com/bertybuttface/docker-element/actions/runs/5856193430

It runs 5 minutes quicker than the other buildx build but it is still very slow. My preferred option at this point is probably rustup. What do you think?

LuckyTurtleDev commented 1 year ago

I have create a draft for this. The whole build process (inclusive docker) takes 5:30 min. see https://github.com/msrd0/docker-element/pull/18

LuckyTurtleDev commented 1 year ago

@bertybuttface keep in mind that oxipng is also build inside the docker image. So this will be also slow with buildx.

msrd0 commented 1 year ago

Can you test whether ghcr.io/msrd0/element:multiarch works for you on aarch64? I build it using the multiarch branch and docker buildx.

bertybuttface commented 1 year ago

@msrd0 That just hangs here but when I went to test my fork it is also hanging. I've definitely seen it working on aarch64 though as that Dockerfile I posted above works. I'll try and get to the bottom of what is different.

bertybuttface commented 1 year ago

Sorry this was an issue with me testing on aarch64-apple-darwin which obviously won't work as it isn't one of the build targets. I misunderstood how Docker worked on Mac.