2022年12月15日 星期四

nginx upstream cookie不會產生問題

 今天發生一個問題

在nodejs以 express-session建立session與cookie

原本運作都很正常

但透過nginx proxy後發現set-cookie都失效了

client browser 不會產生cookie存放session id

導致之後的使用都有問題

查了一下才發現

nginx內設定了

proxy_hide_header Set-Cookie;

拿掉就解決了

2022年10月18日 星期二

在Docker環境安裝MySQL8

要使用Docker安裝MySQL8,並可以遠端作db連線

原先MySQL5的設定方式已經不能用,且my.cnf內容也需要調整

- 編輯my.cnf

  已經沒有/etc/mysql/mysql.conf.d/目錄

  ```

  !includedir /etc/mysql/conf.d/

  [mysqldump]

  user=xxx

  password=xxx

  [mysql]

  user=xxx

  password=xxx

  [mysqld]

  skip-grant-tables // 這個設定完成要以#關閉

  ```

  會發生無法用mysql -u root -p 進入mysql

  暫時把skip-grant-tables開啟

- 進入mysql container 修改root密碼

  會發生無法用mysql -u root -p 進入mysql

  改密碼讓正常可以進入mysql

  ```bash

  sudo docker exec -it mysql99 bash

  ```

  設定root@local的密碼

  ```mysql

  flush privileges;

  ALTER USER 'root'@'localhost' IDENTIFIED BY 'xxxxx';

  ```

- 編輯my.cnf

  關閉 skip-grant-tables

  重啟mysql

- 進入mysql 改以新的方式取得遠端權限設定

  ```bash

  sudo docker exec -it mysql99 bash

  ```

  ```mysql

  CREATE USER 'root'@'%' IDENTIFIED BY 'be5578360';

  GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;

  FLUSH PRIVILEGES;

  ```

2022年10月16日 星期日

ubuntu vagrant 升級

原本使用的vagrant 2.26+virtualbox 6.0

在virtualbox升級到6.1後發生錯誤

no usable default provider could be found for your system.錯誤

需要升級virtualbox 2.3.1

下載

https://releases.hashicorp.com/vagrant/2.3.1/vagrant_2.3.1-1_i686.deb

安裝後有原本plugin版本不符的錯誤

需重新安裝vagrant plugin

vagrant plugin expunge --reinstall

安裝完即可啟動

2022年9月25日 星期日

東港 半日

 騎車 還有去廟裡走走 是我放鬆自己的方式


早上去咖啡鳥工作 下午請了半天的假

騎車到東港 一個小時內就到了 不算遠

小港沿海路這段 經過的是工業區 路上都是大拖車在跑

好處是汽機車分道 不至於危險

但總也是趕快把這段路騎過去 不想做任何停留

過了工業區 出來是林園 兩旁也多是工廠 砂石廠

過了雙園大橋 感覺才開闊起來


過了新園 就是東港

下了橋 轉進中正路 再轉到中山路

下午一點多 走進已經剛收市的菜市場內

各個攤販的小貨車都開進來收載東西

市場往前一些 是每次都會來吃的沙蝦肉圓

肉圓 糯米腸 粉腸 再加上豬血湯

以前mei帶我來 會這樣點,後來自己也喜歡上這裡



再騎車去王爺廟

非假日的下午 人不多

走到廟的三樓 外面剛好就有陣陣的風吹來

安靜 舒服


廟旁邊的水果冰 是每次來都一定來吃的

不管是自己來,跟mei來或是帶妹妹來 都會來上一碗

只是自己一個人 老闆就會幫你弄一人可以吃的份量

再騎車去華僑市場

買生魚片 買旗魚黑輪,晚上給家裡一起吃

騎車回鳳山

半天的假 自己感覺又充滿了一些電 可以繼續接下來的工作







2022年9月21日 星期三

jquery3 .andSelf()不支援問題

在jquey ui上使用到 andSelf()功能

在jquery3.x已經被廢除,解法是以addBack()取代

2022年9月12日 星期一

妹妹的學習服務

中秋節的隔天

妹妹要來大東圖書館 當一日志工的服務學習

這次沒有同學一起

可能因為是連假內 今天沒有其他的學生志工

送妹妹進去後 在圖書館外坐了一會

騎車到附近的龍山寺 最近也好一陣子沒到廟裡

再回到大東旁的麥當勞 準備待到中午再帶妹去吃飯

圖書館旁的Zone Cafe 有位子 先到裏面 等妹休息時間到

12點妹準時出來吃飯

我們在餐廳裡 邊吃邊聊

快1點 妹再回圖書館上班


在圖書館內 很多位子

找了個位子 打開電腦 也寫寫自己的東西

看著妹妹在管理 整理書架

一下拿書來給我看

一下又坐下來 說偷懶 休息一下

這樣的下午 很舒服的在館內

享受著這樣 美好的時光

4點半 妹下班了 拿到了館裡給的服務獎狀

我們回家了




2022年8月29日 星期一

溫暖

2006年 
在自己曾經最低落的一段時間

住在三重一家洗衣店的樓上的一個套房

昏黃的小檯燈旁 寫下這段三拍往前走的旋律

兩年後 到StreetVoice寫音樂播放器

也把這段錄音放到網站上

留下一個紀錄 也紀錄著寫歌的那個下午

寫藉著音樂給自己一點溫暖


2022年8月16日 星期二

nignx alias 403Forbiden問題

今天在建立新主機遇到狀況

在nginx 以alias設定static檔案

ex:

location /test {

  alias ~/myweb;

}


但一直遇到403Forbiden

檢查檔案權限都沒有問題

解決方式是

將nignx啟動使用者設定為

檔案的擁有者 即可

也就是修改

nginx.conf 

user www-data

改成

user xxx使用者帳號

2022年8月1日 星期一

got.js response內容

當以got作 request取得的資料內容為

如果是正確的完成 會取得response物件

物件的內容為{ body, statusCode}

若發生錯誤catch到的error物件

error.response 也是一個response物件

也就是是原始的httpResponse物件

內容一樣是{ body, statusCode}


ex:

const response = await got(url, opt).catch(e => {

  // e.response 就是httpResponse物件 // ex:403

  // e.response.statusCode

  // e.response.body 錯誤資訊 ERR_NON_2XX_3XX_RESPONSE, ETIMEDOUT

})

抱怨一下got.js的文件看起來很多 但可用性真的很低

真的很難找到需要的資訊

2022年7月27日 星期三

開機自動執行pm2

pm2本身內建產生自動執行腳本

// 執行要透過pm2執行的指令

pm2 start src/index.js --name=jdagent

//儲存

pm2 save

// 產生啟動腳本

pm2 startup

執行後通常會提示 你真正要執行的指令

複製 執行就可以了

ex:

sudo env PATH=$PATH:/home/ozzy/.nvm/versions/node/v12.22.8/bin /home/ozzy/.nvm/versions/node/v12.22.8/lib/node_modules/pm2/bin/pm2 startup systemd -u ozzy --hp /home/ozzy

產生的腳本會是存在

ex:

/etc/systemd/system/pm2-ozzy.service


要移除自動啟動

pm2 unstartup systemd

執行後通常會提示 你真正要執行的指令

複製 執行就可以了

ex:

sudo env PATH=$PATH:/home/ozzy/.nvm/versions/node/v12.22.8/bin /home/ozzy/.nvm/versions/node/v12.22.8/lib/node_modules/pm2/bin/pm2 unstartup systemd -u ozzy --hp /home/ozzy


2022年7月14日 星期四

cors錯誤The 'Access-Control-Allow-Origin' header contains multiple values , *', but only one is allowed.

當在nodejs server 已經加入cors設定

就不能在nginx 設定

add_header Access-Control-Allow-Origin *;

add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';

否則就會有重複設定的錯誤

2022年6月21日 星期二

字串轉換json 的幾種狀況

在程式內常會把json資料以text方式存到db內

當拿出來使用再轉為json使用

字串的產生 可能是由物件stringify產生

或是透過組合而成的字串

組合出要可以產生json物件的字串

可能有以下幾種狀況與錯誤


1. 字串內都是用雙引號包起來

可以直接parse成json物件

