使用容器(docker)自架N8N

使用容器 docker 自架N8N社群版非常簡單,但功能有所限制;雲端付費版每月最低20歐元,可解鎖更多功能,建議先使用雲端版14天試用看看,不符合期待再考慮自架。自架方式有很多種,容器方式為首選。

我的環境是:
1. 容器主機
RockyLinux 9.4,docker ce 27.03,postgres sql server 17
2. 代理伺服器主機 apache httpd 2.4
3. dns n8n.test.com

1. 建立docker-compose.yaml檔案
紅字部分須注意斟酌修改

version: "3"
services:
n8n:
image: n8nio/n8n
restart: always
ports:
- "5678:5678"
environment:
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER
- N8N_BASIC_AUTH_PASSWORD
- N8N_HOST=n8n.test.com
- N8N_PORT=5678
- N8N_PROTOCOL=http
- NODE_ENV=production
- WEBHOOK_URL=https://n8n.test.com/
- DB_TYPE=postgresdb
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_HOST=postgres主機ip
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_USER=使用者
- DB_POSTGRESDB_PASSWORD=密碼
- DB_POSTGRESDB_SCHEMA=public
- TZ=Asia/Taipei
- GENERIC_TIMEZONE=Asia/Taipei
- N8N_RUNNERS_ENABLED=true
- N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
- N8N_EMAIL_MODE=smtp
- N8N_SMTP_HOST=mail.hlmt.com.tw
- N8N_SMTP_PORT=587
- N8N_SMTP_USER=郵件帳號
- N8N_SMTP_PASS=郵件密碼
- N8N_SMTP_SENDER=sender@test.com
- N8N_SMTP_SSL=false
- N8N_SMTP_STARTTLS=true
- EXPRESS_TRUST_PROXY=true
- N8N_PROXY_HOPS=1
- N8N_PUSH_BACKEND=sse
# 若使用httpd proxy透過web socket請改成N8N_PUSH_BACKEND=websocket
volumes:
- .n8n:/home/node/.n8n


經過測試這版v1.86版,有權限問題,需要先手動建立.n8n,使用者設定為 1000
# mkdir -p .n8n
# chown -R 1000:1000 .n8n

2. 啟用n8n容器

執行 https://n8n.test.com 之後,就可以設定主人了

安裝完畢 ***社群版限制一個帳號,若郵件設定正確,可以再邀請別人加入。


實作一個玩玩看-檢查咖啡偶文章,有新的就通知

一開始先新增RSS Feed trigger:每天晚上查看一次咖啡偶網站 https://kafeiou.pw/feed


中間增加過濾器 filter,過濾當天是否有新的文章,若有就發email通知。

左邊使用java script,左邊變數名稱可以用拖拉的,把第一關卡日期拉進去,再調整日期格式。
右邊則為目前系統日期。
左右相同才會觸發右邊發郵件通知
左邊抓取RSS Feed Trigger從kafeiou獲得地的日期,右邊是當天

測試一下,大功告成。


另外在步驟一有提到使用web socket的方式進行反向代理參數設定,須修改docker-compose.yaml檔案
請改為N8N_PUSH_BACKEND=websocket 。httpd config 設定參考如下:

<VirtualHost *:443>
ServerName n8n.test.com

ErrorLog /var/log/httpd/ssl_error_log
TransferLog /var/log/httpd/ssl_access_log

SSLEngine On
SSLCertificateFile /etc/letsencrypt/live/n8n.test.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/n8n.test.com/privkey.pem
SSLCACertificateFile /etc/letsencrypt//live/n8n.test.com/fullchain.pem

SSLProxyEngine On
ProxyRequests Off
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto "https"
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://容器主機IP:5678/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
RewriteRule /(.*) http://容器主機IP:5678/$1 [P,L]

<Location />
Order allow,deny
Allow from all
</Location>
</VirtualHost>

RockyLinux 9 使用usb硬碟備份,要避免硬碟進入休眠

過年要到了,小公司需要利用這時間進行系統備份,外接usb備份也很重要,備份完直接切斷usb硬碟連線,但我發現usb會進入休眠,不確定是否能終端機叫醒,因此乾脆直接改成不休眠狀態。

