NGINX Docker 배포 가이드

F5 NGINX Plus는 고성능 애플리케이션 전달 플랫폼, 로드 밸런서 및 웹 서버로, Docker 컨테이너로도 제공됩니다.

목차

1. NGINX Docker 배포 전제 조건
2. 특정 OS 및 아키텍처에 대한 NGINX Plus 이미지 빌드
 2-1. 지원하는 NGINX Plus 버전

 2-2. 지원하는 배포판
 2-3. 지원하는 이미지 유형
 2-4. NGINX Plus 인증서, 키 혹은 JSON Web Token 파일 다운로드
 2-5. NGINX Plus 컨테이너 레지스트리를 위한 Docker 설정
 2-6. NGINX Docker이미지 Pull 하기
 2-7. NGINX Docker 이미지를 개인 레지스트리에 Push 하기
3. Docker 컨테이너에서 NGINX 오픈 소스 실행
4. 커스텀 NGINX Plus Docker 이미지 생성 방법
5. 콘텐츠 및 구성 파일 관리
 5-1. Docker 호스트에서 NGINX 콘텐츠 및 구성 파일 관리
 5-2. Docker 호스트에서 NGINX 콘텐츠 및 구성 파일 복사
 5-3. 컨테이너에서 콘텐츠 및 구성 파일 유지 관리
6. 로깅 관리
 6-1. 기본 로깅 사용
 6-2. 커스텀 로깅 사용
7. NGINX 제어

1. NGINX Docker 배포 전제 조건

  • Docker가 설치됨
  • NGINX Plus: nginx-repo.crtnginx-repo.key 파일 혹은 JSON Web Token 파일
  • NGINX OSS: Docker Hub 계정

2. 특정 OS 및 아키텍처에 대한 NGINX Plus 이미지 빌드

NGINX Plus 릴리즈 31부터, NGINX Plus 이미지를 공식 NGINX Plus Docker 레지스트리에서 pull 하여 개인 레지스트리에 업로드할 수 있습니다.

이미지는 특정한 버전의 NGINX Plus 혹은 NGINX Plus와 NGINX Agent 번들을 포함할 수 있고, 특정 아키텍처를 대상으로 할 수 있습니다.

2-1. 지원하는 NGINX Plus 버전

  • NGINX Plus 릴리즈 32
  • NGINX Plus 릴리즈 32와 NGINX Agent
  • NGINX Plus 릴리즈 31
  • NGINX Plus 릴리즈 31과 NGINX Agent

2-2. 지원하는 배포

  • Alpine (x86_64, aarch64)
  • Debian (x86_64, aarch64)
  • Red Hat Enterprise Linux (x86_64, aarch64)

2-3. 지원하는 이미지 유형

  • base – NGINX Plus만 해당됨
  • agent – 단일 이미지에 NGINX Plus와 NGINX Agent 포함
  • rootless-base – nginx 사용자로 실행되는 NGINX Plus
  • rootless-agent – nginx 사용자로 NGINX Plus와 NGINX Agent를 모두 실행
  • modules – NGINX Plus만 해당됨

2-4. NGINX Plus 인증서, 키 혹은 JSON Web Token 파일 다운로드

컨테이너 이미지를 받기 전에, NGINX Plus 라이센스와 함께 제공된 SSL 인증서, 키 파일 혹은 JSON Web Token 파일이 필요합니다. 해당 파일은 스크립트가 NGINX Plus 패키지를 다운로드할 패키지 저장소에 대한 엑세스 권한을 부여합니다.

JSON Web Token
  1. MyF5 사용자 포털에 로그인합니다.
  2. My Products and Plans > Subscriptions 메뉴로 이동합니다.
  3. 구독중인 제품을 선택합니다.
  4. JSON Web Token 파일을 다운로드합니다.
SSL
  1. MyF5 사용자 포털에 로그인합니다.
  2. My Products and Plans > Subscriptions 메뉴로 이동합니다.
  3. 구독중인 제품을 선택합니다.
  4. SSL 인증서개인 키 파일을 다운로드합니다.

2-5. NGINX Plus 컨테이너 레지스트리를 위한 Docker 설정

Docker가 private-registry.nginx.com에 위치한 NGINX 컨테이너 레지스트리와 통신하도록 설정합니다.

JSON Web Token