str = {"name":"oz"}

obj = JSON.parse(str)


2. 字串以單引號包起來

會發生解析錯誤,可以透過stringify把'轉成"

str = {'name':'oz'}

str = JSON.stringify(str)

obj = JSON.parse(str)


3.若單雙引號混合就無法轉成json物件

雙引號會被加上跳脫字元

單引號會轉成雙引號

str = {"name":'oz'}

str = JSON.stringify(str)

產生的字串為  {\"name\":"oz"}

這樣無法轉成json物件



express api 同時處理form與raw

express api 同時處理form與raw

寫api接收post資料可能會是raw data或form或x-www-form-urlencoded

透過header Content-Type 判斷

如果是raw conten-type會是text/plain

其他分別就會是

1. raw data

content-type==='text/plain'

raw data 無法由req.body拿到資料

必須透過

req.on('data',()=>{})接收

req.on('end',()=>{})完成接收取得完整資料

取到的完整資料會是string


2.application/x-www-form-urlencoded

content-type==='application/x-www-form-urlencoded'

直接由req.body取得資料

req.body為object物件內容


3.multipart/form-data

用來上傳檔案與資料用的

一樣可以透過req.body取到資料

但必須要有安裝multer

app.use(multer({ dest: './uploads/' }))

注意要判斷是否使用form-data

要用contentType.indexOf('multipart/form-data') !== -1 判斷

因為內容值不只multipart/form-data

 const contentType = req.get('Content-Type')  
  // 處理raw data  
  let data = ''  
 if (contentType === 'text/plain') {  
  req.setEncoding('utf8')  
  req.on('data', (chunk) => {  
   data += chunk  
  })  
  req.on('end', async() => {  
   res.send(data)  
  })  
 } else {  
  let data = req.body  
  if (typeof data === 'object') data = JSON.stringify(data)  
  res.json({ data })  
 }  

2022年5月22日 星期日

爬山 水煮蛋

mei沒來爬過柴山

這次回來有比較多的空檔 可以上山來走走



下山 全身汗把衣服都溼透了

龍泉寺登山口旁的佛寺協會

總是登山客方便上廁所打理自己的地方

換好乾淨的衣服

我們坐在樹下的水泥台上

mei剝著早上他準備好的白煮蛋 遞給我

涼風徐徐吹來

吃著蛋 喝個水

還有這大好的 藍天與綠意



2022年5月20日 星期五

東港 星巴克

上班時間 咖啡店裡 只有幾個客人

停好車 中間長排桌子 我們坐在靠邊的位置

打開電腦 這是一天的開始

電腦 冰咖啡

在這空間裡 靜靜做著我們各自的工作

抬起頭 眼前 窗外是藍天白雲






2022年5月10日 星期二

使用tar 解壓縮到指定目錄

使用tar gz壓縮目錄

在解開時希望可以解到指定目錄內

例: 

myfolder 包含了a,b,c目錄內容

壓縮成myfolder.tar.gz 要將內容解壓縮到yourfoder內


如果以正常程序壓縮

tar -zcvf myfolder.tar.gz myfolder

解壓縮

tar -zxvf myfolder.tar.gz yourfoder

那到的yourfolder內會包含了myfolder這個目錄


要避免那一層myfolder的出現

有兩種作法

1.

壓縮時建立只有內容的壓縮檔

cd my_directory/ && tar -zcvf ../my_dir.tgz . && cd ..

建立yourfolder目錄並解到yourfolder目錄下

mkdir yourfolder

tar zxvf my.tar.gz -C yourfolder


2.

正常建立壓縮檔

tar -zcvf myfolder.tar.gz myfolder

解壓縮時 只取第一層的資料

tar --strip-components=1 -zxvf my.tar.gz -C yourfolder

參考資料

2022年5月4日 星期三

透過ansible 匯出docker MySQL db

要把docker mysql container的資料倒出來

當然可以透過像MySql workbench倒回即可

但目標是透過ansible腳本可以遠端隨時把db dump出來

所以需要的是透過單一指令執行

基本作法是

先進入container

sudo docker exec -it mysql99 bash

再執行mysql dump指令

mysqldump -u root -p mydb > mydb.sql


可以簡化成由docker exec直接執行

sudo docker exec -it mysql99 bash -c 'mysqldump -u root -p mydb > mydb.sql'


但如果要自動化這有一個問題是,每次都需要輸入password

解決方式是 在my.cnf加入設定

[mysqldump]

user=xxx

password=xxx

指令可以再簡化連使用者都不用輸入 

sudo docker exec -it mysql99 bash -c 'mysqldump mydb > mydb.sql'


已經準備好自動化的指令

接下來就可以使用ansible腳本來執行

dump.yml

- name: Dump MySQL db

  hosts: myhost

  tasks:

    - name: Dump MySQL DB -e db要帶匯出的db名稱

      become: true

      shell:

        cmd: "docker exec -it contianerName bash -c 'mysqldump {{db}} > {{db}}_{{ ansible_date_time.date }}.sql'"

      register: output

    - debug:

        var: output

執行

ansible-playbook -i hosts.yml -e db=mydb dump.yml

就會將mydb dump到 mydb_20200501.sql這樣帶有日期的sql檔案

2022年5月2日 星期一

勞動節放假一天

勞動節補假 空出來的一天

原本計劃好 要坐火車去金崙


下著毛毛雨的補假日 比起前幾天涼了許多

也沒想跑太遠的地方

開著車去屏東果園

跟老爸聊聊天 走走看看

mei簡單煮了點東西給爸吃

我們就要載了些香蕉先離開



佳平其實就在沿山公路旁邊

從果園開車過來 不過10來分鐘 只是自己都沒來過

沿著山路開上去 路上的指標 山上的咖啡餐廳還蠻多間的

順著山路上去 好朋友餐廳就在路旁

mei有來過這裡 也帶我來看看

進來就看到了mei的朋友在這幫忙

下雨天 又是疫情 整個餐廳只有一桌的客人

我們找了個位置 坐下吃飯





一點半多 再開車去三平咖啡

有點人潮 不過還好 沒有等太久就可以進去了

上次帶妹妹來就覺得很好 要帶mei來看看

喜歡這裡的感覺

日式建築裡

喝咖啡 看小說 是很舒服的地方




看看時間 3點半多 也差不多要回家了

到家帶妹去補習

再跟mei搭捷運去高鐵站

送mei進車站後 再回家


2022年4月28日 星期四

vue3繼承實作

在使用物件導向的程式語言 

class繼承一直是很常使用的架構


在vue2 透過extends vue元件做到做元件繼承

最到類似class繼承後許多方便的功能

使用繼承的目的是

1.定義好通用的props,data,computed 繼承者都可直接使用

2.定義好通用的methods

  如果繼承者有定義相同method會覆蓋掉底層的

3.生命周期

  在底層的會被執行,繼承者有定義相同的也會被執行

透過維護底層元件讓繼承者都可得到對應的功能


vue3 如果使用option api寫還是一樣保有使用extens的功能

但若採用新的composition api則extends就變的無效

以下紀錄在composition api做到類似原來繼承的功能


使用範例

底層元件vAsset.ts

// 設定props資料,繼承者需取這來產生props

export const propsData = {

  parentUid: {

    type: String,

    default: null

  }

}

// 用來產生props

export const injectProps = () => (propsData)

export function vAsset () {

  return {

    ....所有定義好要給外部使用的功能

  }

}

繼承元件vObj.ts

import {vAsset, propsData as myPropsData} from './vAsset'

// 建立包含繼承的prop與自己新增的props資料

export const propsData = {

  ...myPropsData,

  title: {

    type: String,

    default: 'title'

  }

}

// 產生真正提供使用來inject props的function

export const injectProps = () => (propsData)

export function vObj () {

  const oz = vAsset()

  onMounted(() => {

    // 使用到上層元件的功能可以用oz.xx取用有開放的部份

    oz.on('Modal.CMD.Show', (id:string, boolean:boolean, myopenerId = '') => {

      ...

    })

  })

  // 在這裡建立要使用的data或method...

  let modalData = reactive({})

  // export 出去同時包含要繼承進來的所有功能

  return {

      // data

      modalData,

      ...oz

  }

}



在vue元件上使用繼承功能myinstance.vue

<script setup lang='ts'>

import { vObj, injectProps } from 'src/core/vObj'

const {uid, attrs, isVisible} = vObj()

// 定義props, 除了自己本身的還要inject繼承進來的部份

const props = defineProps({

  ...injectProps(),

  host: {

    type: String,

    default: ''

  }

})

onMounted(()=>{

  console.log(`onMounted id=${attrs.id} uid=${uid.value} parent=${props.parentUid}`)

})

</script>

vue2升級vue3 composition api紀錄

將原本的vue2更新使用vue3 composition api改寫

針對原本vue2 option api使用的各個功能對應到vue3的使用

紀錄如下

1.主架構

<script setup lang="ts"></script>

所有要用的功能都由vue import

import {ref,reactive,computed,watch...} from 'vue'

只有在使用setup()才需要return

如果是以script setup則不需要return

在程式內沒有任何的this使用

2.props

設定

以 defineProps({})定義建立

ex:

  const props = defineProps({

    host: {

      type: String,

      default: ''

    }

  })

使用

ex:

  props.host


3.data3.data

以ref或reactive包裝變數

ref:一般的變數都以ref包裝,使用必須以.value讀取

ex:

  建立 const myvar = ref('') 

  使用 myvar.value

reactive: Object或Array以reactive包裝

ex:

  建立 const myvar = reactive({x,y})

  使用 myvar.x

4.computed或取自store的getters

以computed包裝 使用上以.value取值

設定建立

  const inAgent = computed(() => {

    return currentHost.value.inAgent !== undefined && currentHost.value.inAgent

  })

使用

  inAgent.value

5.attrs

  取得網頁上html上設定的attrs

  取得

  import { useAttrs} from 'vue'

  const attrs = useAttrs()

  使用 attrs.xxx 不需要value

6.生命週期

created 就直接寫在setup內其他都有對應的

ex:mounted即改為執行

  onMounted(() => {


  })


7.watch

以watch包裝

  ex:

  watch(props.host, (val, oldVal) => {

    if (val !== oldVal) console.log(`watch!! host=${val}`)

  })


8.methods

不在method內使用this

9.vuex

  使用useStore取得store操作

  import { useStore } from 'vuex'

  const store = useStore()


10.vue-router

  import { useRoute, useRouter } from 'vue-router'

  const route = useRoute()

  const router = useRouter()


2022年4月14日 星期四

vue quasar 透過process.env動態傳遞變數到web內

使用qusar建立vue網頁

可透過執行quasar dev執行或quasar build產生編譯檔案

如果希望可以

例如透過產生quasar build產生開發區或正式區的網站內容

但測試區與正式區取用資料的api是不相同的

希望可以透過

stage=master quasar build 建立正式區網頁

stage=develop quasar build 建立測試測網頁

在指令列上設定的環境變數stage

要如何讀取並轉換成在網頁上可讀取到?

在執行quasar cli 也就是nodejs

會載入quasar.conf.js

在這裡可以使用process.env.stage拿到在cli上設定的stage值

只要帶到 build的env下即可以在web內使用

ex

quasar.conf.js

module.exports = configure(function (ctx) {

  return {

    ..

    build: {

      env: {

        stage: process.env.stage

      },

      ..

    }

  }

在vue頁面或前端的js內

可以用process.env.stage

這邊要注意

quasar.conf.js

內的process.env是nodejs的環境變數

vue內的

process.env是 前端頁面拿到的設定變數

2022年4月9日 星期六

墾丁

 去年夏天 妹妹國小畢業

原本計畫好 要一起騎車環島 因為疫情不能出發

上禮拜騎車去東港 就跟妹妹說好

有機會我們騎車去墾丁



看著今天的好天氣 也過了連續假期

不會有太多的人車 往墾丁

選定今天 我們就要出發


早上8點半出門 去康是美給妹妹買了防曬

這次我們走一號省道 沿著88底下走

才剛往大寮的路上 停紅綠燈 就聽到音樂聲

跟妹妹觀察著是哪台摩托車在放音樂


到了下一個紅綠燈 聽到了是旁邊的一個阿伯在放音樂

馬路很吵雜 我們很用力的要聽出是什麼音樂

妹妹很厲害 這樣吵雜的路上還能聽出

是草蜢的寶貝對不起


過了大寮 過了萬丹 88走到底就是潮州

繞出市區回到一號省道 往南就是墾丁的方向


過了南州 過了佳冬 那條筆直寬廣的路 是戰備跑道

知道 要到枋寮了

先在佳冬的全家停下來休息 吃個冰 再出發



枋山的7-11海豚灣門市 是預定的休息點

去年規劃的機車環島行程 是把這當作第一個休息站

海豚灣是很熱門的中繼點

許多單車或重機 都會停在這裡休息

從這開始

路旁開始可以看到海

也開始看到有一些咖啡車 就在路邊


妹妹看到海 好興奮這是他比較懂事後

這麼近的來到海邊

路邊隨意一停 就可以拿出相機拍照



一路上妹妹唱著歌

11點多 進了恆春

走中山路恆春老街 在西門停了下來

這裡是海角七號裡 開場小巴士過不了的那個城門

穿過了城門再往前 就到了南門

沒有要吃飯 我們就再繼續往墾丁的方向前進



中午 墾丁大街沒什麼人

路邊看到麥當勞 看起來比印象中舊了許多

還以為已經不營業了 以前假日這裡可是超多人潮聚集的地方

今天幾乎都沒什麼人

妹妹餓了 我們就到麥當勞吃午餐

休息吹冷氣 到1點半多 就要離開

繼續出發到鵝鑾鼻 這是今天的目的地

讓妹妹看到這台灣的最南端

鵝鑾鼻的燈塔 還有地標 都是小時候爸媽帶我們來

還有大學後跟同學來時拍照的地點

看著時間不早 妹妹想去沙灘玩沙

就離開鵝鑾鼻 回程



才騎出不久 路邊就看到了可以下到沙灘的地方

停好車 帶妹妹下去玩

看妹妹玩的超開心的 還把褲子都弄濕了

3點半多離開沙灘 再騎回到麥當勞 讓妹換好褲子

就一路回高雄 還有125公里的路程

感覺妹累了 趴在我的背上 繼續唱著歌

他說 他的曲庫快翻完了

還是一路唱歌回到高雄

妹妹想吃焗烤 在地圖上找到大明路就有一家

滿足的吃飽 結束我們開心的一天

騎車 是我們最喜歡的旅遊方式

希望有機會 可以實現我們還沒完成的環島




2022年4月6日 星期三

ansible 檢查檔案是否存在

在ansible內需要檢查檔案是否存在

以當作條件決定後續工作是否執行

檢查遠端主機檔案跟執行local端檔案

是有差異的


檢查要控制的遠端主機檔案(被ansible控制的主機)

- name: check the nginx template config exist

  stat:

    path: '{{遠端檔案路徑}}'

  register: stat_result


檢查主控主機上的檔案(也就是執行ansible的主機)

- name: check the nginx template config exist

  delegate_to: localhost

  stat:

    path: '{{本機檔案路徑}}'

  register: stat_result

作檔案檢查要特別注意不要使用become:true

以root權限執行

2022年4月5日 星期二

ansible 以ssh clone bitbucket git repository

以ansible git module 要git clone 一個repository

過去都會以https方式去 直接綁定帳密去clone最為簡單

- name: clone myrepo

  git:

    repo: 'https://{{git_user}}:{{git_password}}@bitbucket.org/myacc/myrepo.git'

    dest: '{{target_path}}'

    version: 'master'

    clone: true

但因為安全性考量bitbucket在2022/3/1後就不支援這樣直接綁帳密方式取得

改用ssh方式取

作業之前需先把要操作的主機的ssh設定到bitbuket的repo設定上

在要操作的主機

1.建立ssh key

  ~/.ssh ssh-keygen

2.複製public key內容

  cat id_rsa.pub

  複製內容

3.到bitbucket repo設定加入access_keys

  bitbuckey/myrepo/access_keys 加入

在ansible host上執行腳本

- name: clone myrepo

  git:

    repo: 'git@bitbucket.org:{{myacc}}/myrepo.git'

    dest: '{{target_path}}'

    version: 'master'

    clone: true

    accept_hostkey: yes

注意這裡多加上了accept_hostkey的設定

2022年4月3日 星期日

騎車去東港

爸爸: 妹妹這裡左轉一直騎就可以到東港了

妹妹: 好啊 好久沒去了 我們去東港


清明連假4天 掃墓是最後一天

待在家幾天也無聊了 中午過後

想說沒事去夢時代晃晃

沿著凱旋路騎 在中山路口等紅綠燈

臨時又很隨性的改往東港出發



沿著中山路 接沿海路 這裡大車多

總想快快騎過這段

小港,林園,新園過去就是東港

沿著光復路 再轉往中正路市場

帶妹來沙蝦肉圓 難得他可以把整份吃完

再往大鵬灣去

遊客服務中心 拍拍照

再往華僑市場 買了旗魚黑輪 就要回家了

妹妹喜歡坐摩托車 吹風唱歌

出來 去哪 不是重點 騎車唱歌才是目的 




2022年4月1日 星期五

ansible 在使用loop或with_items時加入條件when判斷

目前有一個使用情境

在管理多台主機的nginx設定時

要寫一個更新nginx config設定檔的腳本

因為是要套用在多台主機上

因為設定檔 都會以j2樣板方式寫好再套用各主機資料產生config檔案

所以會先準備好多個樣板

ex:

api.conf.j2 設定api相關

web.conf.j2 設定web相關

service.conf.j2 設定其他各式服務

socket.conf.js 設定 socket服務


但也因為各主機屬性不一樣

並不是所有的主機都會同時有這些設定檔案


因此在寫ansible控制腳本時就會需要使用迴圈

判斷如果樣板檔案存在就使用樣板產生設定檔案的功能


- name: check the nginx template config exist
  with_items:
    - src: '../../files/nginx/default.conf.j2'
      dest: '/etc/nginx/sites-available/default.conf'
    - src: '../../files/nginx/conf/web.conf.j2'
      dest: '/etc/nginx/sites-available/conf/web.conf'
    - src: '../../files/nginx/conf/api.conf.j2'
      dest: '/etc/nginx/sites-available/conf/api.conf'
  delegate_to: localhost
  stat:
    path: '{{item.src}}'
  register: stat_result
- name: build the nginx template config
  become: true
  with_items: '{{stat_result.results}}'
  template:
    src: '{{item.item.src}}'
    dest: '{{item.item.dest}}'
  when: item.stat.exists
- name: restart nginx
  service:
    name: nginx
    state: restarted

說明
以兩段工作來執行
第1段是檢查所有檔案是否存在
第2段是以上面檢查的結果判斷是否執行樣板render
第1段以stat來檢查檔案得到的回應stat_result
取得的 stat_result.results 為loop結果
{
  item: 即為with_items的一項,
  stat: {
    exists: true|false 是否存在
  }
}
第2段就可以以stat_result.results當作迴圈的內容
以when判斷是否執行
這樣 就不會因為檔案不存在由造成loop有錯誤

另外當執行loop發生錯誤
loop 內其他的正常項目還是都會作完
但下一段動作會因為錯誤而不執行
如同sample code內 如果loop出錯
那下一個重啟nginx的動作將不會被執行

這裡有一個特別注意的地方是
要檢查本機上的檔案是否存在
需要加上delegate_to: localhost
而且不可以使用root
也就是不可使用become:true

2022年3月16日 星期三

ssh-copy-id ansible使用

在開發ansible佈署功能主要都是透過ssh

ssh連線時如果希望不用每次輸入密碼

要透過ssh-copy-id xxx@192.168.0.99

將本機的public key丟到遠端主機上

這樣之後就直接連線不需要輸入密碼


ex:

以ansible佈署的架構來看

假設區網內的幾台主機功能分別是

1.本機 192.168.0.60

2.控制機 192.168.0.99

3.應用ap 192.168.0.100

如果我們要透過控制機(99)去操作應用ap(100)

則需要在99上把99的public-key丟到100上

  ssh-copy-id user@192.168.0.100

如果ansible(99)要控制的是也是99上的程式

也要copy id給自己

  ssh-copy-id user@192.168.0.99

這樣在client機器上可以透過ssh控制control(99)機器去

代為操作99跟100的服務


2022年3月1日 星期二

pkg讀取資料檔案路徑

使用pkg將node應用程式封裝成各平台的執行檔

當執行時要讀取其他檔案的路徑

其他檔案有無被封裝 路徑是有差異的

舉例來說

有一個專案目錄

node_proj/

  tmp/

  js/

js目錄內的檔案要被封裝到執行檔內

tmp目錄內的檔案不封裝到執行檔

執行封裝好的執行檔時

1.封裝到執行檔的目錄

  在package.json內需設定要封裝的檔案

  "pkg": {

    "scripts": [

      "./js/**/**/*.js"

    ],

    "assets": ''

  }

  封裝好的執行檔在執行時 js/目錄會是在'snapshot/node_proj/js/file.js'

  在程式內要讀取的路徑需以相對路徑方式寫

  path.resolve(__dirname,'..','js','file.js')

2.若是要讀取未被封裝在執行檔內的檔案

  path.resolve('.','tmp','hello.txt')

  會讀到執行目錄下的檔案


2022年2月17日 星期四

nginx基本操作

一.完全移除

  sudo apt-get remove nginx nginx-common

  sudo apt-get purge nginx nginx-common

  sudo apt-get autoremove

二.重新安裝

  sudo apt-get install nginx

三.操作

  啟動 sudo systemctl start nginx

  停止 sudo systemctl stop nginx

  重啟 sudo systemctl restart nginx

  重載config sudo nginx -s reload

四.設定檔

  /etc/nginx/available-sites/

2022年1月28日 星期五

Linux ssh 使用

一般遠端要進入Linux 都是使用ssh

使用ansible操作也都是透過ssh

確認遠端要連線的主機允許連線

一.遠端主機安裝與啟動ssh服務

  要遠端連線的主機

  檢查/etc/init.d/下 有沒有ssh 或sshd

  若沒有

  安裝

  sudo apt-get install ssh

  啟動

  sudo systemctl start ssh.service

  停止

  sudo systemctl stop ssh.service

  若22 port沒有對外開放

  sudow ufw allow 22 開啟

二.client端連線

  除了使用帳密登入外

  可以將client的ssh public key copy到遠端主機上

  ssh-copy-id ozzy@xxxx (這是帳號@遠端ip) 

  之後就可以以ssh key登入

  ssh ozzy@xxxx

三.清除knows_host

若連線的機器有換或是重裝系統

需要先移除原本紀錄在know host內該ip的紀錄

ssh-keygen -R 192.168.0.99

重新ssh連線就會產生該ip新的host紀錄了

2022年1月14日 星期五

nginx回應文字訊息sample

需要nginx簡易的回傳文字訊息

 location /test_return {

        default_type  text/plain;

        return 200  '回傳文字';

    }

2022年1月13日 星期四

git救回被刪除的branch

不小心把本機尚未推到git server的分支砍掉

還是可以找回來

1.git fsck –full –no-reflogs | grep commit

  列出被刪掉的commit

2.將commit id 一個一個檢查內容

  git log –stat xxxxxx

  注意 順序並非依照時間排列 要一個一個找

3.找到目標的commit點

  git branch 新branch名稱 commit點

  將找到的commit點存成新的branch

4.切換到新branch

  git checkout 新branch

2022年1月3日 星期一

開始的地方

下班後 一個人 小小的房間裡

只留下桌邊 昏黃的燈光

聽著音樂 寫寫東西

也許拿起吉他 彈著唱著

這是我20年前的生活日常


自己寫音樂播放器 播放喜歡的音樂

開始在無名寫blog 寫下自己喜歡的音樂感受

知道有人在看 有人在聽 知道自己並不孤單

轉眼 已經16年

blog也變成大多的工作紀錄

偶爾有些心情 有些感受

忙碌的生活 沒有寫下來 沒有停下紀錄

就忘記了 過幾年後 也許也不記得這幾年

自己的模樣