Search code examples
amazon-web-servicesaws-cli

awscli version 2 on alpine linux


I was trying to put awscli_v2 into an alpine-based docker container and see that it fails with the following error message:

/aws/install: line 78: /aws/dist/aws: not found

Considering that the file itself is there and can be listed with ls, I would guess that some libraries that the executable ./aws/dist/aws relies upon are not present on alpine. Does someone know which libraries that might be?


Solution

  • Actually with a bit a effort it is possible to run AWS CLI v2 on Alpine:

    ARG ALPINE_VERSION=3.17
    
    FROM alpine:${ALPINE_VERSION}
    
    ARG GLIBC_VERSION=2.35-r0
    ARG AWSCLI_VERSION=2.11.11
    
    # install glibc compatibility for alpine
    RUN apk --no-cache add \
            binutils \
            curl \
        && curl -sL https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub -o /etc/apk/keys/sgerrand.rsa.pub \
        && curl -sLO https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VERSION}/glibc-${GLIBC_VERSION}.apk \
        && curl -sLO https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VERSION}/glibc-bin-${GLIBC_VERSION}.apk \
        && curl -sLO https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VERSION}/glibc-i18n-${GLIBC_VERSION}.apk \
        && apk add --no-cache --force-overwrite \
            glibc-${GLIBC_VERSION}.apk \
            glibc-bin-${GLIBC_VERSION}.apk \
            glibc-i18n-${GLIBC_VERSION}.apk \
        && /usr/glibc-compat/bin/localedef -i en_US -f UTF-8 en_US.UTF-8 \
        && ln -sf /usr/glibc-compat/lib/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2 \
        && curl -sL https://awscli.amazonaws.com/awscli-exe-linux-x86_64-${AWSCLI_VERSION}.zip -o awscliv2.zip \
        && unzip awscliv2.zip \
        && aws/install \
        && rm -rf \
            awscliv2.zip \
            aws \
            /usr/local/aws-cli/v2/current/dist/aws_completer \
            /usr/local/aws-cli/v2/current/dist/awscli/data/ac.index \
            /usr/local/aws-cli/v2/current/dist/awscli/examples \
            glibc-*.apk \
        && find /usr/local/aws-cli/v2/current/dist/awscli/botocore/data -name examples-1.json -delete \
        && apk --no-cache del \
            binutils \
            curl \
        && rm -rf /var/cache/apk/*
    

    The above Dockerfile will install the 'glibc' package for Alpine, so that the AWS CLI will be able to find the required shared libraries. The Dockerfile also removes some stuff we probably don't need, such as auto-complete and examples. If you need some other specific packages you can of course add them to the Dockerfile.

    Updated 2023-12-12

    AWS has improved the build process, so now it's also possible to build from git with MUSL glibc (kudos to @Julian Bueno):

    The following will build v2.15.0 of AWS CLI, which is the latest at the time of this edit (2023-12-12)

    ARG ALPINE_VERSION=3.19
    FROM python:3.11-alpine${ALPINE_VERSION} as builder
    
    ARG AWS_CLI_VERSION=2.15.0
    RUN apk add --no-cache git unzip groff build-base libffi-dev cmake
    RUN git clone --single-branch --depth 1 -b ${AWS_CLI_VERSION} https://github.com/aws/aws-cli.git
    
    WORKDIR aws-cli
    RUN ./configure --with-install-type=portable-exe --with-download-deps
    RUN make
    RUN make install
    
    # reduce image size: remove autocomplete and examples
    RUN rm -rf \
        /usr/local/lib/aws-cli/aws_completer \
        /usr/local/lib/aws-cli/awscli/data/ac.index \
        /usr/local/lib/aws-cli/awscli/examples
    RUN find /usr/local/lib/aws-cli/awscli/data -name completions-1*.json -delete
    RUN find /usr/local/lib/aws-cli/awscli/botocore/data -name examples-1.json -delete
    RUN (cd /usr/local/lib/aws-cli; for a in *.so*; do test -f /lib/$a && rm $a; done)
    
    # build the final image
    FROM alpine:${ALPINE_VERSION}
    COPY --from=builder /usr/local/lib/aws-cli/ /usr/local/lib/aws-cli/
    RUN ln -s /usr/local/lib/aws-cli/aws /usr/local/bin/aws
    

    The above reduces the image size even more (from 175MB to 95MB), since we no longer need the glibc-compat hack. Hopefully AWS will also distribute the Alpine binaries, so we do not have to build it ourselves.

    Update 2023-07-01

    Alpine 3.18 includes aws-cli v2 as a 'main' package, so all you need to do is just run apk add aws-cli. One remark on this: The maintainers decided to use the 'dynamically linked' executable, which means it pulls in a ton of Python3 runtime dependencies (179Mb). If you want your images to be as tiny as possible, you can continue to use option #2.