2020-11-27

Mailgun 資源

mailgun 資源

以 mailgun 使用程式發信時,首先要有自己的 domain,個人是使用 godaddy 的網域。 Mailgun 官網是以 Cloudflare 為範例說明,來說明如何設定網域的驗證:Domain-Verification-Walkthrough。 設定的 domain 以 mg.mydomain.com 為例。

申請 Sending API Keys

到 Mailgun 官網登入後,在左側欄點選「Sending」>「Domain」,選擇你要使用的 domain 後,選「Domain Settings」,再點選「Sending API Keys」建立所需的發信 key。

使用 Node.js 發信

官方有出 Node.js package mailgun-js,先在專案中安裝。 參考這篇官方的文件 How To Send Transactional Email In A NodeJS App Using The Mailgun API。 我的 .env 設定大概是長這樣:

MAILGUN_API_KEY=my_secret_key MAILGUN_FROM_WHO=service@mg.mydomain.com MAILGUN_DOMAIN=mg.mydomain.com

測試發給自己信箱時,有可能會進到垃圾郵件,如果沒看到郵件,先到垃圾郵件找找找不到的話,再進行除錯。

官方會提供一個 postmaster@mg.mydomain.com 的帳號,可以在 Domain settings > SMTP credentials 那邊看到。 重設密碼後,應該可以使用 nodemailer 發信。有些人以 nodemailer 搭配 nodemailer-mailgun-transport 使用。

2020-11-21

在 ubuntu 使用 screen 背景執行

在 ubuntu 使用 screen 背景執行

通常終端機指令在其後下 & 就可以背景執行,不過很不方便。screen 用起來就方便多了。 尤其是使用 ssh 遠端登入,就算網路斷線或者筆電進入睡眠狀態,也不用擔心程式跑一半就斷了;同時又可以接回去原本的訊息畫面。

# 查看有沒有安裝 screen $ screen --version # 若沒有安裝,以 apt 安裝 $ sudo apt install screen # 查看背景執行的程式 $ screen -ls # 開始,直接下 screen 指令,然後按 Enter 進入即可 $ screen # 進入後像是進入另一個 shell 一樣,執行你要執行的指令後,可以關掉 terminal # 退出 screen $ exit

以下是查看的例子:

$ screen -ls There are screens on: 220648.pts-4.backup-sfo2-20201024 (11/20/20 11:05:38) (Detached) 210531.pts-0.backup-sfo2-20201024 (11/18/20 23:00:07) (Attached)

使用參數 -r 可以連接目前分離狀態 (Detached) 的 terminal

# id 打前面幾個字元按 tab 即可 $ screen -r 220648.pts-4.backup-sfo2-20201024

使用參數 -x 可以搶用目前不是在分離狀態 (Attached) 的 terminal

# id 打前面幾個字元按 tab 即可 $ screen -x 210531.pts-0.backup-sfo2-20201024

2020-11-20

在 ubuntu 建立磁碟交換區 swap

在 ubuntu 建立磁碟交換區 swap (暫存區)

本篇筆記參考How To Add Swap Space on Ubuntu 16.04

文中警告,swap 可能會降低 SSD 硬碟的壽命!

# 查看是否有磁碟交換區 $ sudo swapon --show # 查看記憶體使用情況(亦會顯示交換區) $ free # 建立 swap 之前,先了解磁碟的使用狀況 $ df -h # 建立一個用來當做 swap 的檔案 swapfile(名稱可自己決定), # 大小為 4g,通常為實體記憶體的一半到相同大小,視情況而定 $ sudo fallocate -l 4G /swapfile # 變更為只有 root 能用 $ sudo chmod 600 /swapfile # 設定檔案為交換區 $ sudo mkswap /swapfile # 啟用檔案為交換區 $ sudo swapon /swapfile # 若要在下次重開機時,重新掛載 swap,需編輯 /etc/fstab # 先備份檔案,以免發生悲劇 $ sudo cp /etc/fstab /etc/fstab.bak # 將設定內容加入檔案,就全部完成 $ echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

2020-11-08

使用 docker-node 測試 nodejs 專案

使用 docker-node 測試 nodejs 專案

首先你的環境必須已經安裝 docker,參考「取得 docker」

# 取得 nodejs,在此使用較舊版本 10 docker pull node:10

在專案中建立 docker-compose.yml 檔:

version: "2" services: node: image: "node:10" working_dir: /Users/shinder/Dropbox/my-nodejs-proj environment: - NODE_ENV=development volumes: - ./:/Users/shinder/Dropbox/my-nodejs-proj ports: - 3000:3000 command: "node ./src/index.js"

其中,比較要注意的是 ports,第一個 3000 是 host 使用的 port,第二個 3000 是 container 使用的 port。 執行使用 up,關閉使用 down:

# 啟動 docker-compose up # 在背景中啟動 docker-compose up -d # 關閉 docker-compose down # 查看正在執行的 containers docker ps

*** 在啟動專案的時候出錯了「invalid ELF header」,無法載入 bcrypt 模組。 問題出在,bcrypt 是平台相依性的,我的 host 是 MacOS,container 則是 Debian。

目前想到的解法是,重新建立 image 檔,將專案內的檔案(排除 node_modules)複製到 container,然後再重新 npm install 所有套件。要設定三個檔案:.dockerignore,Dockerfile,docker-compose.yml。

# .dockerignore node_modules
# Dockerfile FROM node:10 RUN npm install -g nodemon RUN mkdir -p /usr/src/app WORKDIR /usr/src/app COPY package.json /usr/src/app RUN npm install EXPOSE 3000
# docker-compose.yml version: "3" services: node: build: . working_dir: /usr/src/app environment: - NODE_ENV=development volumes: - ./:/usr/src/app - /usr/src/app/node_modules # 上式可以用 container 的路徑覆蓋原來 host 的 node_modules 目錄 ports: - 3000:3000 command: "npm run dev"

執行 docker-compose up 即可建立,若調整設定檔後要重建可使用 docker-compose build。 其它常用的指令:

# 連入 container 的 bash docker exec -it <container-id> /bin/bash # 列出所有 image 檔 docker image ls # 移除某個 image 檔 docker rmi <image-id>

2020-11-07

使用 mongoose 連線遠端 mongodb (ubuntu)

使用 mongoose 連線遠端 mongodb (ubuntu)

通常連線遠端的 Mongodb server,使用 connection string uri:

mongodb://[username:password@]host1[:port1][,...hostN[:portN]][/[defaultauthdb][?options]]

Admin 帳號設定方式同 這篇。但是在使用 mongoose 連線時,一般的 connection uri 設定一直無法正常連線。

爬了文才發現要在 mongoose 連線時,使用 auth, user, pass 三個另外的設定,uri 內就不用放帳號和密碼了。例如我的連線檔案 mongoose-connect.js:

const mongoose = require('mongoose'); mongoose.connect(process.env.MONGO_DSN, { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true, useFindAndModify: false, "auth": { "authSource": "admin" }, "user": process.env.MONGO_USER, "pass": process.env.MONGO_PASS, }); const db = mongoose.connection; db.on('error', (error)=>{ console.log('Mongoose connection error:', error); console.log(`mongoose.connection.readyState: ${mongoose.connection.readyState}`); }); db.on('open', ()=>{ console.log('Mongoose connected ~'); }); module.exports = mongoose;

2020-11-03

ubuntu 備份 mysql

ubuntu 備份 mysql

一般使用 mysqldump 來備份 mysql 資料

# 只備份 schema mysqldump --no-data -u db_user -p'db_password' db_name > mybackup.sql

如果不想把 db_password 放在裡面,可以建立 ~/.my.cnf 輸入如下,並將檔案屬性設定為 600:

[mysqldump] user=db_user password=db_password

把要備份的檔案加上日期,將工作寫成 backup.sh:

#!/bin/bash today=`date +"%Y-%m-%d"` mysqldump --no-data db_name > "mybackup-${today}.sql"

搭配 crontab 使用,即可自動排程備份。以下是備份後複製到遠端主機,然後移除檔案:

#!/bin/bash today=`date +"%Y-%m-%d"` sqlFile="/root/db_bk/mydatabase-${today}-all.sql" mysqldump mydatabase > "${sqlFile}" scp -C "${sqlFile}" root@xxx.xxx.xxx.xxx:/mnt/volume_somewhere/db_bk/ rm "${sqlFile}" echo "ok"

2020-11-01

nginx + nodejs 使用 certbot

nginx + nodejs 使用 certbot

以下的設定參考 教學-申請Let’s Encrypt憑證與啟用https

承上篇,在 nginx 設定中加入一個 server /etc/nginx/sites-enabled/www.shinder.cc,並設定為:

server { listen 80; server_name www.shinder.cc shinder.cc; location / { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; proxy_set_header Host $host; } }

啟動 node/express server,使用 port 3000。 然後測試 http://www.shinder.cc 是否可以看到 node/express 的執行內容。 安裝 certbot:

# 先加入 certbot 的 repo 資料 sudo add-apt-repository ppa:certbot/certbot # 更新 repo 並安裝 sudo apt update sudo apt install certbot

申請憑證:

sudo certbot certonly --webroot --webroot-path=/home/ubuntu/<express專案>/public/ -d www.shinder.cc -d shinder.cc

接著會有幾個詢問, email,是否同意授權,email是否要接收訊息等等。最後就是 key 所放的位置:

