Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
156 changes: 146 additions & 10 deletions content/nginx-one/workshops/lab2.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,151 @@
---
# We use sentence case and present imperative tone
title: "Lab2"
# Weights are assigned in increments of 100: determines sorting order
title: "Run workshop components with Docker"
weight: 200
# Creates a table of contents and sidebar, useful for large documents
toc: false
# Types have a 1:1 relationship with Hugo archetypes, so you shouldn't need to change this
toc: true
nd-content-type: tutorial
# Intended for internal catalogue and search, case sensitive:
# Agent, N4Azure, NIC, NIM, NGF, NAP-DOS, NAP-WAF, NGINX One, NGINX+, Solutions, Unit
nd-product: NGINX-ONE
nd-product: nginx-one
---

blah
## Introduction

This guide shows you how to run a demo backend application and multiple NGINX OSS and Plus containers with Docker. The backend application runs in three `nginxinc/ingress-demo` containers, each serving a simple web page. You’ll also link each NGINX container to NGINX One Console for management and monitoring.

## What you’ll learn

By the end of this tutorial, you’ll know how to:

- Set up environment variables for your data plane key and license
- Log in to the NGINX private registry
- Generate self-signed certificates
- Run Docker Compose to start 9 containers
- Verify your containers in Docker and in NGINX One Console

## Before you begin

Make sure you have:

- An F5 Distributed Cloud (XC) account
- NGINX One service enabled in your XC account
- Docker and Docker Compose installed and running
- An active data plane key from [Lab 1: Get started with NGINX One Console]({{< ref "nginx-one/workshops/lab1/lab1.md" >}})
- A trial or paid NGINX Plus JWT license (saved as `nginx-repo.jwt`) from [MyF5](https://my.f5.com/manage/s/).
- Basic Linux and NGINX know-how
- Git installed and SSH key set up for GitHub access

---

## Clone the NGINX documentation repo

1. **Clone the repo via SSH**

```shell
git clone [email protected]:nginx/documentation.git
```

2. **Change to the Lab 2 directory**

```shell
cd documentation/content/nginx-one/workshops/lab2
```

This folder contains `docker-compose.yml` and `generate_certs.sh`.

---

## Set environment variables

1. **Set your data plane key**

```shell
export TOKEN="paste-your-data-plane-key-here"
echo "$TOKEN"
```

2. **Set your NGINX Plus JWT**

```shell
export JWT=$(cat path/to/nginx-repo.jwt)
echo "$JWT"
```

3. **Give your setup a unique name**

Replace `your.initials` with something that identifies you or your setup (for example, `s.jobs`)

```shell
export NAME="your.initials"
echo "$NAME"
```

---

## Log in to the private registry

Pipe your JWT into Docker login:

```shell
echo "$JWT" | docker login private-registry.nginx.com \
--username "$JWT" --password-stdin
```

You should see **Login Succeeded**.

---

## Generate certificates

Run the script to create self-signed certs:

```shell
chmod +x generate_certs.sh
./generate_certs.sh
```

This creates `1-day.key`, `1-day.crt`, `30-day.key`, and `30-day.crt` in the `nginx-oss/etc/ssl/nginx` subfolder.

---

## Run Docker Compose

Start all nine containers in detached mode:

```shell
docker compose up --force-recreate -d
```

Wait until you see "Started" for each container.

---

## Verify containers

1. **Check Docker**

```shell
docker ps | grep "$NAME"
```

You should see 9 containers listed.

2. **Check NGINX One Console**

- Go to the **Instances** page in the NGINX One Console
- Refresh and search by your `$NAME` (for example, `s.jobs`)
- Confirm each instance shows a green **Online* icon.

If you don’t see them, double-check your `$TOKEN` or generate a new data plane key.

---

## Next steps

Now that your containers are up and registered, go on to explore NGINX One Console features in Lab 3.

[Go to Lab 3 →](../lab3/readme.md)

---

## References

- [NGINX One Console docs](https://docs.nginx.com/nginx-one/)
- [NGINX Agent overview](https://docs.nginx.com/nginx-agent/overview/)
164 changes: 164 additions & 0 deletions content/nginx-one/workshops/lab2/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
# NGINX Plus / OSS with NGINX Agent
# NGINX webservers with ingress-demo pages
# NGINX One Console Instance Registration
# NGINX Basics, Dec 2024
# Chris Akker, Shouvik Dutta, Adam Currier
#
services:
plus1: # Alpine NGINX Plus Web / Load Balancer
environment:
NGINX_AGENT_SERVER_HOST: 'agent.connect.nginx.com'
NGINX_AGENT_SERVER_GRPCPORT: '443'
NGINX_AGENT_TLS_ENABLE: 'true'
NGINX_AGENT_SERVER_TOKEN: $TOKEN # Datakey From One Console
# NGINX_AGENT_INSTANCE_GROUP: $NAME-sync-group
hostname: $NAME-plus1
container_name: $NAME-plus1
image: private-registry.nginx.com/nginx-plus/agent:nginx-plus-r32-alpine-3.20-20240613 # CVE - From Nginx Private Registry
volumes: # Sync these folders to container
- ./nginx-plus/etc/nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx-plus/etc/nginx/conf.d:/etc/nginx/conf.d
- ./nginx-plus/etc/nginx/includes:/etc/nginx/includes
- ./nginx-plus/usr/share/nginx/html:/usr/share/nginx/html
ports:
- 80:80 # Open for HTTP
- 443:443 # Open for HTTPS
- 9000:9000 # Open for stub status page
- 9113:9113 # Open for Prometheus Scraper page
restart: always
#
plus2: # Alpine NGINX Plus Web / Load Balancer
environment:
NGINX_AGENT_SERVER_HOST: 'agent.connect.nginx.com'
NGINX_AGENT_SERVER_GRPCPORT: '443'
NGINX_AGENT_TLS_ENABLE: 'true'
NGINX_AGENT_SERVER_TOKEN: $TOKEN # Datakey Fron Nginx One Console
# NGINX_AGENT_INSTANCE_GROUP: $NAME-sync-group
hostname: $NAME-plus2
container_name: $NAME-plus2
image: private-registry.nginx.com/nginx-plus/agent:nginx-plus-r31-alpine-3.19-20240522 # CVE - From Nginx Private Registry
volumes: # Sync these folders to container
- ./nginx-plus/etc/nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx-plus/etc/nginx/conf.d:/etc/nginx/conf.d
- ./nginx-plus/etc/nginx/includes:/etc/nginx/includes
- ./nginx-plus/usr/share/nginx/html:/usr/share/nginx/html
ports:
- '80' # Open for HTTP
- '443' # Open for HTTPS
- '9000' # Open for API / Dashboard page
- '9113' # Open for Prometheus Scraper page
restart: always
#
plus3: # RHEL UBI NGINX Plus Web / Load Balancer
environment:
NGINX_AGENT_SERVER_HOST: 'agent.connect.nginx.com'
NGINX_AGENT_SERVER_GRPCPORT: '443'
NGINX_AGENT_TLS_ENABLE: 'true'
NGINX_AGENT_SERVER_TOKEN: $TOKEN # Datakey Fron Nginx One Console
# NGINX_AGENT_INSTANCE_GROUP: $NAME-sync-group
hostname: $NAME-plus3
container_name: $NAME-plus3
image: private-registry.nginx.com/nginx-plus/agent:nginx-plus-r31-ubi-9-20240522 # From Nginx Private Registry
volumes: # Sync these folders to container
- ./nginx-plus/etc/nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx-plus/etc/nginx/conf.d:/etc/nginx/conf.d
- ./nginx-plus/etc/nginx/includes:/etc/nginx/includes
- ./nginx-plus/usr/share/nginx/html:/usr/share/nginx/html
ports:
- '80' # Open for HTTP
- '443' # Open for HTTPS
- '9000' # Open for API / Dashboard page
- '9113' # Open for Prometheus Scraper page
restart: always
#
oss1: # Debian NGINX OSS Web / Load Balancer
environment:
NGINX_AGENT_SERVER_HOST: 'agent.connect.nginx.com'
NGINX_AGENT_SERVER_GRPCPORT: '443'
NGINX_AGENT_TLS_ENABLE: 'true'
NGINX_AGENT_SERVER_TOKEN: $TOKEN # Datakey Fron Nginx One Console
hostname: $NAME-oss1
container_name: $NAME-oss1
image: docker-registry.nginx.com/nginx/agent:mainline # From Docker Public Registry
volumes: # Sync these folders to container
- ./nginx-oss/etc/nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx-oss/etc/nginx/conf.d:/etc/nginx/conf.d
- ./nginx-oss/etc/nginx/includes:/etc/nginx/includes
- ./nginx-oss/etc/ssl/nginx:/etc/ssl/nginx
- ./nginx-oss/usr/share/nginx/html:/usr/share/nginx/html
ports:
- '80' # Open for HTTP
- '443' # Open for HTTPS
- '9000' # Open for stub status page
- '9113' # Open for Prometheus Scraper page
restart: always
#
oss2: # Alpine NGINX OSS Web / Load Balancer
environment:
NGINX_AGENT_SERVER_HOST: 'agent.connect.nginx.com'
NGINX_AGENT_SERVER_GRPCPORT: '443'
NGINX_AGENT_TLS_ENABLE: 'true'
NGINX_AGENT_SERVER_TOKEN: $TOKEN # Datakey Fron Nginx One Console
hostname: $NAME-oss2
container_name: $NAME-oss2
image: docker-registry.nginx.com/nginx/agent:alpine # From Docker Public Registry
volumes: # Sync these folders to container
- ./nginx-oss/etc/nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx-oss/etc/nginx/conf.d:/etc/nginx/conf.d
- ./nginx-oss/etc/nginx/includes:/etc/nginx/includes
- ./nginx-oss/etc/ssl/nginx:/etc/ssl/nginx
- ./nginx-oss/usr/share/nginx/html:/usr/share/nginx/html
ports:
- '80' # Open for HTTP
- '443' # Open for HTTPS
- '9000' # Open for stub status page
- '9113' # Open for Prometheus Scraper page
restart: always
#
oss3: # Older Alpine NGINX OSS Web / Load Balancer
environment:
NGINX_AGENT_SERVER_HOST: 'agent.connect.nginx.com'
NGINX_AGENT_SERVER_GRPCPORT: '443'
NGINX_AGENT_TLS_ENABLE: 'true'
NGINX_AGENT_SERVER_TOKEN: $TOKEN # Datakey Fron Nginx One Console
hostname: $NAME-oss3
container_name: $NAME-oss3
image: docker-registry.nginx.com/nginx/agent:1.26-alpine # From Docker Public Registry
volumes: # Sync these folders to container
- ./nginx-oss/etc/nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx-oss/etc/nginx/conf.d:/etc/nginx/conf.d
- ./nginx-oss/etc/nginx/includes:/etc/nginx/includes
- ./nginx-oss/etc/ssl/nginx:/etc/ssl/nginx
- ./nginx-oss/usr/share/nginx/html:/usr/share/nginx/html
ports:
- '80' # Open for HTTP
- '443' # Open for HTTPS
- '9000' # Open for stub status page
- '9113' # Open for Prometheus Scraper page
restart: always
#
web1:
hostname: $NAME-web1
container_name: $NAME-web1
platform: linux/amd64
image: nginxinc/ingress-demo # Image from Docker Hub
ports:
- '80' # Open for HTTP
- '443' # Open for HTTPS
web2:
hostname: $NAME-web2
container_name: $NAME-web2
platform: linux/amd64
image: nginxinc/ingress-demo
ports:
- '80'
- '433'
web3:
hostname: $NAME-web3
container_name: $NAME-web3
platform: linux/amd64
image: nginxinc/ingress-demo
ports:
- '80'
- '443'

7 changes: 7 additions & 0 deletions content/nginx-one/workshops/lab2/generate_certs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
echo "Generate 1-day cert."
openssl req -x509 -nodes -days 1 -newkey rsa:2048 -keyout nginx-oss/etc/ssl/nginx/1-day.key -out nginx-oss/etc/ssl/nginx/1-day.crt -subj "/CN=$NAME-NginxOneWorkshop"
echo "Generate 30-day cert."
openssl req -x509 -nodes -days 30 -newkey rsa:2048 -keyout nginx-oss/etc/ssl/nginx/30-day.key -out nginx-oss/etc/ssl/nginx/30-day.crt -subj "/CN=$NAME-NginxOneWorkshop"
echo "copy certs to lab5 for future labs"
cp nginx-oss/etc/ssl/nginx/1-day.* ../lab5/nginx-oss/etc/ssl/nginx/
cp nginx-oss/etc/ssl/nginx/30-day.* ../lab5/nginx-oss/etc/ssl/nginx/
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# cafe.example.com HTTP
server {
# Listening on port 80 on all IP addresses on this machine
listen 80;

server_name cafe.example.com;

# status_zone cafe-VirtualServer;

# Server specific logging
access_log /var/log/nginx/cafe.example.com.log main_ext;
error_log /var/log/nginx/cafe.example.com_error.log info;

location / {

proxy_buffering off;

# Including best-practice headers are bonus points
include includes/proxy_headers.conf;
include includes/keepalive.conf;

# status_zone /;

proxy_pass http://nginx_cafe;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# ngx_http_stub_status_module (Available in NGINX OSS)
# provides Basic Status information http://nginx.org/en/docs/http/ngx_http_stub_status_module.html

server {
listen 9000 ssl; # Listener for Stub Status

ssl_certificate /etc/ssl/nginx/30-day.crt;
ssl_certificate_key /etc/ssl/nginx/30-day.key;

location /basic_status {
stub_status;
}

# Redirect requests for "/" to "/basic_status"
location / {
return 301 /basic_status;
}

}
Loading
Loading