NGINX with Docker Image



OSS Image Build - Debian

OSS Image Build - Alpine

ETC

  • Image Build Command

    docker build -t alpine-perl -f Dockerfile --no-cache .
    docker build -t alpine-slim -f Dockerfile --no-cache .
    docker build -t alpine -f Dockerfile --no-cache .
    docker build -t debian-perl -f Dockerfile --no-cache .
    docker build -t debian -f Dockerfile --no-cache .
    
  • Image Size ( 1.23.4 기준 )

    alpine-perl   latest    e4edea9dc54b   46 seconds ago       76.5MB
    alpine-slim   latest    08350251902b   About a minute ago   11.5MB
    alpine        latest    24672371dc15   About a minute ago   41MB
    debian        latest    482894c6d1e0   2 minutes ago        142MB
    debian-perl   latest    862ff2c67e82   2 minutes ago        189MB
    

NGINX Plus with Docker Image

공식 Docs 기준 자료

Plus Image Build - Debian

  • 필요 파일

    • DockerFile 경로에, NGINX CERT 필요 ( nginx-repo.crt / nginx-repo.key )
  • Docker File - 기본

    FROM debian:bullseye-slim
    
    LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>"
    
    # Define NGINX versions for NGINX Plus and NGINX Plus modules
    # Uncomment this block and the versioned nginxPackages block in the main RUN
    # instruction to install a specific release
    # ENV NGINX_VERSION   28
    # ENV NJS_VERSION     0.7.9
    # ENV PKG_RELEASE     1~bullseye
    
    # Download certificate and key from the customer portal (<https://account.f5.com>)
    # and copy to the build context
    RUN --mount=type=secret,id=nginx-crt,dst=nginx-repo.crt \\
        --mount=type=secret,id=nginx-key,dst=nginx-repo.key \\
        set -x \\
    # Create nginx user/group first, to be consistent throughout Docker variants
        && addgroup --system --gid 101 nginx \\
        && adduser --system --disabled-login --ingroup nginx --no-create-home --home /nonexistent --gecos "nginx user" --shell /bin/false --uid 101 nginx \\
        && apt-get update \\
        && apt-get install --no-install-recommends --no-install-suggests -y \\
                            ca-certificates \\
                            gnupg1 \\
                            lsb-release \\
        && \\
        NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62; \\
        found=''; \\
        for server in \\
            hkp://keyserver.ubuntu.com:80 \\
            pgp.mit.edu \\
        ; do \\
            echo "Fetching GPG key $NGINX_GPGKEY from $server"; \\
            apt-key adv --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$NGINX_GPGKEY" && found=yes && break; \\
        done; \\
        test -z "$found" && echo >&2 "error: failed to fetch GPG key $NGINX_GPGKEY" && exit 1; \\
        apt-get remove --purge --auto-remove -y gnupg1 && rm -rf /var/lib/apt/lists/* \\
    # Install the latest release of NGINX Plus and/or NGINX Plus modules
    # Uncomment individual modules if necessary
    # Use versioned packages over defaults to specify a release
        && nginxPackages=" \\
            nginx-plus \\
            # nginx-plus=${NGINX_VERSION}-${PKG_RELEASE} \\
            # nginx-plus-module-xslt \\
            # nginx-plus-module-xslt=${NGINX_VERSION}-${PKG_RELEASE} \\
            # nginx-plus-module-geoip \\
            # nginx-plus-module-geoip=${NGINX_VERSION}-${PKG_RELEASE} \\
            # nginx-plus-module-image-filter \\
            # nginx-plus-module-image-filter=${NGINX_VERSION}-${PKG_RELEASE} \\
            # nginx-plus-module-perl \\
            # nginx-plus-module-perl=${NGINX_VERSION}-${PKG_RELEASE} \\
            # nginx-plus-module-njs \\
            # nginx-plus-module-njs=${NGINX_VERSION}+${NJS_VERSION}-${PKG_RELEASE} \\
        " \\
        && echo "Acquire::https::pkgs.nginx.com::Verify-Peer \\"true\\";" > /etc/apt/apt.conf.d/90nginx \\
        && echo "Acquire::https::pkgs.nginx.com::Verify-Host \\"true\\";" >> /etc/apt/apt.conf.d/90nginx \\
        && echo "Acquire::https::pkgs.nginx.com::SslCert     \\"/etc/ssl/nginx/nginx-repo.crt\\";" >> /etc/apt/apt.conf.d/90nginx \\
        && echo "Acquire::https::pkgs.nginx.com::SslKey      \\"/etc/ssl/nginx/nginx-repo.key\\";" >> /etc/apt/apt.conf.d/90nginx \\
        && printf "deb <https://pkgs.nginx.com/plus/debian> `lsb_release -cs` nginx-plus\\n" > /etc/apt/sources.list.d/nginx-plus.list \\
        && mkdir -p /etc/ssl/nginx \\
        && cat nginx-repo.crt > /etc/ssl/nginx/nginx-repo.crt \\
        && cat nginx-repo.key > /etc/ssl/nginx/nginx-repo.key \\
        && apt-get update \\
        && apt-get install --no-install-recommends --no-install-suggests -y \\
                            $nginxPackages \\
                            curl \\
                            gettext-base \\
        && apt-get remove --purge -y lsb-release \\
        && apt-get remove --purge --auto-remove -y && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/nginx-plus.list \\
        && rm -rf /etc/apt/apt.conf.d/90nginx /etc/ssl/nginx \\
    # Forward request logs to Docker log collector
        && ln -sf /dev/stdout /var/log/nginx/access.log \\
        && ln -sf /dev/stderr /var/log/nginx/error.log
    
    EXPOSE 80
    
    STOPSIGNAL SIGQUIT
    
    CMD ["nginx", "-g", "daemon off;"]
    
  • Build Command

    docker build  --no-cache --secret id=nginx-key,src=nginx-repo.key --secret id=nginx-crt,src=nginx-repo.crt -t nginxplus .
    

Plus Image Build - Alpine

  • 필요 파일

    • DockerFile 경로에, NGINX CERT 필요 ( nginx-repo.crt / nginx-repo.key )
  • Docker FIle - 기본

    FROM alpine:3.17
    
    LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>"
    
    # Define NGINX versions for NGINX Plus and NGINX Plus modules
    # Uncomment this block and the versioned nginxPackages in the main RUN
    # instruction to install a specific release
    # ENV NGINX_VERSION 28
    # ENV NJS_VERSION   0.7.9
    # ENV PKG_RELEASE   1
    
    # Download certificate and key from the customer portal (<https://account.f5.com>)
    # and copy to the build context
    RUN --mount=type=secret,id=nginx-crt,dst=cert.pem \\
        --mount=type=secret,id=nginx-key,dst=cert.key \\
        set -x \\
    # Create nginx user/group first, to be consistent throughout Docker variants
        && addgroup -g 101 -S nginx \\
        && adduser -S -D -H -u 101 -h /var/cache/nginx -s /sbin/nologin -G nginx -g nginx nginx \\
    # Install the latest release of NGINX Plus and/or NGINX Plus modules
    # Uncomment individual modules if necessary
    # Use versioned packages over defaults to specify a release
        && nginxPackages=" \\
            nginx-plus \\
            # nginx-plus=${NGINX_VERSION}-r${PKG_RELEASE} \\
            # nginx-plus-module-xslt \\
            # nginx-plus-module-xslt=${NGINX_VERSION}-r${PKG_RELEASE} \\
            # nginx-plus-module-geoip \\
            # nginx-plus-module-geoip=${NGINX_VERSION}-r${PKG_RELEASE} \\
            # nginx-plus-module-image-filter \\
            # nginx-plus-module-image-filter=${NGINX_VERSION}-r${PKG_RELEASE} \\
            # nginx-plus-module-perl \\
            # nginx-plus-module-perl=${NGINX_VERSION}-r${PKG_RELEASE} \\
            # nginx-plus-module-njs \\
            # nginx-plus-module-njs=${NGINX_VERSION}.${NJS_VERSION}-r${PKG_RELEASE} \\
        " \\
        KEY_SHA512="e09fa32f0a0eab2b879ccbbc4d0e4fb9751486eedda75e35fac65802cc9faa266425edf83e261137a2f4d16281ce2c1a5f4502930fe75154723da014214f0655" \\
        && apk add --no-cache --virtual .cert-deps openssl \\
        && wget -O /tmp/nginx_signing.rsa.pub <https://nginx.org/keys/nginx_signing.rsa.pub> \\
        && if echo "$KEY_SHA512 */tmp/nginx_signing.rsa.pub" | sha512sum -c -; then \\
            echo "key verification succeeded!"; \\
            mv /tmp/nginx_signing.rsa.pub /etc/apk/keys/; \\
        else \\
            echo "key verification failed!"; \\
            exit 1; \\
        fi \\
        && apk del .cert-deps \\
        && cat cert.pem > /etc/apk/cert.pem \\
        && cat cert.key > /etc/apk/cert.key \\
        && apk add -X "<https://pkgs.nginx.com/plus/alpine/v$>(egrep -o '^[0-9]+\\.[0-9]+' /etc/alpine-release)/main" --no-cache $nginxPackages \\
        && if [ -f "/etc/apk/keys/nginx_signing.rsa.pub" ]; then rm -f /etc/apk/keys/nginx_signing.rsa.pub; fi \\
        && if [ -f "/etc/apk/cert.key" ] && [ -f "/etc/apk/cert.pem" ]; then rm -f /etc/apk/cert.key /etc/apk/cert.pem; fi \\
    # Bring in gettext so we can get `envsubst`, then throw
    # the rest away. To do this, we need to install `gettext`
    # then move `envsubst` out of the way so `gettext` can
    # be deleted completely, then move `envsubst` back.
        && apk add --no-cache --virtual .gettext gettext \\
        && mv /usr/bin/envsubst /tmp/ \\
        \\
        && runDeps="$( \\
            scanelf --needed --nobanner /tmp/envsubst \\
                | awk '{ gsub(/,/, "\\nso:", $2); print "so:" $2 }' \\
                | sort -u \\
                | xargs -r apk info --installed \\
                | sort -u \\
        )" \\
        && apk add --no-cache $runDeps \\
        && apk del .gettext \\
        && mv /tmp/envsubst /usr/local/bin/ \\
    # Bring in tzdata so users could set the timezones through the environment
    # variables
        && apk add --no-cache tzdata \\
    # Bring in curl and ca-certificates to make registering on DNS SD easier
        && apk add --no-cache curl ca-certificates \\
    # Forward request and error logs to Docker log collector
        && ln -sf /dev/stdout /var/log/nginx/access.log \\
        && ln -sf /dev/stderr /var/log/nginx/error.log
    
    EXPOSE 80
    
    STOPSIGNAL SIGQUIT
    
    CMD ["nginx", "-g", "daemon off;"]
    
    # vim:syntax=Dockerfile
    
  • Build Command

    docker build  --no-cache --secret id=nginx-key,src=nginx-repo.key --secret id=nginx-crt,src=nginx-repo.crt -t nginxplus .
    

