發表文章

目前顯示的是 2024的文章

使用批次檔來更新 cloudflare DDNS

 不熟批次檔(.bat/.cmd),但是家人不可能用 Linux ,還是得客製一下,能動為準 工作環境:     Windows Home          .bat          工作排程器          curl          python(沒有的話,輸出的結果會粘在一起) token varify 確認 apiToken 是正確的 curl "https://api.cloudflare.com/client/v4/user/tokens/verify" -H "Authorization : Bearer tokenHere" get zoneID 把 zoneID 記下來 curl -X GET "https://api.cloudflare.com/client/v4/zones" -H "Authorization : Bearer tokenHere" -H "Content-Type:application/json" get dns records 找到你要更新的網址名稱 name(FQDN,不是zone_name),把它的 id(不是zone_id) 記下來 curl -X GET "https://api.cloudflare.com/client/v4/zones/zoneIDHere/dns_records" -H "authorization : Bearer tokenHere" -H "Content-Type:application/json" | c:\somewhere\python -m json.tool target dns record to update(.bat)************ curl ipinfo.io/ip > ip.txt set /p IP=<ip.txt curl -X PUT "https://api.cloudflare.com/client/v4/zones/zoneIDHere/dns_records/recordIDHere" -H "Authorization : Be

使用 shell script 更新 cloudflare 的 DNS 記錄

 記錄一下使用 shell script 更新 cloudflare 的 DNS 記錄(DDNS)  工作環境:     Linux          curl          jq 使用 curl 和 cloudflare API 溝通,就可以達成更新 DNS 記錄的目的,基本上就是提供 zone ID 和 API Token 給 cloudflare ,指定要更新的域名(FQDN),當然,要抓到目前使用的「對外」的 IP 位址一併提供  範例:updateCfDDNS flkjfldajldfj ddns.your.domain lfkdalfjldjf;lajd;lf #!/bin/sh # update DDNS records with curl using cloudflare API # input: zoneID, FQDN, APIToken, get internet IP addr. # output: none but DNS record update dynamicly # pre-requirements: config cloudflare API token # post-requirement: config crontab to update DDNS regularly # usage: updateCfDDNS zoneID FQDN APIToken if [ -z $1 ]         then                 echo "please provide zoneId, fqdn, apiToken, thank you..." else MYIP = ` curl https://ipinfo.io/ip` RECID = ` curl -X GET "https://api.cloudflare.com/client/v4/zones/ ${1} /dns_records?name= ${2} " -H "Authorization:Bearer ${3} " -H "Content-Type: application/json" | jq -r ".result[] | select

查對外 IP

 記錄一些可以取得對外的 IP 位址的網站: https://adresameaip.ro/ip   https://api.ipify.org   https://icanhazip.com   https://ipinfo.io/ip      

