This guide provides Ansible automation for installing Sentora web hosting control panel on Linux servers.
Sentora is an actively maintained open-source web hosting control panel. This playbook automates the installation process for production deployments.
Current Version: 2.0.2 (stable, PHP 7.4)
Development Version: 2.1.0 (PHP 8.2, NOT for production)
| Distribution | Versions | Support Status |
|---|---|---|
| Debian | 10, 11, 12 | ✅ Fully Supported |
| Ubuntu | 20.04, 22.04, 24.04 LTS | ✅ Fully Supported |
| Rocky Linux | 8, 9 | ✅ Supported |
| AlmaLinux | 8, 9 | ✅ Supported |
| CentOS | 7, 8 Stream | ⚠️ Legacy (use Rocky/Alma) |
Create an inventory file inventory.ini:
[sentora_servers]
sentora1.example.com ansible_host=192.168.1.10
sentora2.example.com ansible_host=192.168.1.11
[sentora_servers:vars]
ansible_user=root
ansible_python_interpreter=/usr/bin/python3
sentora_domain=sentora.example.com
sentora_admin_email=admin@example.com
sentora_version=2.0.2
Create sentora-install.yml:
---
- name: Install Sentora Web Hosting Control Panel
hosts: sentora_servers
become: true
gather_facts: true
vars:
sentora_version: "2.0.2"
sentora_installer_url: "https://raw.githubusercontent.com/sentora/sentora-installers/master/install.sh"
sentora_domain: "{{ inventory_hostname }}"
sentora_admin_email: "admin@example.com"
mysql_root_password: "ChangeMeStrongPassword123!"
sentora_admin_password: "ChangeMeStrongPassword456!"
pre_tasks:
- name: Validate clean system (no Apache installed)
ansible.builtin.shell:
cmd: "which apache2 httpd || echo 'clean'"
register: apache_check
changed_when: false
- name: Warn if Apache detected
ansible.builtin.debug:
msg: "WARNING: Apache detected on system. Sentora installer expects clean system."
when: "'/usr' in apache_check.stdout"
- name: Update package cache (Debian/Ubuntu)
ansible.builtin.apt:
update_cache: true
cache_valid_time: 3600
when: ansible_os_family == "Debian"
- name: Update package cache (RHEL)
ansible.builtin.dnf:
update_cache: true
when: ansible_os_family == "RedHat"
tasks:
- name: Install prerequisites (Debian/Ubuntu)
ansible.builtin.apt:
name:
- curl
- wget
- sudo
- git
- unzip
state: present
when: ansible_os_family == "Debian"
- name: Install prerequisites (RHEL)
ansible.builtin.dnf:
name:
- curl
- wget
- sudo
- git
- unzip
state: present
when: ansible_os_family == "RedHat"
- name: Set hostname
ansible.builtin.hostname:
name: "{{ sentora_domain }}"
- name: Update /etc/hosts
ansible.builtin.lineinfile:
path: /etc/hosts
line: "127.0.0.1 {{ sentora_domain }} sentora"
state: present
- name: Create temporary directory
ansible.builtin.file:
path: /tmp/sentora
state: directory
mode: '0755'
- name: Download Sentora installer
ansible.builtin.get_url:
url: "{{ sentora_installer_url }}"
dest: /tmp/sentora/sentora-install.sh
mode: '0755'
force: true
- name: Run Sentora installer
ansible.builtin.shell: |
cd /tmp/sentora
export SENTORA_DOMAIN="{{ sentora_domain }}"
export SENTORA_ADMIN_EMAIL="{{ sentora_admin_email }}"
export MYSQL_ROOT_PASSWORD="{{ mysql_root_password }}"
export SENTORA_ADMIN_PASSWORD="{{ sentora_admin_password }}"
./sentora-install.sh
args:
creates: /etc/sentora/panel
register: install_output
changed_when: install_output.rc == 0
- name: Verify Sentora installation
ansible.builtin.stat:
path: /etc/sentora/panel
register: sentora_check
- name: Fail if installation incomplete
ansible.builtin.fail:
msg: "Sentora installation failed. Check /tmp/sentora/ for logs."
when: not sentora_check.stat.exists
- name: Start and enable services
ansible.builtin.systemd:
name: "{{ item }}"
state: started
enabled: true
loop:
- apache2
- mysql
- named
- proftpd
failed_when: false
- name: Configure firewall (UFW)
ansible.builtin.ufw:
rule: allow
port: "{{ item }}"
proto: tcp
loop:
- "80"
- "443"
- "8080"
when: ansible_os_family == "Debian"
- name: Configure firewall (firewalld)
ansible.builtin.firewalld:
service: "{{ item }}"
permanent: true
state: enabled
loop:
- http
- https
when: ansible_os_family == "RedHat"
post_tasks:
- name: Display installation summary
ansible.builtin.debug:
msg: |
Sentora Installation Complete!
Panel URL: https://{{ sentora_domain }}/
Admin Email: {{ sentora_admin_email }}
IMPORTANT:
- Change admin password immediately after first login
- Review security hardening guide
- Configure SSL certificates
- name: Save credentials securely
ansible.builtin.copy:
content: |
Sentora Installation Credentials
=================================
Domain: {{ sentora_domain }}
Admin Email: {{ sentora_admin_email }}
MySQL Root Password: {{ mysql_root_password }}
Sentora Admin Password: {{ sentora_admin_password }}
Installation Date: {{ ansible_date_time.iso8601 }}
dest: /root/sentora-credentials.txt
mode: '0600'
ansible-playbook -i inventory.ini sentora-install.yml
ansible-playbook -i inventory.ini sentora-install.yml -vvv
ansible-playbook -i inventory.ini sentora-install.yml --check
ansible-playbook -i inventory.ini sentora-install.yml --limit sentora1.example.com
# Check all services
ansible sentora_servers -a "systemctl status apache2" --become
ansible sentora_servers -a "systemctl status mysql" --become
ansible sentora_servers -a "systemctl status named" --become
# Verify panel files exist
ansible sentora_servers -a "ls -la /etc/sentora/panel" --become
Apply security measures from Sentora Security:
- name: Apply Sentora security hardening
hosts: sentora_servers
become: true
tasks:
- name: Fix password reset vulnerability
ansible.builtin.lineinfile:
path: /etc/sentora/panel/inc/init.inc.php
regexp: "ac_resethash_tx = ''"
line: " ac_resethash_tx = NULL,"
backup: true
- name: Secure zsudo permissions
ansible.builtin.file:
path: /etc/sentora/panel/bin/zsudo
owner: root
group: www-data
mode: '04750'
- name: Restrict Sentora directory permissions
ansible.builtin.file:
path: /etc/sentora
owner: root
group: root
mode: '0750'
recurse: true
Check logs on target host:
ansible sentora_servers -a "tail -100 /tmp/sentora/install.log" --become
# Check Apache
ansible sentora_servers -a "apache2ctl configtest" --become
# Check MySQL
ansible sentora_servers -a "systemctl status mysql" --become
# Check DNS
ansible sentora_servers -a "systemctl status named" --become
- name: Clean failed Sentora installation
hosts: sentora_servers
become: true
tasks:
- name: Stop services
ansible.builtin.systemd:
name: "{{ item }}"
state: stopped
loop:
- apache2
- mysql
- named
- proftpd
failed_when: false
- name: Remove Sentora files
ansible.builtin.file:
path: "{{ item }}"
state: absent
loop:
- /etc/sentora
- /var/sentora
- /tmp/sentora
- name: Remove packages
ansible.builtin.apt:
name:
- apache2
- mysql-server
- php
- bind9
- proftpd
state: absent
purge: true
when: ansible_os_family == "Debian"
| Variable | Default | Description |
|---|---|---|
sentora_version |
2.0.2 |
Sentora version to install |
sentora_installer_url |
GitHub URL | Installer script location |
sentora_domain |
Inventory hostname | Server FQDN |
sentora_admin_email |
admin@example.com |
Admin account email |
mysql_root_password |
Required | MySQL root password |
sentora_admin_password |
Required | Sentora admin password |
Beyond this playbook, we offer:
Contact our automation team: office@linux-server-admin.com