/etc/letsencrypt/live/www.shinder.cc/fullchain.pem /etc/letsencrypt/live/www.shinder.cc/privkey.pem

為了增加安全性產生一個2048-bit Diffie-Hellman的密碼組合:產生的 /etc/ssl/certs/dhparam.pem 之後會用到:

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

更改 nginx 設定

建立設定檔 /etc/nginx/snippets/ssl-www.shinder.cc.conf

ssl_certificate /etc/letsencrypt/live/www.shinder.cc/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/www.shinder.cc/privkey.pem;

建立另一個設定檔 /etc/nginx/snippets/ssl-params.conf

ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; ssl_ecdh_curve secp384r1; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; ssl_dhparam /etc/ssl/certs/dhparam.pem;

最後修改 nginx 設定檔 /etc/nginx/sites-enabled/www.shinder.cc

server { listen 443 ssl http2; listen [::]:443 ssl http2; include snippets/ssl-www.shinder.cc.conf; include snippets/ssl-params.conf; server_name www.shinder.cc shinder.cc; client_max_body_size 1G; location / { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; proxy_set_header Host $host; } } server { listen 80; server_name www.shinder.cc shinder.cc; return 301 https://$server_name$request_uri; }

nginx 重新載入設定就可以測試 https 了。

自動更新憑證

使用 crontab 排程:

# 進入編輯 sudo crontab –e

加入下行,每日早上七點更新:

10 7 * * * /usr/bin/certbot renew --quiet --renew-hook "/bin/systemctl reload nginx"

如果 web document root 變更了,可以在 /etc/letsencrypt/renewal/www.shinder.cc.conf 檔案內修改 webroot_map 。

在 AWS EC2 安裝 nginx

在 AWS EC2 安裝 nginx

安裝 nginx 和 php

前置的步驟:

  • 先登入 AWS console。
  • 選擇 EC2 console。
  • 啟用實體(instance)。
  • 選擇作業系統影像檔,我習慣用 ubuntu。
  • 選虛擬機器規格,一般用途選 t2 系列。
  • 啟動之前會詢問要使用已存在的 key pair 或者建立新的。若選建立新的,要保管好 key,不然無法登入實體。
  • 啟動後可以在 console 看到實體。

注意:記得到 instance console 的 security 分頁,設定 inbound rules,讓一般人都可以透過 http 和 https 拜訪。

登入主機:我自己是使用 Mac zsh,當然也可以使用 linux bash,若使用 Windows 建議用 git bash 來登入。

# 先將 key 檔權限設定為 400 chmod 400 my_ec2_key.pem # 使用 ssh 登入,ubuntu 為預設用戶 ssh -i /my_path/my_ec2_key.pem ubuntu@xxx.xxx.xxx.xxx

將本機的 ~/.ssh/id_rsa.pub 加到遠端 ~/.ssh/authorized_keys 內,之後就可以不需要 pem 檔登入。

# 登入後先更新系統 sudo apt update sudo apt upgrade
# 安裝 nginx sudo apt install nginx # 查看 nginx 狀態,應該會是啟動的狀態 service nginx status
# 利用 curl 測試是否可以正常訪問 curl -I http://xxx.xxx.xxx.xxx
# 安裝 PHP 相關套件 sudo apt install php php-cli php-fpm php-json php-pdo php-mysql php-zip php-gd php-mbstring php-curl php-xml php-pear php-bcmath # 安裝套件後會自動啟動 apache2,但由於未安裝 apache2 所以會看到啟動失敗的錯誤訊息 # 查看 php-fpm 的狀態,應該要為啟動的狀態 service php7.4-fpm status
# 查看 nginx 預設網站設定,原則上不需要變更 sudo nano /etc/nginx/sites-available/default

在 /var/www/ 建立「 網域同名資料夾」,例如 php.shinder.cc,用來服務 php.shinder.cc domain 的站台。 在 /etc/nginx/sites-available/ 新增一個設定檔(通常和你的網域同名),例如: php.shinder.cc。並設定內容如下:

server { listen 80; server_name php.shinder.cc; root /var/www/php.shinder.cc; index index.php index.html; location / { try_files $uri $uri/ =404; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; } location ~ /\.ht { deny all; } }
# 在 sites-enabled 內建立 link sudo ln -s /etc/nginx/sites-available/php.shinder.cc /etc/nginx/sites-enabled/
# 測試一下 nginx 的設定檔,看有沒有寫錯 sudo nginx -t
# 重啟 nginx sudo service nginx restart

在 /var/www/php.shinder.cc 放一個 phpinfo 的測試程式,就可以測試 php 了。

安裝 nodejs

# 目前從官方套件安裝,版本為 10.19 有點舊,不過應該可以應付大部份的需求 sudo apt install nodejs npm

FB 留言