Production deployment
This guide walks you through deploying Infrahub in a production environment with enhanced security, reliability, and maintainability. By following these steps, you'll set up a production-ready Infrahub instance that follows industry best practices.
This guide is currently under development. Please use it as a reference checklist when preparing your Infrahub environment for production deployment.
Prerequisites​
Before beginning your production deployment, ensure you have:
- Selected your deployment technology (Docker or Kubernetes)
- Verified your system meets the hardware requirements
- Administrative access to your deployment environment
- Decided between Community or Enterprise edition based on your support and feature needs
- Access to your organization's identity provider (for SSO configuration)
- A backup strategy and storage location
Step 1: Create a hardened configuration file​
Production environments require secure configuration settings that differ from development defaults. Create a configuration file that overwrites default values to enhance security.
# Environment settings
INFRAHUB_ALLOW_ANONYMOUS_ACCESS=false
INFRAHUB_PRODUCTION=true
INFRAHUB_LOG_LEVEL=INFO
# Security keys & tokens (generate strong unique values)
INFRAHUB_SECURITY_SECRET_KEY=<strong-random-string-at-least-32-chars>
INFRAHUB_INITIAL_ADMIN_PASSWORD=<strong-admin-password>
INFRAHUB_INITIAL_ADMIN_TOKEN=<generate-uuid> # Generate with: uuidgen
INFRAHUB_INITIAL_AGENT_TOKEN=<generate-uuid> # Generate with: uuidgen
# Database & message broker security
INFRAHUB_BROKER_PASSWORD=<strong-broker-password>
INFRAHUB_DB_PASSWORD=<strong-database-password>
# TLS & Certificates
INFRAHUB_DB_TLS_ENABLED=true
INFRAHUB_BROKER_TLS_ENABLED=true
INFRAHUB_CACHE_TLS_ENABLED=true
# Only when your infrastructure uses a private CA: mount the bundle and uncomment, see "Trust a private CA" below
# INFRAHUB_TLS_CA_BUNDLE=/opt/infrahub/tls/ca-bundle.pem
Never use default passwords or tokens in production. Generate strong unique values for each environment. You can generate UUIDs using the uuidgen command or an online UUID generator.
If your infrastructure uses a private certificate authority, mount its bundle into the containers, then set INFRAHUB_TLS_CA_BUNDLE to the mounted path. A component can override the bundle with its own *_TLS_CA_FILE or *_TLS_CA_BUNDLE setting. See Trust a private CA for the mount and verification steps.
Step 2: Install Infrahub​
Install Infrahub using your chosen deployment technology, applying your hardened configuration.
For high availability deployments on Kubernetes, use the HA manifest which includes proper replication and resource requests/limits.
Navigate to https://your-server-address in your browser. You should see the Infrahub login page.
Step 3: Configure SSO (recommended)​
Connect Infrahub to your organization's identity provider to enhance security and simplify user management.
Detailed SSO configuration guide/deploy-manage/user-management/sso/overviewStep 4: Set up database backups​
Implement regular database backups to prevent data loss in case of hardware failure or other issues.
Complete backup and restore guide/deploy-manage/maintain-upgrade/database-backup/overviewTest your backup and restore process periodically to ensure it works as expected.
Least-privilege service credentials​
This section is informational and optional. Infrahub works with administrative credentials for its backing services, but it does not require them. The privileges below let you run Infrahub with restricted users if your security policy calls for it.
Infrahub does not manage users, roles, or server configuration. It primarily uses application-level privileges; only optional first-start Neo4j database bootstrap requires CREATE DATABASE.
Neo4j​
Infrahub reads and writes graph data, declares new labels, relationship types and property names, and manages its own indexes and constraints. The matching privileges are:
ACCESSto the database, plus read (MATCH) andWRITEon the graphNAME MANAGEMENTto declare new labels, relationship types, and property namesINDEX MANAGEMENTandCONSTRAINT MANAGEMENTfor the indexes and constraints it maintains
Restricting privileges per user requires Neo4j Enterprise (role-based access control). Neo4j Community supports only the built-in neo4j user.
A dedicated role and user, created by an administrator against the system database:
CREATE ROLE infrahub IF NOT EXISTS;
GRANT ACCESS ON DATABASE neo4j TO infrahub;
GRANT MATCH {*} ON GRAPH neo4j TO infrahub;
GRANT WRITE ON GRAPH neo4j TO infrahub;
GRANT NAME MANAGEMENT ON DATABASE neo4j TO infrahub;
GRANT INDEX MANAGEMENT ON DATABASE neo4j TO infrahub;
GRANT CONSTRAINT MANAGEMENT ON DATABASE neo4j TO infrahub;
CREATE USER infrahub IF NOT EXISTS SET PLAINTEXT PASSWORD '<strong-database-password>' CHANGE NOT REQUIRED;
GRANT ROLE infrahub TO infrahub;
Replace neo4j with the database name you set in INFRAHUB_DB_DATABASE if you use a dedicated database. Infrahub creates that database on first start if it does not exist, which requires the CREATE DATABASE privilege, so pre-create it as an administrator to keep the application user restricted. If you collect telemetry, also GRANT SHOW SERVERS ON DBMS and GRANT EXECUTE PROCEDURE dbms.queryJmx ON DBMS, otherwise telemetry logs a harmless permission error.
Redis​
Infrahub uses Redis for caching and distributed locks, and in distributed deployments the task manager also uses it for workflow coordination. The task manager is based on Prefect, which coordinates the task manager's background services, such as the scheduler, with a component called Docket. When the Docket URL points at Redis, Docket publishes task state, progress and cancellation events on Redis Pub/Sub channels and subscribes to the cancellation events. The user needs read and write access to keys, the connection commands used to authenticate, the scripting commands used by the locks, transactions (MULTI/EXEC) used by the task manager, and the Pub/Sub commands with access to every channel. It does not need administrative or destructive commands. With a Redis ACL file:
user default off
user infrahub on ><strong-cache-password> ~* allchannels +@read +@write +@connection +@scripting +@transaction +@pubsub -@dangerous
+@transaction is only used when the task manager is backed by Redis (distributed or high-availability deployments). +@pubsub and allchannels are only used when the Docket URL, PREFECT_SERVER_DOCKET_URL, points at Redis, as it does in the Enterprise Docker Compose file and the Enterprise Helm sizing presets. Prefect's default Docket URL is in-memory (memory://). All three are harmless to grant otherwise.
Since Redis 7.0, a new ACL user has no access to Pub/Sub channels unless the ACL grants it, so keep allchannels in the line. Without allchannels or +@pubsub, the task manager stops at startup with an error such as NoPermissionError: User infrahub has no permissions to run the 'publish' command or NoPermissionError: No permissions to access a channel.
RabbitMQ​
Infrahub talks to RabbitMQ over AMQP only: it declares its own exchanges and queues and publishes and consumes messages. It does not use the management API, so the user needs configure, write and read on the virtual host but no administrator or management tags.
rabbitmqctl add_user infrahub '<strong-broker-password>'
rabbitmqctl set_permissions -p / infrahub ".*" ".*" ".*"
# Do not set any user tags: the application does not need management access.
PostgreSQL​
The task manager stores its state in PostgreSQL and runs its own schema migrations, so its role must be able to create and change objects in its own database, but it does not need to be a cluster superuser. Create a non-superuser role that owns its database and schema:
CREATE ROLE prefect WITH LOGIN PASSWORD '<strong-task-manager-db-password>';
ALTER DATABASE prefect OWNER TO prefect;
ALTER SCHEMA public OWNER TO prefect;
GRANT ALL ON SCHEMA public TO prefect;
Then point the task manager's database connection, PREFECT_API_DATABASE_CONNECTION_URL, at this role instead of a superuser, as shown in the next section.
Point Infrahub at the restricted users​
The Infrahub server and the task workers read the INFRAHUB_* settings:
INFRAHUB_DB_USERNAME=infrahub
INFRAHUB_DB_PASSWORD=<strong-database-password>
INFRAHUB_CACHE_USERNAME=infrahub
INFRAHUB_CACHE_PASSWORD=<strong-cache-password>
INFRAHUB_BROKER_USERNAME=infrahub
INFRAHUB_BROKER_PASSWORD=<strong-broker-password>
The task manager connects to Redis and PostgreSQL with its own settings, so set those as well:
INFRAHUB_CACHE_USERNAMEandINFRAHUB_CACHE_PASSWORD: in a distributed deployment, the task manager takes an Infrahub lock in Redis while it starts.PREFECT_REDIS_MESSAGING_USERNAMEandPREFECT_REDIS_MESSAGING_PASSWORD: Prefect's Redis client for workflow coordination. Without them, it connects as thedefaultuser, which theuser default offline above disables.PREFECT_SERVER_DOCKET_URL: the Docket URL, with the username and password in it.PREFECT_API_DATABASE_CONNECTION_URL: the PostgreSQL connection, as theprefectrole.
If a password contains special characters, percent-encode them where the password appears inside a URL, for example @ as %40 and / as %2F.
- Docker Compose
- Helm
The Enterprise Docker Compose file defines the task manager as two services, task-manager and task-manager-background-svc. Both receive the INFRAHUB_CACHE_* settings from your .env file, but not Prefect's Redis credentials, and the file sets a Docket URL without credentials. Create a docker-compose.override.yml file next to your docker-compose.yml for the remaining settings. Docker Compose merges it automatically, so the shipped file stays unchanged for upgrades.
---
services:
task-manager:
environment:
PREFECT_REDIS_MESSAGING_USERNAME: infrahub
PREFECT_REDIS_MESSAGING_PASSWORD: "<strong-cache-password>"
PREFECT_SERVER_DOCKET_URL: "redis://infrahub:<strong-cache-password>@cache:6379/2"
PREFECT_API_DATABASE_CONNECTION_URL: "postgresql+asyncpg://prefect:<strong-task-manager-db-password>@task-manager-db:5432/prefect"
task-manager-background-svc:
environment:
PREFECT_REDIS_MESSAGING_USERNAME: infrahub
PREFECT_REDIS_MESSAGING_PASSWORD: "<strong-cache-password>"
PREFECT_SERVER_DOCKET_URL: "redis://infrahub:<strong-cache-password>@cache:6379/2"
PREFECT_API_DATABASE_CONNECTION_URL: "postgresql+asyncpg://prefect:<strong-task-manager-db-password>@task-manager-db:5432/prefect"
The host names and the Docket database number (2) are the defaults of the Enterprise file. Change them if you set INFRAHUB_CACHE_ADDRESS or run Redis and PostgreSQL elsewhere.
The community Docker Compose file defines the task manager as a single task-manager service that does not use Redis. With that file, set only PREFECT_API_DATABASE_CONNECTION_URL on task-manager and leave out the task-manager-background-svc block.
The Infrahub chart includes the Prefect chart as prefect-server, and you set the task manager settings under that key. In the Enterprise chart, prefect-server is nested under the top-level infrahub key, as below. With the community chart, remove the infrahub level.
Store the Infrahub cache credentials in a Kubernetes Secret:
kubectl create secret generic infrahub-task-manager-cache \
--from-literal=INFRAHUB_CACHE_USERNAME=infrahub \
--from-literal=INFRAHUB_CACHE_PASSWORD='<strong-cache-password>'
Then reference the Secret and set the Prefect credentials in your values file:
infrahub:
prefect-server:
server:
extraEnvVarsSecret: infrahub-task-manager-cache
backgroundServices:
extraEnvVarsSecret: infrahub-task-manager-cache
messaging:
redis:
username: infrahub
password: "<strong-cache-password>"
docket:
url: "redis://infrahub:<strong-cache-password>@infrahub-cache-master:6379/2"
Set the cache credentials through extraEnvVarsSecret rather than server.env: the chart already sets server.env, and Helm replaces a list from the chart with the list in your values file instead of merging them. The Prefect chart can also read the Redis password and the Docket URL from existing Secrets, through the existingSecret settings under backgroundServices.messaging.redis and backgroundServices.messaging.docket.
For PostgreSQL, the user depends on where the database runs:
- With the PostgreSQL chart bundled in the Prefect chart, which the Infrahub chart enables by default, Prefect connects as the user in
prefect-server.postgresql.auth.username(prefectby default). - With an external PostgreSQL server (
prefect-server.postgresql.enabled: false), set the role inprefect-server.secret.usernameandprefect-server.secret.password, together withhost,portanddatabase, as in the high availability example.
Operations and maintenance​
Upgrading Infrahub​
To upgrade to a new version of Infrahub:
- Review the release notes for breaking changes
- Create a full backup of your database
- Update the container images
Always create a backup before upgrading to ensure you can restore if needed.
Support options​
Community support​
- GitHub Issues: github.com/opsmill/infrahub
- Discord Community: discord.gg/infrahub
- Documentation: docs.infrahub.app
Enterprise support Enterprise Edition​
- 24/7 support with SLA guarantees
- Dedicated support engineer
- Professional services for deployment
- Training and certification programs
Contact [email protected] for enterprise support.