Pārlūkot izejas kodu

feat:增加自动化部署脚本

Yin Bin 5 mēneši atpakaļ
vecāks
revīzija
44a81ee271

+ 39 - 0
ansible.cfg

@@ -0,0 +1,39 @@
+[defaults]
+# 主机清单文件路径
+inventory = ./inventory/hosts
+
+# 并发连接数
+forks = 5
+
+# 远程连接超时时间(秒)
+timeout = 30
+
+# 禁用 SSH key 检查
+host_key_checking = False
+
+# 指定远程用户
+remote_user = root
+
+# 日志路径
+log_path = ./ansible.log
+
+# 显示任务执行时间
+callback_whitelist = profile_tasks
+
+# 显示任务执行差异
+diff = True
+
+# roles 路径
+roles_path = ./roles
+
+[privilege_escalation]
+# 是否需要切换成其他用户
+become = True
+become_method = sudo
+become_user = root
+become_ask_pass = False
+
+[ssh_connection]
+# SSH 参数配置
+ssh_args = -o ControlMaster=auto -o ControlPersist=60s
+pipelining = True

+ 19 - 0
ansible.log

@@ -0,0 +1,19 @@
+2024-11-18 13:23:27,646 p=84765 u=fy n=ansible | ERROR! Empty playbook, nothing to do: /home/fy/work/owl-admin/script/ansible/deploy_playbook.yml
+2024-11-18 13:59:52,455 p=102440 u=fy n=ansible | playbook: script/ansible/deploy_playbook.yml
+2024-11-18 13:59:53,026 p=102447 u=fy n=ansible | {
+    "ansible.builtin.runas": "Run As user",
+    "ansible.builtin.su": "Substitute User",
+    "ansible.builtin.sudo": "Substitute User DO",
+    "ansible.netcommon.enable": "Switch to elevated permissions on a network device",
+    "community.general.doas": "Do As user",
+    "community.general.dzdo": "Centrify's Direct Authorize",
+    "community.general.ksu": "Kerberos substitute user",
+    "community.general.machinectl": "Systemd's machinectl privilege escalation",
+    "community.general.pbrun": "PowerBroker run",
+    "community.general.pfexec": "profile based execution",
+    "community.general.pmrun": "Privilege Manager run",
+    "community.general.run0": "Systemd's run0",
+    "community.general.sesu": "CA Privileged Access Manager",
+    "community.general.sudosu": "Run tasks using sudo su -",
+    "containers.podman.podman_unshare": "Run tasks using podman unshare"
+}

+ 10 - 0
inventory/hosts

@@ -0,0 +1,10 @@
+[web]
+# 这里添加您的 Web 服务器
+# example.com ansible_host=192.168.1.10
+
+[db]
+# 这里添加您的数据库服务器
+# db.example.com ansible_host=192.168.1.11
+
+[all:vars]
+ansible_python_interpreter=/usr/bin/python3

+ 3 - 0
script/ansible/README.md

@@ -0,0 +1,3 @@
+# 自动部署工具使用说明
+
+

+ 9 - 0
script/ansible/bin/deploy

@@ -0,0 +1,9 @@
+#!/bin/bash
+
+# Set default APP_VERSION if not provided
+if [ -z "$APP_VERSION" ]; then
+    export APP_VERSION="latest"
+fi
+
+# Run the deploy playbook
+ansible-playbook ../deploy_playbook.yml -i ../inventory/hosts"$@"

+ 4 - 0
script/ansible/bin/frpc

@@ -0,0 +1,4 @@
+#!/bin/bash
+
+# Run the frpc playbook
+ansible-playbook ../frpc_playbook.yml -i ../inventory/hosts "$@"

+ 81 - 0
script/ansible/deploy_playbook.yml

@@ -0,0 +1,81 @@
+---
+- hosts: all
+  vars:
+    deploy_path: /www/wwwroot/xiaoding
+    backup_dir: /www/wwwroot
+    timestamp: "{{ ansible_date_time.year }}-{{ ansible_date_time.month }}-{{ ansible_date_time.day }}-{{ ansible_date_time.hour }}:{{ ansible_date_time.minute }}:{{ ansible_date_time.second }}"
+    backup_file: "xiaoding_backup_{{ timestamp }}.tar.gz"
+    project_archive: "owl-admin.tar.gz"
+
+  tasks:
+    - name: Create backup of existing deployment
+      archive:
+        path: "{{ deploy_path }}"
+        dest: "{{ backup_dir }}/{{ backup_file }}"
+        format: gz
+      ignore_errors: yes
+
+    - name: Create local project archive
+      local_action:
+        module: archive
+        path: "{{ playbook_dir }}/../../*"
+        dest: "/tmp/{{ project_archive }}"
+        format: gz
+        exclude_path:
+          - "*.git"
+          - "node_modules"
+          - "vendor"
+      run_once: true
+
+    - name: Ensure deploy directory exists
+      file:
+        path: "{{ deploy_path }}"
+        state: directory
+        mode: '0755'
+
+    - name: Copy project archive to remote
+      copy:
+        src: "/tmp/{{ project_archive }}"
+        dest: "/tmp/{{ project_archive }}"
+
+    - name: Clean deploy directory
+      file:
+        path: "{{ deploy_path }}"
+        state: absent
+
+    - name: Create deploy directory
+      file:
+        path: "{{ deploy_path }}"
+        state: directory
+        mode: '0755'
+
+    - name: Extract project archive
+      unarchive:
+        src: "/tmp/{{ project_archive }}"
+        dest: "{{ deploy_path }}"
+        remote_src: yes
+
+    - name: Run composer install
+      command:
+        cmd: composer install --no-dev
+        chdir: "{{ deploy_path }}"
+
+    - name: Set proper permissions
+      file:
+        path: "{{ deploy_path }}"
+        owner: www-data
+        group: www-data
+        recurse: yes
+        mode: '0755'
+
+    - name: Clean up remote archive
+      file:
+        path: "/tmp/{{ project_archive }}"
+        state: absent
+
+    - name: Clean up local archive
+      local_action:
+        module: file
+        path: "/tmp/{{ project_archive }}"
+        state: absent
+      run_once: true

BIN
script/ansible/frp/frpc


+ 50 - 0
script/ansible/frp/frpc.toml

@@ -0,0 +1,50 @@
+serverAddr = "47.96.151.43"
+serverPort = 7000
+
+
+
+[[proxies]]
+name = "tcp-redis"
+type = "tcp"
+localIP = "127.0.0.1"
+localPort = 6379
+remotePort = 6379
+
+[[proxies]]
+name = "http80"
+type = "tcp"
+localIP = "127.0.0.1"
+localPort = 80
+remotePort = 80
+
+[[proxies]]
+name = "test_htts2http"
+type = "https"
+customDomains = [
+"xiaodingliu.niusenyun.com",
+"xiaodingbackend.niusenyun.com",
+"saasjing.niusenyun.com",
+"massagejing.niusenyun.com",
+"saasyin.niusenyun.com",
+"mallyin.niusenyun.com",
+"saas.niusenyun.com",
+"saast.niusenyun.com",
+"mall.niusenyun.com",
+"mallt.niusenyun.com",
+"massaget.niusenyun.com",
+"massage.niusenyun.com",
+"xdyin.niusenyun.com",
+"xdjhyuser.niusenyun.com",
+"xdt.niusenyun.com"
+]
+
+
+[proxies.plugin]
+type = "https2http"
+localAddr = "127.0.0.1:80"
+
+# HTTPS 证书相关的配置
+crtPath = "/root/frp/cert.pem"
+keyPath = "/root/frp/key.pem"
+#hostHeaderRewrite = "127.0.0.1"
+requestHeaders.set.x-from-where = "frp"

+ 61 - 0
script/ansible/frpc_playbook.yml

@@ -0,0 +1,61 @@
+---
+- name: Setup and manage frpc
+  hosts: frpclient
+  become: true
+  tasks:
+    - name: Create mall directory if not exists
+      file:
+        path: /root/mall
+        state: directory
+        mode: '0755'
+
+    - name: Create frp directory if not exists
+      file:
+        path: /root/frp
+        state: directory
+        mode: '0755'
+
+    - name: Copy frp directory
+      ansible.builtin.copy:
+        src: frp
+        dest: /root
+        mode: '0644'
+        force: true
+
+    - name: Copy frpc binary to /usr/local/bin
+      copy:
+        src: "../../script/ansible/frp/frpc"
+        dest: "/usr/local/bin/frpc"
+        mode: '0755'
+
+    - name: Create systemd service file
+      copy:
+        dest: /etc/systemd/system/frpc.service
+        content: |
+          [Unit]
+          Description=frpc service
+          After=network.target
+
+          [Service]
+          Type=simple
+          User=root
+          ExecStart=/usr/local/bin/frpc -c /root/frp/frpc.toml
+          Restart=always
+          RestartSec=5
+
+          [Install]
+          WantedBy=multi-user.target
+        mode: '0644'
+
+    - name: Start and enable frpc service
+      systemd:
+        name: frpc
+        state: restarted
+        enabled: true
+        daemon_reload: true
+
+    - name: Check frpc service status
+      command: systemctl status frpc
+      register: frpc_status
+      changed_when: false
+      ignore_errors: true

+ 5 - 0
script/ansible/inventory/hosts

@@ -0,0 +1,5 @@
+[webservers]
+192.168.110.85 ansible_ssh_user=root ansible_python_interpreter=/usr/bin/python3.12
+
+[frpclient]
+192.168.110.85 ansible_ssh_user=root ansible_python_interpreter=/usr/bin/python3.12

+ 168 - 0
script/ansible/ssl.md