iphone 照片增量備份

 原本是想用 immich app 來達成增量備份的目的,就像 icloud 那樣,手機有新照片就自動傳上 icloud 、手機上殺照片時,已經上傳的照片還會留在 icloud 上(然後就因為越存越多所以要花錢買空間來存手機資料),結果變成了鏡像同步備份(手機上殺了檔,伺服器上就不會有檔) 工作環境:     immich app: 開 background + foreground backup 開啟自動備份功能  於是把之前找的解決方案又 review 了遍,再試個替代方案出來,nextcloud, photoprism, syncthing, damefly, home gallery, warmwhole, croc, pandrop, localsend ......,大多是 server 端解決方案,可以透過網路上傳,然後有網頁可以看照片,有些還支援影片播放,但是不一定有 iphone 的 app 可以用,有 app 的,也可能不是原生的,用的是第三方的 app ,而且可能會看起來怪怪的,反正狀況很多,然而,搜尋的時侯覺得很奇怪,沒有什麼討論串,可能是想太多了,應該有很簡單的解法  回頭檢查 iphone 原生的 「儲存到檔案」/「連接伺服器」 的功能,不知道從什麼時侯開始,「檔案」app 裏出現了「連接伺服器」 的功能,不支援 ssh 所以就別想在這裏 scp (無法使用 ssh:無法完成此項操作,因為不支援此URL),可以使用網芳來連,可以讀寫,就和在電腦上操作一樣,反應久了點就是了: 選一些照片,超過100個檔案以上就很卡,分段選檔吧 按左下角開啟其他的 app /功能 的圖示(有個向上的箭頭) 選「儲存到檔案」,一開始會跳進 icloud,按左上角回到上一層,會出現「已共享」的區塊 選右上角有三個點的圓形餅乾,「連接伺服器」 打好網芳的位址(smb://1.2.3.4),id,password 選好你要上傳檔案的資料夾 儲存 過了很久的一下下,傳好檔案會跳回照片 app 繞了一圈還是回到 samba ...... 續骨靈藥,金盒久藏啊~~ 收工! ========================================= 跌倒記錄: 官網討論區上一直說是用手機原生的 app 管理照片,然後用 app 管理 immich-server 的照

關於 immich app 的那些事兒

 簡單地說,immich app 就是個相片同步的 app,真要做到增量備份,現階段還真是沒辦法…… 工作環境:   Linux Server     immich server on docker     immich app on iphone 1.100 雖然說官方說是透過 iphone 自已的「照片」app 殺掉手機上的照片,並不會影響到 immich server 上已經上傳的照片,但是…… 在開啟 backup (foreground/background) 時,app 會讓手機的資料和伺服器上的資料同步,不管你是不是用「照片」app 殺照片 突然想起,沒有試手動上傳,不透過自動 backup 的同步功能是不是就能實現增量備份,不過,醬子的話,就太不方便了,不符合懶人模式,真要手動上傳,就接電腦選照片上傳了,何必搞伺服器又搞 app 搞了老半天,根本上就是出在不想開電腦呀@@" 所以,immich app 就拿來同步/鏡像手機裏的照片吧…… 想要增量備份,回頭找網芳      收工!

Port Knocking or ...…

 Port Knocking 就像是敲門暗號依序敲 2長1短3長 才開門的概念,之前有看到文章提到在 Linux 上實做用來強化安全性,沒想到路由器上面也可以做,更沒想到的是就連設個暗號也能從敲門變成撞門 工作環境:     某牌路由器          firewall rules for port knocking  基本上照著官網上的 port knocking 設定實作就行     要啟用 input DROP all 之前記得先開個後門,否則……所有設備都會連不進來就 GG …… 要啟用 input DROP all 之前記得先開個後門,否則……所有設備都會連不進來就 GG …… 要啟用 input DROP all 之前記得先開個後門,否則……所有設備都會連不進來就 GG ……     以下設定要放在 input DROP all 之前     目標設定  先設定要開啟的服務 dst. port 開啟時,允許的來源為一個自訂的清單(自行增加設定成類似 fin-ips 的群組清單) ,port knocking 嘛最基本的設定值就是 port ,當然你也可以進一步鎖定來源的介面和目的地…等等的參數 敲門設定(N次)  第1次:設定要敲門的 dst. port  ,同樣的,可以進一步鎖定來源的介面和目的地....等等的參數,然後(action)將來源的 ip 加入群組清單(knock1)  第2次起:設定本次要敲門的 dst. port  ,然後指定 ip 來源是上次的清單(knock1)同樣的,可以進一步鎖定來源的介面和目的地....等等的參數,然後(action)將來源的 ip 加入群組清單(knock2),依此類推N次…  最後一次:設定本次要敲門的 dst. port  ,然後指定 ip 來源是上次的清單(knock#)同樣的,可以進一步鎖定來源的介面和目的地....等等的參數,然後(action)將來源的 ip 加入群組清單(fin-ips),這樣就能和目標設定參數相呼應,形成閉環 以後,你指定防護的目標服務,必需按照剛才的設定步驟指定的 port# ,之後再連你要的服務才能進入 實測 比方,你防護了 22 port 的 ssh 服務,指定的 port knocking 依序分別是 2000,1000,3672 設定完成後,直接連 ssh 是連不上

為內網的 IMMICH 設定加密連線

 話說現在的網站都要有 https 沒有那個 s 好像犯天條似的,即使是在內網也要搞個 s 來玩玩,如果你已經當了勇者把伺服器放上公網,也歡迎你分享設定,肯定香啊~,做為一個膽小時間又少的使用者,還是來設一下 s 吧! 工作環境:     debian linux          docker               immich               nginx(做為反向代理用)                反向代理有很多選項,試了很多沒遇上好運,回頭用了最基本的 nginx,或許下次可以試試 caddy 吧 首先,開2個 docker 的網路並且設定 docker network create inner_network docker netowrk create reverse_proxy_network   在開始設定之前,記得把之前的 immich-app 停下來 docker compose down 設定一下 docker-compose.yml :進到你的 immich-app/docker-compose.yml 把每個 service 的 networks 改一下 如果 service 名稱是 immich 開頭的: networks:   - inner_network   - reverse_proxy_network 其他的 networks:   - inner_network networks 的總述 networks:   proxy:     driver: bridge   internal:     driver: bridge  引用 nginx:   nginx :     container_name : nginx     hostname : nginx     image : nginx:latest     environment :       - TZ=${TZ}     volumes :       - ./nginx:/etc/nginx/     ports :       - "80:80"       - "443:443"     networks :       - reverse_proxy_network     depends_on :

繼續 IMMICH 安裝來備份手機上的照片和影片

 之前有提到為了躲避 nextcloud all-in-one 的群坑,所以先擱(割)置(捨)難搞的 nextcloud aio 轉投 immich-app 的懷抱,畢竟原本的目的就沒有要包山包海,主要是要把照片和影片存出來而已 工作環境:     內網的 debian linux          docker(-compose)               immich 後來發現上次用的註解法不是最佳解,所以開大門走大路把整個 immich 抓回來裝: git clone https: //github.com/immich-app/immich.git install.sh 然後到 immich-app 裏把 docker-compose.yml 改一下,可以改一下這個 environment:   - TZ=${TZ} .env 可以改一下這個 UPLOAD_LOCATION=/你想放資料/的位置 TZ=Asia/Taipei 然後 docker compose up -d 連到主機網址 http://192.168.100.100:2283 就可以用了 上傳的檔案在 /你想放資料/的位置/library/admin/ 裏面 是的,你沒有看錯,是 http 不是 https  很在意的人再搞一下 反向代理吧,先醬子將就用著 收工!

合併多個 docker-compose.yml 檔案

 雖然 docker-compose.override.yml 可以將修改後的設定套用到新的 docker image 裏啟用,但是維護1個檔案還是比維護2個檔案好一些,最好合併檔案的時侯不要使用傷眼法,和自已動手剪貼,而是程式自已整理貼好… 工作環境:     Linux Mint          Docker compose docker-compose -f docker-compose.yml -f docker-compose.override.yml config > docker-compose.merged.yml  mkdir orig mv docker-compose.yml orig mv docker-compose.override.yml orig mv docker-compose.merged.yml docker-compose.yml 之後就用新的 docker-compose.yml 來啟用 docker 還有就是後面的檔案會蓋掉前面的檔案的設定,有些設定則是會多個並列,所以還是得進去調一下設定的內容     收工!

docker 容器之使用者 uid 和 gid

 docker 容器的 uid 和 gid 常會讓使用者在 host 端取用 volume 時綁手綁腳,雖然有人說這其中還有安全性的考量,但是使用 sudo 好像也沒有比較好,為了可以直接存取 volume 的檔案,居然花了好久好久,久到夫人說:怎麼最近又開始抱著電腦了?……………………………………其實是電腦沒有放人  工作環境:     Debian          mariadb 10.11 docker(compose) 狀況:裝好 mariadb 之後,volume 的權限是 999.999 ,很煩,得 sudo 才能在本機作業,雖然也沒什麼不行,但就不愛,然後…………搞死自已  2個解法,因為不是 product 環境,先試到這兒,期望有人講白話,把這題解了,免得折騰半天 法1:雖然不能自動化,但是直覺…  先裝起來  dcshell container_name (docker exec -it $1 /bin/bash -l)  usermod -u your_uid_in_host app_user;  groupmod -g your_gid_in_host app_group;  exit  chown -R user_user:user_group docker_volume  然後參照之前的 客製 docker image 的方式, 在 docker-compose.override.yml 設定引用新的 image  法2:真的用 Dockerfile 就可以自動化嗎!?先搞懂 Dockerfile 怎麼用吧  去 下載 所需的檔案,然後加一個超奇怪的 「USER "1000"」 到 Dockerfile 裏,再回到 docker-compose 裏引用 Dockerfile 並且指定 user ,這個解法能用匪夷所思來形容,反正能解,先頂著   總而言之  書到用時恨太多! 先醬!      收工! =================== sample 檔 ================== 法1  docker-compose.yml  version : '3' services : mariadb : image : mariadb:10.11   container_name

IMMICH 的一些坑

 話說 nextcloud aio 安裝要攻克可能還要一段時間,這時 immich 出現在替代方案清單之中,想來主要目的還是照片/影片的同步,先試一下頂多花點時間,最多再多摔個幾跤,頭上多幾包就是了,immich 提供了 server 端和 app ,有 docker-compose.yml 可以下載,想來不會太難……………………………………………………………………………………………… 吧 工作環境:     Linux Mint     Docker      先到 github 把 docker-compose.yml 和 example.env 下載後,發現,原來 .env 裏的IMMICH_VERSION 要自已去找一下,好在這個不難,看一下 github 右側的 Release 就行,目前也就是 v1.97.0 然後,docker-compose up -d 一直出現這個錯誤訊息,很牙起來…… ERROR: The Compose file './docker-compose.yml' is invalid because: 'name' does not match any of the regexes: '^x-' You might be seeing this error because you're using the wrong Compose file version. Either specify a supported version (e.g "2.2" or "3.3") and place your service definitions under the `services` key, or omit the `version` key and place your service definitions at the root of the file to use version 1. For more on the Compose file format versions, see https://docs.docker.com/compose/compose-file/   搞了半天,要設 export VARIABLE_PRO

Docker image 以及物件控管 主要是刪除不必要的物件

docker 真的是好用,一個 docker-compose.yml 就可以配置作業環境,但是… 如果有好多功能要啟用,雖然最後得到適用的設置,除非你是超級幸運星,每次都是一次成功配置這些環境,久了,還是會有些沒有用到的或是中間產物的物件,每次佔用一點點空間,慢慢吃掉你的硬碟空間…,這次就是要清掉這些暫(垃)存(圾)物件。 列出所有 Untag 的容器映像: docker images --filter "dangling=true" 列出所有 Untag 的容器映像,但只顯示 Image ID 而已: docker images --filter "dangling=true" -q 快速移除所有無用的容器映像 (Remove all dangling images): docker rmi $(docker images -f "dangling=true" -q) 移除所有沒用到的容器映像 (Remove all unused images): docker image prune -a 移除所有沒用到的 Docker 物件 (Docker System Prune): 注意!!!會連同以下, 「停用的容器」(stopped containers) 「無用的網路」(dangling networks) 「無用的容器映像」(dangling images) 「無用的建置快取」(dangling build cache) 全都刪除 docker system prune -a 在 N 次 docker-compose up -d 後,把還在用的物件啟用後,一次性地 docker system prune -a 就可以看到一連串療癒的雜湊值,殺了一堆檔案後,居然生出了 12G 的空間,開心!   收工!      

據說 cloudflare 也是可以用 ddns 的

 實作在 mikrotik 上更新 cloudflare ddns ip ,原來只要開通 cloudflare api 就行…… 單藍,要再加些楜椒和鹽… 工作環境:  Linux Shell  Mikrotik routerOS  cloudflare API # 建立更新 cloudflare DNS 記錄用的 API Token # create API Token in cloudflare The TOKEN value is created in the Cloudflare dashboard. Follow these steps: 1.  Click the profile icon in the top right of the dashboard, and choose 'My Profile' . 2.  Click on 'API Tokens' , then 'Create Token' . 3.  Click 'Start with a template' , then choose the 'Edit zone DNS' template. 4.  Under 'Zone Resources' , choose your top level domain name from the pull-down list on the right. 5.  Click 'Continue to summary' . 6.  Click 'Create Token' . 7.  Copy the token shown on the following screen and set the TOKEN environment variable to its value. # 更新 cloudflare DNS 紀錄會用到的變數 # 參考資料說要用 direnv 因為除錯失敗,直接把變數放到 gen_script 裏了…… # Variables needed for updating cloudflare DNS records HOST =api.cloudflare.com DOMAIN =yourDomain.n

django 快速工作環境建置

 很多時侯不是工具本身不好,而是要使用一個工具之前的環境建置 (安裝)就能磨死人了,這次就是又想看看有沒有現成的 django 可以用 工作環境:     ubuntu linux server LTS 22          cookiecutter               cookiecutter-django 安裝時執行 cookiDjango 有約10個問題要回答,主要注意 現在很習慣用 docker 所以 docker選y async 選 y drf 選 y 因為在本地搞,沒有用雲所以 whitenoise 要選 y 開發階段還是把 debug 選 y 吧 你可以依據你的實際需求來選 安裝好了之後在 requirements/base.txt 加入 django-qr-code ==4.0.1 # https://github.com/dprog-philippe-docourt/django-qr-code cookiBuild 然後要等好一下下下下下下 裝好之後記得建立管理者帳號,這個套件不是透過 .env 來設定 admin 帳密的 cookirun django python manage.py createsuperuser cookiup 本文都是以 local 本地端的開發環境來建置,相對要上線的就用 production 一些懶人用的 shell 不想重複打同樣的指令可以自行建置修改 安裝 nano ~/.bin/cookiDjango #!/bin/sh cookiecutter https://github.com/cookiecutter/cookiecutter-django 如果你要裝的是 django + vue.js nano ~/.bin/cookiDjangoV #!/bin/sh cookiecutter https://github.com/cookiecutter/cookiecutter-django 要用 source 的方式 nano ~/.bin/your_app #!/bin/sh cd container/your_app 裝好了以後因為有加客製的套件所以重建映像檔了 nano ~/.bin/cookiBuild #!/bin/sh . your_app docker-compose -f l

客製、套用 devilbox image

 找到了 devilbox 這個跨足許多版本的 LAMP stack ,它少了一些老程式沒有的 pear package ,雖然之前 裝裝老程式 已經解決了安裝問題,如果不小心 docker-compose down 就一(打)言(回)難(原)盡(形)了… 工作環境:     Ubuntu Server 22 LTS          docker               devilbox LAMP stack  要做的事情大致上就是,先把套件裝一裝,然後把裝好套件的這個 image commit,給 commit 之後的 image 命名,之後指名套用新的 image  Commit, Save, and Restore,套用、儲存、回存指令 # 由於 docker-compose down; docker-compose rm -f 之後所做的變動都會重置 # 以 devilbox 的 php-fpm-5.5 為基礎,進入容器中加裝 PEAR 套件, # 目標容器 devilbox_php_1 # install PEAR package and commit new docker image # 把更動過的容器做成新的 image docker commit -a "yourOrgName.org" -m "php-fpm-5.5-noteOfChange" devilbox_php_1   php-fpm-5.5-pear:5.5pAsTagName # 備份:把新的 image 存一個備份到 tar 檔案中 docker image save -o images.tar php-fpm-5.5-pear:5.5pAsTagName [image2 ...] # 回復:從備份的 tar 檔案中建立新的容器 docker image load -i images.tar  停止 docker:        docker-compose down; docker-compose rm -f;  套用新的 image:      devilbox 不去動 docker-compose.yml 用的是 docker-compose.orverwrite.yml # docker-comp

使用 devilbox 建置 LAMP 環境

 docker 功能很強,可以(被)玩的東西很多,雖然要用 docker 自已建置一個 LAMP 環境也不算太難,單藍如果有人建好 LAMP 可以拿來用不就不難了(嗎?)… 工作環境:     Ubuntu Server 22          docker               devilbox  選用這個套件主要是它把很多伺服器 參數 的控制項都寫好了,整體上來說非常方便設定和使用,使用時透過 .env 來設定就行,(被)玩了好一會兒,覺得這個套件主要還是針對開發人員在本機上運行的,如果是放在伺服器遠端連過去的話,dashboard 會和 vhost 打架… 如果你的不打架,可以留言教一下,感激不盡   列出可能會動到的設定 DEBUG_ENTRYPOINT =4 TLD_SUFFIX =yourdomain.name NEW_UID =1000 NEW_GID =1000 TIMEZONE =Asia/Taipei DEVILBOX_UI_SSL_CN =localhost,*.localhost,devilbox,*.dvl.to DEVILBOX_UI_PROTECT =1 DEVILBOX_UI_PASSWORD =your_password DEVILBOX_UI_ENABLE =0 DEVILBOX_HTTPD_MGMT_USER =userName DEVILBOX_HTTPD_MGMT_PASS =your_password HTTPD_VHOST_SSL_TYPE =redir   #自動將 http 導轉到 https PHP_SERVER =uncomment_version_you_like HTTPD_SERVER =uncomment_version_you_like MYSQL_SERVER =uncomment_version_you_like HTTPD_DOCROOT_DIR =dirNameYouLike MYSQL_ROOT_PASSWORD =your_password PGSQL_ROOT_PASSWORD =your_password HOST_PORT_BIND =53 BIND_DNS_RESOLVER =8.8.8.8,168.95.1.1 #DNS server you like BIND_DNSSEC

ssh server 也來調整成 publick key 登入

 使用 public key 登入 ssh server 並不是什麼新玩意,只是很久以來沒(懶)有(得)去(去)碰(管),最近有點空檔,把這些個設定檔搞一搞好了 工作環境:     Windows Client(以下稱 Client)     Ubuntu Server(以下稱 Server)  Server: /etc/ssh/sshd_config 的一些要更改的參數 #如果兩種都 password 和 public key 都開放的設定項,如果只開放其中一種,單藍就是把另一種方式的設定註解掉 # 使用 password 認證 # 這個應該原本就有 PasswordAuthentication yes # 這個還是限制一下吧 PermitEmptyPasswords no # 使用 public key 認證 # 要開放 public key 登入的設定 PubkeyAuthentication yes # 開放 public key 的設定檔 AuthorizedKeysFile      .ssh/authorized_keys .ssh/authorized_keys2 # public key 和 password 都需要才能登入 AuthenticationMethods "publickey,password" # 這時侯要把這個註解掉,不然就會先輸入一次密碼,過一次 public key,再輸入一次密碼 # PubkeyAuthentication yes    Client:  ssh-keygen -t rsa -b 4096  id_rsa.pub 開頭應該長得像這樣 ssh-rsa AAAA  找不到 ssh-copy-id 所以沒辦法 ssh-copy-id username@remote_host  要手動把金鑰加上  cat ~/.ssh/id_rsa.pub | ssh username@remote_host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"  或是到 Server 上  echo public_key_string >> ~/.ssh/authorized_keys  重新登入伺服器

virtualbox也拿出來用一用之 80 port forwarding 不見了

  virtualbox 在 windows 上使用還是蠻直覺的,一個 Linux VM(以下簡稱 VM) 的網頁伺服器,設定完成 NAT 的埠號轉接(port forwarding)就啟用了,想必將 VM 轉到 Linux Server(以下簡稱 Server) 上這個 VM 也(那)是(知)瞬(馬)間(上)完(撞)成(牆)吧(呢)! 工作環境:     Ubuntu Web Server VM 建置於 Windows 平台預計移植到 Linux Server平台  因為 Server 本身就會運行 ssh server 所以 VM 上的 ssh port 勢必得改掉,這樣遠端連入 ssh 時可以用 port 來辨別到底要連到 VM 上還是 Server 上,過了一關  為了讓 VM 的網頁伺服器運行起來和一般連接網頁時一樣,使用者直覺的打上網址(不用另加特殊埠號)就能連結,所以埠號轉送選了預設的 Server 80 port 對 VM 80 port ,接著怎麼連也連不上, netstat 一直不會出現 80 port 而 SSH 的 port 明晃晃的擺在眼前  防火牆開開關關, tcp wrapper, iptables 查了又查,就是沒辦法讓 80 port 現形,直到有人在網頁上說了,1024以下的埠號是保留存取權的,難怪…… 設定都對,別說找不到路,連路口都沒看到,問題就來了,問題發現,問題解釋,都有了,怎麼解決?  chat 被追問了許久,終於說出要 setcap ,指令打了半天,拆解又合併,就是不行,只好選用 VBOX_HARD_CAP_NET_BIND_SERVICE ,本能反應地在指令模式中 export VBOX_HARD_CAP_NET_BIND_SERVICE=1 source 接著和 GPT 確認之後,說是直接 vboxmanage startvm VMName --type headless 就行,結果也撞壁 ……  結果試出是 vboxmanage startvm VMName --type headless --putenv VBOX_HARD_CAP_NET_BIND_SERVICE=1  如此,不用先 export 或是 source .bashrc ,   netstat -tulpan: 80 port 回來了,也登入 V

virtualbox 也拿出來用一用之 vdi 無法使用

 因為懶得折騰一大堆的程式碼,看來去挖之前的 VM 出來用應該是會比較快 ………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………… 嗎!? 工作環境:     windows          virtualbox 7          以前備份的 vdi 檔案  話說之前備份 vm 有點麻煩,還得下指令,只備 vdi 和 vbox 有時侯還是不行,本以為挖備份檔來重建工作環境會是比較快的,至少不用全部的程式重改一通,哪知道人算不如天算…,這大約是莫菲無誤  有些 VM 直接執行就可以,因為它沒離開主要的執行環境,而不能執行的那些備份檔案,要靠重建,或是更改檔案的 uuid  所謂的重建就是複製一個可用的 VM 然後把之前的 vdi 檔案匯入儲存媒體  這時侯可能會遇到之前的 vdi 檔案無法匯入的情形,出現的錯誤訊息很清楚,就是各種各樣的錯誤碼,仔細一看就是外星文,看不懂又解法又難搜,是一堆難啃的說明文件,這時侯就靠更改檔案的 uuid 了  處理好了之後,我回想了一下,可能不用複製 VM 來重建,最主要的要靠更改 uuid ...     收工! ---------------------------------- 一些可能會用到的指令 ----------------------------------  列出目前的 VM 有那些 VBoxManage list vms 複製 VM 到指定位址(不要包含 VM 名字的資料夾,不然 VM 的檔案會跑到指定資料夾下的 VM 名字的資料夾之下) VBoxManage clonevm sourcevm --mode all --name newvm --basefolder /path-to-vm/withoutVmName --register 重設硬碟的 UUID VBoxManage internalcommands sethduuid your-box-disk2.vdi 修改連接埠轉接(port forward)時直接改 vm_name.vbox 檔案內容 啟動 VM VBoxManage startvm vm_name (headless) 查看 VM 的訊息

耍廢文之裝裝老程式到新系統

 想把老程式裝到新的作業系統上,說是都用 Linux 那就 docker 給它開下去,然後就…   發現了骨感的現實 工作環境:     Ubuntu Server 22 TLS for host     Windows host for Ubuntu 14 PHP 5 VM  先把之前的 vm 從老硬碟裏挖出來  確認一下作業環境、使用的應用程式和套件的版本  開始試那家的 docker 可以少花點力氣,一開始選的 lamp 看起來蠻威的,沒想到開下去沒過多久就卡關了,調了很久,因為就算登進去容器裏也因為拔得作業系統很乾淨了,難搞,常用指令找不到,常用的應用程式沒裝,也沒辦法加裝,就醬花了好幾天,換個好幾個 docker ,終於找到了個不錯的傢伙 compose: apache/nginx 前可以,還可以選版本,PHP 可以從 5 選到 8 版,MySQL/mariadb 都支援選版本,如果想要 pgsql 也行,還支持 redis,又能用 .env 來設定參數,這麼威的工具,而我只需要 LAMP … XD...... 為了讓老物運行起來,應用程式版本盡量貼近 VM 裏的作業系統的版本,省(還)得(是)折騰,好在皇天不負苦(老)心(灰)人(啊),被搞了幾天之後,總算摸出一點路子,希望別花太多生命,腦細胞已死不少,不都說嗎,人腦死就是死了… 收工!

耍廢文之裝裝老程式

 最近在移植老程式到新的舊平台上撞上的南(難)牆(強),不管環境怎麼調校就是給你一片空白,這是最嚇人的,因為沒有訊息就沒辦法除錯。  好在喝了一些糖水,腦袋瓜子突然磞出,是不是之前有用了什麼特別的套件… 工作環境:     Ubuntu Server 22 TLS          docker: lamp stack               PHP5.5               pear packages...   想那時,pear install package 就搞定了,重裝時也是幾分鐘的事 果然開始想那時就是老了,程式老了,人也老了,pear 不給裝套件了 好在,當初設計 pear 的神人留了一條後路  所以把要裝的 package.tgz 全部下載下來: curl -o package.tgz http://pear.php.net/somewhere/package.tgz  再手動裝起來: pear install --offline package.tgz 好在選的這個 docker 容器有 pear 可以用,不然不知道還要搞多久 暫時過關     收工!

PHP 重新導向失效修復

 最近,把以前的程式拿出來,準備移植到新的舊平台上,怎麼說呢?程式很舊,用的環境很舊,偏偏作業系統很新,而程式很老,只能用老的套件,這有什麼問題嗎?問題就在新的作業系統本身不提供老的套件,也就是說,老程式就算會跳舞也沒舞臺了 另外還發現人也老了…還有就是修舊如舊也是得花很多工夫的… 能修好嗎?問題是 工作環境:   Ubuntu Server 22 LTS     docker: lamp stack          PHP 5.5  光是修這個重新導向可能就要花好多功了,因為之前寫的時侯用了很多跳轉的做法  找到了個不用自已折騰那麼多的做法,把要跳轉的部份從原本的 header(Location: ...) 換成 redirect_rel($relative_url) 就行了 function server_url () {       $proto = "http" .         (( isset ( $_SERVER [ 'HTTPS' ]) && $_SERVER [ 'HTTPS' ] == "on" ) ? "s" : "" ) . "://" ;     $server = isset ( $_SERVER [ 'HTTP_HOST' ]) ?         $_SERVER [ 'HTTP_HOST' ] : $_SERVER [ 'SERVER_NAME' ];     return $proto . $server ; }     function redirect_rel ( $relative_url ) {     $url = server_url () . dirname ( $_SERVER [ 'PHP_SELF' ]) . "/" . $relative_url ;     if (! headers_sent ())     {         header ( "Location: $url " );     }     else