updated podman_services role and initial work on mailcow service
This commit is contained in:
parent
6c9f41c26c
commit
e1e3eacbed
|
|
@ -15,9 +15,11 @@ wazuh_port: 55000
|
||||||
# 📦 Container Images
|
# 📦 Container Images
|
||||||
nextcloud_aio_image: nextcloud/all-in-one:latest
|
nextcloud_aio_image: nextcloud/all-in-one:latest
|
||||||
keycloak_image: quay.io/keycloak/keycloak:24.0.2
|
keycloak_image: quay.io/keycloak/keycloak:24.0.2
|
||||||
|
mailcow_image: mailcow/mailcow-dockerized:latest
|
||||||
|
|
||||||
# 🗂️ Data Directories
|
# 🗂️ Data Directories
|
||||||
nextcloud_data_dir: /srv/nextcloud
|
nextcloud_data_dir: /srv/nextcloud
|
||||||
|
mailcow_data_dir: /opt/mailcow
|
||||||
backup_base_dir: /srv/backups
|
backup_base_dir: /srv/backups
|
||||||
logs_dir: /var/log/open-cmmc
|
logs_dir: /var/log/open-cmmc
|
||||||
|
|
||||||
|
|
@ -37,3 +39,13 @@ hostname: open-cmmc-gateway
|
||||||
|
|
||||||
# 📜 Default Realm for Keycloak
|
# 📜 Default Realm for Keycloak
|
||||||
keycloak_realm: OpenCMMC
|
keycloak_realm: OpenCMMC
|
||||||
|
|
||||||
|
# 📧 Mailcow Settings
|
||||||
|
mailcow_hostname: mail
|
||||||
|
mailcow_domain: "{{ domain_name }}"
|
||||||
|
mailcow_fqdn: "{{ mailcow_hostname }}.{{ mailcow_domain }}"
|
||||||
|
mailcow_timezone: America/New_York
|
||||||
|
mailcow_admin_user: admin
|
||||||
|
mailcow_admin_password: change_me_securely
|
||||||
|
mailcow_letsencrypt_email: it@example.com
|
||||||
|
mailcow_use_letsencrypt: "n"
|
||||||
|
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
# Ansible Role: keycloak_init
|
|
||||||
|
|
||||||
This role initializes a Keycloak instance with a predefined realm, groups, and clients for the OpenCMMC Stack.
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
---
|
|
||||||
- name: Register SAML client for Nextcloud
|
|
||||||
shell: '/opt/keycloak/bin/kcadm.sh create clients -r OpenCMMC -s clientId=nextcloud-aio -s protocol=saml -s enabled=true'
|
|
||||||
|
|
||||||
- name: Register OIDC client for Mailcow
|
|
||||||
shell: '/opt/keycloak/bin/kcadm.sh create clients -r OpenCMMC -s clientId=mailcow -s protocol=openid-connect -s enabled=true'
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
---
|
|
||||||
- name: Create Keycloak Groups
|
|
||||||
shell: '/opt/keycloak/bin/kcadm.sh create groups -r OpenCMMC -s name=Access_CUI'
|
|
||||||
|
|
||||||
- name: Create FCI Group
|
|
||||||
shell: '/opt/keycloak/bin/kcadm.sh create groups -r OpenCMMC -s name=Access_FCI'
|
|
||||||
|
|
||||||
- name: Create Proprietary Group
|
|
||||||
shell: '/opt/keycloak/bin/kcadm.sh create groups -r OpenCMMC -s name=Access_Proprietary'
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
||||||
---
|
|
||||||
- name: Check if Keycloak is already installed
|
|
||||||
stat:
|
|
||||||
path: /opt/keycloak/bin/kcadm.sh
|
|
||||||
register: keycloak_installed
|
|
||||||
|
|
||||||
- name: Download Keycloak if not already present
|
|
||||||
unarchive:
|
|
||||||
src: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/keycloak-{{ keycloak_version }}.tar.gz"
|
|
||||||
dest: /opt/
|
|
||||||
remote_src: yes
|
|
||||||
when: not keycloak_installed.stat.exists
|
|
||||||
|
|
||||||
- name: Rename keycloak directory
|
|
||||||
command: mv /opt/keycloak-{{ keycloak_version }} /opt/keycloak
|
|
||||||
args:
|
|
||||||
creates: /opt/keycloak/bin/kcadm.sh
|
|
||||||
when: not keycloak_installed.stat.exists
|
|
||||||
|
|
||||||
- name: Set executable permissions on kcadm.sh
|
|
||||||
file:
|
|
||||||
path: /opt/keycloak/bin/kcadm.sh
|
|
||||||
mode: '0755'
|
|
||||||
when: not keycloak_installed.stat.exists
|
|
||||||
|
|
||||||
- name: Log in to Keycloak Admin CLI
|
|
||||||
command: >
|
|
||||||
/opt/keycloak/bin/kcadm.sh config credentials
|
|
||||||
--server http://localhost:8080
|
|
||||||
--realm master
|
|
||||||
--user {{ keycloak_admin_user }}
|
|
||||||
--password {{ keycloak_admin_password }}
|
|
||||||
environment:
|
|
||||||
KC_HOME: /opt/keycloak
|
|
||||||
register: kcadm_login
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Create OpenCMMC realm
|
|
||||||
command: >
|
|
||||||
/opt/keycloak/bin/kcadm.sh create realms
|
|
||||||
-s realm=OpenCMMC -s enabled=true
|
|
||||||
environment:
|
|
||||||
KC_HOME: /opt/keycloak
|
|
||||||
when: kcadm_login is succeeded
|
|
||||||
|
|
||||||
- name: Create groups
|
|
||||||
loop:
|
|
||||||
- Access_CUI
|
|
||||||
- Access_FCI
|
|
||||||
- Access_Proprietary
|
|
||||||
command: >
|
|
||||||
/opt/keycloak/bin/kcadm.sh create groups -r OpenCMMC -s name={{ item }}
|
|
||||||
environment:
|
|
||||||
KC_HOME: /opt/keycloak
|
|
||||||
when: kcadm_login is succeeded
|
|
||||||
|
|
||||||
- name: Create OIDC client for Mailcow
|
|
||||||
command: >
|
|
||||||
/opt/keycloak/bin/kcadm.sh create clients -r OpenCMMC
|
|
||||||
-s clientId=mailcow
|
|
||||||
-s enabled=true
|
|
||||||
-s protocol=openid-connect
|
|
||||||
-s publicClient=false
|
|
||||||
-s 'redirectUris=["https://mail.yourdomain.com/*"]'
|
|
||||||
environment:
|
|
||||||
KC_HOME: /opt/keycloak
|
|
||||||
when: kcadm_login is succeeded
|
|
||||||
|
|
||||||
- name: Create SAML client for Nextcloud
|
|
||||||
command: >
|
|
||||||
/opt/keycloak/bin/kcadm.sh create clients -r OpenCMMC
|
|
||||||
-s clientId=nextcloud
|
|
||||||
-s enabled=true
|
|
||||||
-s protocol=saml
|
|
||||||
-s 'redirectUris=["https://nextcloud.yourdomain.com/*"]'
|
|
||||||
-s 'attributes.saml.assertion.signature=true'
|
|
||||||
-s 'attributes.saml.force.post.binding=true'
|
|
||||||
environment:
|
|
||||||
KC_HOME: /opt/keycloak
|
|
||||||
when: kcadm_login is succeeded
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
---
|
|
||||||
- name: Create Keycloak Realm
|
|
||||||
shell: '/opt/keycloak/bin/kcadm.sh create realms -s realm=OpenCMMC -s enabled=true'
|
|
||||||
args:
|
|
||||||
creates: /opt/keycloak/data/realms/OpenCMMC
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
---
|
|
||||||
- name: Ensure kcadm.sh is present
|
|
||||||
stat:
|
|
||||||
path: /opt/keycloak/bin/kcadm.sh
|
|
||||||
register: kcadm_path
|
|
||||||
|
|
||||||
- name: Install unzip (required for kcadm)
|
|
||||||
apt:
|
|
||||||
name: unzip
|
|
||||||
state: present
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
# 🐮 Mailcow Sample Environment File
|
||||||
|
|
||||||
|
# Host Settings
|
||||||
|
HOSTNAME=mail
|
||||||
|
DOMAINNAME=example.cmmc.local
|
||||||
|
MAILCOW_HOSTNAME=mail.example.cmmc.local
|
||||||
|
|
||||||
|
# Admin Interface
|
||||||
|
MAILCOW_ADMIN_USER=admin
|
||||||
|
MAILCOW_ADMIN_PASSWORD=change_me_securely
|
||||||
|
|
||||||
|
# Timezone
|
||||||
|
TZ=America/New_York
|
||||||
|
|
||||||
|
# DNS Resolver
|
||||||
|
RESOLVER=9.9.9.9
|
||||||
|
|
||||||
|
# Let's Encrypt (n = disabled, y = enabled)
|
||||||
|
SKIP_LETS_ENCRYPT=y
|
||||||
|
LETS_ENCRYPT_EMAIL=it@example.com
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
version: '3.7'
|
||||||
|
|
||||||
|
services:
|
||||||
|
redis:
|
||||||
|
image: redis:alpine
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- redis-data:/data:Z
|
||||||
|
|
||||||
|
mysql:
|
||||||
|
image: mariadb:10.5
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- MYSQL_ROOT_PASSWORD=mailcowrootpass
|
||||||
|
- MYSQL_DATABASE=mailcow
|
||||||
|
- MYSQL_USER=mailcow
|
||||||
|
- MYSQL_PASSWORD=mailcowpass
|
||||||
|
volumes:
|
||||||
|
- mysql-data:/var/lib/mysql:Z
|
||||||
|
|
||||||
|
dovecot:
|
||||||
|
image: mailcow/dovecot:latest
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- vmail-data:/var/vmail:Z
|
||||||
|
- rspamd-data:/var/lib/rspamd:Z
|
||||||
|
environment:
|
||||||
|
- MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
|
||||||
|
|
||||||
|
postfix:
|
||||||
|
image: mailcow/postfix:latest
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
|
||||||
|
|
||||||
|
nginx:
|
||||||
|
image: mailcow/nginx:latest
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "8081:80"
|
||||||
|
- "8443:443"
|
||||||
|
volumes:
|
||||||
|
- nginx-certs:/etc/ssl/mail:Z
|
||||||
|
environment:
|
||||||
|
- MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
redis-data:
|
||||||
|
mysql-data:
|
||||||
|
vmail-data:
|
||||||
|
rspamd-data:
|
||||||
|
nginx-certs:
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
---
|
|
||||||
- name: Deploy keycloak container with Podman
|
|
||||||
containers.podman.podman_container:
|
|
||||||
name: keycloak
|
|
||||||
image: "{{ keycloak_image }}"
|
|
||||||
state: started
|
|
||||||
restart_policy: always
|
|
||||||
volumes:
|
|
||||||
- "{{ keycloak_data_dir }}:/data:z"
|
|
||||||
env:
|
|
||||||
CONFIG_PATH: "/data/config"
|
|
||||||
|
|
||||||
- name: Ensure systemd service is enabled for keycloak
|
|
||||||
copy:
|
|
||||||
dest: "/etc/systemd/system/podman-keycloak.service"
|
|
||||||
content: |
|
|
||||||
[Unit]
|
|
||||||
Description=Podman container for keycloak
|
|
||||||
Wants=network.target
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
ExecStart=/usr/bin/podman start -a keycloak
|
|
||||||
ExecStop=/usr/bin/podman stop -t 10 keycloak
|
|
||||||
Restart=always
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: "0644"
|
|
||||||
|
|
||||||
- name: Reload systemd and enable service for keycloak
|
|
||||||
systemd:
|
|
||||||
daemon_reload: yes
|
|
||||||
name: podman-keycloak.service
|
|
||||||
enabled: yes
|
|
||||||
state: started
|
|
||||||
|
|
@ -1,38 +1,39 @@
|
||||||
---
|
---
|
||||||
- name: Deploy mailcow container with Podman
|
- name: Ensure mailcow service directory exists
|
||||||
containers.podman.podman_container:
|
file:
|
||||||
name: mailcow
|
path: "{{ service.compose_dir }}"
|
||||||
image: "{{ mailcow_image }}"
|
state: directory
|
||||||
state: started
|
mode: "0755"
|
||||||
restart_policy: always
|
owner: "{{ service.user | default('root') }}"
|
||||||
volumes:
|
group: "{{ service.group | default('root') }}"
|
||||||
- "{{ mailcow_data_dir }}:/data:z"
|
|
||||||
env:
|
|
||||||
CONFIG_PATH: "/data/config"
|
|
||||||
|
|
||||||
- name: Ensure systemd service is enabled for mailcow
|
- name: Deploy mailcow .env file from template
|
||||||
|
template:
|
||||||
|
src: mailcow/env.j2
|
||||||
|
dest: "{{ service.compose_dir }}/.env"
|
||||||
|
owner: "{{ service.user | default('root') }}"
|
||||||
|
group: "{{ service.group | default('root') }}"
|
||||||
|
mode: "0600"
|
||||||
|
|
||||||
|
- name: Copy mailcow podman-compose.yml
|
||||||
copy:
|
copy:
|
||||||
dest: "/etc/systemd/system/podman-mailcow.service"
|
src: mailcow/podman-compose.yml
|
||||||
content: |
|
dest: "{{ service.compose_dir }}/podman-compose.yml"
|
||||||
[Unit]
|
owner: "{{ service.user | default('root') }}"
|
||||||
Description=Podman container for mailcow
|
group: "{{ service.group | default('root') }}"
|
||||||
Wants=network.target
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
ExecStart=/usr/bin/podman start -a mailcow
|
|
||||||
ExecStop=/usr/bin/podman stop -t 10 mailcow
|
|
||||||
Restart=always
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: "0644"
|
mode: "0644"
|
||||||
|
|
||||||
- name: Reload systemd and enable service for mailcow
|
- name: Copy mailcow systemd unit file
|
||||||
|
template:
|
||||||
|
src: mailcow/mailcow.service.j2
|
||||||
|
dest: /etc/systemd/system/podman-mailcow.service
|
||||||
|
mode: "0644"
|
||||||
|
|
||||||
|
- name: Reload systemd daemon
|
||||||
|
command: systemctl daemon-reexec
|
||||||
|
|
||||||
|
- name: Enable and start mailcow container service
|
||||||
systemd:
|
systemd:
|
||||||
daemon_reload: yes
|
|
||||||
name: podman-mailcow.service
|
name: podman-mailcow.service
|
||||||
enabled: yes
|
enabled: true
|
||||||
state: started
|
state: started
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,24 @@
|
||||||
---
|
---
|
||||||
- name: Ensure Podman is installed
|
- name: Ensure Podman and dependencies are installed
|
||||||
apt:
|
apt:
|
||||||
name: podman
|
name:
|
||||||
|
- podman
|
||||||
|
- uidmap
|
||||||
|
- slirp4netns
|
||||||
|
- fuse-overlayfs
|
||||||
state: present
|
state: present
|
||||||
become: true
|
become: true
|
||||||
|
|
||||||
- name: Pull and run Podman services
|
- name: Confirm Podman version
|
||||||
|
command: podman --version
|
||||||
|
register: podman_version
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Debug Podman version for audit
|
||||||
|
debug:
|
||||||
|
msg: "Podman version is {{ podman_version.stdout }}"
|
||||||
|
|
||||||
|
- name: Iterate over defined Podman services
|
||||||
include_tasks: run_service.yml
|
include_tasks: run_service.yml
|
||||||
loop: "{{ podman_services }}"
|
loop: "{{ podman_services }}"
|
||||||
loop_control:
|
loop_control:
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,11 @@
|
||||||
- name: Pull image for {{ service.name }}
|
- name: Pull image for {{ service.name }}
|
||||||
containers.podman.podman_image:
|
containers.podman.podman_image:
|
||||||
name: "{{ service.image }}"
|
name: "{{ service.image }}"
|
||||||
|
register: pulled_image
|
||||||
|
|
||||||
|
- name: Debug pulled image result for {{ service.name }}
|
||||||
|
debug:
|
||||||
|
msg: "Image {{ service.image }} pulled: {{ pulled_image }}"
|
||||||
|
|
||||||
- name: Create data directory for {{ service.name }}
|
- name: Create data directory for {{ service.name }}
|
||||||
file:
|
file:
|
||||||
|
|
@ -21,3 +26,8 @@
|
||||||
env: "{{ service.env | default({}) }}"
|
env: "{{ service.env | default({}) }}"
|
||||||
volumes: "{{ service.volumes | default([]) }}"
|
volumes: "{{ service.volumes | default([]) }}"
|
||||||
user: "{{ service.user | default(omit) }}"
|
user: "{{ service.user | default(omit) }}"
|
||||||
|
register: podman_run
|
||||||
|
|
||||||
|
- name: Debug container run status for {{ service.name }}
|
||||||
|
debug:
|
||||||
|
var: podman_run
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
# 🐮 Mailcow Environment File (Generated by Ansible)
|
||||||
|
|
||||||
|
# Host Settings
|
||||||
|
HOSTNAME={{ mailcow_hostname }}
|
||||||
|
DOMAINNAME={{ mailcow_domain }}
|
||||||
|
MAILCOW_HOSTNAME={{ mailcow_fqdn }}
|
||||||
|
|
||||||
|
# Admin Interface
|
||||||
|
MAILCOW_ADMIN_USER={{ mailcow_admin_user }}
|
||||||
|
MAILCOW_ADMIN_PASSWORD={{ mailcow_admin_password }}
|
||||||
|
|
||||||
|
# Timezone
|
||||||
|
TZ={{ mailcow_timezone }}
|
||||||
|
|
||||||
|
# DNS Resolver
|
||||||
|
RESOLVER=9.9.9.9
|
||||||
|
|
||||||
|
# Let's Encrypt
|
||||||
|
SKIP_LETS_ENCRYPT={{ 'n' if mailcow_use_letsencrypt == 'y' else 'y' }}
|
||||||
|
LETS_ENCRYPT_EMAIL={{ mailcow_letsencrypt_email }}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Mailcow Podman Compose Service
|
||||||
|
Wants=network.target
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
RemainAfterExit=yes
|
||||||
|
WorkingDirectory={{ service.compose_dir }}
|
||||||
|
ExecStart=/usr/bin/podman-compose -f {{ service.compose_dir }}/podman-compose.yml up -d
|
||||||
|
ExecStop=/usr/bin/podman-compose -f {{ service.compose_dir }}/podman-compose.yml down
|
||||||
|
TimeoutStartSec=0
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
version: "3.8"
|
||||||
|
|
||||||
|
services:
|
||||||
|
mailcow:
|
||||||
|
image: mailcow/mailcow-dockerized:latest
|
||||||
|
container_name: mailcow
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "25:25"
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
- "587:587"
|
||||||
|
- "993:993"
|
||||||
|
volumes:
|
||||||
|
- mailcow_data:/var/lib/mailcow
|
||||||
|
- mailcow_conf:/etc/mailcow
|
||||||
|
networks:
|
||||||
|
- mailcow_net
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
mailcow_data:
|
||||||
|
mailcow_conf:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
mailcow_net:
|
||||||
|
driver: bridge
|
||||||
Loading…
Reference in New Issue