Deploying NGINX and NGINX Plus with Docker (original) (raw)

  1. Home
  2. F5 NGINX Plus
  3. Admin Guide
  4. Installing NGINX and NGINX Plus Deploying NGINX and NGINX Plus with Docker

F5 NGINX Plus, the high‑performance application delivery platform, load balancer, and web server, is available as the Docker container.

Use official NGINX Plus Docker images

Since NGINX Plus NGINX Plus Release 31 you can get an NGINX Plus image from the official NGINX Plus Docker registry and upload it to your private registry.

The NGINX Plus Docker registry is available at https://private-registry.nginx.com/v2/.

The registry contains the following image types:

The images can be targeted for a particular operating system and NGINX Plus release using tags.

Tags for operating systems

Operating system Basic OS tag Tag examples
Alpine (x86_64, aarch64) alpine r33-alpine, r33-alpine-3.20
Debian (x86_64, aarch64) debian r33-debian, r33-debian-bookworm
Red Hat Enterprise Linux (x86_64, aarch64) ubi r33-ubi, r33-ubi-9, r33-ubi-9-20240624
Operating system Basic OS tag Tag examples
Alpine (x86_64, aarch64) alpine r33-alpine, r33-alpine-3.20
Debian (x86_64, aarch64) debian r33-debian, r33-debian-bookworm
Red Hat Enterprise Linux (x86_64, aarch64) ubi r33-ubi, r33-ubi-9, r33-ubi-9-20240624

Tags for NGINX Plus versions

The NGINX Plus registry contains images for the two most recent versions of NGINX Plus. The basic operating system tag returns the latest version of NGINX Plus built for the latest version of this operating system.

Example: nginx-plus-r33-ubi-9, nginx-plus-r32-alpine-3.19.

nginx-plus-r33-ubi-9, nginx-plus-r32-alpine-3.19.

The image may contain a particular version of NGINX Plus or contain a bundle of NGINX Plus and NGINX Agent, and can be targeted for a specific architecture.

For a complete tag list for NGINX Plus bundled with NGINX Agent images, use the command:

curl https://private-registry.nginx.com/v2/nginx-plus/<nginxplus-image-type>/tags/list --key <nginx-repo.key> --cert <nginx-repo.crt> | jq
curl https://private-registry.nginx.com/v2/nginx-plus/<nginxplus-image-type>/tags/list --key <nginx-repo.key> --cert <nginx-repo.crt> | jq

where:

Download the JSON Web Token or NGINX Plus certificate and key

Before you get a container image, you should provide the JSON Web Token file or SSL certificate and private key files provided with your NGINX Plus subscription. These files grant access to the package repository from which the script will download the NGINX Plus package:

  1. Log in to MyF5.

  2. Go to My Products & Plans > Subscriptions to see your active subscriptions.

  3. Find your NGINX products or services subscription, and select the Subscription ID for details.

  4. Download the JSON Web Token from the subscription page.

  5. Log in to the MyF5 customer portal.

  6. Go to My Products and Plans > Subscriptions.

  7. Select the product subscription.

  8. Download the SSL Certificate and Private Key files.

Set up Docker for NGINX Plus container registry

Set up Docker to communicate with the NGINX Container Registry located at private-registry.nginx.com.

Open the JSON Web Token file previously downloaded from MyF5 customer portal (for example, nginx-repo-12345abc.jwt) and copy its contents.

Log in to the docker registry using the contents of the JSON Web Token file:

docker login private-registry.nginx.com --username=<output_of_jwt_token> --password=none
docker login private-registry.nginx.com --username=<output_of_jwt_token> --password=none

Create a directory and copy your certificate and key to this directory:

shell

mkdir -p /etc/docker/certs.d/private-registry.nginx.com
cp <path-to-your-nginx-repo.crt> /etc/docker/certs.d/private-registry.nginx.com/client.cert
cp <path-to-your-nginx-repo.key> /etc/docker/certs.d/private-registry.nginx.com/client.key
mkdir -p /etc/docker/certs.d/private-registry.nginx.com
cp <path-to-your-nginx-repo.crt> /etc/docker/certs.d/private-registry.nginx.com/client.cert
cp <path-to-your-nginx-repo.key> /etc/docker/certs.d/private-registry.nginx.com/client.key

The steps provided are for Linux. For Mac or Windows, see the Docker for Mac or Docker for Windows documentation. For more details on Docker Engine security, you can refer to the Docker Engine Security documentation.

Log in to the docker registry:

docker login private-registry.nginx.com
docker login private-registry.nginx.com

Next, pull the image you need from private-registry.nginx.com.

To pull an image, replace <version-tag> with the specific NGINX Plus version or the NGINX Plus version and OS version you need.

For NGINX Plus, run:

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

For NGINX Plus with NGINX Agent, run:

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

For NGINX Plus installed from nginx user (rootless installation), run:

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

For NGINX Plus with NGINX Agent installed from nginx user (rootless installation), run:

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

For NGINX modules, run:

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

Protect sensitive data

To protect your system and data, follow these security practices:

  1. JWTs: Treat JSON Web Tokens (JWTs) as sensitive data. Store them securely and delete them after use to prevent unauthorized access.
  2. Shell history: Commands with JWTs or passwords are saved in plain text in your shell history. After running such commands, clear the history to protect credentials. For example:

To protect your system and data, follow these security practices:

  1. JWTs: Treat JSON Web Tokens (JWTs) as sensitive data. Store them securely and delete them after use to prevent unauthorized access.
  2. Shell history: Commands with JWTs or passwords are saved in plain text in your shell history. After running such commands, clear the history to protect credentials. For example:

Push the image to your private registry

After pulling the image, tag it and upload it to your private registry.

Note: Never upload your NGINX Plus images to a public repository such as Docker Hub. Doing so violates your license agreement.

Log in to your private registry:

docker login <my-docker-registry>
docker login <my-docker-registry>

Tag and push the image. Replace <my-docker-registry> with your registry’s path and <version-tag> with the your NGINX Plus version and/or OS version:

docker tag private-registry.nginx.com/nginx-plus/base:<version-tag> <my-docker-registry>/nginx-plus/base:<version-tag>
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>
docker push <my-docker-registry>/nginx-plus/base:<version-tag>

Run the NGINX Plus container

Starting from NGINX Plus Release 33, the JWT file is required for each NGINX Plus instance. For more information, see About Subscription Licenses.

To start the Docker container with NGINX Plus, you will need to pass your JWT license file named license.jwt as the NGINX_LICENSE_JWT environment variable. If the license file needs to be located in a non-default directory, specify its full path using the NGINX_LICENSE_PATH variable (default path: /etc/nginx/license.jwt).

To start the Docker container with NGINX Plus only:

sh

sudo docker run \
--env=NGINX_LICENSE_JWT=$(cat license.jwt) \
--restart=always \
--runtime=runc \
-d <YOUR_REGISTRY>/nginx-plus/base:<VERSION_TAG>
sudo docker run \
--env=NGINX_LICENSE_JWT=$(cat license.jwt) \
--restart=always \
--runtime=runc \
-d <YOUR_REGISTRY>/nginx-plus/base:<VERSION_TAG>

To start the Docker container with NGINX Plus and NGINX Agent, you will need to additionally pass the NGINX One data plane key as the NGINX_AGENT_SERVER_TOKEN environment variable. For more information, see Create and manage data plane keys:

sh

sudo docker run \
--env=NGINX_LICENSE_JWT=$(cat license.jwt) \
--env=NGINX_AGENT_SERVER_GRPCPORT=443 \
--env=NGINX_AGENT_SERVER_HOST=agent.connect.nginx.com \
--env=NGINX_AGENT_SERVER_TOKEN="YOUR_NGINX_ONE_DATA_PLANE_KEY" \
--env=NGINX_AGENT_TLS_ENABLE=true \
--restart=always \
--runtime=runc \
-d <YOUR_REGISTRY>/nginx-plus/agent:<VERSION_TAG>
sudo docker run \
--env=NGINX_LICENSE_JWT=$(cat license.jwt) \
--env=NGINX_AGENT_SERVER_GRPCPORT=443 \
--env=NGINX_AGENT_SERVER_HOST=agent.connect.nginx.com \
--env=NGINX_AGENT_SERVER_TOKEN="YOUR_NGINX_ONE_DATA_PLANE_KEY" \
--env=NGINX_AGENT_TLS_ENABLE=true \
--restart=always \
--runtime=runc \
-d <YOUR_REGISTRY>/nginx-plus/agent:<VERSION_TAG>

where:

Example:

To start the Docker Container with NGINX Plus and NGINX Agent on Debian or Ubuntu:

sh

sudo docker run \
--env=NGINX_LICENSE_JWT=$(cat license.jwt) \
--env=NGINX_AGENT_SERVER_GRPCPORT=443 \
--env=NGINX_AGENT_SERVER_HOST=agent.connect.nginx.com \
--env=NGINX_AGENT_SERVER_TOKEN="YOUR_NGINX_ONE_DATA_PLANE_KEY" \
--env=NGINX_AGENT_TLS_ENABLE=true \
--restart=always \
--runtime=runc \
-d private-registry.nginx.com/nginx-plus/agent:debian
sudo docker run \
--env=NGINX_LICENSE_JWT=$(cat license.jwt) \
--env=NGINX_AGENT_SERVER_GRPCPORT=443 \
--env=NGINX_AGENT_SERVER_HOST=agent.connect.nginx.com \
--env=NGINX_AGENT_SERVER_TOKEN="YOUR_NGINX_ONE_DATA_PLANE_KEY" \
--env=NGINX_AGENT_TLS_ENABLE=true \
--restart=always \
--runtime=runc \
-d private-registry.nginx.com/nginx-plus/agent:debian

To start the Docker Container with NGINX Plus and NGINX Agent on Debian or Ubuntu:

sh

sudo docker run \
--env=NGINX_LICENSE_JWT=$(cat license.jwt) \
--env=NGINX_AGENT_SERVER_GRPCPORT=443 \
--env=NGINX_AGENT_SERVER_HOST=agent.connect.nginx.com \
--env=NGINX_AGENT_SERVER_TOKEN="YOUR_NGINX_ONE_DATA_PLANE_KEY" \
--env=NGINX_AGENT_TLS_ENABLE=true \
--restart=always \
--runtime=runc \
-d private-registry.nginx.com/nginx-plus/agent:debian
sudo docker run \
--env=NGINX_LICENSE_JWT=$(cat license.jwt) \
--env=NGINX_AGENT_SERVER_GRPCPORT=443 \
--env=NGINX_AGENT_SERVER_HOST=agent.connect.nginx.com \
--env=NGINX_AGENT_SERVER_TOKEN="YOUR_NGINX_ONE_DATA_PLANE_KEY" \
--env=NGINX_AGENT_TLS_ENABLE=true \
--restart=always \
--runtime=runc \
-d private-registry.nginx.com/nginx-plus/agent:debian

Using NGINX Open Source Docker Images

You can create an NGINX instance in a Docker container using the NGINX Open Source image from the Docker Hub.

  1. Launch an instance of NGINX running in a container and using the default NGINX configuration with the following command:
docker run --name mynginx1 -p 80:80 -d nginx  
docker run --name mynginx1 -p 80:80 -d nginx  

where:

  1. Verify that the container was created and is running with the docker ps command:
    shell
$ 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  
$ 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  

This command also allows viewing the port mappings set in the previous step: the PORTS field in the output reports that port 80 on the Docker host is mapped to port 80 in the container.

Creating custom NGINX Plus Docker Image

As NGINX Plus is a commercial offering, NGINX Plus Docker images are not available at Docker Hub, so first you will need to create an NGINX Plus Docker image.

Note: Never upload your NGINX Plus images to a public repository such as Docker Hub. Doing so violates your license agreement.

To generate a custom NGINX Plus image:

  1. Create the Docker build context, or a Dockerfile, for example:
  2. As with NGINX Open Source, default NGINX Plus image has the same default settings:
    • access and error logs are linked to the Docker log collector
    • no volumes are specified: a Dockerfile can be used to create base images from which you can create new images with volumes specified, or volumes can be specified manually:
      dockerfile
VOLUME /usr/share/nginx/html  
VOLUME /etc/nginx  
VOLUME /usr/share/nginx/html  
VOLUME /etc/nginx  
  1. Log in to MyF5 Customer Portal and download your nginx-repo.crt and nginx-repo.key files. For a trial of NGINX Plus, the files are provided with your trial package.
  2. Copy the files to the directory where the Dockerfile is located.
  3. Create a Docker image, for example, nginxplus (note the final period in the command).
docker build  --no-cache --secret id=nginx-key,src=nginx-repo.key --secret id=nginx-crt,src=nginx-repo.crt -t nginxplus .  
docker build  --no-cache --secret id=nginx-key,src=nginx-repo.key --secret id=nginx-crt,src=nginx-repo.crt -t nginxplus .  

The --no-cache option tells Docker to build the image from scratch and ensures the installation of the latest version of NGINX Plus. If the Dockerfile was previously used to build an image without the --no-cache option, the new image uses the version of NGINX Plus from the previously built image from the Docker cache. 6. Verify that the nginxplus image was created successfully with the docker images command:
shell

$ docker images nginxplus  
REPOSITORY  TAG     IMAGE ID      CREATED        SIZE  
nginxplus   latest  ef2bf65931cf  6 seconds ago  91.2 MB  
$ docker images nginxplus  
REPOSITORY  TAG     IMAGE ID      CREATED        SIZE  
nginxplus   latest  ef2bf65931cf  6 seconds ago  91.2 MB  
  1. Create a container based on this image, for example, mynginxplus container:
docker run --name mynginxplus -p 80:80 -d nginxplus  
docker run --name mynginxplus -p 80:80 -d nginxplus  
  1. Verify that the mynginxplus container is up and running with the docker ps command:
    shell
$ 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  
$ 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  

NGINX Plus containers are controlled and managed in the same way as NGINX Open Source containers.

Managing Content and Configuration Files

Content served by NGINX and NGINX configuration files can be managed in several ways:

Maintaining Content and Configuration Files on the Docker Host

When the container is created, you can mount a local directory on the Docker host to a directory in the container. The NGINX image uses the default NGINX configuration, which uses /usr/share/nginx/html as the container’s root directory and puts configuration files in /etc/nginx. For a Docker host with content in the local directory /var/www and configuration files in /var/nginx/conf, run the command:

shell

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 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

Any change made to the files in the local directories /var/www and /var/nginx/conf on the Docker host are reflected in the directories /usr/share/nginx/html and /etc/nginx in the container. The readonly option means these directories can be changed only on the Docker host, not from within the container.

Copy content and configuration files from the Docker host

Docker can copy the content and configuration files from a local directory on the Docker host during container creation. Once a container is created, the files are maintained by creating a new container when files change or by modifying the files in the container.

A simple way to copy the files is to create a Dockerfile with commands that are run during generation of a new Docker image based on the NGINX image. For the file‑copy (COPY) commands in the Dockerfile, the local directory path is relative to the build context where the Dockerfile is located.

Let’s assume that the content directory is content and the directory for configuration files is conf, both subdirectories of the directory where the Dockerfile is located. The NGINX image has the default NGINX configuration files, including default.conf, in the /etc/nginx/conf.d directory. To use the configuration files from the Docker host only, delete the default files with the RUN command:

dockerfile

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

Create NGINX image by running the command from the directory where the Dockerfile is located. The period (“.”) at the end of the command defines the current directory as the build context, which contains the Dockerfile and the directories to be copied:

docker build -t mynginx_image1 .
docker build -t mynginx_image1 .

Create a container mynginx3 based on the mynginx_image1 image:

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

To make changes to the files in the container, use a helper container as described in the next section.

Maintain content and configuration files in the container

As SSH cannot be used to access the NGINX container, to edit the content or configuration files directly you need to create a helper container that has shell access. For the helper container to have access to the files, create a new image that has the proper Docker data volumes defined for the image:

  1. Copy nginx content and configuration files and define the volume for the image with the Dockerfile:
    dockerfile
FROM nginx  
COPY content /usr/share/nginx/html  
COPY conf /etc/nginx  
VOLUME /usr/share/nginx/html  
VOLUME /etc/nginx  
FROM nginx  
COPY content /usr/share/nginx/html  
COPY conf /etc/nginx  
VOLUME /usr/share/nginx/html  
VOLUME /etc/nginx  
  1. Create the new NGINX image by running the following command:
docker build -t mynginx_image2 .  
docker build -t mynginx_image2 .  
  1. Create an NGINX container mynginx4 based on the mynginx_image2 image:
docker run --name mynginx4 -p 80:80 -d mynginx_image2  
docker run --name mynginx4 -p 80:80 -d mynginx_image2  
  1. Start a helper container mynginx4_files that has a shell, providing access the content and configuration directories of the mynginx4 container we just created:
    shell
$ docker run -i -t --volumes-from mynginx4 --name mynginx4_files debian /bin/bash  
root@b1cbbad63dd1:/#  
$ docker run -i -t --volumes-from mynginx4 --name mynginx4_files debian /bin/bash  
root@b1cbbad63dd1:/#  

where:

To start and stop the container, run the commands:

shell

docker start mynginx4_files
docker stop mynginx4_files
docker start mynginx4_files
docker stop mynginx4_files

To exit the shell but leave the container running, press Ctrl+p followed by Ctrl+q. To regain shell access to a running container, run this command:

docker attach mynginx4_files
docker attach mynginx4_files

To exit the shell and terminate the container, run the exit command.

You can use default logging or customize logging.

By default, the NGINX image is configured to send NGINX access log and error log to the Docker log collector. This is done by linking them to stdout and stderr: all messages from both logs are then written to the file /var/lib/docker/containers/container-ID/container-ID-json.log on the Docker host. The container‑ID is the long‑form ID returned when you create a container. To display the long form ID, run the command:

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

You can use both the Docker command line and the Docker Engine API to extract the log messages.

To extract log messages from the command line, run the command:

docker logs container-name
docker logs container-name

To extract log messages using the Docker Remote API, send a GET request using the Docker Unix sock:

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

To include only access log messages in the output, include only stdout=1. To limit the output to error log messages, include only stderr=1. For other available options, see Get container logs section of the Docker Engine API documentation.

If you want to configure logging differently for certain configuration blocks (such as server {} and location {}), define a Docker volume for the directory in which to store the log files in the container, create a helper container to access the log files, and use any logging tools. To implement this, create a new image that contains the volume or volumes for the logging files.

For example, to configure NGINX to store log files in /var/log/nginx/log, add a VOLUME definition for this directory to the Dockerfile (provided that content and configuration Files are managed in the container):

dockerfile

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

Then you can create an image and use it to create an NGINX container and a helper container that have access to the logging directory. The helper container can have any desired logging tools installed.

Since there is no direct access to the command line of the NGINX container, NGINX commands cannot be sent to a container directly. Instead, signals can be sent to a container via Docker kill command.

To reload the NGINX configuration, send the HUP signal to Docker:

docker kill -s HUP container-name
docker kill -s HUP container-name

To restart NGINX, run this command to restart the container:

docker restart container-name
docker restart container-name