2019-11-08

Angular 環境

官網:https://angular.io/

安裝:
npm i @angular/cli -g

建立專案:
ng new my-proj

或建立專案時產生routes模組:
ng new hello-cli --routing

啟動測試的 web server:
ng serve
ng serve --prod

測試網址:
http://localhost:4200

建立產品版本:
ng build --prod

建立 component:
ng generate component my-component
ng g c my-component










2019-10-20

建立 python 虛擬環境

預先安裝:
1. 已經安裝好 homebrew
2. 並使用 brew 安裝 python3

python3 在 3.5 之後的版本,都會隨附安裝 pip3 和 pyvenv,因此要建立虛擬環境,十分容易。建立專案資料夾後,進入專案目錄,並執行:

python3 -m venv venv

建立之後,Mac 在專案的資料夾內的 terminal 命令列執行下式以啟動虛擬設定:
source venv/bin/activate

離開則是下:
deactivate

2019-03-20

mac 上使用 npm i -g 時

在 mac 上使用 npm i -g 時,常發生「Error: EACCES: permission denied, access...」的錯誤。

npmjs 官方的建議:https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally

terminal 輸入:
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'

在 .profile 或 .bash_profile 或 .zshrc 加入:
export PATH=~/.npm-global/bin:$PATH

原則上就是把全域的安裝資料夾設定在用戶的家目錄下。

2019-03-03

安裝 Caddy 及 PHP-fpm

在 ubuntu 18.4 上從無到有安裝 Caddy
Caddy 的一個特色就是有申請設定 domain name 時,可以自動啟動 https。

參考這篇 https://www.digitalocean.com/community/tutorials/how-to-host-a-website-with-caddy-on-ubuntu-16-04

1. 安裝 golang 環境,並設定好 $GOPATH
$ sudo apt-get update $ sudo apt-get install golang-go

2. 新增用戶 (optional)
$ sudo adduser [username]
$ sudo adduser [username] sudo

3. 建立 Caddy
go get github.com/mholt/caddy/caddy # 取得 caddy
cd $GOPATH/src/github.com/mholt/caddy # 進入專案資料夾
git tag # 查看標籤,用以查看較新的版本,此時為 v0.11.4
git checkout -b "adding_plugins" "v0.11.4" # 建立分支
go install github.com/mholt/caddy/caddy # 建立
cd $GOPATH/bin # 進入執行檔資料夾
./caddy # 測試執行,預設 port 為 2015

4. 設置 Caddy
sudo cp $GOPATH/bin/caddy /usr/local/bin/ # 將執行檔拷備到執行目錄
sudo chown root:root /usr/local/bin/caddy # 設定所有人
sudo chmod 755 /usr/local/bin/caddy # 設定存取權限
sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/caddy # 設定可以使用 1024 以下的 port
sudo mkdir /etc/caddy # 建立 Caddy 所使用的設定資料夾
sudo chown -R root:www-data /etc/caddy # 設定可以給 www-data 讀取
sudo mkdir /etc/ssl/caddy # 建立儲存 ssl 簽證檔的資料夾
sudo chmod 0770 /etc/ssl/caddy
sudo mkdir /var/www # 建立網站根目錄
sudo chown www-data:www-data /var/www # 設定資料夾所有人
sudo touch /etc/caddy/Caddyfile # 建立 Caddy 的設定檔
sudo cp $GOPATH/src/github.com/mholt/caddy/dist/init/linux-systemd/caddy.service /etc/systemd/system/ # 拷備服務啟動檔
sudo chmod 644 /etc/systemd/system/caddy.service
sudo systemctl daemon-reload # 服務重新載入
sudo systemctl status caddy # 查看狀態

5. 防火牆
sudo ufw allow 80
sudo ufw allow 443
sudo ufw allow OpenSSH
sudo ufw allow sftp
sudo ufw enable

6. 設定 Caddy
sudo touch /var/www/index.html # 建立測試首頁
sudo nano /var/www/index.html # 編輯一下
sudo nano /etc/caddy/Caddyfile # 編輯設定檔

# 注意:修改成你自己主機的 domain name
shinder.riarock.com {
    root /var/www
    gzip {
        ext .html .htm .php
        level 6
    }
}

sudo systemctl start caddy # 啟動 Caddy
sudo service caddy status # 查看狀態

7. 使用 Caddy 外掛
cd $GOPATH/src/github.com/mholt/caddy
nano caddy/caddymain/run.go # 編輯設定檔
# 以下就不做了,請參考原文

