Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prebuilt Raspberry Pi Docker images #92

Closed
brandonaut opened this issue Mar 12, 2020 · 35 comments
Closed

Prebuilt Raspberry Pi Docker images #92

brandonaut opened this issue Mar 12, 2020 · 35 comments

Comments

@brandonaut
Copy link

I know this is already on the roadmap, but I wanted a way to vote for it, so I created this issue :)

As far as I'm concerned, either a binary or a Docker image that works on Raspberry Pi (Raspbian Buster) would be great!

@deluan
Copy link
Member

deluan commented Mar 13, 2020

I did some research a while ago on how to build it for the Pi, I was planning to buy one to test it out, but if you can help testing it, I can try to work on this this week. Can you help with that?

@brandonaut
Copy link
Author

Sure! I just got a PI 4, so I can test with that.

@brandonaut
Copy link
Author

I tried to build it from source on the PI, but ran into what looked like a missing dependency on go-bindata:

go-bindata -fs -prefix "ui/build" -tags embed -nocompress -pkg assets -o assets/embedded_gen.go ui/build/...
/bin/sh: 1: go-bindata: not found

I haven't built anything with Go before, so I'm not familiar with the ecosystem. Is this a dependency that needs to be specified in the project somewhere?

@deluan
Copy link
Member

deluan commented Mar 13, 2020

You need to install go-bindata on your Pi system: go get -u github.com/go-bindata/go-bindata/...

Did you run the steps described in the "Build from source" section of the README? This is one of the tools installed my make setup

@deluan
Copy link
Member

deluan commented Mar 13, 2020

I was able to cross-compile Navidrome to ARM. I generated ARMv6, ARMv7 and ARM64 binaries, all should work on the Pi 4. Can you try on your system?

navidrome_v0.9.2-next_Linux_armv6.tar.gz
navidrome_v0.9.2-next_Linux_armv7.tar.gz
navidrome_v0.9.2-next_Linux_arm64.tar.gz

Let me know if they work

PS: Don't forget you still need ffmpeg on your Pi. If Raspbian does not include it, you can download from: https://johnvansickle.com/ffmpeg/

@0xERR0R
Copy link
Contributor

0xERR0R commented Mar 14, 2020

I would recommend to use docker buildx to build cross-platform images. I tried this out with github actions, works nice. I used it in my project (Golang), see this workflow as reference, may be you can go the same way

@deluan
Copy link
Member

deluan commented Mar 14, 2020

Thanks @0xERR0R , I'll surely take a look. Right now I'm using bepsays/ci-goreleaser, it has the cross-compile toolset for various platforms, but misses Arm and Linux 32bits. I was able to add the dependencies for Arm, but having a hard time with Linux 32-bits.

@0xERR0R
Copy link
Contributor

0xERR0R commented Mar 14, 2020

I think goreleaser can only build binaries, not docker images? But maybe I'm wrong.

@deluan
Copy link
Member

deluan commented Mar 14, 2020

It can, but I'm only using it to build the binaries. I use Docker Hub's automated builds to build the docker image, but I'll take a look at your solution, never used buildx before

@brandonaut
Copy link
Author

@deluan The armv7 binary works great! Thanks for working on it.

@deluan deluan closed this as completed in e36a42f Mar 15, 2020
@deluan
Copy link
Member

deluan commented Mar 15, 2020

Thanks for testing this out. I'll add the ARM binaries as part of the automated release. I'll keep this issue open to track the work on the cross-platform docker images

@deluan deluan reopened this Mar 15, 2020
@jvoisin
Copy link
Collaborator

jvoisin commented Mar 15, 2020

I can also confirm that the armv7 image is working flawlessly ♥

@deluan deluan changed the title Prebuilt Raspberry Pi images Prebuilt Raspberry Pi Docker images Apr 2, 2020
@SenorSmartyPants
Copy link

Please include armv8 64 bit images as well. Thanks.

@0xERR0R
Copy link
Contributor

0xERR0R commented Apr 15, 2020

I tried to build the docker image for raspberry pi3 (arm7) and had following problems:

@deluan
Copy link
Member

deluan commented Apr 15, 2020

Hey @0xERR0R , thanks for taking a look at this. Here's the answers:

  • Node: I rather use strict versions to avoid mysterious errors popping up here and there due to version differences. That being said, the Node project takes semantic versioning very serious, so I think this is fine
  • ffmpeg: I downloaded it as a static binary, to avoid polluting the final image with apk leftovers and dynamic libraries. If we can install ffmpeg in the gobuilder image using apk, then copy just the binary into the release image, then great! If not, I think it is worth to code some logic to download the correct static binary from johnvansickle's site
  • tini: I added it when troubleshooting some zombie ffmpeg processes, don't think it is required anymore. We can remove it, and I'll keep an eye at my instance

Let me know if you encounter any more issues

@0xERR0R
Copy link
Contributor

0xERR0R commented Apr 16, 2020

I could successfully build multi-arch docker image for

  • linux/386
  • linux/amd64
  • linux/arm/v6
  • linux/arm/v7
  • linux/arm64

with this GitHub Workflow. I tested the arm/v7 image on my pi3 and it works fine. The corresponding docker image is here.

I changed the Dockerfile as described (replaced ffmpeg with apk version, removed tini and changed the image).

@deluan
Copy link
Member

deluan commented Apr 16, 2020

Awesome! I'll take a look tonight. Wanna prepare a PR?

