admin管理员组文章数量:1194136
I am trying to minimize of size of my Docker image as small as possible, the Dockerfile looks like this:
ARG DISTRO=fedora
ARG FEDORA_VERSION=36
#FROM ${DISTRO}:${FEDORA_VERSION} AS dev
FROM ${DISTRO}:${FEDORA_VERSION} AS dev
#Toolchain
RUN dnf -y install \
gcc gcc-c++ \
pkgconfig \
cmake make \
autoconf automake autogen libtool \
flex bison \
git rpm-build
#Dependencies
RUN dnf -y install \
openssl-devel \
#libuuid-devel \
libcurl-devel \
jansson-devel \
spdlog-devel \
fmt-devel \
libconfig-devel \
libusb-devel \
lua-devel \
libnice-devel \
libwebsockets-devel
# Add local and 64-bit locations to linker paths
RUN echo /usr/local/lib >> /etc/ld.so.conf && \
echo /usr/local/lib64 >> /etc/ld.so.conf
ADD packaging/deps.sh /
RUN bash deps.sh
EXPOSE 80
EXPOSE 443
ENV LC_ALL C.UTF-8
ENV LANG C.UTF-8
FROM dev AS builder
ARG FLAGS
# Disable all default features
RUN FLAGS+=" -DWITH_DEFAULTS=OFF" && \
# Enable the villas-* binaries from ./src again
FLAGS+=" -DWITH_SRC=ON" && \
# Enable the villas-* tools from ./tools again
FLAGS+=" -DWITH_TOOLS=ON" && \
# Enable libconfig configuration syntax
FLAGS+=" -DWITH_CONFIG=ON" && \
# Enable the nodes
FLAGS+=" -DWITH_NODE_TEST_RTT=ON" && \
FLAGS+=" -DWITH_NODE_WEBRTC=ON" && \
FLAGS+=" -DWITH_NODE_SIGNAL=ON" && \
# Enable hooks, in&out support
FLAGS+=" -DWITH_IN=ON" && \
FLAGS+=" -DWITH_HOOKS=ON" && \
FLAGS+=" -DWITH_OUT=ON"
COPY . /villas/
WORKDIR /villas/build
RUN cmake ${FLAGS} -S .. && \
make -j$(nproc) install && \
ldconfig
ENTRYPOINT ["villas"]
So far, i tried to reduce the number of dependencies and the layers. But i found out that the dependencies can not be pruned anymore, deleting any one of them will lead to failure when building the Dockerfile. And by reducing the layers did not help much.
So i tried to use 'Alpine Linux base image' to reduce the image size, and i tried it by adding 'FROM alpine:latest
' before 'COPY . /villas/
'. But it didn't work, i could not build the Dockerfile with it. So what is the right way in my case to reduce the size of image using 'Alpine Linux base image'?
I am trying to minimize of size of my Docker image as small as possible, the Dockerfile looks like this:
ARG DISTRO=fedora
ARG FEDORA_VERSION=36
#FROM ${DISTRO}:${FEDORA_VERSION} AS dev
FROM ${DISTRO}:${FEDORA_VERSION} AS dev
#Toolchain
RUN dnf -y install \
gcc gcc-c++ \
pkgconfig \
cmake make \
autoconf automake autogen libtool \
flex bison \
git rpm-build
#Dependencies
RUN dnf -y install \
openssl-devel \
#libuuid-devel \
libcurl-devel \
jansson-devel \
spdlog-devel \
fmt-devel \
libconfig-devel \
libusb-devel \
lua-devel \
libnice-devel \
libwebsockets-devel
# Add local and 64-bit locations to linker paths
RUN echo /usr/local/lib >> /etc/ld.so.conf && \
echo /usr/local/lib64 >> /etc/ld.so.conf
ADD packaging/deps.sh /
RUN bash deps.sh
EXPOSE 80
EXPOSE 443
ENV LC_ALL C.UTF-8
ENV LANG C.UTF-8
FROM dev AS builder
ARG FLAGS
# Disable all default features
RUN FLAGS+=" -DWITH_DEFAULTS=OFF" && \
# Enable the villas-* binaries from ./src again
FLAGS+=" -DWITH_SRC=ON" && \
# Enable the villas-* tools from ./tools again
FLAGS+=" -DWITH_TOOLS=ON" && \
# Enable libconfig configuration syntax
FLAGS+=" -DWITH_CONFIG=ON" && \
# Enable the nodes
FLAGS+=" -DWITH_NODE_TEST_RTT=ON" && \
FLAGS+=" -DWITH_NODE_WEBRTC=ON" && \
FLAGS+=" -DWITH_NODE_SIGNAL=ON" && \
# Enable hooks, in&out support
FLAGS+=" -DWITH_IN=ON" && \
FLAGS+=" -DWITH_HOOKS=ON" && \
FLAGS+=" -DWITH_OUT=ON"
COPY . /villas/
WORKDIR /villas/build
RUN cmake ${FLAGS} -S .. && \
make -j$(nproc) install && \
ldconfig
ENTRYPOINT ["villas"]
So far, i tried to reduce the number of dependencies and the layers. But i found out that the dependencies can not be pruned anymore, deleting any one of them will lead to failure when building the Dockerfile. And by reducing the layers did not help much.
So i tried to use 'Alpine Linux base image' to reduce the image size, and i tried it by adding 'FROM alpine:latest
' before 'COPY . /villas/
'. But it didn't work, i could not build the Dockerfile with it. So what is the right way in my case to reduce the size of image using 'Alpine Linux base image'?
2 Answers
Reset to default 1The most important thing you can do with this setup is to introduce a multi-stage build. The image as you've shown it contains a complete C toolchain and development libraries, which are quite large. The size difference between a Fedora and Alpine image is miniscule compared to this (50-100 MB of base image, compared to 1 GB+ of toolchain and libraries).
The Dockerfile already starts with FROM image AS name
syntax to declare a named stage. You need to add a third stage at the end:
FROM ${DISTRO}:${FEDORA_VERSION}
# Install non-development versions of C shared libraries that will
# be used at runtime. See https://packages.fedoraproject.org/
# to find package names.
RUN dnf -y install \
openssl-libs \
libcurl \
...
# Copy the installed application into the final image.
COPY --from=builder /usr/local /usr/local
RUN ldconfig
# Set metadata for how to run the image.
# USER ...
# EXPOSE ...
CMD ["villas"]
This image will still be based on Fedora and not Alpine, but it will be substantially smaller than the image you're using now.
In principle it's possible to change that last FROM
line to FROM alpine
. You'll need to use Alpine's apk
package manager instead of Fedora's dnf
, and find dependencies on https://pkgs.alpinelinux.org/packages.
However, note that one of the things that makes Alpine-based images smaller is using an alternate C system library, musl libc instead of GNU libc. There are a number of very-low-level incompatibilities here. Many things will work with musl libc, but not all. If your application depends on a significant number of other shared libraries and also installs its own, I'd be worried about weird compatibility problems.
The easiest answer here often is to rewrite the entire build system to be Alpine- and not Fedora-based. A complete rewrite is beyond the scope of this answer. It's possible your application will run into build-time or link-time problems as well, but these should give clear pointers into your source code.
The multi-stage build approach will save you a huge amount of space in the final image. You may decide that saving a relatively small amount of space by switching base distributions isn't worth the effort of completely rebuilding and debugging the Dockerfile.
what is the right way in my case to reduce the size of image using 'Alpine Linux base image'?
The right way is rewritting the Dockerfile to support alpine linux, which is called "porting". Most significant change, as with any Linux distribution, is different package manager - apk
in Alpine linux.
Additionally, not everything supports musl C standard library that is used in alpine linux, so the software has to be additionally rewritten or patched to work with musl C standard library.
本文标签: How to use alpine to reduce docker image sizeStack Overflow
版权声明:本文标题:How to use alpine to reduce docker image size? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738493952a2089871.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
dnf
is a package manager for Fedora, RHEL, CentOS, Rocky and other distors. It's not supported by Alpine. Alpine usesapk
. You should clean up after the installation of packages or even avoid package managers at all in order to minimize the image size. – jabaa Commented Jan 23 at 14:02dnf
hasdnf clean
. Since Alpine is designed for minimal image sizes,apk
cleans up after itself. – jabaa Commented Jan 23 at 14:09