이전에 MyF5 사용자 포털에서 다운로드한 JSON Web Token 파일(예: nginx-repo-12345abc.jwt)을 열고, 내용을 복사합니다.

JSON Web Token 파일의 내용을 사용하여 Docker 레지스트리에 로그인합니다.

$ docker login private-registry.nginx.com --username=<JWT 파일 내용> --password=none
SSL

디렉토리를 생성하고, 인증서 파일과 키 파일을 해당 디렉토리로 복사합니다.

$ mkdir -p /etc/docker/certs.d/private-registry.nginx.com
$ cp <nginx-repo.crt 파일 경로> /etc/docker/certs.d/private-registry.nginx.com/client.cert
$ cp <nginx-repo.key 파일 경로> /etc/docker/certs.d/private-registry.nginx.com/client.key

예시 명령어는 Linux를 위한 명령어입니다. Docker 엔진 보안을 위한 더 많은 정보는 Docker Engine security 문서를 참고하세요.

Docker 레지스트리에 로그인합니다.

$ docker login private-registry.nginx.com

2-6. NGINX Docker 이미지 Pull 하기

필요한 이미지를 private-registry.nginx.com에서 pull 합니다.

이미지를 pull 하기 위해 <version-tag>를 필요한 NGINX Plus 버전 혹은 NGINX Plus 버전과 OS 버전으로 변경하세요. 예를 들어, r32-ubi-9.

NGINX Plus 이미지 예시:

$ docker pull private-registry.nginx.com/nginx-plus/base:<version-tag>

NGINX Plus와 NGINX Agent 이미지 예시:

$ docker pull private-registry.nginx.com/nginx-plus/agent:<version-tag>

nginx 사용자로 설치된(rootless 설치) NGINX Plus 이미지 예시:

$ docker pull private-registry.nginx.com/nginx-plus/rootless-base:<version-tag>

nginx 사용자로 설치된(rootless 설치) NGINX Plus와 NGINX Agent 이미지 예시:

$ docker pull private-registry.nginx.com/nginx-plus/rootless-agent:<version-tag>

NGINX modules 예시:

$ docker pull private-registry.nginx.com/nginx-plus/modules:<version-tag>

태그 예시:

  • nginx_releaseOS_typer32-ubir32-alpiner32-debian
  • nginx_releaseOS_typeOS_versionr32-ubi-9r32-alpine-9.99r32-debian-sid
  • 최신 릴리즈 이미지의 OS_type 태그는 alpinedebian 혹은 ubi가 지정됩니다.
  • 최신 debain 기반의 이미지는 짧은 릴리즈 태그(예: R32)와 nginx-plus 태그를 함께 가집니다.

Docker 레지스트리 API를 사용해서 유효한 이미지 태그 목록을 확인할 수 있습니다. <path-to-your-nginx-repo.key> 를 키 파일의 위치로, <path-to-your-nginx-repo.crt> 를 인증서 파일의 위치로 변경하세요. 선택사항인 jq 명령어는 JSON 형식의 출력을 읽기 쉽게 출력해주며,  jq JSON 프로세서를 설치해야합니다.

$ curl https://private-registry.nginx.com/v2/nginx-plus/base/tags/list --key <path-to-your-nginx-repo.key> --cert <path-to-your-nginx-repo.crt> | jq

출력 예시:

