-
Notifications
You must be signed in to change notification settings - Fork 38
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
Leaner Docker Image #5
Conversation
@captn3m0 Thanks for looking into this - I already looked a bit around and found that my docker knowledge is really outdated. For now I changed base image to debian:stretch-slim, which decreased image by 1G. I think two stage docker file is definitely the way to go. I've made too many useless layer, so just efficiently reorganizing Docker file in this way could help a lot. For completely static build I looked at this builder image Completely static build in Rust looks bit complicated as it need musl libc as base, which means everything else needs to be recompiled. So above mentioned builder image needs at least taglib and taglibc. Considering that I never tested with musl libc, I think this should be probably only optional solution now for people really in need of small image. By using good two stage build with debian slim we can get to 100s MB with gcc libc and few other libs, shell, etc., which would be good progress. Then we can look at fully static build. |
Debian Slim should work great! I'll still keep this open for the other improvements (fewer layers, cleaner entrypoint etc) I tried going with Alpine for musl, but I couldn't find libtag1 packaged. |
And re: SSL termination - I agree, I'm using nginx as rev proxy. And mounting ssl dir sounds reasonable. |
I looked into this too, but unfortunately for me my complete lack of rust knowledge is a hindrance. :) |
@mpatton125 - I added some more dependencies to be able to compile with new feature libavformat too (replacement for taglib - it's from ffmpeg package support matroska, webm etc. basically everything what exists). But this increased size to 2.7G. Later in evening I just changed from ubuntu to debian slim and it reduces size back to 1.9GB (when build locally - for some reason on Docker Hub it's bigger). I'll try 2 stage Dockerfile with Debian to see now it can be reduced without static compilation. |
I pushed new version of Dockerfile to master. I think it's not final, but at least builds significantly smaller image ( ~ 200MB). It's based on debian:stretch-slim and is using two stages. Also it's now using statically build ffmpeg (which itself is of considerable size ~ 60MB). Next step could be complete static build and alpine based image? But as I was thinking about it there are other thing to consider. audioserve now needs ffmpeg - so it should be also in the image (and available static build is against gcc libc - rebuilding against musl can be a challenge, so it's probably not worst to try, just use it as it is). And we're using also shell script to start the program - but shell is simple I guess busybox can handle it? |
eca9c9c
to
ccfbedb
Compare
Separating out the node and rust builds into different stages (build gets faster). Working on the remaining changes as well. I think 200MB image size is decent enough for now. |
As per rust documentation, lockfiles should be committed for binary applications.
ccfbedb
to
6d8689a
Compare
Agreed. A ~200Mb build is inline with a lot of other container images out there and a significant improvement. Well done guys. 😀 |
COPY audioserve.sh . | ||
|
||
CMD ./audioserve.sh | ||
ENTRYPOINT ["/audioserve/audioserve"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to keep wrapper script - for demo/testing purposes it's invaluable as one can play with command line args. $PORT is for instance needed if one wants to try on heroku.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Docker allows passing command line args to the entrypoint, I was relying on that
Will keep PORT
, but it might be better handled at the app itself. (instead of reading it as env and passing it as a argument)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see now - that could be easier solution then script unless we would need to mess with args - like $PORT or $USE_UNSECURE_CERT
ENV SECRET=mypass | ||
ENV SSLKEY=./ssl/audioserve.p12 | ||
ENV SSLPASS=mypass | ||
ENV DIRS=/audiobooks | ||
ENV PORT=3000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If wrapper script is not use it does not make sense, as audioserve will then always run on port 3000
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes - but I've seen on Heroku that it requires that image use $PORT container listening port. But can be added to app as you noted.
Hi, |
Yeah, closing this as current is quite lean already. 👍 |
@captn3m0 OK closing, thanks. |
Still a WIP. Planning to switch this to a 2-stage docker build, similar to what https://github.com/fornwall/rust-static-builder/ suggests.
Need help with converting this to a completely static binary.
Ideally, the ssl certs should not be built into the image. With Docker based setups, either of these two is the norm: