Restore from Gitea ZIP snapshot (12.08.2026) after full instance reinstall
Git history was lost when the previous Gitea instance was wiped and reinstalled due to an unresolved corruption bug — this commit is the last known-good file content, exported before the reinstall. Prior commit history is not recoverable through this path.
This commit is contained in:
@@ -0,0 +1,6 @@
|
|||||||
|
*.retry
|
||||||
|
*.log
|
||||||
|
.env
|
||||||
|
*.swp
|
||||||
|
.DS_Store
|
||||||
|
__pycache__/
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# osTicket Ansible Playbook for Debian 13
|
||||||
|
|
||||||
|
Автоматическая установка osTicket.
|
||||||
|
|
||||||
|
## Переменные для Semaphore
|
||||||
|
|
||||||
|
- `MARIADB_ROOT_PASSWORD` - пароль root MySQL
|
||||||
|
- `APP_DB_PASSWORD` - пароль пользователя osTicket
|
||||||
|
- `DOMAIN_NAME` - домен или IP сервера
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
- name: Полная установка osTicket с правильными правами
|
||||||
|
hosts: all
|
||||||
|
become: yes
|
||||||
|
gather_facts: yes
|
||||||
|
vars:
|
||||||
|
ansible_become_method: sudo
|
||||||
|
|
||||||
|
roles:
|
||||||
|
- apache
|
||||||
|
- php
|
||||||
|
- mariadb
|
||||||
|
- osticket
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
---
|
||||||
|
- name: Включение root доступа по SSH
|
||||||
|
hosts: all
|
||||||
|
become: yes
|
||||||
|
gather_facts: yes
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Разрешить root логин через SSH
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /etc/ssh/sshd_config
|
||||||
|
regexp: '^#?PermitRootLogin'
|
||||||
|
line: 'PermitRootLogin yes'
|
||||||
|
backup: yes
|
||||||
|
notify: Restart SSH
|
||||||
|
|
||||||
|
- name: Разрешить аутентификацию по паролю для root (если нужно)
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /etc/ssh/sshd_config
|
||||||
|
regexp: '^#?PasswordAuthentication'
|
||||||
|
line: 'PasswordAuthentication yes'
|
||||||
|
notify: Restart SSH
|
||||||
|
|
||||||
|
- name: Убедиться, что SSH сервис запущен
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: ssh
|
||||||
|
state: started
|
||||||
|
enabled: yes
|
||||||
|
|
||||||
|
handlers:
|
||||||
|
- name: Restart SSH
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: ssh
|
||||||
|
state: restarted
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# Переменные переопределяются в Semaphore через Environment Variables
|
||||||
|
mariadb_root_password: "{{ lookup('env', 'MARIADB_ROOT_PASSWORD') | default('CHANGE_ME', true) }}"
|
||||||
|
app_db_name: "osticket"
|
||||||
|
app_db_user: "osticket_user"
|
||||||
|
app_db_password: "{{ lookup('env', 'APP_DB_PASSWORD') | default('CHANGE_ME', true) }}"
|
||||||
|
domain_name: "{{ lookup('env', 'DOMAIN_NAME') | default('CHANGE_ME', true) }}"
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
- name: Полная установка osTicket
|
||||||
|
hosts: all
|
||||||
|
become: yes
|
||||||
|
become_method: sudo
|
||||||
|
gather_facts: yes
|
||||||
|
|
||||||
|
roles:
|
||||||
|
- apache
|
||||||
|
- php
|
||||||
|
- mariadb
|
||||||
|
- osticket
|
||||||
Binary file not shown.
@@ -0,0 +1,48 @@
|
|||||||
|
---
|
||||||
|
- name: Сброс пароля root MariaDB
|
||||||
|
hosts: all
|
||||||
|
become: yes
|
||||||
|
gather_facts: yes
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Stop MariaDB service
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: mariadb
|
||||||
|
state: stopped
|
||||||
|
|
||||||
|
- name: Start MariaDB in safe mode with skip-grant-tables
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
mysqld_safe --skip-grant-tables &
|
||||||
|
sleep 5
|
||||||
|
async: 10
|
||||||
|
poll: 0
|
||||||
|
|
||||||
|
- name: Reset root password
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
mysql -u root << EOF
|
||||||
|
FLUSH PRIVILEGES;
|
||||||
|
ALTER USER 'root'@'localhost' IDENTIFIED BY '{{ mariadb_root_password }}';
|
||||||
|
FLUSH PRIVILEGES;
|
||||||
|
EOF
|
||||||
|
|
||||||
|
- name: Stop MariaDB safe mode
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: mariadb
|
||||||
|
state: stopped
|
||||||
|
|
||||||
|
- name: Start MariaDB normally
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: mariadb
|
||||||
|
state: started
|
||||||
|
enabled: yes
|
||||||
|
|
||||||
|
- name: Create .my.cnf file for root user
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: |
|
||||||
|
[client]
|
||||||
|
user=root
|
||||||
|
password={{ mariadb_root_password }}
|
||||||
|
dest: /root/.my.cnf
|
||||||
|
mode: '0600'
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
- name: Restart Apache
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: apache2
|
||||||
|
state: restarted
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
---
|
||||||
|
- name: Update apt cache
|
||||||
|
ansible.builtin.apt:
|
||||||
|
update_cache: yes
|
||||||
|
cache_valid_time: 3600
|
||||||
|
|
||||||
|
- name: Install Apache
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: apache2
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Enable mod_rewrite
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: a2enmod rewrite
|
||||||
|
creates: /etc/apache2/mods-enabled/rewrite.load
|
||||||
|
notify: Restart Apache
|
||||||
|
|
||||||
|
- name: Create website root directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "/var/www/{{ domain_name }}"
|
||||||
|
state: directory
|
||||||
|
owner: www-data
|
||||||
|
group: www-data
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Configure virtual host
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: vhost.conf.j2
|
||||||
|
dest: "/etc/apache2/sites-available/{{ domain_name }}.conf"
|
||||||
|
mode: '0644'
|
||||||
|
notify: Restart Apache
|
||||||
|
|
||||||
|
- name: Enable virtual host
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "a2ensite {{ domain_name }}.conf"
|
||||||
|
creates: "/etc/apache2/sites-enabled/{{ domain_name }}.conf"
|
||||||
|
notify: Restart Apache
|
||||||
|
|
||||||
|
- name: Disable default site
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: a2dissite 000-default.conf
|
||||||
|
ignore_errors: yes
|
||||||
|
notify: Restart Apache
|
||||||
|
|
||||||
|
- name: Start and enable Apache
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: apache2
|
||||||
|
state: started
|
||||||
|
enabled: yes
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<VirtualHost *:80>
|
||||||
|
ServerName {{ domain_name }}
|
||||||
|
DocumentRoot /var/www/{{ domain_name }}
|
||||||
|
|
||||||
|
<Directory /var/www/{{ domain_name }}>
|
||||||
|
Options Indexes FollowSymLinks
|
||||||
|
AllowOverride All
|
||||||
|
Require all granted
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
ErrorLog ${APACHE_LOG_DIR}/error.log
|
||||||
|
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
||||||
|
</VirtualHost>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
mariadb_root_password: "CHANGE_ME"
|
||||||
|
app_db_name: "CHANGE_ME"
|
||||||
|
app_db_user: "CHANGE_ME"
|
||||||
|
app_db_password: "CHANGE_ME"
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
- name: Restart MariaDB
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: mariadb
|
||||||
|
state: restarted
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
---
|
||||||
|
- name: Check if MariaDB is already installed
|
||||||
|
ansible.builtin.command: dpkg -l mariadb-server
|
||||||
|
register: mariadb_installed
|
||||||
|
failed_when: false
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Check if MariaDB is running
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: mariadb
|
||||||
|
register: mariadb_status
|
||||||
|
failed_when: false
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Install MariaDB server (if not installed)
|
||||||
|
block:
|
||||||
|
- name: Install MariaDB packages
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name:
|
||||||
|
- mariadb-server
|
||||||
|
- mariadb-client
|
||||||
|
- python3-pymysql
|
||||||
|
state: present
|
||||||
|
update_cache: yes
|
||||||
|
|
||||||
|
- name: Start and enable MariaDB
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: mariadb
|
||||||
|
state: started
|
||||||
|
enabled: yes
|
||||||
|
when: mariadb_installed.rc != 0
|
||||||
|
|
||||||
|
- name: Check current root authentication method
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
sudo mysql -e "SELECT plugin FROM mysql.user WHERE user='root' AND host='localhost';" -s -N
|
||||||
|
register: root_plugin
|
||||||
|
changed_when: false
|
||||||
|
ignore_errors: yes
|
||||||
|
|
||||||
|
- name: Switch root authentication from unix_socket to password
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
sudo mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '{{ mariadb_root_password }}';"
|
||||||
|
sudo mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '{{ mariadb_root_password }}';"
|
||||||
|
sudo mysql -e "FLUSH PRIVILEGES;"
|
||||||
|
when: root_plugin.stdout == 'unix_socket'
|
||||||
|
changed_when: true
|
||||||
|
|
||||||
|
- name: Create .my.cnf for root user
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: |
|
||||||
|
[client]
|
||||||
|
user=root
|
||||||
|
password={{ mariadb_root_password }}
|
||||||
|
dest: /root/.my.cnf
|
||||||
|
mode: '0600'
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
|
||||||
|
- name: Test MySQL connection with password
|
||||||
|
ansible.builtin.command: mysql -u root -p{{ mariadb_root_password }} -e "SELECT 1"
|
||||||
|
register: mysql_test
|
||||||
|
changed_when: false
|
||||||
|
ignore_errors: yes
|
||||||
|
|
||||||
|
- name: Remove anonymous users
|
||||||
|
community.mysql.mysql_user:
|
||||||
|
name: ""
|
||||||
|
host_all: yes
|
||||||
|
login_user: root
|
||||||
|
login_password: "{{ mariadb_root_password }}"
|
||||||
|
state: absent
|
||||||
|
ignore_errors: yes
|
||||||
|
|
||||||
|
- name: Remove test database
|
||||||
|
community.mysql.mysql_db:
|
||||||
|
name: test
|
||||||
|
login_user: root
|
||||||
|
login_password: "{{ mariadb_root_password }}"
|
||||||
|
state: absent
|
||||||
|
ignore_errors: yes
|
||||||
|
|
||||||
|
- name: Check if database exists
|
||||||
|
ansible.builtin.command: mysql -u root -p{{ mariadb_root_password }} -e "USE {{ app_db_name }}"
|
||||||
|
register: db_exists
|
||||||
|
failed_when: false
|
||||||
|
changed_when: false
|
||||||
|
ignore_errors: yes
|
||||||
|
|
||||||
|
- name: Create osTicket database (if not exists)
|
||||||
|
community.mysql.mysql_db:
|
||||||
|
name: "{{ app_db_name }}"
|
||||||
|
login_user: root
|
||||||
|
login_password: "{{ mariadb_root_password }}"
|
||||||
|
state: present
|
||||||
|
when: db_exists.rc != 0
|
||||||
|
|
||||||
|
- name: Check if user exists
|
||||||
|
ansible.builtin.command: mysql -u root -p{{ mariadb_root_password }} -e "SELECT User FROM mysql.user WHERE User='{{ app_db_user }}'"
|
||||||
|
register: user_exists
|
||||||
|
failed_when: false
|
||||||
|
changed_when: false
|
||||||
|
ignore_errors: yes
|
||||||
|
|
||||||
|
- name: Create osTicket database user (if not exists)
|
||||||
|
community.mysql.mysql_user:
|
||||||
|
name: "{{ app_db_user }}"
|
||||||
|
password: "{{ app_db_password }}"
|
||||||
|
priv: "{{ app_db_name }}.*:ALL"
|
||||||
|
host: localhost
|
||||||
|
login_user: root
|
||||||
|
login_password: "{{ mariadb_root_password }}"
|
||||||
|
state: present
|
||||||
|
when: user_exists.rc != 0
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
---
|
||||||
|
- name: Install unzip
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: unzip
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Copy local osTicket ZIP to remote server
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ playbook_dir }}/osTicket.zip"
|
||||||
|
dest: /tmp/osticket.zip
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Create temp extraction directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /tmp/osticket_extract
|
||||||
|
state: directory
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Extract osTicket ZIP to temp directory
|
||||||
|
ansible.builtin.unarchive:
|
||||||
|
src: /tmp/osticket.zip
|
||||||
|
dest: /tmp/osticket_extract
|
||||||
|
remote_src: yes
|
||||||
|
|
||||||
|
- name: Find upload directory in extracted files
|
||||||
|
ansible.builtin.find:
|
||||||
|
paths: /tmp/osticket_extract
|
||||||
|
patterns: "upload"
|
||||||
|
file_type: directory
|
||||||
|
register: upload_dir
|
||||||
|
|
||||||
|
- name: Debug - show found upload directory
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "Upload directory found at: {{ upload_dir.files[0].path if upload_dir.files else 'NOT FOUND' }}"
|
||||||
|
|
||||||
|
- name: Copy files to webroot (if upload directory found)
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ upload_dir.files[0].path }}/"
|
||||||
|
dest: "/var/www/{{ domain_name }}/"
|
||||||
|
remote_src: yes
|
||||||
|
owner: www-data
|
||||||
|
group: www-data
|
||||||
|
mode: '0755'
|
||||||
|
when: upload_dir.files
|
||||||
|
|
||||||
|
- name: Copy all files to webroot (if no upload directory)
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "/tmp/osticket_extract/"
|
||||||
|
dest: "/var/www/{{ domain_name }}/"
|
||||||
|
remote_src: yes
|
||||||
|
owner: www-data
|
||||||
|
group: www-data
|
||||||
|
mode: '0755'
|
||||||
|
when: not upload_dir.files
|
||||||
|
|
||||||
|
- name: Check if sample config exists
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: "/var/www/{{ domain_name }}/include/ost-sampleconfig.php"
|
||||||
|
register: sample_config
|
||||||
|
|
||||||
|
- name: Copy configuration file
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "/var/www/{{ domain_name }}/include/ost-sampleconfig.php"
|
||||||
|
dest: "/var/www/{{ domain_name }}/include/ost-config.php"
|
||||||
|
owner: www-data
|
||||||
|
group: www-data
|
||||||
|
mode: '0666'
|
||||||
|
remote_src: yes
|
||||||
|
when: sample_config.stat.exists
|
||||||
|
|
||||||
|
- name: Set correct permissions
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "/var/www/{{ domain_name }}/include"
|
||||||
|
state: directory
|
||||||
|
owner: www-data
|
||||||
|
group: www-data
|
||||||
|
mode: '0755'
|
||||||
|
recurse: yes
|
||||||
|
|
||||||
|
- name: Create attachment directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "/var/www/{{ domain_name }}/attachments"
|
||||||
|
state: directory
|
||||||
|
owner: www-data
|
||||||
|
group: www-data
|
||||||
|
mode: '0777'
|
||||||
|
|
||||||
|
- name: Clean up temp files
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
loop:
|
||||||
|
- /tmp/osticket.zip
|
||||||
|
- /tmp/osticket_extract
|
||||||
|
|
||||||
|
- name: Display completion message
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg:
|
||||||
|
- "✅ osTicket successfully installed!"
|
||||||
|
- "📍 Access web installer at: http://{{ domain_name }}/"
|
||||||
|
- "⚠️ Complete setup via browser"
|
||||||
|
- "🔒 After installation, run: chmod 0644 /var/www/{{ domain_name }}/include/ost-config.php"
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
---
|
||||||
|
- name: Install prerequisite packages for PHP repository
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name:
|
||||||
|
- ca-certificates
|
||||||
|
- curl
|
||||||
|
- gpg
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Add PHP repository key (Ondrej)
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
curl -fsSL https://packages.sury.org/php/apt.gpg | gpg --dearmor -o /etc/apt/trusted.gpg.d/sury-php.gpg
|
||||||
|
args:
|
||||||
|
creates: /etc/apt/trusted.gpg.d/sury-php.gpg
|
||||||
|
|
||||||
|
- name: Add PHP repository
|
||||||
|
ansible.builtin.apt_repository:
|
||||||
|
repo: "deb https://packages.sury.org/php/ {{ ansible_facts['lsb']['codename'] }} main"
|
||||||
|
state: present
|
||||||
|
update_cache: yes
|
||||||
|
|
||||||
|
- name: Install PHP 8.4 and extensions
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name:
|
||||||
|
- php8.4
|
||||||
|
- libapache2-mod-php8.4
|
||||||
|
- php8.4-mysql
|
||||||
|
- php8.4-cli
|
||||||
|
- php8.4-curl
|
||||||
|
- php8.4-gd
|
||||||
|
- php8.4-mbstring
|
||||||
|
- php8.4-xml
|
||||||
|
- php8.4-zip
|
||||||
|
- php8.4-intl
|
||||||
|
- php8.4-bcmath
|
||||||
|
- php8.4-imap
|
||||||
|
state: present
|
||||||
|
notify: Restart Apache
|
||||||
|
|
||||||
|
- name: Set index.php priority
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /etc/apache2/mods-enabled/dir.conf
|
||||||
|
regexp: '^(\s*DirectoryIndex)'
|
||||||
|
line: '\1 index.php index.html index.cgi index.pl index.xhtml index.htm'
|
||||||
|
backrefs: yes
|
||||||
|
notify: Restart Apache
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
- name: Настройка sudo для пользователя без пароля
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /etc/sudoers
|
||||||
|
state: present
|
||||||
|
regexp: '^{{ ansible_user }} ALL='
|
||||||
|
line: '{{ ansible_user }} ALL=(ALL) NOPASSWD:ALL'
|
||||||
|
validate: 'visudo -cf %s'
|
||||||
|
when: ansible_user != 'root'
|
||||||
Reference in New Issue
Block a user