{
  "name": "nginx-plus/base",
  "tags": [
    "alpine",
    "debian",
    "nginx-plus-20240313",
    "nginx-plus-20240326",
    "nginx-plus-r31-20240313",
    "nginx-plus-r31-20240326",
    "nginx-plus-r31-alpine-3.18-20240313",
    "nginx-plus-r31-alpine-3.18-20240326",
    "nginx-plus-r31-alpine-3.18",
    "nginx-plus-r31-debian-bookworm-20240313",
    "nginx-plus-r31-debian-bookworm-20240326",
    "nginx-plus-r31-debian-bookworm",
    "nginx-plus-r31-ubi-9-20240313",
    "nginx-plus-r31-ubi-9-20240326",
    "nginx-plus-r31-ubi-9",
    "nginx-plus-r31",
    "nginx-plus-r32-20240313",
    "nginx-plus-r32-20240326",
    "nginx-plus-r32-alpine-3.19-20240313",
    "nginx-plus-r32-alpine-3.19-20240326",
    "nginx-plus-r32-alpine-3.19",
    "nginx-plus-r32-debian-bookworm-20240313",
    "nginx-plus-r32-debian-bookworm-20240326",
    "nginx-plus-r32-debian-bookworm",
    "nginx-plus-r32-ubi-9-20240313",
    "nginx-plus-r32-ubi-9-20240326",
    "nginx-plus-r32-ubi-9",
    "nginx-plus-r32",
    "nginx-plus",
    "r31-alpine-3.18-20240313",
    "r31-alpine-3.18-20240326",
    "r31-alpine-3.18",
    "r31-debian-bookworm-20240313",
    "r31-debian-bookworm-20240326",
    "r31-debian-bookworm",
    "r31-ubi-9-20240313",
    "r31-ubi-9-20240326",
    "r31-ubi-9",
    "r31",
    "r32-alpine-3.19-20240313",
    "r32-alpine-3.19-20240326",
    "r32-alpine-3.19",
    "r32-alpine",
    "r32-debian-bookworm-20240313",
    "r32-debian-bookworm-20240326",
    "r32-debian-bookworm",
    "r32-debian",
    "r32-ubi-9-20240313",
    "r32-ubi-9-20240326",
    "r32-ubi-9",
    "r32-ubi",
    "r32",
    "ubi"
  ]
}

Note:

보안을 위해, 다음 JSON Web Tokens(JWTs), 비밀번호, shell history 관련 지침을 따르세요.

1. JWTs: JWTs는 민감한 정보이므로, 안전하게 보관하세요. 허가되지 않은 접근을 방지하기 위해 사용 후 삭제하세요.

2. Shell history: JWTs와 비밀번호를 포함하는 명령어는 당신의 shell history에 일반 텍스트로 기록됩니다. 관련된 명령어를 사용 시 shell history를 지우세요. 예를 들어, bash를 사용할 경우, ~/.bash_history 파일의 명령어를 삭제할 수 있습니다. 또는 history -c 명령어를 통해 shell history를 지울 수 있습니다.

시스템, 데이터의 보안을 위해 위 지침을 따르세요.

2-7. NGINX Docker 이미지를 개인 레지스트리에 Push 하기

이미지를 pull 한 이후, 태그를 지정하여 개인 레지스트리에 push 합니다.

$ docker login <my-docker-registry>

태그를 지정하고 이미지를 push 합니다. <my-docker-registry> 를 레지스트리 경로로 변경하고, <version-tag> 를 NGINX Plus 버전, 혹은 NGINX Plus 버전과 OS 버전으로 변경합니다.

$ docker tag private-registry.nginx.com/nginx-plus/base:<version-tag> <my-docker-registry>/nginx-plus/base:<version-tag>
$ docker push <my-docker-registry>/nginx-plus/base:<version-tag>

3. Docker 컨테이너에서 NGINX 오픈 소스 실행

Docker Hub의 NGINX OSS 이미지를 사용하여 Docker 컨테이너에 NGINX 인스턴스를 생성할 수 있습니다.

1. 다음 명령어를 통해 컨테이너에서 실행되고 기본 NGINX 설정을 사용하는 NGINX 인스턴스를 시작합니다.

$ docker run --name mynginx1 -p 80:80 -d nginx
  • mynginx1 은 NGINX 이미지를 사용하여 생성된 컨테이너의 이름입니다.
  • -d 옵션은 컨테이너를 detatched mode로 실행하도록 명시합니다. 컨테이너는 중지될 때 까지 계속 실행되지만, 명령줄에서 실행되는 명령어에 응답하지 않습니다.
  • -p 옵션은 NGINX image에 의해 컨테이너 내부에 노출된 포트(포트 80)를 Docker 호스트의 지정된 포트로 매핑하도록 명시합니다. 첫 번째 매개변수는 Docker 호스트의 포트 번호, 두 번째 매개변수는 컨테이너 내부에 노출된 포트에 매핑됩니다.

명령어는 컨테이너 ID의 긴 형식을 반환합니다: fcd1fb01b14557c7c9d991238f2558ae2704d129cf9fb97bb4fadf673a58 이 형식의 ID는 로그 파일 이름에 사용됩니다.

2. docker ps 명령어를 사용하여 컨테이너가 생성되고, 실행 중인지 확인하세요.

$ docker ps
CONTAINER ID  IMAGE         COMMAND               CREATED         STATUS        ...
fcd1fb01b145  nginx:latest  "nginx -g 'daemon of  16 seconds ago  Up 15 seconds ...

    ... PORTS              NAMES
    ... 0.0.0.0:80->80/tcp mynginx1

이 명령어는 이전 단계의 포트 매핑 설정도 표시합니다. 출력의 PORTS 필드는 Docker 호스트의 80번 포트가 컨테이너 내부에 80번 포트에 매핑된 것을 알려줍니다.

4. 커스텀 NGINX Plus Docker 이미지 생성 방법

NGINX Plus는 상용 서비스이므로, NGINX Plus Docker 이미지는 Docker Hub에서 제공되지 않습니다. 따라서 NGINX Plus Docker 이미지를 먼저 생성해야 합니다.

Note: NGINX Plus 이미지를 Docker Hub와 같은 공개 저장소에 절대 업로드하지 마세요. 이는 라이선스 계약 위반 사항입니다.

커스텀 NGINX Plus 이미지 생성을 위해선 다음 과정을 따르세요.

1. Docker build 컨텍스트 혹은 Dockerfile을 생성하세요. 예를들어:

ARG RELEASE=bookworm
FROM debian:${RELEASE}-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
# ARG RELEASE
# ENV NGINX_VERSION=32
# ENV NGINX_PKG_RELEASE=1~${RELEASE}
# ENV NJS_VERSION=0.8.4
# ENV NJS_PKG_RELEASE=1~${RELEASE}
# ENV OTEL_VERSION=0.1.0
# ENV OTEL_PKG_RELEASE=1~${RELEASE}
# ENV PKG_RELEASE=1~${RELEASE}

# Download your NGINX license certificate and key from the F5 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
    && groupadd --system --gid 101 nginx \
    && useradd --system --gid nginx --no-create-home --home /nonexistent --comment "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_GPGKEYS="573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 8540A6F18833A80E9C1653A42FD21310B49F6B46 9E9BE90EACBCDE69FE9B204CBCDCD8A38D88A2B3"; \
    NGINX_GPGKEY_PATH=/usr/share/keyrings/nginx-archive-keyring.gpg; \
    export GNUPGHOME="$(mktemp -d)"; \
    found=''; \
    for NGINX_GPGKEY in $NGINX_GPGKEYS; do \
        for server in \
            hkp://keyserver.ubuntu.com:80 \
            pgp.mit.edu \
        ; do \
            echo "Fetching GPG key $NGINX_GPGKEY from $server"; \
            gpg1 --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; \
    done; \
    gpg1 --export "$NGINX_GPGKEYS" > "$NGINX_GPGKEY_PATH" ; \
    rm -rf "$GNUPGHOME"; \
    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 (written and maintained by F5)
# Uncomment any desired module packages to install the latest release or use the versioned package format to specify a release
# For an exhaustive list of supported modules and how to install them, see https://docs.nginx.com/nginx/admin-guide/dynamic-modules/dynamic-modules/
    && nginxPackages=" \
        nginx-plus \
        # nginx-plus=${NGINX_VERSION}-${NGINX_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-njs \
        # nginx-plus-module-njs=${NGINX_VERSION}+${NJS_VERSION}-${NJS_PKG_RELEASE} \
        # nginx-plus-module-otel \
        # nginx-plus-module-otel=${NGINX_VERSION}+${OTEL_VERSION}-${OTEL_PKG_RELEASE} \
        # nginx-plus-module-perl \
        # nginx-plus-module-perl=${NGINX_VERSION}-${PKG_RELEASE} \
        # nginx-plus-module-xslt \
        # nginx-plus-module-xslt=${NGINX_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 \
    && echo "deb [signed-by=$NGINX_GPGKEY_PATH] 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;"]
ARG RELEASE=3.20
FROM alpine:${RELEASE}

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=32
# ENV NGINX_PKG_RELEASE=1
# ENV NJS_VERSION=0.8.4
# ENV NJS_PKG_RELEASE=1
# ENV OTEL_VERSION=0.1.0
# ENV OTEL_PKG_RELEASE=1
# ENV PKG_RELEASE=1

