Browse Source

:wrench: add systemd services support

China Kassapa 2 months ago
parent
commit
46e05eee7e

+ 8 - 9
deploy/group_vars/all.yml

@@ -2,24 +2,23 @@ ansible_user: "deploy"
 ansible_python_interpreter: /usr/bin/python3
 ansible_ssh_private_key_file: "{{ inventory_dir }}/.ssh/id_ed25519"
 
-app_deploy_target: "/srv/{{ app_domain }}/mint-{{ mint_version }}"
+app_deploy_target: "/srv/{{ app_domain }}/{{ mint_version }}"
 app_debug: false
 
 app_api_v8_php_base_path: "/api"
-app_api_v8_php_version: "8.1"
-app_api_v8_php_fpm_port: 9810
-app_api_v8_php_image: "wikipali/mint:php-8.1-20251225"
-
 app_api_v12_php_base_path: "/api-v2026"
-app_api_v12_php_version: "8.4"
-app_api_v12_php_fpm_port: 9840
-app_api_v12_php_image: "wikipali/mint:php-8.4-20260108"
-
 app_dashboard_v4_base_path: "/pcd"
 app_dashboard_v6_base_path: "/pcd-v2026"
 
 app_dashboard_token_key: "token.20260116"
 app_php_memory_limit: "128M"
 app_consumer_loop_limit_ai_translate: 16
+app_deploy_keeps: 7
+
+app_php_fpm81_port: 9840
+app_php_fpm84_port: 9810
 
+app_php81_image: "wikipali/mint:php-8.1-20251225"
+app_php84_image: "wikipali/mint:php-8.4-20260108"
 app_python_image: "wikipali/mint:php-8.4-20260108"
+app_nodejs_image: "wikipali/mint:php-8.4-20260108"

+ 20 - 2
deploy/mint.yml

@@ -1,10 +1,28 @@
-- name: Building mint release package
+- name: Prepare the env
   hosts: localhost
+  tasks:
+    - name: Check if mint.tar.xz file exists
+      ansible.builtin.stat:
+        path: "{{ playbook_dir }}/tmp/{{ app_domain }}-{{ mint_version }}.tar.xz"
+      register: mint_release_file_status
+
+- name: Building release package
+  hosts: localhost      
   roles:
-    - mint-build-v2.3
+    - role: mint-build-v2.3
+      when: not mint_release_file_status.stat.exists
   vars:
     app_workspace: "{{ ansible_facts['env']['HOME'] }}/build/mint"
 
+- name: Upload and setup release package
+  hosts:
+    - task
+    - php_fpm
+    - task
+    - ai_translate
+    - openai_proxy
+  roles:
+    - role: mint-v2.3
 
 # - name: Setup local build folder
 #   hosts: localhost

+ 29 - 27
deploy/roles/mint-build-v2.3/tasks/main.yml

@@ -2,7 +2,7 @@
   ansible.builtin.file:
     path: "{{ app_workspace | dirname }}"
     state: directory
-    owner: "{{ ansible_user }}"
+    # owner: "{{ ansible_user }}"
     mode: "0755"
 
 - name: Git checkout mint repo
@@ -47,7 +47,7 @@
   args:
     executable: /bin/bash
     chdir: "{{ app_workspace }}/dashboard-v4/dashboard"
-    creates: "{{ app_workspace }}/tmp/{{ app_domain }}-{{ mint_version }}/dashboard-v6"
+    creates: "{{ app_workspace }}/tmp/{{ app_domain }}-{{ mint_version }}/dashboard-v4"
   environment:
     BUILD_PATH: "{{ app_workspace }}/tmp/{{ app_domain }}-{{ mint_version }}/dashboard-v4"
     NODE_OPTIONS: "--max_old_space_size=5120"
@@ -68,7 +68,7 @@
 
 - name: Build dashboard-v6
   ansible.builtin.shell: |
-    source ~/.nvm/nvm.sh && vite build --base={{ app_dashboard_v6_base_path }} --outDir {{ app_workspace }}/tmp/{{ app_domain }}-{{ mint_version }}/dashboard-v6
+    source ~/.nvm/nvm.sh && npm run build -- --base={{ app_dashboard_v6_base_path }} --outDir {{ app_workspace }}/tmp/{{ app_domain }}-{{ mint_version }}/dashboard-v6
   args:
     executable: /bin/bash
     chdir: "{{ app_workspace }}/dashboard-v6"
@@ -90,7 +90,7 @@
     
 - name: Build open-ai proxy server
   ansible.builtin.shell: |
-    source ~/.nvm/nvm.sh && webpack --config webpack.config.js --output-path {{ app_workspace }}/open-ai-server
+    source ~/.nvm/nvm.sh && npm run build -- --output-path {{ app_workspace }}/tmp/{{ app_domain }}-{{ mint_version }}/open-ai-server
   args:
     executable: /bin/bash
     chdir: "{{ app_workspace }}/open-ai-server"
@@ -99,31 +99,33 @@
     NODE_ENV: production
     
 - name: Copy api-v8 to release folder
-  ansible.builtin.copy:
-    remote: true
+  ansible.posix.synchronize:    
     src: "{{ app_workspace }}/api-v8"
-    dest: "{{ app_workspace }}/tmp/{{ app_domain }}-{{ mint_version }}/api-v8/"
-    mode: '0755'
-  args:
-    creates: "{{ app_workspace }}/tmp/{{ app_domain }}-{{ mint_version }}/api-v8"
-
+    dest: "{{ app_workspace }}/tmp/{{ app_domain }}-{{ mint_version }}/api-v8"
+    recursive: true
+    
 - name: Copy api-v12 to release folder
-  ansible.builtin.copy:
-    remote: true
+  ansible.posix.synchronize:    
     src: "{{ app_workspace }}/api-v12"
-    dest: "{{ app_workspace }}/tmp/{{ app_domain }}-{{ mint_version }}/api-v12/"
-    mode: '0755'
+    dest: "{{ app_workspace }}/tmp/{{ app_domain }}-{{ mint_version }}/api-v12"
+    recursive: true
+    
+# - name: Archive release.tar.xz
+#   community.general.archive:
+#     path: "{{ app_workspace }}/tmp/{{ app_domain }}-{{ mint_version }}/*"
+#     dest: "{{ app_workspace }}/tmp/{{ app_domain }}-{{ mint_version }}.tar.xz"
+#     format: xz
+#     remove: true
+
+- name: Archive release.tar.xz
+  ansible.builtin.shell: tar --remove-files -cJf {{ app_workspace }}/tmp/{{ app_domain }}-{{ mint_version }}.tar.xz -C {{ app_workspace }}/tmp/{{ app_domain }}-{{ mint_version }} .
   args:
-    creates: "{{ app_workspace }}/tmp/{{ app_domain }}-{{ mint_version }}/api-v12"
+    creates: "{{ app_workspace }}/tmp/{{ app_domain }}-{{ mint_version }}.tar.xz"
+  environment:
+    XZ_OPT: "-9"
 
-- name: Archive only the contents of the /var/www/html folder
-  community.general.archive:
-    path: "{{ app_workspace }}/tmp/{{ app_domain }}-{{ mint_version }}/*"
-    dest: "{{ app_workspace }}/tmp/{{ app_domain }}-{{ mint_version }}.tar.xz"
-    format: xz
-    remove: true
- 
-- name: Download mint.tar.xz
-    ansible.builtin.fetch:
-      src: "{{ app_workspace }}/tmp/{{ app_domain }}-{{ mint_version }}.tar.xz"
-      dest: "{{ playbook_dir }}/tmp/"
+- name: Download release.tar.xz
+  ansible.builtin.fetch:
+    src: "{{ app_workspace }}/tmp/{{ app_domain }}-{{ mint_version }}.tar.xz"
+    dest: "{{ playbook_dir }}/tmp/"
+    flat: true

+ 17 - 0
deploy/roles/mint-v2.3/files/clean.py

@@ -0,0 +1,17 @@
+#!/usr/bin/env python3
+
+import logging
+
+logger = logging.getLogger(__name__)
+
+def launch(keeps):
+    # TODO
+    root = "change-me"
+    logger.warning("try to clean %s and keep %d records", root, keeps)
+    logger.info("done.")
+    
+if __name__ == "__main__":
+    logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname).1s %(name)s: %(message)s')
+    # TODO
+    launch(7)
+    

+ 8 - 0
deploy/roles/mint-v2.3/files/php-fpm.sh

@@ -0,0 +1,8 @@
+#!/bin/bash
+
+set -e
+
+# TODO
+sleep 60*60*24
+
+exit 0

+ 4 - 0
scripts/container/mint.sh → deploy/roles/mint-v2.3/files/run.sh

@@ -15,6 +15,10 @@ if [[ "$ID" != "ubuntu" ]]; then
 fi
 # -----------------------------------------------------------------------------
 
+# TODO 
+
+# php artisan mq:wbw.analyses
+
 if [[ "$#" -eq 1 && "$1" == "diagnose" ]]; then
     php --version
     echo "NodeJs: $(node -v)"

+ 0 - 0
deploy/roles/mint-v2.3/tasks/build.yml


+ 128 - 3
deploy/roles/mint-v2.3/tasks/main.yml

@@ -1,3 +1,128 @@
-- name: Setup clove
-  ansible.builtin.import_tasks: build.yml
-  
+- name: Create /srv/bin folder
+  become: true
+  ansible.builtin.file:
+    path: /srv/bin
+    state: directory
+    owner: "{{ ansible_user }}"
+    mode: "0755"
+
+- name: Create workspace folder
+  become: true
+  ansible.builtin.file:
+    path: "{{ app_deploy_target | dirname }}"
+    state: directory
+    owner: "{{ ansible_user }}"
+    mode: "0755"
+
+- name: Create scripts folder
+  ansible.builtin.file:
+    path: "{{ app_deploy_target }}/scripts"
+    state: directory
+    mode: "0755"
+
+- name: Extract release
+  ansible.builtin.unarchive:
+    src: "{{ playbook_dir }}/tmp/{{ app_domain }}-{{ mint_version }}.tar.xz"
+    dest: "{{ app_deploy_target }}"
+    creates: "{{ app_deploy_target }}/api-v12"
+
+- name: Pull php v8.1 image
+  ansible.builtin.shell: docker pull {{ app_php81_image }}
+
+- name: Pull php v8.4 image
+  ansible.builtin.shell: docker pull {{ app_php84_image }}
+
+- name: Pull python image
+  ansible.builtin.shell: docker pull {{ app_python_image }}
+
+- name: Pull nodejs image
+  ansible.builtin.shell: docker pull {{ app_nodejs_image }}
+
+- name: Upload clean.py
+  ansible.builtin.copy:
+    src: clean.py
+    dest: "{{ app_deploy_target | dirname }}/"
+    mode: '0444'
+
+- name: Upload run.sh
+  ansible.builtin.copy:
+    src: run.sh
+    dest: "{{ app_deploy_target }}/"
+    mode: '0555'
+
+- name: Upload php-fpm.sh
+  ansible.builtin.copy:
+    src: php-fpm.sh
+    dest: "/srv/bin/"
+    mode: '0555'
+
+- name: Upload clean.service
+  become: true
+  ansible.builtin.template:
+    src: clean.service.j2
+    dest: "/etc/systemd/system/{{ app_domain }}-clean.service"
+    mode: "0444"
+
+- name: Upload timer.service
+  become: true
+  ansible.builtin.template:
+    src: clean.timer.j2
+    dest: "/etc/systemd/system/{{ app_domain }}-clean.timer"
+    mode: "0444"
+
+- name: Upload php-fpm-v8.1.service
+  become: true
+  ansible.builtin.template:
+    src: php-fpm-8.1.service.j2
+    dest: "/etc/systemd/system/php-fpm-8.1.service"
+    mode: "0444"
+
+- name: Upload php-fpm-8.4.service
+  become: true
+  ansible.builtin.template:
+    src: php-fpm-8.4.service.j2
+    dest: "/etc/systemd/system/php-fpm-8.4.service"
+    mode: "0444"
+
+- name: Upload open-ai-server.sh
+  ansible.builtin.template:
+    src: open-ai-server.sh.j2
+    dest: "{{ app_deploy_target }}/scripts/open-ai-server.sh"
+    mode: "0555"
+
+- name: Upload open-ai-server.service
+  become: true
+  ansible.builtin.template:
+    src: open-ai-server.service.j2
+    dest: "/etc/systemd/system/{{ app_domain }}-open-ai-server.service"
+    mode: "0444"
+
+
+- name: Upload laravel-job.sh
+  ansible.builtin.template:
+    src: laravel-job.sh.j2
+    dest: "{{ app_deploy_target }}/scripts/laravel-job.sh"
+    mode: "0555"
+
+- name: Upload laravel-worker.service
+  become: true
+  ansible.builtin.template:
+    src: laravel-job.service.j2
+    dest: "/etc/systemd/system/{{ app_domain }}-laravel-job-{{ item.name }}.service"
+    mode: "0444"
+  with_items:
+    - { name: "mq-discussion", image: "{{ app_php81_image }}"}
+    - { name: "mq-pr", image: "{{ app_php81_image }}"}
+    - { name: "mq-progress", image: "{{ app_php81_image }}"}
+    - { name: "mq-wbw.analyses", image: "{{ app_php81_image }}"}
+
+- name: Reload systemd profiles
+  become: true
+  ansible.builtin.shell: systemctl daemon-reload
+
+- name: Enable clean timer
+  become: true
+  ansible.builtin.systemd_service:
+    name: "{{ app_domain }}-clean.timer"
+    state: started
+    enabled: true

+ 14 - 0
deploy/roles/mint-v2.3/templates/clean.service.j2

@@ -0,0 +1,14 @@
+[Unit]
+Description=Clean legacy files({{ app_domain }}).
+Wants=network-online.target
+After=network-online.target
+
+[Service]
+Type=oneshot
+User=root
+Group=root
+ExecStart=/usr/bin/python3 clean.py -k {{ app_deploy_keeps }}
+WorkingDirectory={{ app_deploy_target | dirname }}
+
+[Install]
+WantedBy=multi-user.target

+ 9 - 0
deploy/roles/mint-v2.3/templates/clean.timer.j2

@@ -0,0 +1,9 @@
+[Unit]
+Description=Clean legacy files daily({{ app_domain }}).e.
+
+[Timer]
+OnCalendar=*-*-* 3:00:00
+Persistent=false
+
+[Install]
+WantedBy=timers.target

+ 15 - 0
deploy/roles/mint-v2.3/templates/laravel-job.service.j2

@@ -0,0 +1,15 @@
+[Unit]
+Description=laravel job({{ app_domain }}-{{ item.name }}).
+Wants=network-online.target
+After=network-online.target
+
+[Service]
+Type=simple
+User={{ ansible_user }}
+ExecStart=/usr/bin/docker run --rm --name {{ app_domain }}-laravel-job-{{ item.name }} -v /srv:/srv:z {{ item.image }} {{ app_deploy_target }}/scripts/laravel-job.sh {{ item.name }}
+ExecStop=/usr/bin/docker stop {{ app_domain }}-laravel-job-{{ item.name }}
+WorkingDirectory={{ app_deploy_target }}
+Restart=always
+
+[Install]
+WantedBy=multi-user.target

+ 4 - 0
scripts/container/run.sh → deploy/roles/mint-v2.3/templates/laravel-job.sh.j2

@@ -1,3 +1,7 @@
 #!/bin/bash
 
 set -e
+
+# TODO
+
+exit 0

+ 15 - 0
deploy/roles/mint-v2.3/templates/open-ai-server.service.j2

@@ -0,0 +1,15 @@
+[Unit]
+Description=open-ai server({{ app_domain }}).
+Wants=network-online.target
+After=network-online.target
+
+[Service]
+Type=simple
+User={{ ansible_user }}
+ExecStart=/usr/bin/docker run --rm --name {{ app_domain }}-open-ai-server -p 127.0.0.1:{{ app_openai_proxy_listen_port }}:8080/tcp -v /srv:/srv:z {{ app_nodejs_image }} {{ app_deploy_target }}/scripts/open-ai-server.sh
+ExecStop=/usr/bin/docker stop {{ app_domain }}-open-ai-server
+WorkingDirectory={{ app_deploy_target }}
+Restart=always
+
+[Install]
+WantedBy=multi-user.target

+ 7 - 0
deploy/roles/mint-v2.3/templates/open-ai-server.sh.j2

@@ -0,0 +1,7 @@
+#!/bin/bash
+
+set -e
+
+# TODO
+
+exit 0

+ 15 - 0
deploy/roles/mint-v2.3/templates/php-fpm-8.1.service.j2

@@ -0,0 +1,15 @@
+[Unit]
+Description=php-fpm 8.1(mint).
+Wants=network-online.target
+After=network-online.target
+
+[Service]
+Type=simple
+User={{ ansible_user }}
+ExecStart=/usr/bin/docker run --rm --name php-fpm-8.1 -p 127.0.0.1:{{ app_php_fpm81_port }}:9000/tcp -v /srv:/srv:z {{ app_php81_image }} /srv/bin/php-fpm.sh
+ExecStop=/usr/bin/docker stop php-fpm-8.1
+WorkingDirectory={{ app_deploy_target }}
+Restart=always
+
+[Install]
+WantedBy=multi-user.target

+ 15 - 0
deploy/roles/mint-v2.3/templates/php-fpm-8.4.service.j2

@@ -0,0 +1,15 @@
+[Unit]
+Description=php-fpm 8.4(mint).
+Wants=network-online.target
+After=network-online.target
+
+[Service]
+Type=simple
+User={{ ansible_user }}
+ExecStart=/usr/bin/docker run --rm --name php-fpm-8.4 -p 127.0.0.1:{{ app_php_fpm84_port }}:9000/tcp -v /srv:/srv:z {{ app_php84_image }} /srv/bin/php-fpm.sh
+ExecStop=/usr/bin/docker stop php-fpm-8.4
+WorkingDirectory={{ app_deploy_target }}
+Restart=always
+
+[Install]
+WantedBy=multi-user.target