Docker with NGINX 운영 관련

Config File

Config File - OS File Mount

  • NGINX Config / Content : OS FIle 활용하여 Docker Running

  • Sample Docker Command

    docker run --name mynginx2 \\
       --mount type=bind,source=/var/www,target=/usr/share/nginx/html,readonly \\
       --mount type=bind,source=/var/nginx/conf,target=/etc/nginx/conf,readonly \\
       -p 80:80 \\
       -d nginxplus
    

Config File - Image Build 에 통합

  • NGINX Config / Content : Image 에 build 하여 Container Running

  • Sample File Tree

    .
    ├── 10-listen-on-ipv6-by-default.sh
    ├── 20-envsubst-on-templates.sh
    ├── 30-tune-worker-processes.sh
    ├── docker-entrypoint.sh
    ├── Dockerfile
    ├── sample-config
    │   └── nginx.conf
    └── sample-content
        └── index.html
    
  • Sample Docker FIle

    # BASE : Alpine-Slim 
    
    #
    # NOTE: THIS DOCKERFILE IS GENERATED VIA "update.sh"
    #
    # PLEASE DO NOT EDIT IT DIRECTLY.
    #
    FROM alpine:3.17
    
    LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>"
    
    ENV NGINX_VERSION 1.23.4
    ENV PKG_RELEASE   1
    
    RUN set -x \\
    # create nginx user/group first, to be consistent throughout docker variants
        && addgroup -g 101 -S nginx \\
        && adduser -S -D -H -u 101 -h /var/cache/nginx -s /sbin/nologin -G nginx -g nginx nginx \\
        && apkArch="$(cat /etc/apk/arch)" \\
        && nginxPackages=" \\
            nginx=${NGINX_VERSION}-r${PKG_RELEASE} \\
        " \\
    # install prerequisites for public key and pkg-oss checks
        && apk add --no-cache --virtual .checksum-deps \\
            openssl \\
        && case "$apkArch" in \\
            x86_64|aarch64) \\
    # arches officially built by upstream
                set -x \\
                && KEY_SHA512="e09fa32f0a0eab2b879ccbbc4d0e4fb9751486eedda75e35fac65802cc9faa266425edf83e261137a2f4d16281ce2c1a5f4502930fe75154723da014214f0655" \\
                && wget -O /tmp/nginx_signing.rsa.pub <https://nginx.org/keys/nginx_signing.rsa.pub> \\
                && if echo "$KEY_SHA512 */tmp/nginx_signing.rsa.pub" | sha512sum -c -; then \\
                    echo "key verification succeeded!"; \\
                    mv /tmp/nginx_signing.rsa.pub /etc/apk/keys/; \\
                else \\
                    echo "key verification failed!"; \\
                    exit 1; \\
                fi \\
                && apk add -X "<https://nginx.org/packages/mainline/alpine/v$>(egrep -o '^[0-9]+\\.[0-9]+' /etc/alpine-release)/main" --no-cache $nginxPackages \\
                ;; \\
            *) \\
    # we're on an architecture upstream doesn't officially build for
    # let's build binaries from the published packaging sources
                set -x \\
                && tempDir="$(mktemp -d)" \\
                && chown nobody:nobody $tempDir \\
                && apk add --no-cache --virtual .build-deps \\
                    gcc \\
                    libc-dev \\
                    make \\
                    openssl-dev \\
                    pcre2-dev \\
                    zlib-dev \\
                    linux-headers \\
                    bash \\
                    alpine-sdk \\
                    findutils \\
                && su nobody -s /bin/sh -c " \\
                    export HOME=${tempDir} \\
                    && cd ${tempDir} \\
                    && curl -f -O <https://hg.nginx.org/pkg-oss/archive/${NGINX_VERSION}-${PKG_RELEASE}.tar.gz> \\
                    && PKGOSSCHECKSUM=\\"8f3f6c1ddd984c0c7320d3bea25eee42749db6d69c251223cf91d69b8d80b703ab39eb94fcf731399a7693ebd8dd37d1b3232ea1184ca98e5ca0ba6165e1a05c *${NGINX_VERSION}-${PKG_RELEASE}.tar.gz\\" \\
                    && if [ \\"\\$(openssl sha512 -r ${NGINX_VERSION}-${PKG_RELEASE}.tar.gz)\\" = \\"\\$PKGOSSCHECKSUM\\" ]; then \\
                        echo \\"pkg-oss tarball checksum verification succeeded!\\"; \\
                    else \\
                        echo \\"pkg-oss tarball checksum verification failed!\\"; \\
                        exit 1; \\
                    fi \\
                    && tar xzvf ${NGINX_VERSION}-${PKG_RELEASE}.tar.gz \\
                    && cd pkg-oss-${NGINX_VERSION}-${PKG_RELEASE} \\
                    && cd alpine \\
                    && make base \\
                    && apk index -o ${tempDir}/packages/alpine/${apkArch}/APKINDEX.tar.gz ${tempDir}/packages/alpine/${apkArch}/*.apk \\
                    && abuild-sign -k ${tempDir}/.abuild/abuild-key.rsa ${tempDir}/packages/alpine/${apkArch}/APKINDEX.tar.gz \\
                    " \\
                && cp ${tempDir}/.abuild/abuild-key.rsa.pub /etc/apk/keys/ \\
                && apk del .build-deps \\
                && apk add -X ${tempDir}/packages/alpine/ --no-cache $nginxPackages \\
                ;; \\
        esac \\
    # remove checksum deps
        && apk del .checksum-deps \\
    # if we have leftovers from building, let's purge them (including extra, unnecessary build deps)
        && if [ -n "$tempDir" ]; then rm -rf "$tempDir"; fi \\
        && if [ -n "/etc/apk/keys/abuild-key.rsa.pub" ]; then rm -f /etc/apk/keys/abuild-key.rsa.pub; fi \\
        && if [ -n "/etc/apk/keys/nginx_signing.rsa.pub" ]; then rm -f /etc/apk/keys/nginx_signing.rsa.pub; fi \\
    # Bring in gettext so we can get `envsubst`, then throw
    # the rest away. To do this, we need to install `gettext`
    # then move `envsubst` out of the way so `gettext` can
    # be deleted completely, then move `envsubst` back.
        && apk add --no-cache --virtual .gettext gettext \\
        && mv /usr/bin/envsubst /tmp/ \\
        \\
        && runDeps="$( \\
            scanelf --needed --nobanner /tmp/envsubst \\
                | awk '{ gsub(/,/, "\\nso:", $2); print "so:" $2 }' \\
                | sort -u \\
                | xargs -r apk info --installed \\
                | sort -u \\
        )" \\
        && apk add --no-cache $runDeps \\
        && apk del .gettext \\
        && mv /tmp/envsubst /usr/local/bin/ \\
    # Bring in tzdata so users could set the timezones through the environment
    # variables
        && apk add --no-cache tzdata \\
    # forward request and error logs to docker log collector
        && ln -sf /dev/stdout /var/log/nginx/access.log \\
        && ln -sf /dev/stderr /var/log/nginx/error.log \\
    # create a docker-entrypoint.d directory
        && mkdir /docker-entrypoint.d
    
    COPY docker-entrypoint.sh /
    COPY 10-listen-on-ipv6-by-default.sh /docker-entrypoint.d
    COPY 20-envsubst-on-templates.sh /docker-entrypoint.d
    COPY 30-tune-worker-processes.sh /docker-entrypoint.d
    ## REMOVE Content
    RUN rm /etc/nginx/conf.d/default.conf
    RUN rm /etc/nginx/nginx.conf
    RUN rm /usr/share/nginx/html/index.html
    ## ADD New Content
    COPY sample-config/nginx.conf /etc/nginx/nginx.conf
    COPY sample-content/index.html /usr/share/nginx/html/index.html 
    
    ENTRYPOINT ["/docker-entrypoint.sh"]
    
    EXPOSE 803
    
    STOPSIGNAL SIGQUIT
    
    CMD ["nginx", "-g", "daemon off;"]
    
  • Sample Image Build

    docker build -t alpine-test -f Dockerfile --no-cache .
    
  • Sample Docker Access with CURL

    # curl 0
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
    html { color-scheme: light dark; }
    body { width: 35em; margin: 0 auto;
    font-family: Tahoma, Verdana, Arial, sans-serif; }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>**Customize Building NGINX Image - HTML Pages** </p>
    
    <p>For online documentation and support please refer to
    <a href="<http://nginx.org/>">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="<http://nginx.com/>">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>