# Download your NGINX license certificate and key from the F5 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 (written and maintained by F5)
# Uncomment any desired module packages to install the latest release or use the versioned package format to specify a release
# For an exhaustive list of supported modules and how to install them, see https://docs.nginx.com/nginx/admin-guide/dynamic-modules/dynamic-modules/
    && nginxPackages=" \
        nginx-plus \
        # nginx-plus=${NGINX_VERSION}-r${NGINX_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-njs \
        # nginx-plus-module-njs=${NGINX_VERSION}.${NJS_VERSION}-r${NJS_PKG_RELEASE} \
        # nginx-plus-module-otel \
        # nginx-plus-module-otel=${NGINX_VERSION}.${OTEL_VERSION}-r${OTEL_PKG_RELEASE} \
        # nginx-plus-module-perl \
        # nginx-plus-module-perl=${NGINX_VERSION}-r${PKG_RELEASE} \
        # nginx-plus-module-xslt \
        # nginx-plus-module-xslt=${NGINX_VERSION}-r${PKG_RELEASE} \
    " \
    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 \
    && 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 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

2. NGINX OSS와 마찬가지로, NGINX Plus 이미지는 동일한 기본 설정을 가지고 있습니다.

  • access, error 로그는 Docker 로그 수집기와 연결되어 있습니다.
  • 볼륨이 정의되어 있지 않습니다: Dockerfile을 사용해 지정된 볼륨으로 이미지를 생성하거나, 볼륨을 수동으로 지정할 수 있습니다.
VOLUME /usr/share/nginx/html
VOLUME /etc/nginx
  • 컨테이너 생성 시 Docker 호스트로부터 파일을 복사하지 않습니다: 각 Dockerfile에 COPY 정의를 추가하거나, 당신이 생성한 이미지를 다른 이미지의 기반으로 사용할 수 있습니다.

3. MyF5 사용자 포털로 로그인하여 nginx-repo.crt 파일과 nginx-repo.key 파일을 다운드합니다. NGINX Plus 체험판의 경우, 체험판 패키지와 함께 파일이 제공됩니다.

4. 다운로드한 파일을 Dockerfile이 있는 위치에 복사합니다.

5. Docker 이미지를 생성합니다. 예제의 이미지 이름은 nginxplus 입니다. 명령어 마지막의 .을 주의하세요.

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

--no-cache 옵션은 Docker가 이미지를 처음부터 생성하고, NGINX Plus의 최신 버전을 설치하도록 합니다. 만약 Dockerfile이 --no-cache 옵션 없이 이미지를 생성했다면, 새로운 이미지는 Docker 캐시의 이전에 생성된 NGINX Plus 버전을 사용합니다.

6. docker images 명령어를 사용해 nginxplus 이미지가 성공적으로 생성된 것을 확인합니다.

$ docker images nginxplus
REPOSITORY  TAG     IMAGE ID      CREATED        SIZE
nginxplus   latest  ef2bf65931cf  6 seconds ago  91.2 MB

7. 생성한 이미지를 기반으로 컨테이너를 생성합니다. 예제의 컨테이너 이름은 mynginxplus  입니다.

$ docker run --name mynginxplus -p 80:80 -d nginxplus

8. docker ps 명령어를 사용해 mynginxplus 컨테이너가 생성되고 동작하는 것을 확인합니다.

$ docker ps
CONTAINER ID  IMAGE             COMMAND               CREATED         STATUS        ...
eb7be9f439db  nginxplus:latest  "nginx -g 'daemon of  1 minute ago    Up 15 seconds ...

    ... PORTS              NAMES
    ... 0.0.0.0:80->80/tcp mynginxplus

5. 콘텐츠 및 구성 파일 관리

NGINX에서 제공하는 콘텐츠와 NGINX 설정 파일은 다양한 방법으로 관리할 수 있습니다.

  • Docker 호스트에서 파일 유지 관리
  • Docker 호스트에서 컨테이너로 파일 복사
  • 컨테이너 내부에서 파일 유지 관리

5-1. Docker 호스트에서 NGINX 콘텐츠 및 구성 파일 관리

컨테이너를 생성할 때, Docker 호스트의 로컬 디렉토리를 컨테이너로 마운트할 수 있습니다. NGINX 이미지는 컨테이너의 root 디렉토리로 /usr/share/nginx/html를 사용하고, /etc/nginx에 설정 파일을 저장하는 기본 NGINX 설정을 사용합니다. 로컬 디렉토리 /var/www에 콘텐츠 파일이 있고, 설정 파일이 /var/nginx/conf에 있는 Docker 호스트의 경우, 다음 명령어를 사용합니다:

$ 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

Docker 호스트 로컬 디렉토리 /var/www, /var/nginx/conf의 파일이 변경되면, 컨테이너 내부 디렉토리 /usr/share/nginx/html와 /etc/nginx에 반영됩니다. readonly 옵션은 이러한 디렉토리가 컨테이너 내부가 아닌 Docker 호스트에서만 변경될 수 있음을 의미합니다.

5-2. Docker 호스트에서 NGINX 콘텐츠 및 구성 파일 복사

Docker는 컨테이너 생성 시 Docker 호스트의 로컬 디렉토리에서 콘텐츠 및 구성 파일을 복사할 수 있습니다. 컨테이너를 생성한 이후에는, 파일 변경 시 새로운 컨테이너를 생성하거나, 컨테이너 내부에서 파일을 변경하여 관리합니다.

파일을 복사하는 간단한 방법은 NGINX 이미지를 기반으로 하는 새 Docker 이미지를 생성하는 동안 실행되는 명령어를 포함하여 Dockerfile을 만드는 것입니다. Dockerfile의 파일 복사(COPY) 명령어에서, 로컬 디렉토리 경로는 Dockerfile이 위치한 빌드 컨텍스트를 기준의 상대 경로입니다.

콘텐츠 디렉토리는 content, 설정 파일 디렉토리는 conf이고, 두 디렉토리 모두 Dockerfile 이 위치한 디렉토리의 하위 디렉토리라고 가정하겠습니다. NGINX 이미지는 /etc/nginx/conf.d 디렉토리에 default.conf 파일을 포함한 기본 설정 파일을 가지고 있습니다. Docker 호스트에 있는 설정 파일만을 사용하려면, 기본 파일을 RUN명령어로 삭제합니다.

FROM nginx
RUN rm /etc/nginx/conf.d/default.conf
COPY content /usr/share/nginx/html
COPY conf /etc/nginx

Dockerfile이 위치한 디렉토리에서 명령어를 사용해 NGINX 이미지를 생성합니다. 명령어 마지막의 점(“.”)은 현재 디렉토리를 Dockerfile과 복사할 디렉토리가 포함된 빌드 컨텍스트로 정의합니다.

$ docker build -t mynginx_image1 .

mynginx_image1 이미지를 기반으로 하는 mynginx3 컨테이너를 생성합니다:

$ docker run --name mynginx3 -p 80:80 -d mynginx_image1

컨테이너 내부의 파일을 변경하려면, 다음 섹션에서 설명하는 헬퍼 컨테이너를 사용합니다.

5-3. 컨테이너에서 콘텐츠 및 구성 파일 유지 관리

NGINX 컨테이너에 SSH를 통한 엑세스가 불가능하므로, 콘텐츠나 설정 파일을 직접 수정하려면 shell 엑세스가 있는 헬퍼 컨테이너를 생성해야 합니다. 헬퍼 컨테이너가 파일에 엑세스할 수 있도록 하려면, 이미지에 대해 적절한 Docker 데이터 볼륨이 정의된 새 이미지를 생성하세요.

1. NGINX 콘텐츠와 설정 파일을 복사하고 Dockerfile에서 이미지의 볼륨을 정의합니다.

FROM nginx
COPY content /usr/share/nginx/html
COPY conf /etc/nginx
VOLUME /usr/share/nginx/html
VOLUME /etc/nginx

2. 다음 명령어를 사용해 새 NGINX 이미지를 생성합니다.

$ docker build -t mynginx_image2 .

3. mynginx_image2 이미지를 기반으로 하는 mynginx4 NGINX 컨테이너를 생성합니다.

$ docker run --name mynginx4 -p 80:80 -d mynginx_image2

4. 생성한 mynginx4 컨테이너의 컨텐츠 및 설정 디렉토리에 접근할 수 있는 shell을 가진 mynginx4_files 헬퍼 컨테이너를 시작합니다.

$ docker run -i -t --volumes-from mynginx4 --name mynginx4_files debian /bin/bash
root@b1cbbad63dd1:/#
  • mynginx4_files 헬퍼 컨테이너는 지속적인 표준 입력(-i 옵션)과 TTY(-t 옵션)를 가지고 포그라운드에서 실행됩니다. mynginx4에 정의된 모든 볼륨은 헬퍼 컨테이너 내부의 로컬 디렉토리에 마운트됩니다.
  • debian 인수는 헬퍼 컨테이너가 Dock Hub의 Debian 이미지를 사용함을 뜻합니다. NGINX 이미지도 Debian을 사용하기 때문에, Docker를 통해 다른 운영체제를 로드하는 것보다, 헬퍼 컨테이너에 Debian을 사용하는 게 효율적입니다.