@@ -0,0 +1,168 @@
+# 使用acme.sh申请和安装SSL证书教程
+
+## 1. 安装acme.sh
+
+```bash
+# 安装所需工具
+apt update
+apt install -y socat curl wget
+
+# 安装acme.sh
+curl https://get.acme.sh | sh -s email=mall@niusenyun.com
+
+# 重新加载环境变量
+source ~/.bashrc
+```
+
+## 2. 清除已存在的证书
+
+```bash
+# 删除已存在的证书文件
+rm -f /root/frp/cert.pem /root/frp/key.pem
+
+# 移除acme.sh中的证书记录
+acme.sh --remove -d niusenyun.com
+acme.sh --remove -d "*.niusenyun.com"
+
+# 清除acme.sh的域名配置
+rm -rf ~/.acme.sh/niusenyun.com
+rm -rf ~/.acme.sh/*.niusenyun.com
+```
+
+## 3. 申请证书
+
+### 3.1 设置腾讯云DNS API
+
+```bash
+# 设置腾讯云API密钥(需要先在腾讯云控制台获取SecretId和SecretKey)
+export DP_Id="82be64b0a33311efbcaf475f4b5bfbc8"
+export DP_Key="d2087abec1f643329e6b7e0635043705"
+# 设置腾讯云DNS API的标识符
+userId:67371376616d0500c5162a87
+secretId:82be64b0a33311efbcaf475f4b5bfbc8
+secretKey:d2087abec1f643329e6b7e0635043705
+```
+
+### 3.2 查看DNS解析记录
+
+```bash
+# 使用腾讯云API获取解析记录
+curl -X POST https://dnspod.tencentcloudapi.com \
+  -H "Authorization: SECRET_ID" \
+  -H "Content-Type: application/json" \
+  -d '{
+    "Domain": "niusenyun.com",
+    "Subdomain": "_acme-challenge"
+  }'
+
+# 或者使用dig命令查询
+dig TXT _acme-challenge.niusenyun.com @8.8.8.8
+
+# 等待解析生效检查
+nslookup -type=TXT _acme-challenge.niusenyun.com
+```
+
+### 3.3 验证DNS记录
+
+在申请证书之前,可以先验证DNS记录是否正确设置:
+
+```bash
+# 手动添加DNS TXT记录
+# 主域名验证
+记录类型: TXT
+主机记录: _acme-challenge
+记录值: uF1OMd8vv7Yfvn5lxmR328NyXT1yzEDD0h8C8dwmOkw
+
+# 泛域名验证
+记录类型: TXT
+主机记录: _acme-challenge
+记录值: uF1OMd8vv7Yfvn5lxmR328NyXT1yzEDD0h8C8dwmOkw
+
+# 验证DNS记录是否生效
+dig _acme-challenge.niusenyun.com TXT
+
+# 等待DNS记录生效(通常需要等待1-5分钟)
+```
+
+### 3.4 网络配置(Ubuntu 24.04)
+
+```bash
+# 查看网卡状态
+ip addr
+
+# 重启网卡方法1(使用netplan)
+sudo netplan apply
+
+# 重启网卡方法2(使用systemd)
+sudo systemctl restart systemd-networkd
+
+# 重启网卡方法3(针对特定网卡)
+sudo ip link set dev [网卡名] down
+sudo ip link set dev [网卡名] up
+
+# 验证网络连接
+ping -c 4 niusenyun.com
+```
+
+### 3.5 申请证书
+
+```bash
+# 使用DNS方式验证域名所有权(腾讯云DNS)
+acme.sh --issue --dns dns_dp -d niusenyun.com -d '*.niusenyun.com' --force
+
+# 说明:dns_dp 是腾讯云DNS API的标识符
+# --force 参数用于强制重新申请证书
+```
+
+## 4. 安装证书到frp指定目录
+
+```bash
+# 创建证书存放目录
+mkdir -p /root/frp
+
+# 安装证书到指定目录(PEM格式)
+acme.sh --install-cert -d niusenyun.com \
+--key-file /root/frp/key.pem \
+--fullchain-file /root/frp/cert.pem \
+--reloadcmd "systemctl restart frpc"
+```
+
+## 5. 验证证书
+
+```bash
+# 查看证书内容
+openssl x509 -in /root/frp/cert.pem -text -noout
+
+# 验证私钥
+openssl rsa -in /root/frp/key.pem -check
+```
+
+## 6. 自动更新
+
+acme.sh会自动创建一个cron任务,每天检查并在需要时自动更新证书,无需手动操作。
+
+可以通过以下命令查看cron任务:
+```bash
+crontab -l
+```
+
+## 注意事项
+
+1. 已配置域名为:niusenyun.com(包含泛域名 *.niusenyun.com)
+2. 替换`your-secret-id`和`your-secret-key`为腾讯云API密钥(在腾讯云控制台 -> 访问密钥 -> API密钥管理中获取)
+3. 确保域名已正确解析到服务器IP
+4. DNS记录生效可能需要一些时间,如果证书申请失败,请等待几分钟后重试
+
+## 故障排查
+
+如果遇到问题,可以查看以下日志:
+
+```bash
+# 查看acme.sh日志
+acme.sh --log
+
+# 检查证书权限
+ls -l /root/frp/cert.pem /root/frp/key.pem
+
+# 检查DNS记录
+dig _acme-challenge.niusenyun.com TXT