Secure Gateway on RHEL with Podman
Deploy Secure Gateway on Red Hat Enterprise Linux hosts without Kubernetes, with the gateway and its encrypted cache running as Podman containers managed by Roboflow Deployment Manager.
Secure Gateway also runs on Red Hat Enterprise Linux hosts that have neither Docker nor Kubernetes. A dedicated installer deploys the gateway and its encrypted cache as Podman containers, supervised by the Roboflow Deployment Manager (rfdm), which drives Podman through its Docker-compatible API. You get the same gateway as the Docker deployment (one controlled point of egress that proxies the Roboflow API and caches model weights and container images for your fleet) with the same air-gapped bundle model, on the container runtime that ships with RHEL.
Architecture
The Roboflow Deployment Manager runs on the host as a systemd service and manages the containers through Podman's Docker-compatible API (
podman.socket). It keeps the gateway configured, updated, and running.The gateway and its cache backend (SeaweedFS, an S3-compatible store with encryption at rest) run as containers under the system (root) Podman instance.
The gateway publishes ports
80and443directly on the host: HTTPS on443, with HTTP on80redirecting to HTTPS.The cache is stored in
/data/seaweedfson the host filesystem, bind-mounted into the cache container. No LVM volume group or storage provisioner is required.SELinux stays enforcing. Volume mounts in the managed container configuration carry SELinux labels (
:Z/z), so no manual relabeling and no permissive mode are needed.
This is a single-host deployment. High availability and multi-host clusters are not supported.
Use a dedicated host for the gateway. Podman and CRI-O (the runtime MicroShift uses) share the host's container storage, so image cleanup in one (ex: podman image prune) can reclaim images the other runtime cached. If the host runs MicroShift, use the MicroShift deployment instead.
Prerequisites
A Red Hat Enterprise Linux 9.x host on x86_64, with Podman 4.x or newer. The installer bundle is built for
linux-amd64only. Podman comes from the RHEL repositories with no extra subscription, but a minimal installation may not have it: runsudo dnf install podmanfirst ifpodman --versionfails. See the support matrix.Root access: the gateway installs under the system (root) Podman instance
Disk: about 3 GB on
/for the container images, plus room for the cache under/data, which grows to 50 GBPorts
80and443available for the gateway on the hostFor connected installs, outbound HTTPS to
api.roboflow.comandrepo.roboflow.com
Install on a connected host
Download the Podman installer bundle and verify its integrity:
Extract it and run the installer as root:
The installer:
Enables the Podman API socket (
podman.socket), the Docker-compatible API the Deployment Manager manages containers through.Loads the bundled Secure Gateway and SeaweedFS images into the host's root Podman storage. Nothing is pulled from a registry.
Switches Podman's network backend to netavark if legacy CNI leftovers on the host would otherwise break DNS between containers.
Generates the gateway's TLS certificate and private key.
Installs the Roboflow Deployment Manager as a systemd service in Podman mode and writes its device configuration.
Enables
podman-restart.serviceso the containers come back after a host reboot.Starts the Deployment Manager, which creates and starts the gateway and cache containers.
Verify the deployment:
The gateway and cache containers should both be Up, and the health check should return HTTP 200. The -k flag is needed until you trust the gateway's certificate; see TLS and trust.
Install air-gapped
The same bundle installs on hosts with no internet access. The container images ship inside it as OCI archives and are loaded directly into the host's Podman storage. The containers reference exact version tags, so nothing is ever pulled from a registry, at install time or later.
Download and verify the bundle on a connected machine, transfer it to the host by removable media or your internal file transfer process, then extract and run install-podman.sh exactly as above. Verification is the same.
TLS and trust
The installer generates a self-signed certificate for the gateway, which serves HTTPS with it on port 443 and redirects HTTP on port 80 to HTTPS. The generated certificate uses the common name repo.roboflow.com, also covers *.roboflow.com, localhost, and 127.0.0.1, and is valid for 10 years. Re-running the installer keeps that generated pair while more than a year is left on it, so trust you already distributed to clients keeps working. This applies only to the generated material: the installer tracks it separately, so a re-run without --cert and --key overwrites a certificate you supplied with a self-signed one.
The gateway reads its certificate and key from /etc/secure-gateway/tls/tls.crt and /etc/secure-gateway/tls/tls.key on the host. Pass --cert and --key to install-podman.sh to install your own material from the start, or replace those two files and restart the gateway container. Your certificate has to cover repo.roboflow.com: the client install script repoints that hostname at the gateway in /etc/hosts, and container runtimes check the TLS hostname before pulling images.
The gateway process runs as UID 1000 with group 0 inside its container, so it reads the files through their owner permissions. The installer sets both files to owner 1000:0, mode 0640 on the key and 0644 on the certificate, and the directory to owner root:0 and mode 0750. Replacing the files as root and leaving them root-owned is the most common cause of a gateway that can no longer read its key (see Troubleshooting).
Connecting Inference Servers
On each machine that runs a Roboflow Inference Server, run the gateway's client install script. It adds the gateway's certificate to the machine's trust store and routes its Roboflow traffic (API calls, model weights, and container image pulls) through the gateway:
The -k flag is required here: the machine does not trust the gateway's certificate yet, which is what the script installs. Run this only over a network path you control, or copy the script across yourself and check it first.
Alternatively, point an individual Inference Server at the gateway with the SECURE_GATEWAY environment variable; see Connecting Inference Servers. Use SECURE_GATEWAY=https://repo.roboflow.com. Use the explicit HTTPS scheme across versions; the pending runtime-hardening build changes how bare addresses and plaintext gateways are handled, as described in Security Configuration Migration. The hostname matters too: the generated certificate covers repo.roboflow.com and not the host's IP address, so https://<host-ip> fails certificate validation even after the machine trusts the certificate. Run the client install script first, which points repo.roboflow.com at the gateway in /etc/hosts and installs the certificate. To use the IP address instead, issue your own certificate covering it and install it with --cert and --key. Only the gateway needs outbound access to api.roboflow.com and repo.roboflow.com.
Troubleshooting
Containers cannot resolve each other by name, and the gateway logs name-resolution errors reaching its cache
Podman is using the legacy CNI network backend, which has no container DNS, usually because of CNI leftovers from an earlier container runtime. Check with sudo podman info --format '{{.Host.NetworkBackend}}'; it should report netavark. The installer writes a drop-in under /etc/containers/containers.conf.d/ to select netavark when needed. Existing containers stay on the old backend after the fix, so remove them with sudo podman rm -f secure-gateway seaweedfs and restart the Deployment Manager (sudo systemctl restart rfdm) to recreate them.
Gateway fails with Permission denied reading its TLS key
The certificate and key files must be owned 1000:0 (mode 0640 on the key, 0644 on the certificate), in a directory owned root:0 with mode 0750. The installer sets this; the usual cause is a certificate replaced manually as root. Set them by hand, then restart the gateway container: sudo chown 1000:0 /etc/secure-gateway/tls/tls.crt /etc/secure-gateway/tls/tls.key, sudo chmod 0640 /etc/secure-gateway/tls/tls.key, sudo chmod 0644 /etc/secure-gateway/tls/tls.crt. Re-running install-podman.sh also fixes it, but pass --cert and --key again if you brought your own certificate, or the re-run replaces it with a self-signed one.
Permission denied writing to a mounted directory
The volume mount is missing its SELinux label. Every volume in the managed configuration carries a :Z (or shared :z) option; if you added a mount by hand, add the label rather than putting SELinux in permissive mode.
Gateway crash-loops with PermissionError reading /etc/ssl/certs/ca-certificates.crt
SELinux is blocking the container from the host CA bundle the Deployment Manager mounts in. The denial is suppressed, so audit searches turn up nothing. Run sudo setsebool -P container_read_certs on. The installer sets this boolean, so re-running it fixes the host as well.
Gateway logs Init handshake failed ... starting in local-cache-only mode
The gateway could not reach the Roboflow API at startup (wrong API key, no outbound connectivity, or the cache was still starting). It keeps serving traffic and still caches locally, but runs without its S3-backed cache and cannot report telemetry or events to the backend until the next restart. Fix the cause, then restart the gateway container: sudo podman restart <gateway-container>, with the container name from sudo podman ps.
Where the logs are
Deployment Manager: sudo journalctl -u rfdm. Gateway and cache: sudo podman logs <container>, with the container names from sudo podman ps.
Support matrix
9.x
4.x
Podman 4 ships with RHEL 9
9.x
5.x
Validated on RHEL 9.6 with Podman 5.4.0
Podman 4.x is the minimum supported version. The Podman that ships with a current RHEL 9.x release is supported without any additional repositories or packages.
Last updated
Was this helpful?