2025/02/15

macOS Dock 加入分隔線

defaults write com.apple.dock persistent-apps -array-add '{"tile-type"="spacer-tile";}'
killall Dock

2025/02/12

Ubuntu 24.04.1 Install Zabbix Server 7.2


# 下載 Zabbix 7.2 的安裝套件(適用於 Ubuntu 24.04)
wget https://repo.zabbix.com/zabbix/7.2/release/ubuntu/pool/main/z/zabbix-release/zabbix-release_latest_7.2+ubuntu24.04_all.deb

# 安裝 Zabbix 的套件來源並刪除安裝檔案
sudo dpkg -i zabbix-release_latest_7.2+ubuntu24.04_all.deb && rm -fr zabbix-release_latest_7.2+ubuntu24.04_all.deb

# 更新 apt 軟體庫並安裝 Zabbix 伺服器、前端、Nginx 設定、SQL 腳本、Zabbix Agent 2 及相關 MySQL 套件
sudo apt update && sudo apt install -y zabbix-server-mysql zabbix-frontend-php zabbix-nginx-conf zabbix-sql-scripts zabbix-agent2 zabbix-agent2-plugin-mssql mysql-server mysql-client net-tools locales

# 執行 MySQL 安全性設定精靈,設定 root 密碼及其他安全選項
sudo mysql_secure_installation

# 啟用並立即啟動 MySQL 伺服器
sudo systemctl enable --now mysql

# 進入 MySQL
mysql -u root -p

# 設定 root 帳號的密碼認證方式為 mysql_native_password
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'rootPassword';

# 建立 Zabbix 資料庫,使用 UTF-8 編碼
CREATE DATABASE zabbix CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;

# 建立 Zabbix 使用者並設定密碼
CREATE USER 'zabbix'@'localhost' IDENTIFIED WITH mysql_native_password BY 'zabbixPassword';

# 賦予 Zabbix 使用者所有資料庫權限
GRANT ALL PRIVILEGES ON zabbix.* TO 'zabbix'@'localhost';

# 允許資料庫函式的 binlog
set global log_bin_trust_function_creators = 1;

# 刷新 MySQL 權限表,確保新權限生效
FLUSH PRIVILEGES;

# 退出 MySQL
QUIT;

# 將 Zabbix 伺服器 SQL 初始化腳本匯入資料庫
sudo zcat /usr/share/zabbix/sql-scripts/mysql/server.sql.gz | mysql --default-character-set=utf8mb4 -u zabbix -p zabbix

# 產生並設定系統語言環境為英文 UTF-8
sudo locale-gen en_US.UTF-8
sudo update-locale LANG=en_US.UTF-8

# 設定 PHP 預設語言環境為 en_US
sudo sed -i '/^\[intl\]/a intl.default_locale = en_US' /etc/php/8.3/fpm/php.ini

# 啟用 Nginx 監聽 8080 埠(預設為註解,移除 #)
sudo sed -i 's/^#\s*listen\s*8080;/listen 8080;/' /etc/nginx/conf.d/zabbix.conf

# 設定 Zabbix 伺服器收集 VMware 監控資料的 Collector 數量為 5(預設為 0)
sudo sed -i '/^# StartVMwareCollectors=0/a StartVMwareCollectors=5' /etc/zabbix/zabbix_server.conf

# 增加 VMware 緩存大小至 128MB(預設為 8MB)
sudo sed -i 's/^# VMwareCacheSize=8M/VMwareCacheSize=128M/' /etc/zabbix/zabbix_server.conf

# 設定 Zabbix 伺服器的資料庫名稱
sudo sed -i 's/^DBName=zabbix$/DBName=zabbix/' /etc/zabbix/zabbix_server.conf

# 設定 Zabbix 伺服器的資料庫使用者名稱
sudo sed -i 's/^DBUser=zabbix$/DBUser=zabbix/' /etc/zabbix/zabbix_server.conf

# 設定 Zabbix 伺服器的資料庫密碼
sudo sed -i '/^# DBPassword=$/a DBPassword=zabbix' /etc/zabbix/zabbix_server.conf

# 啟用並立即啟動 Zabbix 伺服器、Zabbix Agent、Nginx 和 PHP 服務
sudo systemctl enable --now zabbix-server zabbix-agent2 nginx php8.3-fpm

# 瀏覽器輸入以下網址即可進入設定畫面
http://ip:8080

2024/11/19

Auto-filling JWT Token in NestJS Swagger Documentation


import {
    DocumentBuilder,
    SwaggerModule as NestSwaggerModule
} from '@nestjs/swagger'

     // 建立Swagger的設定
        const config = new DocumentBuilder()
            .addSecurity('JWT', {
                type: 'http',
                scheme: 'bearer',
                bearerFormat: 'JWT',
                in: 'header'
            })
            .build()

        // 設定Swagger的路徑
        NestSwaggerModule.setup(path, app, document, {
            swaggerOptions: {
                // 永久儲存授權
                persistAuthorization: true,
                // 預設分類不展開
                docExpansion: 'none',
                onComplete: () => {
                    // 設定是否為登入請求
                    let isLoginRequest = false

                    // 取得fetch
                    const originalFetch = window.fetch

                    // 覆寫fetch
                    window.fetch = async function (...args) {
                        // 執行原本的fetch
                        const response = await originalFetch.apply(this, args)

                        try {
                            // 如果為SingIn Request
                            if (isLoginRequest) {
                                // clone response
                                const clone = response.clone()
                                // 取得Content-Type
                                const contentType =
                                    response.headers.get('content-type')

                                // 如果為JSON
                                if (contentType?.includes('application/json')) {
                                    // 取得JSON
                                    const data = await clone.json()

                                    // 檢查 token
                                    const token = data?.data?.token
                                    // 如果有token
                                    if (token) {
                                        // 設定 Token
                                        ;(window as any).ui.preauthorizeApiKey(
                                            'JWT',
                                            token
                                        )

                                        // 重置標記
                                        isLoginRequest = false
                                    }
                                }
                            }
                        } catch (error) {
                            console.error('Error processing response:', error)
                        }

                        return response
                    }

                    // 添加點擊事件監聽
                    ;(window as any).document.addEventListener(
                        'click',
                        (e: any) => {
                            if (
                                e.target.matches(
                                    '.btn.execute.opblock-control__btn'
                                )
                            ) {
                                // 取得URL的Query
                                const urlQuery = window.location.hash.slice(1)
                                // 如果URL的Query包含 _singIn_
                                if (urlQuery.includes('_singIn_')) {
                                    // 如果是登入請求
                                    isLoginRequest = true
                                }
                            }
                        }
                    )
                }
            },
            customSiteTitle: 'API Documentation'
        })