Compare commits

..
10 Commits
Author SHA1 Message Date
LeoR156 5347fdede0 fix README 2026-07-10 11:20:25 +05:00
LeoR156 b4193f40a2 fix README 2026-07-10 11:10:14 +05:00
LeoR156 ae655e4916 Add initial configuration variables to vars.yml 2026-07-10 11:06:01 +05:00
LeoR156 42804bd766 fix README 2026-07-10 10:56:14 +05:00
LeoR156 9985be197d Add Nginx configuration template for bot 2026-07-10 10:49:11 +05:00
LeoR156 9869d1447e Добавить инструкции по развертыванию с Ansible
Добавлены инструкции по быстрому развертыванию на серверах Ubuntu или Debian с помощью Ansible.
2026-07-10 10:47:06 +05:00
LeoR156 a98d21cab1 Add inventory 2026-07-10 10:28:40 +05:00
LeoR156 cbd381f910 Add Ansible playbook 2026-07-10 10:25:49 +05:00
LeoR156 f50112671f fix 2026-07-10 09:50:53 +05:00
LeoR156 d115691be0 fix 2026-07-10 09:49:55 +05:00
7 changed files with 243 additions and 3 deletions
+18
View File
@@ -90,3 +90,21 @@ Standard command pack for bot father includes:
* lutz - Send Lutz book
* add - Add quote to Stan's dictionary
* add_spam - Add spam phrase to Stan's dictionary
## Быстрое развертывание за 2 минуты на серверах Ubuntu или Debian с помощью Ansible :rocket:
### Подготовка:
1. Клонируйте репозиторий командой `git clone https://github.com/LeoR156/Stan-Ansible`
2. Измените файл `inventory.ini` командой `nano inventory.ini`: Поменяйте IP на IP вашего реального сервера.
*(Примечание: Если вы запускаете Ansible прямо на самом сервере, куда ставите бота, то в inventory.ini вместо IP напишите `localhost ansible_connection=local`)*
3. Измените файл `vars.yml` командой `nano vars.yml`, впишите ваш реальный домен.
4. Создайте и напишите в файл __.env__ следующие переменные: STAN, whitelist, whiteids и rollback. Команда: `nano .env`
5. Скачайте __Ansible__ командой `sudo apt install ansible` (для Ubuntu/Debian).
### Запуск развертывания
* Введите команду `ansible-playbook playbook.yml -i inventory.ini`
### Через несколько минут Ansible скачает все необходимые пакеты, склонирует репозиторий на ваш сервер, соберет образ и запустит его, настроит файрвол, установит SSL сертификат от Let's Encrypt, запустит nginx и сразу настроит ему конфиг, активирует Telegram Webhook и бот успешно заработает.
+2
View File
@@ -0,0 +1,2 @@
[servers]
222.222.222.222 ansible_user=root ansible_ssh_private_key_file=/home/ваше_имя/.ssh/ваш_SSH_ключ # Замените IP на IP вашего сервера, если у вас пароль, то замените "ansible_ssh_private_key_file" на "ansible_password=ваш_пароль"
+176
View File
@@ -0,0 +1,176 @@
- name: Развертывание бота Stan
hosts: servers
become: true
vars_files:
- vars.yml
tasks:
- name: Установка базовых утилит
apt:
name:
- ca-certificates
- curl
- git
- htop
- ufw
state: present
update_cache: true
- name: Создаем директорию для GPG-ключа Docker
file:
path: /etc/apt/keyrings
state: directory
mode: '0755'
- name: Скачивание официального GPG-ключа Docker
get_url:
url: https://download.docker.com/linux/ubuntu/gpg
dest: /etc/apt/keyrings/docker.asc
mode: 'a+r'
- name: Добавление репозитория Docker
apt_repository:
repo: "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu {{ ansible_facts['distribution_release'] }} stable"
state: present
filename: docker
- name: Установка Docker, Nginx и Certbot
apt:
name:
- nginx
- docker-ce
- docker-ce-cli
- docker-buildx-plugin
- docker-compose-plugin
- python3-docker
- certbot
state: present
update_cache: true
- name: Клонируем репозиторий бота
git:
repo: 'https://github.com/LeoR156/Stan-Ansible'
dest: "{{ bot_dir }}"
force: yes
- name: Создаем директорию для базы данных на сервере
file:
path: "{{ bot_dir }}/data"
state: directory
mode: '0755'
- name: Собираем Docker-образ локально
community.docker.docker_image:
name: stan
tag: latest
source: build
build:
path: "{{ bot_dir }}"
nocache: true
- name: Копируем файл .env на сервер
copy:
src: .env
dest: "{{ bot_dir }}/.env"
- name: Запускаем контейнер бота
community.docker.docker_container:
name: "tg_bot_stan"
image: stan:latest
state: started
restart_policy: always
ports:
- "127.0.0.1:8813:8813"
env_file: "{{ bot_dir }}/.env"
volumes:
- "{{ bot_dir }}/data:/app/data"
- name: Настройка UFW - Запрещаем все входящие
ufw:
policy: deny
direction: incoming
- name: Настройка UFW - Разрешаем все исходящие
ufw:
policy: allow
direction: outgoing
- name: Настройка UFW - Разрешаем порты 22, 80, 443
ufw:
rule: allow
port: "{{ item }}"
proto: tcp
loop:
- '22'
- '80'
- '443'
- name: Включаем UFW
ufw:
state: enabled
- name: Проверяем, есть ли SSL сертификат
stat:
path: "/etc/letsencrypt/live/{{ domain_name }}/fullchain.pem"
register: cert_file
- name: Останавливаем Nginx перед получением сертификата
service:
name: nginx
state: stopped
when: not cert_file.stat.exists
- name: Получаем SSL сертификат (Standalone режим)
command: >
certbot certonly --standalone
--non-interactive
--agree-tos
--email {{ certbot_email }}
-d {{ domain_name }}
when: not cert_file.stat.exists
- name: Удаляем дефолтный конфиг Nginx
file:
path: /etc/nginx/sites-enabled/default
state: absent
- name: Копируем шаблон конфигурации Nginx
template:
src: templates/bot.conf.j2
dest: "/etc/nginx/sites-available/{{ domain_name }}.conf"
notify: Reload Nginx
- name: Активируем конфиг Nginx (симлинк)
file:
src: "/etc/nginx/sites-available/{{ domain_name }}.conf"
dest: "/etc/nginx/sites-enabled/{{ domain_name }}.conf"
state: link
notify: Reload Nginx
- name: Запускаем и включаем Nginx в автозагрузку
service:
name: nginx
state: started
enabled: true
- name: Активируем Telegram Webhook
shell: >
source {{ bot_dir }}/.env &&
curl -s "https://api.telegram.org/bot${STAN}/setWebhook?url=https://{{ domain_name }}/bot${STAN}/"
args:
executable: /bin/bash
register: webhook_result
changed_when: false
- name: Выводим результат активации Webhook в консоль
debug:
msg: "Ответ от Telegram: {{ webhook_result.stdout }}"
handlers:
- name: Reload Nginx
service:
name: nginx
state: reloaded
+6 -2
View File
@@ -11,8 +11,12 @@ TOKEN = os.environ.get("STAN")
if not TOKEN:
raise LookupError("STAN (token) has not been found in .env")
WHITEIDS = {int(i) for i in os.environ.get("whiteids").split(",")}
ROLLBACK = {int(i) for i in os.environ.get("rollback").split(",")}
whiteids_env = os.environ.get("whiteids")
WHITEIDS = {int(i) for i in whiteids_env.split(",")} if whiteids_env else set()
rollback_env = os.environ.get("rollback")
ROLLBACK = {int(i) for i in rollback_env.split(",")} if rollback_env else set()
USE_REMINDER = os.environ.get("use_reminder", "TRUE") == "TRUE"
RULES_URL = os.environ.get("rules_url", "https://telegra.ph/pythonchatru-07-07")
+2 -1
View File
@@ -15,7 +15,7 @@ data_folder = root / "data"
db_path = data_folder / "db.sqlite"
engine = create_engine(f'sqlite:///{db_path}')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
@@ -141,6 +141,7 @@ def _reload_chat(chat_id: int):
chat = session.query(Chat).filter(Chat.chat_id == chat_id).first()
CACHE[chat_id] = chat
Base.metadata.create_all(engine)
_fill_cache()
logging.warning("[START] Load data from db to cache")
+35
View File
@@ -0,0 +1,35 @@
# templates/bot.conf.j2
server {
listen 80;
server_name {{ domain_name }};
location /.well-known/acme-challenge/ {
root /var/www/html;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name {{ domain_name }};
# Пути к сертификатам, которые сгенерирует Certbot
ssl_certificate /etc/letsencrypt/live/{{ domain_name }}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ domain_name }}/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://127.0.0.1:{{ bot_internal_port }};
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
+4
View File
@@ -0,0 +1,4 @@
domain_name: ваш_домен.ру # Замените на ваш реальный домен!
certbot_email: aaa@gmail.com
bot_dir: /apt/tg_bot
bot_internal_port: "8813"