@0xERR0R
Copy link
Contributor

0xERR0R commented Apr 16, 2020

PR is not a problem, but 2 points are still open: node version in image and ffmpeg. I saw that apk version installs a bunch of dependencies (libs) like lame etc. I don't know if all of them are necessary. I understand your point of view with "not polluting the image". But otherwise the apk version is optimized for alpine...

Same for node: Always using the same version is fine, but sometimes the fixed version will be removed from docker hub. Maybe it would be better to use always the last npm version?

Another point is the integration in your release job (setting of properly version tag in docker, ...)

I would like to help, but I do not have the big picture of your release in my head.

@deluan
Copy link
Member

deluan commented Apr 16, 2020

For Node, if you use 13-alpine3.10 as above, it will always use the latest Node 13 (right now it is 13.13-alpine3.10), so it is fine.

For the other points, I'll check later. Thanks!

@deluan
Copy link
Member

deluan commented Apr 17, 2020

Hey @0xERR0R I'm working on some pipeline improvements, and also playing with your modifications: https://github.com/deluan/navidrome-test/pull/1

I got the multiplatform docker image building working with builderx, but it is too slow and it is flaky, failing sometimes. Seems that the node build is super slow on ARM platforms.

Any ideas on how to optimize it? Maybe build the JS bundles before the docker build, as the bundles should be the same for all platforms? Thoughts?

@0xERR0R
Copy link
Contributor

0xERR0R commented Apr 18, 2020

Yes, the build takes > 1h. The docker image will be built several times (one per architecture) and node build is really heavy. Since the web client artifact is not platform dependent, it could be possible to build it once and include into target docker image, which build platform dependent go binary. But this would introduce new step into the build pipeline for docker image. The current implementation is really simple: git checkout and docker build. No need to install any build tools, docker image does install everything and builds everything from scratch.
Maybe you should create a docker image only for web client (will be build once for amd64) and use it as build image for go (per architecture)? I will try it today evening

@0xERR0R
Copy link
Contributor

0xERR0R commented Apr 18, 2020

I tried to analyze the build log, you're right:

#28 [linux/arm64 jsbuilder 6/6] RUN npm run build
...
#28 1912. Compiled successfully.
...
#28 DONE 1912.4s


#53 [linux/amd64 jsbuilder 6/6] RUN npm run build
...
#53 253.6 Compiled successfully.
...
#53 DONE 256.1s

npm build ist very slow on arm. You are already building node stuff in "binaries", step "Build UI". Would it be possible to reuse this in later docker image buld step?

@deluan
Copy link
Member

deluan commented Apr 18, 2020

That was my idea. The only downside of this is that we would use a specific Dockerfile for this, that would be used only for the pipeline. But maybe it is not a big deal, considering the optimization it will bring. I'll try this later

@0xERR0R
Copy link
Contributor

0xERR0R commented Apr 19, 2020

I tried following:

  • reduced platforms count to 3
  • removed "go test" step from Docker image (this should be already checked by ci job)
  • extracted web ui build step to stand alone Docker image (see here

Build runs now in 19 min (instead of 1h 5m)

@deluan
Copy link
Member

deluan commented Apr 19, 2020

That's great! Thanks for this. A couple considerations:

  1. I think we should use a pair of separated Dockerfiles for the pipeline, and not change the current one. I'd like to allow devs to build their own image locally, which would be the purpose of the main Dockerfile.
  2. I think we should only remove the go test if we combine the build pipeline with the `release, to be sure the change that triggered the release is always tested.
  3. I don't think we need a webui image. We can just pass it from the binaries job to the docker job using "artifacts", like I do in my test build pipeline

@0xERR0R
Copy link
Contributor

0xERR0R commented Apr 19, 2020

  1. agreed, it would be better to have a single docker file, which build everything, even if the build time is about 45 min.
  2. This with an extra image is a quick and dirty hack, if you have a better solution, this is great!

@deluan
Copy link
Member

deluan commented Apr 23, 2020

Hey @0xERR0R, using the binaries generated by goreleaser, I was able to bring down the total time to 13 mins. I need to test the Docker images on a Raspberry Pi, would you be able to test it?
The image tag is deluan/deluan:0.0.11

I also reworked the workflows, combined them into one. Let me know what you think. The commit in question is this: https://github.com/deluan/navidrome-test/commit/ebae298d1e19ce8d0ee790ddcc3e9c15e65c303d

@0xERR0R
Copy link
Contributor

0xERR0R commented Apr 23, 2020

A you sure, that the image name is deluan/deluan:0.0.11? I can't find it on docker hub...

@deluan
Copy link
Member

deluan commented Apr 23, 2020

Ops... the Docker repository was private. You can try again now :)

@0xERR0R
Copy link
Contributor

0xERR0R commented Apr 23, 2020

Works like a charm!

@deluan
Copy link
Member

deluan commented Apr 23, 2020

Nice! Will merge the changes tonight! Thanks for all the help on this issue!

@0xERR0R
Copy link
Contributor

0xERR0R commented Apr 23, 2020

@GitSchorsch Could you test it too please? ;)

@GitSchorsch
Copy link

@0xERR0R of course :-) Same result here (Raspbian on Raspberry Pi 4)! No problems. Fast and responsive all the time.

deluan added a commit that referenced this issue Apr 23, 2020
@deluan
Copy link
Member

deluan commented Apr 23, 2020

Fixed in #204 , thank you all for the help

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 14, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants