Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Renamed demo and added unprivileged docker image support #173

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ utilizing *fleet* and *etcd*.

* **mysql-galera-demo**: This demo uses NGINX Plus as a TCP load balancer for a MySQL Galera cluster consisting of two mysqld servers. It does round-robin load balancing between the 2 mysqld servers and also does active health checks using an xinetd script running on port 9200 inside each mysqld container.

* **nginx-agent-docker**: This demo helps building a docker image to deploy NGINX Plus and NGINX Agent for NGINX Management Suite, with optional support for NGINX App Protect WAF and NGINX Developer Portal for API Connectivity Manager
* **nginx-docker-builder**: This demo helps building a docker image to deploy NGINX Plus (privileged and unprivileged), NGINX App Protect WAF and NGINX Agent for NGINX Instance Manager and NGINX One Console

* **nginx-hello**: NGINX running as webserver in a docker container that serves a simple page containing the container's hostname, IP address and port

Expand Down
File renamed without changes.
75 changes: 75 additions & 0 deletions nginx-docker-builder/Dockerfile.plus.unprivileged
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
FROM debian:bullseye-slim

ARG NMS_URL
ARG NAP_WAF=false

ARG UID=101
ARG GID=101

# Initial packages setup
RUN apt-get -y update \
&& apt-get -y install apt-transport-https lsb-release ca-certificates wget gnupg2 curl debian-archive-keyring iproute2 \
&& mkdir -p /deployment /etc/ssl/nginx /etc/nms \
&& addgroup --system --gid $GID nginx \
&& adduser --system --disabled-login --ingroup nginx --no-create-home --home /nonexistent --gecos "nginx user" --shell /bin/false --uid $UID nginx \
&& wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/bin/yq \
&& chmod +x /usr/bin/yq

# Use certificate and key from kubernetes secret
RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \
--mount=type=secret,id=nginx-key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \
set -x \
# Install prerequisite packages:
&& wget -qO - https://cs.nginx.com/static/keys/nginx_signing.key | gpg --dearmor > /usr/share/keyrings/nginx-archive-keyring.gpg \
&& printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/plus/debian `lsb_release -cs` nginx-plus\n" > /etc/apt/sources.list.d/nginx-plus.list \
&& wget -P /etc/apt/apt.conf.d https://cs.nginx.com/static/files/90pkgs-nginx \
&& apt-get -y update \
&& apt-get -y install nginx-plus nginx-plus-module-njs nginx-plus-module-prometheus \
# Optional NGINX App Protect WAF
&& if [ "$NAP_WAF" = "true" ] ; then \
wget -qO - https://cs.nginx.com/static/keys/app-protect-security-updates.key | gpg --dearmor > /usr/share/keyrings/app-protect-security-updates.gpg \
&& printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/app-protect/debian `lsb_release -cs` nginx-plus\n" > /etc/apt/sources.list.d/nginx-app-protect.list \
&& printf "deb [signed-by=/usr/share/keyrings/app-protect-security-updates.gpg] https://pkgs.nginx.com/app-protect-security-updates/debian `lsb_release -cs` nginx-plus\n" >> /etc/apt/sources.list.d/nginx-app-protect.list \
&& apt-get -y update \
&& apt-get -y install app-protect app-protect-attack-signatures; fi \
# 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 \
# User and group
&& groupadd -g 1001 nginx-agent \
&& usermod root -G nginx-agent \
&& usermod nginx -G nginx-agent \
# NGINX Instance Manager agent installation
&& if [ `curl -o /dev/null -sk -w "%{http_code}\n" $NMS_URL/install/nginx-agent` = 200 ] ; then \
bash -c 'export DATA_PLANE_KEY="placeholder" && curl -k $NMS_URL/install/nginx-agent | sh' && echo "NGINX Agent installed"; else \
fabriziofiorucci marked this conversation as resolved.
Show resolved Hide resolved
bash -c 'export DATA_PLANE_KEY="placeholder" && curl -k $NMS_URL/nginx-agent/install | sh || :' && echo "NGINX Agent installed"; fi

# implement changes required to run NGINX as an unprivileged user
RUN rm /etc/nginx/conf.d/default.conf \
&& sed -i '/user nginx;/d' /etc/nginx/nginx.conf \
&& sed -i 's,/var/run/nginx.pid,/tmp/nginx.pid,' /etc/nginx/nginx.conf \
&& sed -i "/^http {/a \ proxy_temp_path /tmp/proxy_temp;\n client_body_temp_path /tmp/client_temp;\n fastcgi_temp_path /tmp/fastcgi_temp;\n uwsgi_temp_path /tmp/uwsgi_temp;\n scgi_temp_path /tmp/scgi_temp;\n" /etc/nginx/nginx.conf \
# nginx user must own the cache and etc directory to write cache and tweak the nginx config
&& chown -R $UID:0 /var/cache/nginx \
&& chmod -R g+w /var/cache/nginx \
&& chown -R $UID:0 /etc/nginx \
&& chmod -R g+w /etc/nginx \
&& chown -R $UID:0 /usr/lib/nginx/modules \
&& chmod -R g+w /usr/lib/nginx/modules \
&& chown -R $UID:0 /etc/nms \
&& chmod -R g+w /etc/nms \
&& chown -R $UID:0 /etc/nginx-agent \
&& chmod -R g+w /etc/nginx-agent \
&& chown -R $UID:0 /var/lib/nginx-agent \
&& chmod -R g+w /var/lib/nginx-agent

# Startup script
COPY ./container/start.sh /deployment/
RUN chmod +x /deployment/start.sh && touch /.dockerenv

EXPOSE 80
STOPSIGNAL SIGTERM

USER $UID

CMD ["/deployment/start.sh"]
35 changes: 24 additions & 11 deletions nginx-agent-docker/README.md → nginx-docker-builder/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
# NGINX Plus and NGINX Agent - Docker image builder
# NGINX Docker image builder

## Description

This repository can be used to build a docker image with NGINX (Plus or Opensource) and NGINX Instance Manager Agent (https://docs.nginx.com/nginx-instance-manager/).
This repository can be used to build a docker image that includes:

- [NGINX Plus](https://docs.nginx.com/nginx) in privileged or unprivileged/non-root mode
- [NGINX Open Source](https://nginx.org/)
- [NGINX App Protect WAF](https://docs.nginx.com/nginx-app-protect-waf)
- [NGINX Agent](https://docs.nginx.com/nginx-agent)

It is also available as part of [official NGINX Demos](https://github.com/nginxinc/NGINX-Demos/tree/master/nginx-agent-docker)

## Tested releases

This repository has been tested with: NGINX agent for:
This repository has been tested with:

- NGINX Plus R29+
- NGINX Opensource 1.24.0+
Expand All @@ -19,19 +26,19 @@ This repository has been tested with: NGINX agent for:

- Linux host running Docker to build the image
- NGINX Plus license
- One of
- Access to either control plane:
- [NGINX Instance Manager](https://docs.nginx.com/nginx-instance-manager/)
- [NGINX One Cloud Console](https://docs.nginx.com/nginx-one/)
- Openshift/Kubernetes cluster
fabriziofiorucci marked this conversation as resolved.
Show resolved Hide resolved
- Docker/Docker-compose or Openshift/Kubernetes cluster

## Building the docker image

The install script can be used to build the Docker image:

```
NGINX Opensource/Plus & NGINX Agent Docker image builder
NGINX Plus & NGINX Instance Manager agent Docker image builder

fabriziofiorucci marked this conversation as resolved.
Show resolved Hide resolved
This tool builds a Docker image to run NGINX Opensource/Plus and NGINX Agent
This tool builds a Docker image to run NGINX Plus and NGINX Instance Manager agent

=== Usage:

Expand All @@ -43,9 +50,10 @@ NGINX Opensource/Plus & NGINX Agent Docker image builder
-t [target image] - The Docker image to be created
-C [file.crt] - Certificate to pull packages from the official NGINX repository
-K [file.key] - Key to pull packages from the official NGINX repository
-n [URL] - NGINX Instance Manager / NGINX SaaS console URL to fetch the agent
-n [URL] - NGINX Instance Manager URL to fetch the agent
-w - Add NGINX App Protect WAF (requires NGINX Plus)
-O - Use NGINX Opensource instead of NGINX Plus
-u - Build unprivileged image (only for NGINX Plus)

=== Examples:

Expand All @@ -55,6 +63,9 @@ NGINX Opensource/Plus & NGINX Agent Docker image builder
NGINX Plus, NGINX App Protect WAF and NGINX Agent image:
./scripts/build.sh -C nginx-repo.crt -K nginx-repo.key -t registry.ff.lan:31005/nginx-with-agent:latest-nap -w -n https://nim.f5.ff.lan

NGINX Plus, NGINX App Protect WAF and NGINX Agent unprivileged image:
./scripts/build.sh -C nginx-repo.crt -K nginx-repo.key -t registry.ff.lan:31005/nginx-with-agent:latest-nap -w -n https://nim.f5.ff.lan -u

NGINX Opensource and NGINX Agent image:
./scripts/build.sh -O -t registry.ff.lan:31005/nginx-oss-with-agent:latest -n https://nim.f5.ff.lan
```
Expand All @@ -69,6 +80,7 @@ the build script will push the image to your private registry once build is comp
### Running the docker image on Kubernetes

1. Edit `manifests/1.nginx-nim.yaml` and specify the correct image by modifying the `image:` line, and set the following environment variables. Default values for `NIM_HOST` and `NIM_GRPC_PORT` can be used if NGINX Instance Manager is deployed using https://github.com/nginxinc/NGINX-Demos/tree/master/nginx-nms-docker
- `NGINX_LICENSE` - NGINX R33+ JWT license token
- `NIM_HOST` - NGINX Instance Manager hostname/IP address
- `NIM_GRPC_PORT` - NGINX Instance Manager gRPC port
- `NIM_TOKEN` - NGINX One Cloud Console authentication token
Expand All @@ -86,15 +98,16 @@ $ ./scripts/nginxWithAgentStart.sh start
$ ./scripts/nginxWithAgentStart.sh stop
```

3. After startup NGINX instances will register to NGINX Instance Manager / NGINX SaaS console and will be displayed on the "instances" dashboard
3. After startup NGINX instances will register to NGINX Instance Manager / NGINX One console and will be displayed on the "instances" dashboard

### Running the docker image on Docker

1. Start using

```
docker run --rm --name nginx -p [PORT_TO_EXPOSE] \
-e "NIM_HOST=<NGINX_INSTANCE_MANAGER_FQDN_OR_IP>" \
-e "NGINX_LICENSE=<NGINX_JWT_LICENSE_TOKEN>" \
-e "NIM_HOST=<NGINX_CONTROL_PLANE_FQDN_OR_IP>" \
-e "NIM_GRPC_PORT=<GRPC_PORT>" \
fabriziofiorucci marked this conversation as resolved.
Show resolved Hide resolved
-e "NIM_TOKEN=<OPTIONAL_AUTHENTICATION_TOKEN>" \
-e "NIM_INSTANCEGROUP=<OPTIONAL_INSTANCE_GROUP_NAME>" \
Expand All @@ -106,4 +119,4 @@ docker run --rm --name nginx -p [PORT_TO_EXPOSE] \
<NGINX_DOCKER_IMAGE_NAME:TAG>
```

2. After startup NGINX Plus instances will register to NGINX Instance Manager and will be displayed on the "instances" dashboard
2. After startup NGINX Plus instances will register to NGINX Instance Manager / NGINX One Console and will be displayed on the "instances" dashboard
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
#!/bin/bash

if [[ `whoami` == "nginx" ]]; then
IS_UNPRIVILEGED="true"
else
IS_UNPRIVILEGED=
fi

if [[ ! -z "$NGINX_LICENSE" ]]; then
echo ${NGINX_LICENSE} > /etc/nginx/license.jwt
fi

nginx
sleep 2

Expand Down Expand Up @@ -61,8 +71,13 @@ if [[ "$NAP_WAF" == "true" ]]; then
.extensions += ["nginx-app-protect","nap-monitoring"]
' /etc/nginx-agent/nginx-agent.conf

su - nginx -s /bin/bash -c "/opt/app_protect/bin/bd_agent &"
su - nginx -s /bin/bash -c "/usr/share/ts/bin/bd-socket-plugin tmm_count 4 proc_cpuinfo_cpu_mhz 2000000 total_xml_memory 471859200 total_umu_max_size 3129344 sys_max_account_id 1024 no_static_config &"
if [[ "$IS_UNPRIVILEGED" ]]; then
/opt/app_protect/bin/bd_agent &
/usr/share/ts/bin/bd-socket-plugin tmm_count 4 proc_cpuinfo_cpu_mhz 2000000 total_xml_memory 471859200 total_umu_max_size 3129344 sys_max_account_id 1024 no_static_config &
else
su - nginx -s /bin/bash -c "/opt/app_protect/bin/bd_agent &"
su - nginx -s /bin/bash -c "/usr/share/ts/bin/bd-socket-plugin tmm_count 4 proc_cpuinfo_cpu_mhz 2000000 total_xml_memory 471859200 total_umu_max_size 3129344 sys_max_account_id 1024 no_static_config &"
fi

while ([ ! -e /opt/app_protect/pipe/app_protect_plugin_socket ] || [ ! -e /opt/app_protect/pipe/ts_agent_pipe ])
do
Expand All @@ -79,4 +94,8 @@ fi

fi

sg nginx-agent "/usr/bin/nginx-agent $PARM"
if [[ "$IS_UNPRIVILEGED" ]]; then
/usr/bin/nginx-agent $PARM
else
sg nginx-agent "/usr/bin/nginx-agent $PARM"
fi
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ spec:
- name: http
containerPort: 80
env:
- name: NGINX_LICENSE
# NGINX Plus R33+ JWT license token
value: "NGINX_JWT_LICENSE_TOKEN"
- name: NIM_HOST
# NGINX Instance Manager hostname or IP address
value: "nginx-nim2.nginx-nim2"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,33 @@

# https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-docker/#docker_plus

BANNER="NGINX Opensource/Plus & NGINX Agent Docker image builder\n\n
This tool builds a Docker image to run NGINX Opensource/Plus and NGINX Agent\n\n
BANNER="NGINX Plus & NGINX Instance Manager agent Docker image builder\n\n
This tool builds a Docker image to run NGINX Plus and NGINX Instance Manager agent\n\n
=== Usage:\n\n
$0 [options]\n\n
=== Options:\n\n
-h\t\t\t- This help\n
-t [target image]\t- The Docker image to be created\n
-C [file.crt]\t\t- Certificate to pull packages from the official NGINX repository\n
-K [file.key]\t\t- Key to pull packages from the official NGINX repository\n
-n [URL]\t\t- NGINX Instance Manager / NGINX SaaS console URL to fetch the agent\n
-n [URL]\t\t- NGINX Instance Manager URL to fetch the agent\n
-w\t\t\t- Add NGINX App Protect WAF (requires NGINX Plus)\n
-O\t\t\t- Use NGINX Opensource instead of NGINX Plus\n\n
-O\t\t\t- Use NGINX Opensource instead of NGINX Plus\n
-u\t\t\t- Build unprivileged image (only for NGINX Plus)\n\n
=== Examples:\n\n
NGINX Plus and NGINX Agent image:\n
$0 -C nginx-repo.crt -K nginx-repo.key -t registry.ff.lan:31005/nginx-with-agent:latest -n https://nim.f5.ff.lan\n\n

NGINX Plus, NGINX App Protect WAF and NGINX Agent image:\n
$0 -C nginx-repo.crt -K nginx-repo.key -t registry.ff.lan:31005/nginx-with-agent:latest-nap -w -n https://nim.f5.ff.lan\n\n

NGINX Plus, NGINX App Protect WAF and NGINX Agent unprivileged image:\n
$0 -C nginx-repo.crt -K nginx-repo.key -t registry.ff.lan:31005/nginx-with-agent:latest-nap -w -n https://nim.f5.ff.lan -u\n\n

NGINX Opensource and NGINX Agent image:\n
$0 -O -t registry.ff.lan:31005/nginx-oss-with-agent:latest -n https://nim.f5.ff.lan\n"

while getopts 'ht:C:K:a:n:wO' OPTION
while getopts 'ht:C:K:a:n:wOu' OPTION
do
case "$OPTION" in
h)
Expand All @@ -47,6 +53,9 @@ do
O)
NGINX_OSS=true
;;
u)
UNPRIVILEGED=true
;;
esac
done

Expand All @@ -64,7 +73,7 @@ fi

if [ -z "${NMSURL}" ]
then
echo "NGINX Instance Manager / NGINX SaaS console URL is required"
echo "NGINX Instance Manager URL is required"
exit
fi

Expand All @@ -83,10 +92,21 @@ fi

if [ -z "${NGINX_OSS}" ]
then
DOCKER_BUILDKIT=1 docker build --no-cache -f Dockerfile.plus \
if [ -z "${UNPRIVILEGED}" ]
then
DOCKERFILE_NAME=Dockerfile.plus
echo "=> Building with NGINX Plus"
else
DOCKERFILE_NAME=Dockerfile.plus.unprivileged
echo "=> Building with NGINX Plus unprivileged"
fi

DOCKER_BUILDKIT=1 docker build --no-cache -f $DOCKERFILE_NAME \
--secret id=nginx-key,src=$NGINX_KEY --secret id=nginx-crt,src=$NGINX_CERT \
--build-arg NMS_URL=$NMSURL --build-arg NAP_WAF=$NAP_WAF -t $IMAGENAME .
--build-arg NMS_URL=$NMSURL --build-arg NAP_WAF=$NAP_WAF \
-t $IMAGENAME .
else
echo "=> Building with NGINX Open Source"
DOCKER_BUILDKIT=1 docker build --no-cache -f Dockerfile.oss \
--build-arg NMS_URL=$NMSURL -t $IMAGENAME .
fi
Expand Down
Loading