Deploy ACM Developer Portal Using Helm
Follow the steps in the guide to deploy the API Connectivity Manager Developer Portal to Kubernetes using a Helm chart.
This documentation applies to NGINX Management Suite API Connectivity Manager 1.3.0 and later.
Overview
Follow the steps in this section to install, upgrade, or uninstall the ACM Developer Portal on Kubernetes using Helm.
Before You Begin
To complete the steps in this section, you need the following:
- A working knowledge of Docker and how to build and extend containers
- An installed, licensed, and running version of API Connectivity manager
- A installed version of Helm v3.10.0 or newer
- An externally-accessible private Docker registry to push the container images to
- Your NGINX Plus certificate and key files, which you can download from MyF5
See Also:
Take a few minutes to review the Configurable Helm Settings at the end of this topic. You can change these settings to customize your installation to meet your needs.
Check out the Deployment Patterns for Developer Portal topic if you’re considering installing the Developer Portal on a single host or on a cluster for high availability.
Build the API Gateway Container Image
The Developer Portal Helm chart requires a container image that includes the NGINX Plus service and NGINX Agent in order to deploy the chart and have the API Gateway register with the API Connectivity Manager control plane.
In this example, we use Ubuntu (focal), but other supported distributions can be used.
Supported Linux distributions
The Developer Portal supports the following Linux distributions:
Distribution | Version | Platform | ACM Developer Portal |
---|---|---|---|
Amazon Linux | 2 LTS | x86_64 | 1.0.0 and later |
CentOS | 7.4 and later in the 7.x family | x86_64 | 1.0.0 and later |
Debian | 10 11 |
x86_64 x86_64 |
1.0.0 and later 1.0.0 and later |
Oracle Linux | 7.4 and later in the 7.x family | x86_64 | 1.0.0 and later |
RHEL | 7.4 and later in the 7.x family 8.x |
x86_64 x86_64 |
1.0.0 and later 1.0.0 and later |
Ubuntu | 18.04 20.04 |
x86_64 x86_64 |
1.0.0 and later 1.0.0 and later |
Create a Dockerfile similar to the following example:
-
Create a Dockerfile similar to the following example:
Example Dockerfile
FROM ubuntu:focal # NGXIN Plus release e.g 27 ARG NGINX_PLUS_VERSION # DEVPORTAL release e.g 1.3.0 ARG DEVPORTAL_UI_VERSION ARG CONTROL_PLANE_IP # Install NGINX Plus 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 -ex \ && apt-get update \ && apt-get upgrade -y \ && apt-get install --no-install-recommends --no-install-suggests -y \ curl \ gnupg \ ca-certificates \ apt-transport-https \ lsb-release \ procps \ && \ NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62; \ for server in \ hkp://keyserver.ubuntu.com:80 \ pgp.mit.edu; do \ echo "Fetching GPG key $NGINX_GPGKEY from $server"; \ gpg --keyserver "$server" \ --recv-keys "$NGINX_GPGKEY" \ && break; \ done \ # Configure APT repos && curl -k -sS -L https://$CONTROL_PLANE_IP/packages-repository/nginx-signing.key | gpg --import - \ && gpg --export "$NGINX_GPGKEY" > /etc/apt/trusted.gpg.d/nginx.gpg \ && gpg --export "support@nginx.com" > /etc/apt/trusted.gpg.d/nginx-agent.gpg \ && printf "Acquire::https::pkgs.nginx.com::SslCert \"/etc/ssl/nginx/nginx-repo.crt\";\n" >> /etc/apt/apt.conf.d/90pkgs-nginx \ && printf "Acquire::https::pkgs.nginx.com::SslKey \"/etc/ssl/nginx/nginx-repo.key\";\n" >> /etc/apt/apt.conf.d/90pkgs-nginx \ && printf "Acquire::https::$CONTROL_PLANE_IP::Verify-Peer \"false\";\n" >> /etc/apt/apt.conf.d/90pkgs-nginx-agent \ && printf "Acquire::https::$CONTROL_PLANE_IP::Verify-Host \"false\";\n" >> /etc/apt/apt.conf.d/90pkgs-nginx-agent \ && printf "deb https://pkgs.nginx.com/plus/$(lsb_release -is | tr '[:upper:]' '[:lower:]') $(lsb_release -cs) nginx-plus\n" > /etc/apt/sources.list.d/nginx-plus.list \ && printf "deb https://pkgs.nginx.com/nms/$(lsb_release -is | tr '[:upper:]' '[:lower:]') $(lsb_release -cs) nginx-plus\n" > /etc/apt/sources.list.d/nms.list \ && printf "deb https://$CONTROL_PLANE_IP/packages-repository/deb/$(lsb_release -is | tr '[:upper:]' '[:lower:]') $(lsb_release -cs) agent\n" > /etc/apt/sources.list.d/nginx-agent.list \ && apt-get update \ # Install NGINX Plus & agent\ && apt-get install -y \ nginx-plus=${NGINX_PLUS_VERSION}* \ nginx-plus-module-njs=${NGINX_PLUS_VERSION}* \ nginx-devportal-ui=${DEVPORTAL_UI_VERSION}* \ nginx-agent \ # 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 \ # Cleanup \ && apt-get autoremove --purge -y \ curl \ gnupg \ apt-transport-https \ lsb-release \ && rm -rf /root/.gnupg \ && rm -rf /var/lib/apt/lists/* COPY /packaging/docker/entrypoint.sh / STOPSIGNAL SIGTERM CMD bash /entrypoint.sh
-
Add an
entrypoint.sh
file similar to the following example to the same directory where you added the Dockerfile:Example entrypoint.sh
Download example entrypoint.sh file
#!/bin/bash set -euxo pipefail handle_term() { echo "received TERM signal" echo "stopping nginx-agent ..." kill -TERM "${agent_pid}" 2>/dev/null echo "stopping nginx ..." kill -TERM "${nginx_pid}" 2>/dev/null } trap 'handle_term' TERM if [ -z "${CONTROL_PLANE_IP}" ]; then echo "ERROR CONTROL_PLANE_IP environment variable needs to be set." exit 1 fi if [ -z "${INSTANCE_GROUP}" ]; then echo "ERROR INSTANCE_GROUP environment variable needs to be set." exit 1 fi # Launch nginx echo "starting nginx ..." nginx -g "daemon off;" & nginx_pid=$! # start nginx-agent, pass args echo "starting nginx-agent ..." nginx-agent --instance-group "${INSTANCE_GROUP}" --server-host "${CONTROL_PLANE_IP}" & agent_pid=$! wait_term() { wait ${agent_pid} trap - TERM kill -QUIT "${nginx_pid}" 2>/dev/null echo "waiting for nginx to stop..." wait ${nginx_pid} } wait_term echo "nginx-agent process has stopped, exiting."
-
Add your NGINX Plus certificate and key files to the same directory as the Dockerfile. You can download these files from the MyF5 site.
-
Build the Dockerfile and specify the following settings:
CONTROL_PLANE_IP
: The IP address or hostname of your API Connectivity Manager control plane hostNGINX_PLUS_VERSION
: The version of NGINX Plus that you want to use; for example,27
DEVPORTAL_UI_VERSION
: The version of the Developer Portal UI that you want to use; for example,1.3.0
REGISTRY_URL
: The private registry for your images
export CONTROL_PLANE_IP=<NGINX-INSTANCE-MANAGER-FQDN> export NGINX_PLUS_VERSION=<NGINX-PLUS-VERSION> export DEVPORTAL_UI_VERSION=<ACM-VERSION> export REGISTRY_URL=<REGISTRY-URL> export DOCKER_BUILDKIT=1 docker build \ -t ${REGISTRY_URL}/apigw:latest \ --build-arg CONTROL_PLANE_IP \ --build-arg NGINX_PLUS_VERSION \ --build-arg DEVPORTAL_UI_VERSION \ --secret id=nginx-crt,src=nginx-repo.crt \ --secret id=nginx-key,src=nginx-repo.key \ .
Download the Developer Portal API Image
-
On the MyF5 website, select Resources > NGINX Downloads.
-
In the NGINX products list, select NGINX API Connectivity Manager.
-
Select the following download options. Pick the version that you require; in this guide, we’ve chosen 1.3.0 as an example:
Product version: 1.3.0
Linux distribution: Ubuntu
Distribution Version: 20.04
Architecture: amd64 -
Download the
nginx-devportal-<version>-img.tar.gz
file.
Load Docker Image
-
Change to the directory where you downloaded the Docker image:
cd <directory name>
-
Load the Docker image:
docker load -i nginx-devportal-<version>-img.tar.gz
The output looks similar to the following:
$ docker load -i nginx-devportal-<version>-img.tar.gz 1b5933fe4b5: Loading layer [==================================================>] 5.796MB/5.796MB fbe0fc9bcf95: Loading layer [==================================================>] 17.86MB/17.86MB ... 112ae1f604e0: Loading layer [==================================================>] 67.8MB/67.8MB 4b6a693b90f4: Loading layer [==================================================>] 3.072kB/3.072kB Loaded image: devportal-api:1.3.0
-
For the output of the
docker load
command, note the loaded images name and tag. For example, in the output directly above,devportal-api
is the image name and1.3.0
is the tag. You’ll need to reference this image and tag in the next section when pushing the image to your private registry. The tag1.3.0
could be different depending on the product version you downloaded from MyF5.
Push Images to Private Registry
Before you begin:
To complete this step, you need an externally-accessible private Docker registry to push the container images to.
After building or loading the Docker images, you can now tag and push the images to your private Docker registry. Replace <my-docker-registry>
in the examples below with the path to your private Docker registry.
-
Log in to your private registry:
docker login <my-docker-registry>
-
Tag the images with the values you noted when completing the Load Docker Images steps above. In this example, the images are tagged with version
1.3.0
.docker tag apigw:latest <my-docker-registry>/apigw:1.3.0 docker tag devportal-api:1.3.0 <my-docker-registry>/devportal-api:1.3.0
-
Push the images to your private registry:
docker push <my-docker-registry>/apigw:1.3.0 docker push <my-docker-registry>/devportal-api:1.3.0
Add Helm Repository
Run the following commands to install the NGINX Management Suite chart from the Helm repository:
helm repo add nginx-stable https://helm.nginx.com/stable
helm repo update
The first command, helm repo add nginx-stable https://helm.nginx.com/stable
, adds the nginx-stable
repository to your local Helm repository list. This repository contains the Helm charts for deploying NGINX Management Suite.
The second command, helm repo update
, updates the local Helm repository list with the newest versions of the charts from the nginx-stable
repository. This command ensures you have the most up-to-date version of the charts available for installation.
Install the Chart
The Developer Portal does not require (although it is recommended) a dedicated namespace for the data plane. You can create this namespace yourself, or you can allow Helm to create it for you by using the --create-namespace
flag when installing.
Note:
If persistent storage is not configured in your cluster, set theapigw.persistence.enabled
abdapi.persistence.enabled
values tofalse
either in the values file or using the--set
helm commands.
To install the chart with the release name devportal
and namespace devportal
, run the following command:
helm install devportal nginx-stable/nginx-devportal --namespace devportal --create-namespace --wait
Upgrade the Chart
You can upgrade to the latest Helm chart from the version immediately before it. For example, you can upgrade from v1.3.0 to v1.3.1.
Upgrade the Release
To upgrade the release devportal
in the devportal
namespace, run the following command:
helm upgrade devportal nginx-stable/nginx-devportal --namespace devportal --wait
Change Configuration Options
You can use the helm upgrade
command to change or apply additional configurations to the release.
To change a configuration, use --set
commands or -f <my-values-file>
, where my-values-file
is a path to a values file with your desired configuration.
Uninstall the Chart
To uninstall and delete the release devportal
in the devportal
namespace, take the following step:
helm uninstall devportal --namespace devportal
This command removes all of the Kubernetes components associated with the Developer Portal release. The namespace is not deleted.
Configurable Helm Settings
The values.yaml
file within the nginx-devportal
Helm chart contains the deployment configuration for the Developer Portal.
You can update these fields directly in the values.yaml
file or by specifying the --set
flag when running helm install
.
To modify a configuration for an existing release, run the helm upgrade
command and use the --set
flag or -f <my-values-file>
, where my-values-file
is a path to a values file with your desired configuration.
The following table lists the configurable parameters and default values used by the Developer Portal chart when installing from a Helm chart.
Parameter | Description | Default |
---|---|---|
api.acm.client.caSecret.name |
This secret can be used in order to provide a custom CA certificate when communicating from ACM to the Developer Portal via a TLS secured http connection. This should be set to the name of the secret in the release namespace that contains the CA certificate. | "" |
api.acm.client.caSecret.key |
Key used in the secret to specify the CA file content (to add multiple certificates, chain them into one file). | "" |
api.container.port |
TCP port for the pod to listen on. | 8080 |
api.db.external |
PostgreSQL server can be external. | false |
api.db.host |
PostgreSQL server to use; defaults to the internal deployment service name. | postgres.devportal.svc |
api.db.name |
Database schema name to use. | devportal |
api.db.pass |
Password to use for PostgreSQL. | nginxdm |
api.db.port |
Port to use for PostgreSQL. If api.db.external is true , the port PostgreSQL is listening on. If api.db.external is false , the port the internal PostgreSQL should listen on. |
5432 |
api.db.tls.secretName |
User-provided secret containing TLS CA certificate for database server validation. An optional certificate/key when using client certificates can also be provided. Values are tls.crt , tls.key , and ca.crt . If you provide just the TLS certificate/key pair, a kubernetes.io/tls will suffice; otherwise, an opaque secret can be used. |
"" |
api.db.tls.verifyMode |
TLS verification modes for connecting to PostgreSQL. Options are disable , require , verify-ca , or verify-full |
require |
api.db.type |
Database type to use with the Developer Portal api service. The database type can be sqlite or psql (for PostgreSQL) |
psql |
api.db.user |
Username to use for PostgreSQL. | nginxdm |
api.image.pullPolicy |
Image pull policy. | IfNotPresent |
api.image.repository |
Repository name and path for the api image. |
api |
api.image.tag |
Tag used for pulling images from registry. | latest |
api.logLevel |
Set the log level for the backend API service. The log level can be fatal , error , warning , info , or debug |
info |
api.name |
Set the deployment name of the api. | api |
api.persistence.claims.accessMode |
Claim access mode. Can be ReadWriteOnce or ReadWriteMany |
ReadWriteOnce |
api.persistence.claims.existingClaim |
Enable reuse of an existing claim. | false |
api.persistence.claims.size |
Size of claim to allocate. | 250Mi |
api.persistence.enabled |
Optionally disable persistent storage, used for database data. | true |
api.replicas |
Set the number of API replicas in the deployment. This can be scaled above 1 only when api.db.type is psql . |
1 |
api.resources.requests.cpu |
CPU resource limits to allow for the api pods. |
125m |
api.resources.requests.memory |
Memory resource limits to allow for the api pods. |
128Mi |
api.service.port |
TCP port for the api service to listen on. This port maps to the ACM Environment ServiceTarget Listener port. For example, you may change this to 8443 when running the api with TLS. |
8080 |
api.tls.clientNames |
Common Names of client certificates to allow in a space seperated list. | "" |
api.tls.clientValidation |
Verify client certificates if sent with CA file. | false |
api.tls.secretName |
User provided secret containing TLS certificate/key pair and optional CA when using client certificates. Values are tls.crt , tls.key , and ca.crt . If you provide just the TLS certificate/key pair, a kubernetes.io/tls will suffice; otherwise, an opaque secret can be used. |
"" |
apigw.container.port |
TCP port for the pod to listen on. | 80 |
apigw.controlPlane.host |
The ACM control plane IP address or hostname. | 127.0.0.1 |
apigw.controlPlane.instance_group |
The ACM control plane instance_group for this agent to become a member of. | devportal |
apigw.image.pullPolicy |
Image pull policy. | IfNotPresent |
apigw.image.repository |
Repository name and path for the apigw image. |
apigw |
apigw.image.tag |
Tag used for pulling images from the registry. | latest |
apigw.ingress.enabled |
Optionally enable ingress via an Ingress Controller. | false |
apigw.ingress.host |
Host to apply ingress rules to. | localhost |
apigw.name |
Set the deployment name of the API Gateway. | apigw |
apigw.persistence.claims.accessMode |
Claim access mode. Can be ReadWriteOnce or ReadWriteMany |
ReadWriteOnce |
apigw.persistence.claims.existingClaim |
Enable reuse of an existing claim. | false |
apigw.persistence.claims.size |
Size of claim to allocate. | 250Mi |
apigw.persistence.enabled |
Optionally disable persistent storage used for OIDC session data. | true |
apigw.resources.requests.cpu |
CPU resource limits to allow for the apigw pods. |
125m |
apigw.resources.requests.memory |
Memory resource limits to allow for the apigw pods. |
128Mi |
apigw.service.annotations |
Annotations to apply to the apigw service. |
{} |
apigw.service.port |
TCP port for the apigw service to listen on. This is the port that is exposed in the LoadBalancer endpoint and is the traffic ingress point to the Developer Portal cluster. For example, you may change this to 443 when running the apigw with TLS. |
80 |
fullnameOverride |
Override the full name of the Developer Portal chart. | devportal |
imagePullSecrets |
List of secrets to use for pulling images. | [] |
nameOverride |
Override the name of the Developer Portal chart. | devportal |
serviceAccount.annotations |
Annotations to apply to the service account. | {} |
serviceAccount.name |
Name of the service account to use. | devportal |
Common Deployment Configurations
Select from the following options to view some of the commonly used configurations for the Developer Portal. To apply these configurations, edit the values.yaml
file as needed.
Deploy Developer Portal with an SQLite database
You can use an SQLite database for backend API service storage when deploying the Developer Portal from a Helm chart. This configuration uses a PersistentVolumeClaim (PVC) for storage of the SQLlite data files.
To use SQLite database, you need the following:
- An installed, licensed, and running version of API Connectivity Manager
- Access to a Kubernetes (or similar) cluster
Set the following configuration options to use a SQLite database:
Parameter | Value |
---|---|
api.db.external |
false |
api.db.type |
sqlite |
Deploy Developer Portal with an embedded PostgreSQL database
You can use an embedded PostgreSQL database for backend API service storage when deploying the Developer Portal from a Helm chart. This configuration uses a PersistentVolumeClaim (PVC) for storage of the the PostgreSQL data files. Access between the backend API service and the database is secured using auto-generated client TLS certificates.
To use an embedded PostgreSQL database, you need the following:
- An installed, licensed, and running version of API Connectivity Manager
- Access to a Kubernetes (or similar) cluster
Set the following configuration options to use an embedded PostgreSQL database:
Parameter | Value |
---|---|
api.db.external |
false |
api.db.pass |
nginxdm |
api.db.type |
psql |
api.db.user |
nginxdm |
api.persistence.claims.accessMode |
ReadWriteOnce |
api.persistence.claims.existingClaim |
false |
api.persistence.claims.size |
250Mi |
api.persistence.enabled |
true |
Deploy Developer Portal with an external PostgreSQL database
You can use an external PostgreSQL database for backend API service storage when deploying the Developer Portal from a Helm chart. Access between the backend API service and the database can be secured using TLS server certificates and optional client TLS certificates.
To use an external PostgreSQL database, you need the following:
- An installed, licensed, and running version of API Connectivity Manager
- Access to a Kubernetes (or similar) cluster
- A PostgreSQL service that your Kubernetes cluster can connect to using the required TCP port
- (Optional) a TLS CA certificate for verifying PostgreSQL server TLS certificates
- (Optional) a TLS client certificate and key for authenticating with the PostgreSQL server
Set the following configuration options to use an external PostgreSQL database:
Parameter | Value |
---|---|
api.db.external |
true |
api.db.host |
pg.nginx.com |
api.db.pass |
nginxdm |
api.db.tls.secretName |
db-certs |
api.db.tls.verify_mode |
verify-full |
api.db.type |
psql |
api.db.user |
nginxdm |
Deploy Developer Portal using TLS for the backend API service
When deploying the Developer Portal using a helm hcart, you can configure TLS to secure communication between the NGINX API Gateway and backend API service.
To use TLS with the backend API service, you need the following:
- An installed, licensed, and running version of API Connectivity Manager
- Access to a Kubernetes (or similar) cluster
- (Optional) A TLS CA certificate to verify NGINX API Gateway client TLS certificates
- (Optional) A TLS server certificate and key pair for validation with the NGINX API Gateway
Set the following configuration options to use TLS with the backend API service:
Parameter | Value |
---|---|
api.db.external |
false |
api.db.type |
sqlite |
api.tls.client_names |
`` |
api.tls.client_validation |
true |
api.tls.secretName |
test |