做到這裡基本上已經完成,此時 http 和 https 都可以正常使用。

8. 設定 PHP
sudo apt show php-fpm # 查看 php-fpm 最新版本
sudo apt install -y php7.2-fpm php7.2-cli curl # 安裝
sudo service php7.2-fpm status # 檢查狀態
sudo service php7.2-fpm start # 啟動
sudo nano /etc/caddy/Caddyfile # 編輯 Caddy 設定檔

shinder.riarock.com {
    root /var/www
    gzip {
        ext .html .htm .php
        level 6
    }
    fastcgi / /run/php/php7.2-fpm.sock php {
        ext .php
        split .php
        index index.php
    }
}

放個 phpinfo 檔測試一下,已經可以跑 php 囉。

9. 安裝 php modules
sudo apt-get install php7.2-mbstring
sudo apt-get install php7.2-mysqli
sudo phpenmod mbstring
sudo phpenmod mysqli
sudo phpenmod pdo_mysql

再安裝個 MySQL 差不多東西就齊全了。






2019-02-21

JavaScript 在 for 迴圈內使用 let

for(let i=0; i<10; i++){
setTimeout(function(){
console.log(i);
}, 100*i);
}
雖然只用了一個 let ,但實際上卻是依據迴圈的執行次數,宣告了 10 個區域變數。每個匿名函式所在的區域,都有一個 i 。

下面的例子可以說明這種情況:
let funcs = [];
for(let i=0; i<10; i++){
funcs.unshift(function(){
return i;
});
}
for(let s in funcs){
console.log( funcs[s]() );
}

但這個例子,由於函式不位於變數的區域內,因此會造成問題。
const f = ()=>{
console.log(i);
}
for(let i=0; i<10; i++){
setTimeout(f, 100*i);
}

2019-02-09

MongoDB 遠端連線 (ubuntu 18.04)

MongoDB 的安裝可以直接參考官方說明:
https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/

這裡的 MongoDB 版本為 4.0.6。MongoDB 安裝完成後,只允許 localhost 的連線,而且沒有任何的權限限制,可以連上線的都是管理者權限。但不用太擔心,因為沒有設定的情況下,遠端是無法連線的。

如果使用 ssh 連線到主機,再使用 mongo client 管理,理應也不需要設定。但我希望可以用家裡的 mac 使用 Robo 3T 連線到主機管理,這個時候就需要做些設定,本篇是採用簡便的 Role-Based Access Control 做法。

1. 針對 admin 資料庫設定管理者。選用 admin 資料庫,並建立管理權限的管理者帳號,請參考 Enable Auth 。預設的權限角色請參考 Built-In Roles 。
use admin
db.createUser(
  {
    user: "myUserAdmin",
    pwd: "abc123",
    roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
  }
)

2. 先將服務停下來:
$ sudo service mongod stop

3. 設定 /etc/mongod.conf 裡的 net.bindIp。伺服器綁定的 IP,可將 net.bindIp 設定為 0.0.0.0 或使用 net.bindIpAll 設定為 true。亦或者設定為 Server 實際使用的 IP 及 127.0.0.1。
net:
  port: 27017
  bindIp: 127.0.0.1,157.23.???.???

4. 設定 /etc/mongod.conf 裡的 security.authorization 為 enabled,啟用帳密限定連線。
security:
  authorization: enabled

5. 啟動服務:
$ sudo service mongod start

6. 連線時,需要輸入帳號及密碼
$ mongo -u myUserAdmin -p abc123

如此就可以透過 Robo 3T 從遠端連線管理 MongoDB 了。

另外,可以參考這篇使用 ufw 防火牆去限定連線來的 ip。記得要開啟必要的 ports:
$ sudo ufw allow OpenSSH
$ sudo ufw allow from 你個人電腦的IP to any port 27017
$ sudo ufw allow http
$ sudo ufw allow https







正式環境使用 PM2 啟動 Node.js app

以往開發 Node.js app 時常使用 nodemon 在測試環境中啟動 app,其 watch 的功能,可以在檔案變更後自動重新啟動 app,對開發人員來說相當方便。

不過當 app 要發佈到遠端的虛擬機及設定比較複雜時,PM2 似乎是比較理想的工具。個人的一個專案需求是,production 會同時需要 http 及 https, development 則只需使用 http,而且 http port number 不同。

PM2 說明文件

以下是大致上的使用步驟:

1. 安裝 PM2 (使用 ubuntu 18.04)
  sudo npm i -g pm2

2. 在專案的資料夾內初始化建立 PM2 的設定檔 ecosystem.config.js
  pm2 init

3. 修改 ecosystem.config.js
    apps: [{
        name: 'der_linebot',
        script: 'app.js',
        output: './logs/output.log',
        error: './logs/error.log',
        // log: './logs/combined.log',

        // Options reference: https://pm2.io/doc/en/runtime/reference/ecosystem-file/
        args: 'one two',
        instances: 1,
        autorestart: true,
        watch: false,
        max_memory_restart: '1G',
        env: {
            NODE_ENV: 'development',
            HTTP_PORT: 3000,
            HTTPS_PORT: 3002
        },
        env_production: {
            NODE_ENV: 'production',
            HTTP_PORT: 80,
            HTTPS_PORT: 443
        }
    }],

主要是設定 logs 的輸出資料夾及檔名。另外就是開發和正式環境使用不同的埠號。

4. 設定 package.json 的 scripts
  "scripts": {
    "dev": "pm2 start",
    "pro": "sudo pm2 start --env production"
  },

5. 在正式環境時,已經使用 sudo 以 root 的權限啟動,但還是發生某些檔案讀取時發生權限不足的問題。又不想切換成為系統管理者(su root)。解法是完全停掉 pm2 後(sudo pm2 kill),將 ~/.pm2/ 裡的 .sock 檔變更所有者及所有者群組,例如:
  sudo chown shinder:shinder /home/shinder/.pm2/rpc.sock /home/shinder/.pm2/pub.sock




2019-02-04

使用 Certbot 和 LetsEncrypt 實現 Node/Express 的 HTTPS

基本上是參考這篇
Node + Express + LetsEncrypt : Generate a free SSL certificate and run an HTTPS server in 5 minutes or less

原則上是依他的說明操作,這邊是防痴呆記錄一下。

1. 先在 local 準備一個簡單的 node/express 專案,只要先安裝 express 即可,寫個 hello world。

2. 在遠端開一台 VM。我是直接在 digitalocean 開一台 ubuntu 18.4 VM,每月五塊美金的(之後有需要再擴充)。開完就可以取得主機的 IP。

3. 設定 domain name。我個人是使用 godaddy 的服務,設定對應的子網域。

4. 使用 ssh 登入主機,更新 apt 並安裝 certbot。

$ apt-get update
$ apt-get install certbot

5. 使用 cetbot 啟用手動設定

$ certbot certonly --manual

在過程中,會需要回答一些問題、輸入連絡的 email 和申請的 domain name。

6. 看到以下訊息時,請先暫停,別冒然按下 Enter。

Create a file containing just this data:
辨識用的一串編碼
And make it available on your web server at this URL:
http://你的網域/.well-known/acme-challenge/一串編碼

7. 編輯你的專案,實作上述的功能,然後使用 sftp 上傳到主機。

app.get('/.well-known/acme-challenge/一串編碼', (req, res)=>{
    res.send('辨識用的一串編碼');
});

8. 在主機,使用另一個 terminal 啟動 node server,port number 使用 80。然後才在最初的 terminal 按下 Enter。

9. 看到以下的訊息就表示成功了

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/你的網域/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/你的網域/privkey.pem
   Your cert will expire on 2019-05-04. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - If you like Certbot, please consider supporting our work by:
   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

10. 在 node/express 專案中設定:
const privateKey = fs.readFileSync('/etc/letsencrypt/live/你的網域/privkey.pem', 'utf8');
const certificate = fs.readFileSync('/etc/letsencrypt/live/你的網域/fullchain.pem', 'utf8');
const credentials = {
    key: privateKey,
    cert: certificate,
    ca: certificate
};

11. 啟動 sever 應該就可以看到 https 了。




2019-01-24

使用 docker mongo

啟動 mongo ,將 27017 port bind 到 localhost 的 27017 port,可方便使用 robo 3T 工具(儲存區沒有設定):

$ docker run -d -p 27017:27017 --name 容器名稱  mongo

若要使用 mongo console,依據官方文件(不一定要 bind port):

$ docker run -it --link 容器名稱:mongo --rm mongo mongo --host mongo test

使用 robo 3T 是比較方便的。
若要使用 local 磁碟當儲存區:

mkdir ~/data
sudo docker run -d -p 27017:27017 -v ~/data:/data/db mongo



FB 留言