first commit

This commit is contained in:
2026-04-05 18:17:09 +07:00
commit 97109c2336
77 changed files with 2913 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
[defaults]
inventory = inventory/hosts.ini
roles_path = roles
host_key_checking = False
retry_files_enabled = False
interpreter_python = auto_silent
collections_path = ./collections
[privilege_escalation]
become = True
+16
View File
@@ -0,0 +1,16 @@
---
# Публичные переменные плейбука (секреты — в vault.yml, см. vault.yml.example).
project_domain: app.example.com
letsencrypt_email: admin@example.com
deploy_user: deploy
project_path: "/home/{{ deploy_user }}/laravel"
# Репозиторий (публичный). Для приватного задайте vault_git_repo_url в vault.yml.
git_repo_url_public: "https://gitlab.com/yourgroup/yourproject.git"
git_branch: main
gitlab_url: "https://gitlab.com/"
# Публичные SSH-ключи для входа пользователя deploy (строки authorized_keys).
deploy_authorized_keys: []
@@ -0,0 +1,20 @@
---
# Скопируйте в vault.yml и зашифруйте: ansible-vault encrypt group_vars/laravel/vault.yml
# ansible-vault edit group_vars/laravel/vault.yml
# Обязательно: токен регистрации GitLab Runner (Settings → CI/CD → Runners).
vault_gitlab_runner_token: "glrt-xxxxxxxxxxxxxxxxxxxx"
# Пароли БД и корня MySQL (должны совпадать с шаблоном docker/app.env).
vault_mysql_password: "сгенерируйте_надёжный_пароль"
vault_mysql_root_password: "сгенерируйте_надёжный_root"
# Ключ приложения Laravel: сгенерируйте локально `php artisan key:generate --show`
vault_app_key: "base64:................................................"
# Опционально: полный URL клона приватного репозитория (перекрывает git_repo_url_public).
# Пример: https://oauth2:glpat-xxx@gitlab.com/group/project.git
vault_git_repo_url: ""
# Опционально: пароль для пользователя БД при отличии от vault_mysql_password (редко нужно).
vault_db_username: "db"
+4
View File
@@ -0,0 +1,4 @@
[laravel]
# Скопируйте этот файл в hosts.ini и укажите адрес чистого Debian 11.
# cp inventory/hosts.ini.example inventory/hosts.ini
debian11 ansible_host=203.0.113.10 ansible_user=root
+12
View File
@@ -0,0 +1,12 @@
---
# Полный разворот: Debian 11 → Docker, приложение, TLS, GitLab Runner.
- name: Laravel Docker инфраструктура
hosts: laravel
become: true
roles:
- role: common
- role: docker
- role: security
- role: laravel_docker
- role: nginx_letsencrypt
- role: gitlab_runner
+49
View File
@@ -0,0 +1,49 @@
---
- name: Обновить кэш apt
ansible.builtin.apt:
update_cache: true
cache_valid_time: 3600
- name: Базовые пакеты
ansible.builtin.apt:
name:
- curl
- git
- acl
- ca-certificates
- gnupg
- software-properties-common
state: present
- name: Пользователь деплоя
ansible.builtin.user:
name: "{{ deploy_user }}"
shell: /bin/bash
create_home: true
- name: Каталог .ssh для {{ deploy_user }}
ansible.builtin.file:
path: "/home/{{ deploy_user }}/.ssh"
state: directory
owner: "{{ deploy_user }}"
group: "{{ deploy_user }}"
mode: "0700"
- name: authorized_keys для {{ deploy_user }}
ansible.builtin.lineinfile:
path: "/home/{{ deploy_user }}/.ssh/authorized_keys"
line: "{{ item }}"
create: true
mode: "0600"
owner: "{{ deploy_user }}"
group: "{{ deploy_user }}"
loop: "{{ deploy_authorized_keys }}"
when: deploy_authorized_keys | length > 0
- name: Каталог проекта
ansible.builtin.file:
path: "{{ project_path }}"
state: directory
owner: "{{ deploy_user }}"
group: "{{ deploy_user }}"
mode: "0755"
+19
View File
@@ -0,0 +1,19 @@
---
- name: Docker и плагин Compose (Debian)
ansible.builtin.apt:
name:
- docker.io
- docker-compose-plugin
state: present
- name: Сервис Docker
ansible.builtin.service:
name: docker
state: started
enabled: true
- name: Пользователь {{ deploy_user }} в группе docker
ansible.builtin.user:
name: "{{ deploy_user }}"
groups: docker
append: true
@@ -0,0 +1,39 @@
---
- name: Скрипт репозитория GitLab Runner
ansible.builtin.get_url:
url: https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh
dest: /tmp/gitlab-runner-repo.sh
mode: "0755"
- name: Подключить репозиторий GitLab Runner
ansible.builtin.command: bash /tmp/gitlab-runner-repo.sh
args:
creates: /etc/apt/sources.list.d/runner_gitlab-runner.list
- name: Установить gitlab-runner
ansible.builtin.apt:
name: gitlab-runner
state: present
update_cache: true
- name: Проверить наличие зарегистрированных runner
ansible.builtin.stat:
path: /etc/gitlab-runner/config.toml
register: gitlab_runner_cfg
- name: Зарегистрировать GitLab Runner (docker executor + docker.sock)
ansible.builtin.shell: |
set -e
gitlab-runner register \
--non-interactive \
--url "{{ gitlab_url }}" \
--token "{{ vault_gitlab_runner_token }}" \
--executor "docker" \
--docker-image "docker:24-cli" \
--docker-volumes "/var/run/docker.sock:/var/run/docker.sock" \
--description "debian-ansible" \
--tag-list "docker" \
--run-untagged=false \
--locked=false
when: not gitlab_runner_cfg.stat.exists
no_log: true
@@ -0,0 +1,30 @@
---
- name: Эффективный URL Git
ansible.builtin.set_fact:
effective_git_repo_url: "{{ (vault_git_repo_url | default('') | length > 0) | ternary(vault_git_repo_url, git_repo_url_public) }}"
- name: Клонирование приложения
ansible.builtin.git:
repo: "{{ effective_git_repo_url }}"
dest: "{{ project_path }}"
version: "{{ git_branch }}"
force: false
accept_hostkey: true
become_user: "{{ deploy_user }}"
- name: Конфигурация docker/app.env для Laravel и Compose
ansible.builtin.template:
src: docker.app.env.j2
dest: "{{ project_path }}/docker/app.env"
owner: "{{ deploy_user }}"
group: "{{ deploy_user }}"
mode: "0600"
- name: Запуск стека Docker Compose
ansible.builtin.shell: |
set -e
cd {{ project_path }}
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build --remove-orphans
become_user: "{{ deploy_user }}"
args:
executable: /bin/bash
@@ -0,0 +1,37 @@
# Сгенерировано Ansible — не редактируйте вручную на сервере (обновляйте vault и плейбук).
MYSQL_DATABASE=laravel
MYSQL_USER={{ vault_db_username | default('db') }}
MYSQL_PASSWORD={{ vault_mysql_password }}
MYSQL_ROOT_PASSWORD={{ vault_mysql_root_password }}
APP_NAME=Laravel
APP_ENV=production
APP_KEY={{ vault_app_key }}
APP_DEBUG=false
APP_URL=https://{{ project_domain }}
LOG_CHANNEL=stack
LOG_LEVEL=warning
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME={{ vault_db_username | default('db') }}
DB_PASSWORD={{ vault_mysql_password }}
SESSION_DRIVER=file
CACHE_STORE=file
FILESYSTEM_DISK=local
QUEUE_CONNECTION=redis
REDIS_CLIENT=phpredis
REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=log
PMA_ABSOLUTE_URI=https://{{ project_domain }}/pma/
@@ -0,0 +1,56 @@
---
- name: Nginx и certbot
ansible.builtin.apt:
name:
- nginx
- certbot
- python3-certbot-nginx
state: present
update_cache: true
- name: Виртуальный хост (HTTP → Docker)
ansible.builtin.template:
src: laravel.nginx.conf.j2
dest: /etc/nginx/sites-available/laravel.conf
mode: "0644"
- name: Включить сайт
ansible.builtin.file:
src: /etc/nginx/sites-available/laravel.conf
dest: /etc/nginx/sites-enabled/laravel.conf
state: link
force: true
- name: Отключить default сайт
ansible.builtin.file:
path: /etc/nginx/sites-enabled/default
state: absent
- name: Проверить и перезагрузить nginx
ansible.builtin.command: nginx -t
changed_when: false
- name: Перезапуск nginx
ansible.builtin.service:
name: nginx
state: reloaded
- name: Получить сертификат Let's Encrypt
ansible.builtin.command: >
certbot --nginx
-d {{ project_domain }}
--non-interactive
--agree-tos
-m {{ letsencrypt_email }}
--redirect
args:
creates: /etc/letsencrypt/live/{{ project_domain }}/fullchain.pem
tags:
- letsencrypt
- name: Автообновление сертификатов (timer или cron от пакета certbot)
ansible.builtin.service:
name: certbot.timer
state: started
enabled: true
ignore_errors: true
@@ -0,0 +1,15 @@
server {
listen 80;
listen [::]:80;
server_name {{ project_domain }};
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
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;
proxy_read_timeout 120s;
}
}
+25
View File
@@ -0,0 +1,25 @@
---
- name: Пакет ufw
ansible.builtin.apt:
name: ufw
state: present
- name: Разрешить входящие порты
ansible.builtin.command: ufw allow {{ item }}/tcp
loop:
- "22"
- "80"
- "443"
register: ufw_allow
changed_when: "'added' in ufw_allow.stdout | default('') | lower or 'updated' in ufw_allow.stdout | default('') | lower"
failed_when: false
- name: Политика по умолчанию — запрет входящих
ansible.builtin.command: ufw default deny incoming
changed_when: false
- name: Включить ufw
ansible.builtin.command: ufw --force enable
register: ufw_en
changed_when: "'Firewall is active' in ufw_en.stdout | default('') or ufw_en.rc == 0"
failed_when: false