Deploy with the Offline RPM Bundle
This guide walks you through deploying API7 Enterprise on Red Hat-family operating
systems (RHEL, Rocky Linux, AlmaLinux, and CentOS 8 and 9) from the offline RPM
bundle. The deployment requires only tar, systemctl, a text editor, and a
browser. After you download the bundle, no internet access is required.
Architecture
API7 Enterprise has two layers: the control plane (CP) and the data plane (DP):
| Layer | Role | Notes |
|---|---|---|
| Control plane | Management & control | Configures gateways, signs data-plane certs, pushes config, aggregates observability; persists to PostgreSQL |
| Data plane | Traffic processing | Runs APISIX/OpenResty, executes routes and plugins; stateless, config synced from the control plane |
For evaluation, the control plane and data plane can run on the same host. For production, run them on separate hosts. This guide uses "CP host" for the control-plane host and "DP host" for the data-plane host; in a single-host deployment, both terms refer to the same machine.
Required Dashboard Components
The Dashboard management UI and API require these components for a fully functional control plane. The first three are systemd services from the RPM bundle; the rest are prerequisites you provide.
| Component | Provided by | Required | Purpose |
|---|---|---|---|
api7ee-dashboard | api7ee-dashboard RPM (bundles Node.js) | Yes | Control-plane backend; serves the UI/API on 7443 |
api7ee-console | same RPM (runs on the bundled Node.js) | Yes | Web console UI, reverse-proxied by the dashboard (3000 → 7443) |
api7ee-dp-manager | api7ee-dp-manager RPM | Yes | Pushes config to gateways, issues data-plane mTLS certs, handles heartbeat (7943) |
| PostgreSQL | external; Single-Host RPM Evaluation Quickstart installs a local one; provide your own for production | Yes | Persistence: configuration, users, audit logs, etc. |
| Prometheus | external (not in the bundle) | For metrics | Stores gateway metrics via dp-manager remote-write; powers dashboard analytics (see Install Prometheus) |
| Jaeger | external (not in the bundle) | For tracing | Stores request traces for the dashboard's online-debug / tracing views (dp-manager → OTLP collector 4318; dashboard → query UI 16686) |
api7-gateway | api7-gateway RPM | Data plane | Serves API traffic; not required to run the dashboard, but needed for it to manage anything (see Onboard the data-plane gateway) |
System Requirements
| Item | Requirement |
|---|---|
| OS | RHEL / Rocky / AlmaLinux / CentOS 8 or 9, x86_64 |
| Init system | systemd (all components run as systemd services). Container-based evaluation must run systemd as PID 1 (see Method A) |
| Privileges | root (or sudo) |
| PostgreSQL | 13+ (15 recommended); the control plane's only external dependency, local, on a separate host, or cloud-managed |
| Ports (control plane) | 7443 (console/API, external), 7943 (data-plane mTLS onboarding, open to DP hosts), 7900/7901/7080/7081 (local/internal) |
| Ports (data plane) | 9080/9443 (business traffic ingress) |
| Network | Fully offline; for split deployment the DP host must reach the CP host's 7943, and the control plane must reach PostgreSQL's 5432 |
Obtain the Bundle
Pick the bundle that matches the target host. Identify its CPU architecture and RHEL-family major version first:
uname -m # CPU architecture → <arch> (e.g. x86_64)
cat /etc/os-release # see PLATFORM_ID (e.g. "platform:el9") → <dist> (e.g. el9)
The bundle filename uses the format
api7-ee-rpm-<version>-<dist>.<arch>.tar.gz, such as
api7-ee-rpm-3.10.1-el9.x86_64.tar.gz.
| Field | Source | Example |
|---|---|---|
<version> | The API7 Enterprise release you are installing | 3.10.1 |
<dist> | RHEL-family major version, from PLATFORM_ID in /etc/os-release | el8, el9 |
<arch> | CPU architecture from uname -m (the bundle is x86_64 today) | x86_64 |
Download the matching bundle, substituting the three values:
export API7EE_VERSION="3.10.1" # the release you are installing
export API7EE_DIST="el9" # from PLATFORM_ID in /etc/os-release
export API7EE_ARCH="x86_64" # from uname -m
curl -fSLO "https://run.api7.ai/api7-ee/api7-ee-rpm-${API7EE_VERSION}-${API7EE_DIST}.${API7EE_ARCH}.tar.gz"
If the target host is air-gapped, run the download on a machine with internet
access and copy the .tar.gz over. Only this step needs the internet; extraction
and installation are fully offline.
Bundle Contents
After extraction, the directory contains:
| File | Category | Contents |
|---|---|---|
api7ee-dp-manager-*.rpm | Control plane | Data-plane management / config push / cert-signing service |
api7ee-dashboard-*.rpm | Control plane | Control-plane backend + Web console (TLS 7443); bundled Node.js. One package provides two systemd services: api7ee-dashboard and api7ee-console |
api7-gateway-*.rpm | Data plane | Gateway (APISIX, bundled OpenResty runtime) |
which-*.rpm, libxslt-*.rpm, etc. | OS dependencies | The few system libraries the gateway needs, bundled in |
install.sh | Installer | One-shot offline install of all the RPMs above |
quickstart.sh | Evaluation helper | Single-host evaluation one-shot (see Method A) |
Each package ships its own runtime (Node.js / OpenResty). The host's nodejs and
openresty are not required, so installation is fully offline and does not affect
software already on the host.
The bundle does not include these external dependencies and deployment artifacts:
- PostgreSQL: the control plane's only external dependency (see System Requirements / Prepare PostgreSQL).
- License: upload it in the console after installation.
- Data-plane certificate: issued automatically per gateway group by the console (see Onboard the data-plane gateway).
Deployment Overview
For the standard deployment path, complete these tasks in order:
- Prepare PostgreSQL.
- Install the RPM packages.
- Configure and start the control plane.
- Bootstrap the dashboard: change the password and upload the License.
- Onboard the data-plane gateway: use the console-issued certificate and connection parameters to configure the gateway on the DP host.
- Verify that the instance is Healthy in the console.
Choose one path for your deployment:
| Path | Use case | Characteristics |
|---|---|---|
| Method A: Single-Host RPM Evaluation Quickstart | Single-host evaluation / PoC | One command; installs and initializes a local PostgreSQL automatically; ready in minutes |
| Method B: Standard Deployment | Production | Manual step-by-step; supports external/HA DB, split CP/DP, security hardening |
Method A: Evaluation Quickstart
For a single-host evaluation or PoC, the bundled quickstart.sh brings the
control plane up in minutes. It installs the RPMs, installs and initializes a
local PostgreSQL, configures and starts the control plane, and prints the access
URL.
See Single-Host RPM Evaluation Quickstart for the dedicated evaluation workflow, including container-based evaluation.
Method B: Standard Deployment for Production
Prepare PostgreSQL
The control plane needs a PostgreSQL (13+, 15 recommended). The schema is migrated automatically when the control plane starts, with no manual table creation. If you already have an instance, skip to Create database and role.
Install
Online host:
sudo dnf -y module enable postgresql:15 # required on RHEL/Rocky 8; optional on 9
sudo dnf -y install postgresql-server
Offline host: download the RPMs on a same-version online machine, then copy them over and install:
# online machine
sudo dnf -y module enable postgresql:15 # required on RHEL/Rocky 8, else you get the default PG 10 (< 13)
sudo dnf install -y --downloadonly --downloaddir=./pg-rpms postgresql-server
# target machine (after copying in pg-rpms/)
sudo dnf -y localinstall ./pg-rpms/*.rpm --disablerepo='*'
Initialize and Start PostgreSQL
Initialize the PostgreSQL data directory, then start the service:
sudo /usr/bin/postgresql-setup --initdb
sudo systemctl enable --now postgresql
Create Database and Role
Create the database user and database used by the control plane:
sudo -u postgres psql <<'SQL'
CREATE USER api7ee WITH PASSWORD 'YourStrongPassword';
CREATE DATABASE api7ee OWNER api7ee;
SQL
Enable Password Authentication
The control plane connects with "username + password + TCP," but the stock
PostgreSQL on RHEL defaults local TCP to ident, which makes the connection fail.
Edit /var/lib/pgsql/data/pg_hba.conf and add these lines before the generic
rules:
host api7ee api7ee 127.0.0.1/32 scram-sha-256
host api7ee api7ee ::1/128 scram-sha-256
If the DB and the control plane are on separate hosts, also set
listen_addresses = '*' in postgresql.conf, add the control-plane subnet to
pg_hba.conf (e.g. host api7ee api7ee 10.0.0.0/24 scram-sha-256), and open
port 5432 in the firewall.
Reload PostgreSQL after editing:
sudo systemctl reload postgresql
Verify and Record the Connection String
Confirm that the new database credentials work:
PGPASSWORD='YourStrongPassword' psql -h 127.0.0.1 -U api7ee -d api7ee -c '\conninfo'
Use this connection string in the next step:
postgres://api7ee:YourStrongPassword@<PG_HOST>:5432/api7ee. If the password
contains special characters such as @, colon (:), slash (/), or question
mark (?), URL-encode them. For example, @ becomes %40.
Install Packages
Run once on the CP host and once on the DP host:
tar -xzf api7-ee-rpm-<version>-<dist>.<arch>.tar.gz
cd api7-ee-rpm-<version>-<dist>.<arch>/
sudo ./install.sh # equivalent to dnf -y localinstall ./*.rpm --disablerepo='*'
For split deployment: the CP host needs only the two control-plane packages
(api7ee-dp-manager, api7ee-dashboard); the DP host needs only api7-gateway.
Installing the whole bundle is also supported. Do not start the services you do
not need.
Configure the Control Plane
Put the database connection string into two configs (both pointing at the same database); leave everything else at the defaults.
Set the same database connection string in /usr/local/api7/dp-manager/conf/dp-manager.yaml
and /usr/local/api7/dashboard/conf/dashboard.yaml:
database:
dsn: "postgres://api7ee:YourStrongPassword@<PG_HOST>:5432/api7ee"
The console listens on 7443 with TLS by default. To use your own certificate,
set server.tls.cert_file and server.tls.key_file in dashboard.yaml; leave
them empty to use the built-in self-signed certificate.
You usually do not need to change console.env. Keep PORT=3000 because the
dashboard reverse-proxies to 127.0.0.1:3000; changing it causes a 502.
Start the Control Plane
Start the control-plane services and confirm that all three are active:
sudo systemctl enable --now api7ee-dp-manager
sudo systemctl enable --now api7ee-dashboard # also brings up api7ee-console
systemctl is-active api7ee-dp-manager api7ee-dashboard api7ee-console # expect all three active
Open 7443 for browser access, and 7943 (DP→CP) for split deployment:
sudo firewall-cmd --add-port=7443/tcp --add-port=7943/tcp --permanent && sudo firewall-cmd --reload
If SELinux is Enforcing and a service misbehaves, check sudo ausearch -m avc -ts recent;
you may temporarily sudo setenforce 0 to confirm, then configure a proper
policy. Do not disable it globally without reason.
Bootstrap the Dashboard
- Open
https://<CP_HOST>:7443in a browser (accept the self-signed cert). - Log in for the first time with
admin / adminand change the password as prompted. - Go to Settings → License, upload the License (contains a
BEGIN CERTIFICATEsegment + aBEGIN LICENSEsegment), and confirm the status is normal.
Onboard the Data-Plane Gateway
The console issues the data plane's connection parameters and mTLS certificate centrally. Do not copy them by hand.
If the Add Instance dialog asks for the DP Manager (control-plane) endpoint,
enter https://<CP_HOST>:7943. <CP_HOST> is the control-plane IP or hostname
reachable from the DP host. Port 7943 is the data-plane mTLS port, and the DP
host must be able to reach it.
- In the console, go to Gateway Groups, select or create a group, and click Add Instance.
- The console generates a deployment script with the group's certificate and the control-plane address embedded.
The console's Add Instance currently generates Docker, Docker Compose, and Helm
scripts; it does not yet emit a native RPM script. For an RPM-installed gateway,
follow Deploy an RPM Data Plane from a Docker Script
to apply those same connection parameters to /usr/local/apisix/conf/config.yaml,
then restart the gateway service:
systemctl restart api7-gateway
Verify the Deployment
# DP host
systemctl is-active api7-gateway # active
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:9080/ # 404 = serving (no route yet)
In the console, open the gateway group → Instances: when the instance status is Healthy (heartbeat + config sync both succeeded), the deployment is complete. After that, publish routes/services in the console and the data plane syncs them automatically.
Install Prometheus
The dashboard's metrics and analytics are not stored in the dp-manager. The gateway pushes metric blocks to the dp-manager, which remote-writes them to a Prometheus instance. Prometheus is a required external service and is not included in the RPM bundle. Install and run Prometheus, then point the dp-manager at it.
-
Install Prometheus on the CP host (or a reachable host) and start it with the remote-write receiver enabled:
prometheus --web.enable-remote-write-receiver # Prometheus v2.54+
# older builds: --enable-feature=remote-write-receiver -
Configure the dp-manager to use your Prometheus instance:
prometheus:
addr: "http://127.0.0.1:9090" # your Prometheus address
remote_write_path: "/api/v1/write"Restart the dp-manager after saving the configuration:
systemctl restart api7ee-dp-manager
Until Prometheus is installed and configured, the dashboard shows no traffic metrics
and the gateway logs agent.lua:544: upload metrics block failed, status: 500.
This is expected when Prometheus is absent; proxying and instance health are unaffected.
Operations Reference
File Layout After Installation
After installation, the file layout is:
/usr/local/api7/ # control plane
├── dp-manager/ # binaries and configuration
└── dashboard/ # dashboard, console, config, Node.js runtime
/usr/local/apisix/ # data plane gateway
├── conf/ # config.yaml and onboarding certs/params
└── logs/ # gateway logs
/usr/local/openresty/ # bundled OpenResty runtime
/usr/bin/apisix # gateway CLI
/usr/lib/systemd/system/ # systemd unit files
/var/log/api7/ # control-plane logs
/var/lib/api7/ # control-plane runtime data
Common files you may inspect or edit:
| Purpose | Path |
|---|---|
| dp-manager config | /usr/local/api7/dp-manager/conf/dp-manager.yaml |
| dashboard config | /usr/local/api7/dashboard/conf/dashboard.yaml |
| console config | /usr/local/api7/dashboard/conf/console.env |
| gateway config | /usr/local/apisix/conf/config.yaml |
| control-plane logs | /var/log/api7/*.log |
| gateway logs | /usr/local/apisix/logs/error.log |
Services and Ports
| Layer | Service (systemd) | Default ports | Main config |
|---|---|---|---|
| Control plane | api7ee-dp-manager | 7900 / 7943 (mTLS) / 7901 | /usr/local/api7/dp-manager/conf/dp-manager.yaml |
| Control plane | api7ee-dashboard | 7443 (UI/API) / 7080 / 7081 | /usr/local/api7/dashboard/conf/dashboard.yaml |
| Control plane | api7ee-console | 3000 internal (reverse-proxied by dashboard) | /usr/local/api7/dashboard/conf/console.env |
| Data plane | api7-gateway | 9080 / 9443 (traffic ingress) | /usr/local/apisix/conf/config.yaml |
api7-gateway has the compatibility alias apisix.service (systemctl ... apisix also works).
Package Behavior
dnf upgrade installs the new RPMs; %config(noreplace) keeps your config intact
(new defaults are saved as *.rpmnew). Restart the affected services after upgrading.
Services run under dedicated accounts (control plane api7, data plane apisix),
created automatically at install time.
Troubleshooting
| Symptom | Where to look |
|---|---|
| Console UI 502 | console.env's PORT must be 3000; fix it and systemctl restart api7ee-console |
| Control plane fails to start | Usually the DB is unreachable: check the database connection string, PostgreSQL reachability, that the api7ee database/role exist, and that pg_hba.conf has password auth enabled |
Data-plane instance OutOfSync or cannot reach the control plane | Usually DP→CP 7943 is unreachable, or the cert and connection parameters come from different environments; re-run the console-generated onboarding script |
Offline install reports nothing provides which/libxslt | You have a slim package without the dependencies; use the official full bundle instead |
System has not been booted with systemd as init system | The host/container is not running systemd as PID 1; API7 EE runs as systemd services (see System requirements / Method A) |
Uninstall
Stop the services and remove the RPM packages:
sudo systemctl disable --now api7-gateway api7ee-console api7ee-dashboard api7ee-dp-manager
# console is installed by the dashboard package and has no standalone RPM, so it is not listed below
sudo dnf -y remove api7-gateway api7ee-dashboard api7ee-dp-manager
# config and data remain under /usr/local/api7, /usr/local/apisix, /var/log/api7, /var/lib/api7; clean up manually as needed