2013年有篇文章,有大佬分享心得

Linux官方參考資料

RockyLinux 9 /etc/fstab 掛載新的磁碟

以前掛載新的磁碟或分區(partition),只要確認磁碟在哪就可以直接掛載上去。

例如新的磁碟在/dev/sdb1 ,就可以直接寫在fstab,執行systemctl daemon-reload,重開機就能直接掛載辛的磁碟機。

/dev/sdb1  /docker   xfs   defaults   1 1

沒想到我這次栽了跟斗,RL9重開機後系統直接掛掉,原來是新磁碟機從sdb變成sda,而原本開機的sda變成sdb;我更正後重開機,又亂變代號,此時系統正式掛掉,只能重新安裝。

我後來才發現,fstab早就改成UUID的掛載方式,讓UUID自動綁定磁碟代號,以往我沒遇到問題,直到用了RL9,甚至AlmaLinux也是一樣狀況。

輸入 ls -al /dev/disk/by-uuid 可以查看磁碟對應的UUID

讓 nextcloud 有全文檢索能力FullText Search ElasticSearch

nextcloud 搜尋很好用,若能有全文檢索能力就更棒了,於是外掛 fulltextsearch_elasticsearch就登場了。

開發團隊只針對還在維護的nextcloud版本進行更新,也就是說一旦我們的nextcloud已經EOL了,就不會再收到ElasticSearch的更新。

以下是甘苦談

原本使用的nextcloud 25.x 能搭配ElasticSearch 7.x ,但遇到外掛存在非常嚴重效能低下問題(兩萬個檔案有設定分享,100人使用,建立索引表算一算需要至少三、四個月,太誇張了);由於nextcloud 25版已經停止維護,於是我只剩下升級nextcloud一途。 

我的nextcloud架設在 CentOS 7,docker上面跑好多容器,很穩定;但nextcloud要升級到26時候,出現容器dns錯亂,無法進行dns查詢,只好先還原回25版。

初步認定是CentOS 7或docker版本過於老舊,但我不敢隨意升級docker,最後只能將nextcloud資料複製到新的虛擬主機(RockyLinux 9.4),測試由25升級到26,然後26升級27 結果就很正常,沒有出現dns錯亂問題。

移轉注意事項請參考「將nextcloud從CentOS7移轉到RockyLinux9。

** 升級nextcloud到27,搭配新fulltextsearch外掛,初始索引要18小時,效率差了百倍以上。

開始安裝囉

安裝 ElasticSearch 8.x(ES 8) 引擎

Nextcloud 26或以上必須搭配 ES 8,最新docker版本可至此查詢 https://hub.docker.com/_/elasticsearch

#RockyLinux 9.4、docker 27.0.2

##############  檔案 ./docker-compose.yaml  ################

version: "3.9"

services:
elasticsearch:
build:
context: .
dockerfile: ./docker/es/Dockerfile
container_name: elasticsearch

environment:
- discovery.type=single-node
- xpack.security.enabled=false
- xpack.security.http.ssl:enabled=false
ports:
- 9200:9200
- 9300:9300
networks:
- elastic
restart: always
volumes:
- indexdata:/usr/share/elasticsearch/data
# 索引過的資料將存放到 /usr/share/elasticsearch/data裡面

networks:
elastic:
driver: bridge

volumes:
indexdata:
driver: local

###########################################################



################ 檔案 ./docker/es/Dockerfile ###############
FROM elasticsearch:8.14.2
# ingest-attachment 一定要安裝
RUN bin/elasticsearch-plugin install ingest-attachment
###########################################################
# 執行容器
docker-compose up -d

安裝完畢,瀏覽器測試一下引擎是否正常 http://ip:9200/ ,事後需填入到nextcloud外掛設定裡面。

nextcloud 安裝外掛 fulltextsearch

#若安裝出問題,請移除app後,再刪除以下資料庫資料,之後就可以正常安裝了
drop table oc_fulltextsearch_indexes;
drop table oc_fulltextsearch_ticks;
delete from oc_appconfig where appid='fulltextsearch';
delete from oc_appconfig where appid='fulltextsearch_elasticsearch';
delete from oc_appconfig where appid='files_fulltextsearch';
delete from oc_appconfig where appid='files_fulltextsearch_tesseract';
DELETE FROM oc_migrations WHERE app='fulltextsearch';
DELETE FROM oc_preferences WHERE appid='fulltextsearch';

