Skip to content

Commit 3913879

Browse files
committed
Add ability to deploy into a container like vms
Signed-off-by: Eric D. Helms <ericdhelms@gmail.com>
1 parent d9f1497 commit 3913879

File tree

5 files changed

+175
-0
lines changed

5 files changed

+175
-0
lines changed

DEVELOPMENT.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@
22

33
## Requirements
44

5+
### For Virtual Machine Development
56
* Vagrant - 2.2+
67
* Ansible - 2.14+
78
* [Vagrant Libvirt provider plugin](https://github.com/vagrant-libvirt/vagrant-libvirt)
89
* Virtualization enabled in BIOS
910

1011
Follow [instruction](https://github.com/theforeman/forklift/blob/master/docs/vagrant.md) to install vagrant
1112

13+
### For Container Development (Alternative)
14+
* Podman - 5.0+ (recommended for systemd support)
15+
* Ansible - 2.14+
1216

1317
## Development environment
1418

@@ -21,6 +25,8 @@ source .venv/bin/activate
2125

2226
## Deployment
2327

28+
### Using Virtual Machines
29+
2430
This setup uses Vagrant to create a basic VM for running the deployment on:
2531

2632
```
@@ -30,6 +36,35 @@ source .venv/bin/activate
3036
./foremanctl deploy --foreman-initial-admin-password=changeme
3137
```
3238

39+
### Using Containers (Alternative)
40+
41+
As an alternative to VMs, you can use containers for faster deployment and testing:
42+
43+
```
44+
./setup-environment
45+
source .venv/bin/activate
46+
./forge containers start
47+
./foremanctl deploy --foreman-initial-admin-password=changeme
48+
```
49+
50+
The containers command provides the following benefits:
51+
- **Faster startup** - No VM boot time required
52+
- **Lower resource usage** - Containers use less memory and CPU than VMs
53+
- **Systemd support** - Properly configured systemd environment for service management
54+
- **Port mapping** - Services accessible on host ports 8080 (HTTP) and 8443 (HTTPS)
55+
56+
Container management commands:
57+
```
58+
./forge containers start # Start container (default name: quadlet)
59+
./forge containers status # Check container status
60+
./forge containers stop # Stop and remove container
61+
```
62+
63+
You can also specify a custom container name:
64+
```
65+
./forge containers start mycontainer
66+
```
67+
3368
## Deploy hammer (optional)
3469

3570
```
@@ -38,10 +73,16 @@ source .venv/bin/activate
3873
```
3974
To teardown the environment:
4075

76+
**For VMs:**
4177
```
4278
./forge vms stop
4379
```
4480

81+
**For containers:**
82+
```
83+
./forge containers stop
84+
```
85+
4586
## Testing
4687

4788
Ensure you have a deployment. Now run the tests:
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
---
2+
- name: Create a container to deploy and test in
3+
gather_facts: false
4+
hosts:
5+
- localhost
6+
tasks:
7+
- name: Start containers
8+
when: container_action == 'start'
9+
block:
10+
- name: Start CentOS 9 Stream container
11+
containers.podman.podman_container:
12+
name: "{{ containers | default('quadlet') }}"
13+
image: quay.io/centos/centos:stream9
14+
state: started
15+
force_restart: true
16+
privileged: true
17+
hostname: "{{ containers | default('quadlet') }}.example.com"
18+
restart_policy: "always"
19+
ports:
20+
- "22"
21+
- "8080:80"
22+
- "8443:443"
23+
command: sleep infinity
24+
25+
- name: Wait for container to be ready
26+
ansible.builtin.wait_for:
27+
timeout: 10
28+
29+
- name: Install systemd and SSH in container
30+
containers.podman.podman_container_exec:
31+
name: "{{ containers | default('quadlet') }}"
32+
command: "{{ item }}"
33+
loop:
34+
- "dnf install -y systemd openssh-server passwd python3"
35+
- "echo 'root:password' | chpasswd"
36+
- "sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config"
37+
changed_when: false
38+
39+
- name: Commit container with systemd installed
40+
ansible.builtin.command:
41+
cmd: "podman commit {{ containers | default('quadlet') }} {{ containers | default('quadlet') }}-systemd"
42+
changed_when: false
43+
44+
- name: Stop container to restart with systemd
45+
containers.podman.podman_container:
46+
name: "{{ containers | default('quadlet') }}"
47+
state: stopped
48+
49+
- name: Remove container completely
50+
containers.podman.podman_container:
51+
name: "{{ containers | default('quadlet') }}"
52+
state: absent
53+
54+
- name: Start new container with systemd as PID 1
55+
containers.podman.podman_container:
56+
name: "{{ containers | default('quadlet') }}"
57+
image: "{{ containers | default('quadlet') }}-systemd"
58+
state: started
59+
privileged: true
60+
hostname: "{{ containers | default('quadlet') }}.example.com"
61+
restart_policy: "always"
62+
ports:
63+
- "22"
64+
- "8080:80"
65+
- "8443:443"
66+
command: /usr/sbin/init
67+
68+
- name: Wait for systemd to initialize
69+
ansible.builtin.wait_for:
70+
timeout: 15
71+
72+
- name: Create local_containers inventory
73+
ansible.builtin.copy:
74+
dest: "{{ inventory_dir }}/local_containers"
75+
content: |
76+
all:
77+
hosts:
78+
{{ containers | default('quadlet') }}:
79+
ansible_connection: podman
80+
ansible_user: root
81+
mode: "0664"
82+
83+
- name: Stop containers
84+
when: container_action == 'stop'
85+
block:
86+
- name: Stop and remove container
87+
containers.podman.podman_container:
88+
name: "{{ containers | default('quadlet') }}"
89+
state: absent
90+
91+
- name: Remove containers inventory
92+
ansible.builtin.file:
93+
state: absent
94+
path: "{{ inventory_dir }}/local_containers"
95+
96+
- name: Show container status
97+
when: container_action == 'status'
98+
block:
99+
- name: Get container status
100+
containers.podman.podman_container_info:
101+
name: "{{ containers | default('quadlet') }}"
102+
register: container_info
103+
ignore_errors: true
104+
105+
- name: Display container status
106+
ansible.builtin.debug:
107+
msg: |
108+
Container Status:
109+
{% if container_info.containers | length > 0 %}
110+
Name: {{ container_info.containers[0].Name }}
111+
State: {{ container_info.containers[0].State.Status }}
112+
Image: {{ container_info.containers[0].Config.Image }}
113+
Created: {{ container_info.containers[0].Created }}
114+
{% else %}
115+
Container "{{ containers | default('quadlet') }}" not found or not running
116+
{% endif %}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
help: |
3+
Manage development and testing containers.
4+
5+
variables:
6+
container_action:
7+
parameter: container_action
8+
help: Start the containers
9+
choices:
10+
- start
11+
- stop
12+
- status
13+
containers:
14+
help: Which containers to manage, defaults to quadlet.
15+
action: store

development/requirements.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
collections:
33
- ansible.posix
44
- community.general
5+
- name: containers.podman
6+
version: ">=1.16.4"
57
- name: https://github.com/theforeman/forklift
68
type: git
79
- name: theforeman.operations

src/roles/httpd/tasks/main.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
name: httpd_can_network_connect
1212
state: true
1313
persistent: true
14+
when: ansible_selinux.status == "enabled"
1415

1516
- name: Disable welcome page
1617
ansible.builtin.file:

0 commit comments

Comments
 (0)