컨테이너를 시작하고 중지하려면 다음 명령어를 사용합니다.

$ docker start mynginx4_files
$ docker stop mynginx4_files

컨테이너의 실행을 유지하며 shell을 종료하려면 Ctrl+q를 입력하고 Ctrl+p 를 입력합니다. 실행중인 컨테이너의 shell에 다시 접근하려면 다음 명령어를 사용합니다:

$ docker attach mynginx4_files

shell을 종료하고 컨테이너를 종료하려면 exit 명령어를 사용합니다.

6. 로깅 관리

기본 로깅과 커스텀 로깅을 사용할 수 있습니다.

6-1. 기본 로깅 사용

기본적으로, NGINX 이미지는 access 로그와 error 로그를 Docker 로그 수집기로 전송하도록 설정되어 있습니다. 이는 stdout와  stderr에 연결되어 동작합니다. 두 로그의 모든 메시지는 Docker 호스트의 /var/lib/docker/containers/container-ID/container-ID-json.log 파일에 기록됩니다. The container‑ID는 컨테이너를 생성할때의 긴 형식의 ID입니다. 긴 형식의 ID를 출력하려면 다음 명령어를 사용합니다.

$ docker inspect --format '{{ .Id }}' container-name

로그 메세지 추출을 위해 Docker 커맨드 라인과 Docker Engine API를 모두 사용할 수 있습니다.

커맨드 라인으로부터 로그 메시지를 출력하려면 다음 명령어를 사용합니다:

$ docker logs container-name

Docker Remote API를 사용하여 로그 메시지를 출력하려면 Docker Unix sock를 사용하여 GET 요청을 전송합니다:

$ curl --unix-sock /var/run/docker-sock http://localhost/containers/container-name/logs?stdout=1&stderr=1

access 로그 메세지만을 출력하려면 stdout=1만 사용합니다. error 로그 메세지만을 출력하려면 stderr=1만 사용합니다. 다른 유효한 옵션은 Docker Engine API 문서의 Get container logs 섹션에서 확인하세요.

6-2. 커스텀 로깅 사용

특정 설정 블록(server {}와 location {}과 같은)에 대해 로깅을 다르게 구성하려면, 컨테이너에 로그 파일을 저장할 디렉토리에 대한 Docker 볼륨을 정의하고, 로그 파일에 엑세스하기 위한 헬퍼 컨테이너를 생성한 후, 로깅 도구를 사용합니다. 이를 구현하려면 볼륨 혹은 로깅 파일에 대한 볼륨을 포함하는 새 이미지를 만듭니다.

예를 들어, NGINX가 로그 파일을 /var/log/nginx/log에 저장하도록 설정하려면 해당 디렉토리에 대한 VOLUME  정의를 Dockerfile에 추가합니다. (컨텐츠 및 구성 파일이 컨테이너에서 관리 되는 경우 )

FROM nginx
COPY content /usr/share/nginx/html
COPY conf /etc/nginx
VOLUME /var/log/nginx/log

이후 이미지를 생성하고 해당 이미지를 통해 NGINX 컨테이너와 로깅 디렉토리에 접근 권한을 가진 헬퍼 컨테이너를 생성할 수 있습니다. 헬퍼 컨테이너에는 원하는 로깅 도구를 설치할 수 있습니다.

7. NGINX 제어

NGINX 컨테이너의 커맨드 라인에 직접적으로 접근할 수 없으므로, NGINX 명령어는 컨테이너에 직접적으로 전달될 수 없습니다. 대신, Docker kill 명령어를 통해 컨테이너에 신호를 전송할 수 있습니다.

NGINX 설정을 리로드 하기 위해 Docker에 HUP 신호를 전송합니다.

$ docker kill -s HUP container-name

NGINX를 재시작하기 위해 다음 명령어를 사용하여 컨테이너를 재시작합니다.

$ docker restart container-name

NGINX STORE를 통한 솔루션 도입 및 기술지원 무료 상담 신청

* indicates required