This document describes how to set up and use the Foreman development environment that deploys Foreman source code directly on the VM while using containerized backend services.
The development environment provides:
- Git-based Foreman installation (cloned from GitHub)
- Containerized backend services (PostgreSQL, Valkey, Candlepin, Pulp, Apache HTTP Server)
- Plugin support with registry system
- Development-specific configurations
- Direct Rails server access for debugging
- A running EL9 virtual machine, and inventory that contains knowledge of the VM. For example, using
./forge vms start.- CentOS Stream 9 is recommended and tested
- Other EL9 variants should work too. Please report if they do not.
- Run
./setup-environmentand activate the virtual environment
-
Start the development environment:
./forge deploy-dev
-
Access the environment:
- To run commands on the VM, SSH into it:
vagrant ssh quadlet - Navigate to Foreman directory:
cd /home/vagrant/foreman - Start Rails server:
bundle exec foreman start
- To run commands on the VM, SSH into it:
-
Access URLs:
- Foreman UI:
http://$(hostname -f):3000(development server) - Production-style UI:
https://$(hostname -f)(via Apache proxy)
- Foreman UI:
Note
Do not run ./foremanctl or ./forge from inside the VM. These commands should be run on the control node (where foremanctl source is cloned) and use the --target-host parameter to deploy to the VM remotely via SSH. See Deploying to a Remote Host for details.
You can deploy directly to a remote host using the --target-host parameter:
# Deploy to a specific hostname or IP
./forge deploy-dev --target-host=my-server.example.com
# Deploy to an IP address
./forge deploy-dev --target-host=192.168.1.100You can define custom hosts in boxes.yaml:
---
# User-local box definitions (this file is gitignored)
# Each entry becomes a vagrant box. Available settings:
# box: base box (default: centos/stream10)
# memory: RAM in MB (default: 3072)
# cpus: CPU count (default: 1)
# disk_size: disk in GB (default: 50)
katello-production:
memory: 12288
cpus: 4
disk_size: 50
This repository does not use the vagrant-hostmanager plugin; instead, it automatically configures /etc/hosts inside all VMs during provisioning. However, to enable host-to-VM communication (e.g., using ssh or scp from your host, which is required for proxy/capsule node deployments), you need a working DNS resolution of the libvirt VMs.
This can be configured by editing the default libvirt network on your host:
virsh net-edit defaultAnd ensuring that the domain name tag matches your VAGRANT_DOMAIN environment variable (which defaults to example.com):
<network>
<domain name='example.com' localOnly='yes' register='yes'/>
</network>After the network is restarted
virsh net-destroy default && virsh net-start defaultthe guest hostnames should resolve automatically on modern Linux distributions with systemd-resolved.
When deploying to remote hosts that require SSH password authentication:
# Using environment variable
ANSIBLE_ASK_PASS=true ./forge deploy-dev --target-host=192.168.1.100Similarly to production deployments with foremanctl, using forge there is support for enabling hammer and foreman-proxy as features. Features can be enabled with --add-feature=$feature, which can be used multiple times.
By default hammer feature will set up hammer-cli and hammer-cli-foreman, foreman-proxy will set up smart-proxy itself. If any plugins are enabled, they're respective hammer or smart-proxy plugins will be set up as well.
All the projects set up as part of the feature are deployed as git checkouts.
The Foreman development environment uses official Pulp containers from pulp-oci-images which include all necessary plugins including pulp-smart-proxy by default.
The official containers provide:
- All Katello-supported Pulp plugins (ansible, container, deb, ostree, rpm, python, smart_proxy)
- Proper service wrapper scripts and configuration
For development scenarios requiring specific Pulp plugin versions or compatibility fixes, you can build custom Pulp container images using the pulp-development project in pulp-oci-images.
To pin specific versions, edit images/pulp-development/requirements.txt in the cloned repository (see the pulp-oci-images README for details):
git clone https://github.com/theforeman/pulp-oci-images.git
cd pulp-oci-images
# Optionally pin versions in images/pulp-development/requirements.txt
# e.g., change "pulpcore" to "pulpcore==3.105.1"
PROJECT=pulp-development make buildDeploy using the custom Pulp container image:
./forge deploy-dev \
--target-host=my-dev-box \
--extra-vars pulp_container_image="quay.io/foreman/pulp-development" \
--extra-vars pulp_container_tag="latest" \
--add-feature=foreman-proxyEach enabled plugin is cloned into its own directory alongside the Foreman checkout (for example /home/vagrant/katello) and wired in as a local path gem, so edits to the plugin source are picked up by the development server.
katelloforeman_remote_execution
The system includes a plugin registry with predefined configurations:
katello- Katello subscription managementforeman_remote_execution- Remote execution pluginforeman_ansible- Ansible integrationforeman_rh_cloud- Red Hat Cloud integrationforeman_discovery- Host discoveryforeman_openscap- OpenSCAP complianceforeman_bootdisk- Boot disk creationforeman_openscap- Foreman plug-in for displaying OpenSCAP audit reportsforeman_theme_satellite- Branding for Satelliteforeman_tasks- Tasks management engine and plugin for Foremanforeman_webhooks- Call external webhooks from Foremanforeman_templates- A plugin for Foreman to sync provisioning templates from an external sourceforeman_leapp- A plugin that allows to run inplace upgrades for RHEL hosts in Foreman using Leapp tool.foreman_puppet- A plugin that adds Puppet External node classification functionality to Foreman.
Use the --foreman-development-enabled-plugin parameter (can be used multiple times):
# Enable specific plugins
./forge deploy-dev start --foreman-development-enabled-plugin katello --foreman-development-enabled-plugin foreman_ansible --foreman-development-enabled-plugin foreman_discovery
# Enable single plugin
./forge deploy-dev start --foreman-development-enabled-plugin katello
# Enable all available plugins
./forge deploy-dev start --foreman-development-enabled-plugin katello --foreman-development-enabled-plugin foreman_remote_execution --foreman-development-enabled-plugin foreman_ansible --foreman-development-enabled-plugin foreman_rh_cloud --foreman-development-enabled-plugin foreman_discovery --foreman-development-enabled-plugin foreman_openscap --foreman-development-enabled-plugin foreman_bootdiskAfter deployment, the environment includes:
- Cloned Foreman repository
- Installed Ruby and Node.js dependencies
- Database migrations and seeding
- Plugin repositories and configurations
- Development-specific settings
- if
hammerfeature was enabled,hammer-cliand its plugins - if
foreman-proxyfeature was enabledsmart-proxyand its plugins- the development smart proxy registered into Foreman
This section is intended for users with foremanctl source cloned onto the same machine where foreman is being deployed on.
In a source install, git branches control versioning instead of RPM packages. Stable branches (e.g. 2.y-stable) track a specific Foreman Y-stream, while the master branch tracks nightly changes (most recent).
Run all the steps as the root user in the foremanctl source directory unless otherwise specified.
- Pull the latest changes using
git pull. - Begin the upgrade by stopping all Foreman processes by running
systemctl stop foreman.target. - Switch to the preferred target branch:
- Switch to a stable Y-stream:
git fetch origin && git checkout origin/X.y-stable - Switch to nightly:
git fetch origin && git checkout origin/master
- Switch to a stable Y-stream:
- Run upgrade tasks by re-deploying foremanctl with your customized deploy command:
foremanctl deploy [...]. Please see Parameters for available deploy options.
This final deploy command will pull new images and run all upgrade jobs required by Foreman, its dependencies, and your configured plugins. Expect this deploy to take longer than typical deploys.
The development environment integrates:
- Apache HTTP Server: Provides HTTPS proxy to the Rails development server
- Backend Services: All services (PostgreSQL, Valkey, Candlepin, Pulp) run in containers
- Rails Development Server: Runs directly on the VM for live debugging and development
- Pulp Smart Proxy Registration: Automatically configures Pulp integration during deployment
- Hammer CLI: Automatically sets up hammer for development, if
hammerfeature was enabled - Smart Proxy: Automatically set up a smart proxy for development and registers it into Foreman, if
foreman-proxyfeature was enabled
Development certificates are copied to /home/vagrant/foreman-certs/:
proxy_ca.pem- CA certificateclient_cert.pem- Client certificateclient_key.pem- Client private key
- Backup/Restore with Multiple Nodes: When running both quadlet and proxy nodes with the same controller, ensure you're switching to the correct
obsah_statecontext before performing backup or restore operations. On user installs, foreman quadlet and smart proxy map to localhost (same machine). In the development environment, these are separate VMs which alters behavior. - BACKUP_DIR Location: The
BACKUP_DIRargument in backup/restore commands refers to a directory on the target node (the VM running quadelt/proxy), not the controller node running foremanctl.
After deployment, verify the Foreman service and API on the target host:
systemctl status foreman-development
curl -sk http://$(hostname -f):3000/api/v2/pingIf the API does not respond, inspect the service log and restart the service:
journalctl -u foreman-development -n 100 --no-pager
sudo systemctl restart foreman-developmentFor container and systemd health checks, inspect the services with:
sudo podman ps -a
systemctl list-units --type=service --all --no-pager \\
| grep -E '(foreman|pulp|candlepin|httpd|postgres|valkey)'
systemctl --failed --no-pager