外掛需要設定

外掛安裝完畢,還需要填入引擎網址、與索引名稱,其他預設值即可。

「檢查」外掛設定是否正常

docker exec -t --user www-data <nextcloud容器名稱> php occ fulltextsearch:check

「測試」外掛設定是否正常

 docker exec -t --user www-data <nextcloud容器名稱> php occ fulltextsearch:test

一切正常後,就可以開始建立索引表了,這裡建議定期重做索引。

 docker exec -t --user www-data <nextcloud容器名稱> php occ fulltextsearch:index

這裡強烈建議「文件掃描PDF檔」需要利用acrobat adobe pro版內建文字辨識功能(OCR),進行一次自我辨識

第一次初始化索引建立後,才可以使用

最後還需要額外執行live指令,針對後續異動的檔案進行索引

# 自動索引官方沒建議怎做,我自己是在容器本體VM(RL9.4)利用console常駐執行
# 這樣做比較麻煩,需要注意重開後需要手動做
docker exec -t --user www-data <nextcloud容器名稱> php occ fulltextsearch:live

** 有一次我要刪除原本的索引,一直失敗,搞了很久很久很久很久,才發現要先進入容器下指令才有用

docker exec -t --user www-data <nextcloud容器名稱> php occ fulltextsearch:reset

** 目錄裡面新增「 .noindex」 這個檔案,就可以不做index

** 若有安裝tesseract ocr這個外掛,記得進nextcloud容器,額外安裝相關程式(此功能我一直沒成功過)

apt install tesseract-ocr tesseract-ocr-chi-tra-vert  tesseract-ocr-chi-tra tesseract-ocr-chi-sim  tesseract-ocr-script-viet tesseract-ocr-script-hant tesseract-ocr-script-hant-vert

** 以前安裝Micro$oft單機版sharepoint,是個重量級系統,早就有全文檢索功能,但實在是太吃系統資源了,果斷不用。

wordpress 6.5.5 出現ERR_TOO_MANY_REDIRECTS error

場景

  1. 有對外IP充當反向代理程式VM(CentOS 7.9)
    httpd reverse proxy 2.4.6
  2. 無對外IP,內部vm (RockyLinux 9.4)
    Docker CE + Container WordPress 6.5.5

讓反向代理程式連到wordpress,網頁測試居然出現ERR_TOO_MANY_REDIRECTS 錯誤

爬文之後,要在wordpress的wp-config.php加上

if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$_SERVER['HTTPS'] = 'on';
}

再不行,要加上

if (isset($_SERVER['HTTP_X_FORWARDED_HOST']) && isset($_SERVER['HTTP_X_FORWARDED_PORT'])) {
$_SERVER['HTTP_HOST'] = $_SERVER["HTTP_X_FORWARDED_HOST"];
$_SERVER['SERVER_PORT'] = $_SERVER["HTTP_X_FORWARDED_PORT"];
}

來源 https://lukashermann.dev/writing/wordpress-too-many-redirects/

docker上的nextcloud 為何要移轉到新的vm上?

為何要移轉到新的虛擬主機上? 因為原本虛擬主機已經是EOL了,若nextcloud升級,會面臨資料庫版本不符、docker版本過舊問題;需要另外安裝新虛擬主機、安裝新docker,升級資料庫版本,才能解決nextcloud無法升級問題。

作法如下:

  1. 使用mysqldump 將nextcloud資料匯出,並匯入到新的vm上的資料庫
  2. 將 volume 資料匯出,新docker建立相對應的volume後,再將匯出的資料丟進volume裡面
  3. docker 拉取nextcloud原本images後,重新啟動nextcloud容器
  4. 確認啟動成功後,才能進行nextcloud升級

Linux背景執行

以前我在Linux要背景執行程式,在最後面加上 「&」即可,後來發現這樣好像不正統,因此改用nohub以shell方式執行。

啟動(start.sh)

#!/bin/bash
nohup /usr/lib/jvm/jdk-17-oracle-x64/bin/java -jar api.jar &> /dev/null &

結束(stop.sh)

#!/bin/bash
ps -ef | grep "api.jar" | grep -v grep | sed 's/ [ ]*/:/g'|cut -d: -f2| kill -9 `cat`

nohub解釋如下(出處)

說明
nohup 指令會執行 Command 參數及任何相關 Arg 參數所指定的指令,忽略所有掛斷信號 (SIGHUP) 或修改使用 -p 選項指定的處理程序以忽略所有 SIGHUP 信號。 SIGHUP 是在處理程序的控制端關閉時傳送給處理程序的信號。

在登出之後,也可以使用 nohup 指令在背景中執行程式。 To run a nohup command in the background, add an & (ampersand) to the end of the command.

jgit clone專案失敗,原來要把帳號密碼存起來才行

自己寫 java 呼叫 jgit 函式庫clone專案,卻失敗,我看到錯誤訊息是沒有帳號密碼;可是程式明明有輸入帳號密碼,後來爬文才發現我有案子有使用LFS,需要設定快取把帳號密碼儲存起來,否則會一直要求輸入帳號密碼造成程式錯誤。

git lfs 需要2.0或是以上才行

git config --global lfs.cachecredentials

小公司應用軟體系統-戰略與戰術

對於一個小公司來說,當然非常想用各式各樣的應用軟體系統,可是公司沒人懂IT,對於所謂的上雲端更是丈二金剛摸不著頭腦,搞不清楚,若找來軟體公司,公司說了一大堆,一開口說預算多少,老闆也跟著張大口嚇得不要不要的。

所以我常建議軟體公司,必須提供小企業能負擔的解決方案,至少要能解決小公司「辦公室能用到的軟體系統」,如nextcloud這樣的雲端檔案系統,同樣也必須做到虛擬伺服器(proxmox ve) + 虛擬主機(容器服務);一個應用系統必須虛擬化、容器化,千萬不要安裝在一台實體主機(除非是故意的,這樣才能賺錢,反正客戶都不懂)。

前幾天看到YT閱部客談到《跨能致勝:顛覆一萬小時打造天才的迷思,最適用於AI世代的成功法》這本書,提到「戰略與戰術」,我相當認同其中的見解:單一專業的部分交給AI,綜觀全局的部分就交給人類。

https://www.youtube.com/watch?v=-j8MSMqDfs0

軟體公司能提供給小公司的戰略重點就是「備份」,而且要麻瓜都懂的備份方式,我先前就遇到一家小公司透過朋友輾轉向我求救,他們IT突然跑了,沒有交接,他做好的系統是運行3年多的實體機,看起來搖搖欲墜,後端NAS也無人知曉如何登入。

我接手後,先確認他們只需要mail server 與 對會員收費網站(wordpress),我花了很多功夫,終於移植到一台單一主機(ssd*1 for os、hdd*3 for zfs),pve 8.0 +RockyLinux 9.2 +podman container。

系統移植成功後,還要考慮麻瓜備份問題,戰略戰術一併考慮,我額外安裝一個容器:nextcloud雲端檔案系統,透過此雲端檔案系統能連到外部空間的特異能力(external storage support),直接俗又有力的掛載宿主(pve)主機已準備好的備份目錄,最後只要讓麻瓜安裝nextcloud 用戶端app,就能同步備份目錄到麻瓜其他檔案空間,達到離線備份的效果,離線異地備份就再也跟IT沒關(頂多半年協助做個還原演練即可),我也能全身而退。

iredmail 1.6.3 設定白名單

幫朋友安裝開源好用的mail server 「iredmail」,若需要加白名單,有兩個方法:

  1. 購買專業版
  2. 下指令
    https://docs.iredmail.org/amavisd.wblist.html
# python wblist_admin.py --list --whitelist
# python wblist_admin.py --list --blacklist
# python wblist_admin.py --add --whitelist 202.96.134.133 john@example.com @test.com @.abc.com
# python wblist_admin.py --add --blacklist 202.96.134.133 john@example.com @test.com @.abc.co

先找出 wblist_admin 在哪個地方,然後加上白名單即可

1 2 3 ... 8