Skip to content
Merged
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
38 changes: 25 additions & 13 deletions content/includes/use-cases/monitoring/enable-nginx-plus-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,36 @@ files:
- content/nginx-one/getting-started.md
---
<!-- include in content/nginx-one/getting-started.md disabled, hopefully temporarily -->
To collect comprehensive metrics for NGINX Plus--including bytes streamed, information about upstream systems and caches, and counts of all HTTP status codes--add the following to your NGINX Plus configuration file (for example, `/etc/nginx/nginx.conf` or an included file):
To collect comprehensive metrics for NGINX Plus -- including bytes streamed, information about upstream systems and caches, and counts of all HTTP status codes -- add the following to your NGINX Plus configuration file (for example, `/etc/nginx/nginx.conf` or an included file):

```nginx
# Enable the /api/ location with appropriate access control
# to use the NGINX Plus API.
# Server block for enabling the NGINX Plus API and dashboard
#
location /api/ {
api write=on;
allow 127.0.0.1;
deny all;
}
```
# This block requires NGINX Plus. It turns on the API in write mode
# and serves the built-in dashboard for monitoring.
# Change the listen port if 9000 conflicts; 8080 is the conventional API port.
# For production, secure the API with TLS and limit access by IP or auth.
server {
# Listen for API and dashboard traffic
listen 9000 default_server;
server_name localhost;

# Handle API calls under /api/ in read-write mode
location /api/ {
api write=on;
}

This configuration:
# Serve the dashboard page at /dashboard.html
location = /dashboard.html {
root /usr/share/nginx/html;
}

- Enables the NGINX Plus API.
- Allows requests only from `127.0.0.1` (localhost).
- Blocks all other requests for security.
# Redirect any request to the root path “/” to the dashboard
location / {
return 301 /dashboard.html;
}
}
```

For more details, see the [NGINX Plus API module documentation](https://nginx.org/en/docs/http/ngx_http_api_module.html).

Expand Down
27 changes: 27 additions & 0 deletions content/includes/workshops/nginx-one-env-variables.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
docs:
files:
- content/nginx-one/workshops/lab4/config-sync-groups.md
- content/nginx-one/workshops/lab5/upgrade-nginx-plus-to-r34.md

---

Set these environment variables:

- **TOKEN**: your data plane key, for example:

```shell
export TOKEN="your-data-plane-key"
```

- **JWT**: your NGINX Plus license JWT. Save it as `nginx-repo.jwt`, then run:

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

- **NAME**: a unique ID for your workshop (for example, `s.jobs`):

```shell
export NAME="s.jobs"
```
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,7 @@ Make sure you have:

- An F5 Distributed Cloud (XC) account with NGINX One enabled
- All containers from [Lab 2](nginx-one/workshops/lab2/run-workshop-components-with-docker.md) running and registered
- Your unique identifier in the `NAME` environment variable (set in Lab 2), for example `s.jobs`:

```shell
export NAME="s.jobs"
```

- {{< include "workshops/nginx-one-env-variables.md" >}}
- Basic NGINX and Linux knowledge

---
Expand Down
19 changes: 1 addition & 18 deletions content/nginx-one/workshops/lab4/config-sync-groups.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,7 @@ Make sure you have:

- Completed [Lab 2: Run workshop components with Docker]({{< ref "nginx-one/workshops/lab2/run-workshop-components-with-docker.md" >}})
- Docker and Docker Compose installed and running
- Your data plane key in the `TOKEN` environment variable (set in Lab 2):

```shell
export TOKEN="your-data-plane-key"
```

- Your NGINX Plus JWT license file saved as `nginx-repo.jwt`, and `JWT` set (set in Lab 2):

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

- Your unique identifier in the NAME environment variable (set in Lab 2), for example `s.jobs`:

```shell
export NAME="s.jobs"
```

- {{< include "workshops/nginx-one-env-variables.md" >}}
- Basic familiarity with Linux command line and NGINX concepts

---
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
title: "Lab 5: Upgrade NGINX Plus to the latest version"
weight: 500
toc: true
nd-content-type: tutorial
nd-product:
- nginx-one
- nginx-plus
---

## Overview

In this lab, you upgrade NGINX Plus from R32 (or earlier) to the latest version in two ways:

- **Docker**: Deploy a new container running the latest NGINX Plus image, add it to your Config Sync Group, then shift traffic and retire older containers.
- **VM**: Push your JWT license to an existing VM instance, install the new NGINX Plus package, and restart the service.

Pick the scenario that matches your setup.

## What you’ll learn

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

- Deploy a Docker container running the latest NGINX Plus with NGINX Agent installed
- Add a VM to a Config Sync Group and push your JWT license
- Install or upgrade to the latest NGINX Plus on a VM
- Check version and sync status in the NGINX One Console
- Clean up unavailable instances in the NGINX One Console

## Before you begin

Make sure you have:

- Completed [Lab 4: Config Sync Groups]({{< ref "nginx-one/workshops/lab4/config-sync-groups.md" >}})
- Docker and Docker Compose installed and running (for Docker scenario)
- A VM with NGINX Plus R32 (or earlier), SSH access, and the NGINX Agent installed (for VM scenario)
- {{< include "workshops/nginx-one-env-variables.md" >}}
- Basic familiarity with Linux command line and NGINX concepts

## Scenario A: Upgrade NGINX Plus in Docker

### Exercise A1: Pull and run the latest NGINX Plus image

1. In your shell, log in to the private registry:

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

2. Open `docker-compose.yaml` in a text editor and uncomment the **plus4** service block (lines 74–95). This block pulls the latest Debian NGINX Plus image with the latest NGINX Agent installed, and sets your data plane key, JWT, and config sync group.

```yaml
plus4: # Debian latest 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 # Data plane key from NGINX One Console
NGINX_LICENSE_JWT: $JWT
NGINX_AGENT_INSTANCE_GROUP: $NAME-sync-group
hostname: $NAME-plus4
container_name: $NAME-plus4
image: private-registry.nginx.com/nginx-plus/agent:debian # 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
```

{{< call-out "note" "Tip" "" >}} If you use VS Code, highlight lines 74–95 and press `Ctrl` + `/` to uncomment them. {{< /call-out >}}

3. Restart your containers:

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

4. In the NGINX One Console, go to **Instances**.
5. You should see your new instance (`$NAME-plus4`) in the list (for example, `s.jobs-plus4`).
6. Select that instance and verify it runs the latest versions of NGINX Plus and NGINX Agent.
7. The `$NAME-plus4` container was added to the `$NAME-sync-group` config sync group and inherited the shared config.

{{< call-out "note" "Tip" "" >}} Because new containers in a sync group automatically pick up the shared config, you get a consistent, tested setup across versions. You can shift traffic to the new container one at a time for a safer, zero-downtime upgrade, and avoid any manual copy-and-paste steps. {{< /call-out >}}

### Exercise A2: Delete unavailable containers

When you recreate containers, they re-register in the NGINX One Console. Use the filter to clean up old entries:

1. In the NGINX One Console, go **Instances**.
2. Select **Add filter > Availability > Unavailable**.
3. Check the boxes next to the unavailable hosts.
4. Select **Delete selected**, then confirm.
5. Remove the filter: Hover over the **Availability is Unavailable** filter tag, then select **X** to clear it and show all instances again.

<span style="display: inline-block;">
{{< img src="nginx-one/images/unavailable-instances.png"
alt="Table of three NGINX One Console instances filtered to ‘Availability = Unavailable.’ Shows hostnames (s.jobs-plus1, s.jobs-plus2, s.jobs-plus3), NGINX versions, grey ‘Unavailable’ circles, CVE and recommendation indicators, certificate status, operating system, and last reported times. The ‘Delete selected’ button appears at top right." >}}
</span>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
33 changes: 28 additions & 5 deletions static/workshops/nginx-one/lab2/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ services:
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_SERVER_TOKEN: $TOKEN # Data plane key from NGINX One Console
# NGINX_AGENT_INSTANCE_GROUP: $NAME-sync-group
hostname: $NAME-plus2
container_name: $NAME-plus2
Expand All @@ -54,7 +54,7 @@ services:
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_SERVER_TOKEN: $TOKEN # Data plane key from NGINX One Console
# NGINX_AGENT_INSTANCE_GROUP: $NAME-sync-group
hostname: $NAME-plus3
container_name: $NAME-plus3
Expand All @@ -71,12 +71,35 @@ services:
- '9113' # Open for Prometheus Scraper page
restart: always
#
# plus4: # Debian R34 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 # Data plane key from NGINX One Console
# NGINX_LICENSE_JWT: $JWT
# NGINX_AGENT_INSTANCE_GROUP: $NAME-sync-group
# hostname: $NAME-plus4
# container_name: $NAME-plus4
# image: private-registry.nginx.com/nginx-plus/agent:debian # From NGINX Private Registry R34
# 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
NGINX_AGENT_SERVER_TOKEN: $TOKEN # Data plane key from NGINX One Console
hostname: $NAME-oss1
container_name: $NAME-oss1
image: docker-registry.nginx.com/nginx/agent:mainline # From Docker Public Registry
Expand All @@ -98,7 +121,7 @@ services:
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_SERVER_TOKEN: $TOKEN # Data plane key from NGINX One Console
hostname: $NAME-oss2
container_name: $NAME-oss2
image: docker-registry.nginx.com/nginx/agent:alpine # From Docker Public Registry
Expand All @@ -120,7 +143,7 @@ services:
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_SERVER_TOKEN: $TOKEN # Data plane key from NGINX One Console
hostname: $NAME-oss3
container_name: $NAME-oss3
image: docker-registry.nginx.com/nginx/agent:1.26-alpine # From Docker Public Registry
Expand Down