199 lines
No EOL
5 KiB
YAML
199 lines
No EOL
5 KiB
YAML
---
|
|
# Install and configure Mailcow
|
|
|
|
- name: Install required packages
|
|
apt:
|
|
name:
|
|
- git
|
|
- curl
|
|
- docker.io
|
|
- docker-compose
|
|
- python3-pip
|
|
- python3-docker
|
|
- jq
|
|
state: present
|
|
update_cache: true
|
|
|
|
- name: Ensure docker service is running
|
|
systemd:
|
|
name: docker
|
|
state: started
|
|
enabled: true
|
|
|
|
- name: Create mailcow user
|
|
user:
|
|
name: mailcow
|
|
groups: docker
|
|
shell: /bin/bash
|
|
home: /home/mailcow
|
|
create_home: true
|
|
state: present
|
|
|
|
- name: Ensure mailcow base directory exists
|
|
file:
|
|
path: "{{ mailcow_base_path }}"
|
|
state: directory
|
|
owner: mailcow
|
|
group: mailcow
|
|
mode: '0755'
|
|
|
|
- name: Check if Mailcow repository exists
|
|
stat:
|
|
path: "{{ mailcow_base_path }}/.git"
|
|
register: mailcow_repo
|
|
|
|
- name: Remove non-git Mailcow directory
|
|
file:
|
|
path: "{{ mailcow_base_path }}"
|
|
state: absent
|
|
when:
|
|
- mailcow_base_path is defined
|
|
- not mailcow_repo.stat.exists
|
|
|
|
- name: Clone Mailcow repository
|
|
git:
|
|
repo: "{{ mailcow_git_repo }}"
|
|
dest: "{{ mailcow_base_path }}"
|
|
version: "{{ mailcow_git_branch }}"
|
|
force: true
|
|
when: not mailcow_repo.stat.exists
|
|
|
|
- name: Add Mailcow directory to git safe directories
|
|
command: git config --global --add safe.directory {{ mailcow_base_path }}
|
|
when: mailcow_repo.stat.exists
|
|
|
|
- name: Update Mailcow repository
|
|
git:
|
|
repo: "{{ mailcow_git_repo }}"
|
|
dest: "{{ mailcow_base_path }}"
|
|
version: "{{ mailcow_git_branch }}"
|
|
update: true
|
|
when: mailcow_repo.stat.exists
|
|
register: git_update_result
|
|
failed_when:
|
|
- git_update_result.failed
|
|
- "'Local modifications exist' not in git_update_result.msg | default('')"
|
|
|
|
- name: Change ownership of Mailcow directory
|
|
file:
|
|
path: "{{ mailcow_base_path }}"
|
|
owner: mailcow
|
|
group: mailcow
|
|
recurse: true
|
|
|
|
# Let generate_config.sh create the default configuration
|
|
|
|
- name: Create docker-compose override file
|
|
template:
|
|
src: docker-compose.override.yml.j2
|
|
dest: "{{ mailcow_base_path }}/docker-compose.override.yml"
|
|
owner: mailcow
|
|
group: mailcow
|
|
mode: '0640'
|
|
backup: true
|
|
notify: restart mailcow
|
|
|
|
- name: Make generate_config.sh executable
|
|
file:
|
|
path: "{{ mailcow_base_path }}/generate_config.sh"
|
|
mode: '0755'
|
|
owner: mailcow
|
|
group: mailcow
|
|
|
|
- name: Check if mailcow is already configured
|
|
stat:
|
|
path: "{{ mailcow_base_path }}/mailcow.conf"
|
|
register: mailcow_configured
|
|
|
|
- name: Remove incomplete mailcow.conf
|
|
file:
|
|
path: "{{ mailcow_base_path }}/mailcow.conf"
|
|
state: absent
|
|
when:
|
|
- mailcow_configured.stat.exists
|
|
- mailcow_configured.stat.size < 1000 # If config is too small, it's incomplete
|
|
|
|
- name: Run generate_config.sh script
|
|
shell: |
|
|
cd {{ mailcow_base_path }}
|
|
./generate_config.sh << EOF
|
|
{{ mailcow_hostname }}
|
|
{{ timezone }}
|
|
EOF
|
|
args:
|
|
creates: "{{ mailcow_base_path }}/mailcow.conf"
|
|
|
|
- name: Update mailcow.conf with secure passwords
|
|
lineinfile:
|
|
path: "{{ mailcow_base_path }}/mailcow.conf"
|
|
regexp: "^{{ item.key }}="
|
|
line: "{{ item.key }}={{ item.value }}"
|
|
state: present
|
|
loop:
|
|
- { key: "DBPASS", value: "{{ vault_mailcow_dbpass }}" }
|
|
- { key: "DBROOT", value: "{{ vault_mailcow_dbroot }}" }
|
|
- { key: "REDISPASS", value: "{{ vault_mailcow_redispass }}" }
|
|
- { key: "API_KEY", value: "{{ vault_mailcow_api_key }}" }
|
|
no_log: true
|
|
|
|
- name: Stop any running Mailcow containers
|
|
command: docker compose down
|
|
args:
|
|
chdir: "{{ mailcow_base_path }}"
|
|
failed_when: false
|
|
|
|
- name: Prune unused Docker networks
|
|
command: docker network prune -f
|
|
changed_when: true
|
|
|
|
- name: Pull docker images
|
|
command: docker compose pull
|
|
args:
|
|
chdir: "{{ mailcow_base_path }}"
|
|
|
|
- name: Start Mailcow services
|
|
command: docker compose up -d
|
|
args:
|
|
chdir: "{{ mailcow_base_path }}"
|
|
|
|
- name: Check if ufw is installed
|
|
command: which ufw
|
|
register: ufw_check
|
|
changed_when: false
|
|
failed_when: false
|
|
|
|
- name: Configure firewall for mail services
|
|
ufw:
|
|
rule: allow
|
|
port: "{{ item.port }}"
|
|
proto: "{{ item.proto }}"
|
|
comment: "{{ item.comment }}"
|
|
loop:
|
|
- { port: "25", proto: "tcp", comment: "SMTP" }
|
|
- { port: "587", proto: "tcp", comment: "SMTP Submission" }
|
|
- { port: "465", proto: "tcp", comment: "SMTPS" }
|
|
# - { port: "143", proto: "tcp", comment: "IMAP" } # Disabled non-TLS
|
|
- { port: "993", proto: "tcp", comment: "IMAPS" }
|
|
# - { port: "110", proto: "tcp", comment: "POP3" } # Disabled non-TLS
|
|
- { port: "995", proto: "tcp", comment: "POP3S" }
|
|
- { port: "4190", proto: "tcp", comment: "Sieve" }
|
|
when:
|
|
- ansible_facts['os_family'] == "Debian"
|
|
- ufw_check.rc == 0
|
|
|
|
- name: Create systemd service for Mailcow
|
|
template:
|
|
src: mailcow.service.j2
|
|
dest: /etc/systemd/system/mailcow.service
|
|
owner: root
|
|
group: root
|
|
mode: '0644'
|
|
notify: restart mailcow
|
|
|
|
- name: Enable Mailcow service
|
|
systemd:
|
|
name: mailcow
|
|
enabled: true
|
|
daemon_reload: true
|
|
|
|
# Caddy not needed - Mailcow includes nginx for SSL termination |