顯示具有 Server 標籤的文章。 顯示所有文章
顯示具有 Server 標籤的文章。 顯示所有文章

2019年3月12日 星期二

DNS Challenge for HTTPs

簡而言之 你要在DNS加一筆record
每次更新他會要求你放不同的值


https://community.letsencrypt.org/t/i-am-confused-about-dns-challenge/18754




2018年12月2日 星期日

Ansible + rails + letsencrypt


First, install nginx

roles/nginx/tasks/main.yml

```yml
- name: Install nginx
  apt:
    name: nginx
    state: latest
- name: Disable default nginx config
  file:
    path: /etc/nginx/sites-enabled/default
    state: absent
  notify:
    - Restart nginx
```

roles/nginx/handlers/main.yml


```yml
- name: Restart nginx
  service: name=nginx state=restarted
```

Then, install LetsEncrypt

roles/letsencrypt/tasks/main.yml

```yml
- name: Generate dhparams file
  shell: openssl dhparam -out {{ dhparam_pem_path }} 2048
  args:
    creates: "{{ dhparam_pem_path }}"
- name: Update apt cache
  apt: update_cache=yes cache_valid_time=86400
- name: Install depends
  apt: name={{ item }} state=latest
  with_items:
    - python
    - python-dev
    - gcc
    - dialog
    - libaugeas0
    - augeas-lenses
    - libssl-dev
    - libffi-dev
    - ca-certificates
    - python-pip
    - python-virtualenv
    - git
    - libpython-dev
    - zlib1g-dev
- name: Lets Encrypt client
  git: dest=/opt/certbot clone=yes repo=https://github.com/certbot/certbot force=yes
# Auto-renew certificates and reload nginx
- name: Add crontab to renew certificates
  cron: minute="30" hour="2" weekday="1" job="/opt/certbot/certbot-auto renew >> /var/log/le-renew.log"
- name: Add crontab to reload server
  cron: minute="35" hour="2" weekday="1" job="/etc/init.d/nginx reload"
```


Last, configure service

roles/service/tasks/main.yml

```yml
- name: Add http nginx configuration
  template:
    src: templates/http.conf.j2
    dest: /etc/nginx/sites-available/{{ service_name }}.http.conf
  notify:
    - Restart nginx
- name: Enable nginx config
  file:
    src: /etc/nginx/sites-available/{{ service_name }}.http.conf
    dest: /etc/nginx/sites-enabled/{{ service_name }}.http.conf
    state: link
  notify:
    - Restart nginx
- name: Create letsencrypt certificate
  shell: ./certbot-auto certonly --webroot --email {{ service_admin_email }} --agree-tos --webroot-path=/usr/share/nginx/html -d {{ service_host }};
  args:
    chdir: /opt/certbot
- name: Add https nginx configuration
  template:
    src: templates/https.conf.j2
    dest: /etc/nginx/sites-available/{{ service_name }}.https.conf
  notify:
    - Restart nginx
- name: Add external https nginx symlink
  file:
    src: /etc/nginx/sites-available/{{ service_name }}.https.conf
    dest: /etc/nginx/sites-enabled/{{ service_name }}.https
    state: link
  notify:
    - Restart nginx
```

with nginx http template, this will redirect all http request into https


roles/service/templates/http.conf.j2

```
server {
  listen 80;
  server_name {{ service_host }};

  root /usr/share/nginx/html;

  index index.html index.htm index.nginx-debian.html;

  location ~ /.well-known {
    allow all;
  }

  location / {
    return 301 https://$host$request_uri;
  }
}
```

also add a https template for rails


roles/service/templates/https.conf.j2

```
upstream app {
  server unix:///home/deploy/apps/waynechu_blog/shared/tmp/sockets/puma.sock fail_timeout=0;
}

server {
  listen 443 ssl;
  server_name {{ service_host }};

  root /home/deploy/apps/{{ service_name }}/current/public;

  try_files $uri/index.html $uri @app;

  ssl_certificate {{ letsencrypt_ssl_dir }}/{{ service_host }}/fullchain.pem;
  ssl_certificate_key {{ letsencrypt_ssl_dir }}/{{ service_host }}/privkey.pem;

  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers on;
  ssl_dhparam {{ dhparam_pem_path }};
  ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
  ssl_session_timeout 1d;
  ssl_session_cache shared:SSL:50m;
  ssl_stapling on;
  ssl_stapling_verify on;

  location @app {
    proxy_pass http://app;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Host $http_host;
    proxy_redirect off;
  }

  error_page 500 502 503 504 /500.html;
  client_max_body_size 10M;
  keepalive_timeout 10;
}
```

roles/service/handlers/main.yml


```yml
- name: Restart nginx
  service: name=nginx state=restarted
```


At the last, set your own vars

vars/main.yml

```yml
service_host: "example.cc"
service_name: "example"
service_admin_email: "example@gmail.com"
letsencrypt_ssl_dir: "/etc/letsencrypt/live"
dhparam_pem_path: "/home/deploy/dhparams.pem"
```


That's it, now you have a https rails web



References:

https://medium.com/@gmaliar/generating-lets-encrypt-certificates-for-nginx-using-ansible-9fd27b90993a
https://gist.github.com/mattiaslundberg/ba214a35060d3c8603e9b1ec8627d349
https://docs.ansible.com/ansible/2.5/modules/letsencrypt_module.html
https://gorails.com/guides/free-ssl-with-rails-and-nginx-using-let-s-encrypt
https://blog.frost.tw/posts/2018/05/28/Getting-started-deploy-your-Ruby-on-Rails-Part-8/

2018年8月19日 星期日

setup ubuntu with ansible for rails deployment


https://semaphoreci.com/community/tutorials/how-to-deploy-rails-applications-with-ansible-capistrano-and-semaphore


2018年5月22日 星期二

explain https again


CA 憑證方發憑證,所謂的憑證就是包含

1. 公鑰
2. 用 CA 方的私鑰加密過的 Hash


## 具體步驟是:


  1. client端發起Https request
  2. Server端返回CA發的憑證
  3. Client端收到憑證,並驗證憑證是否可信,如果可信(或是使用者選擇相信)則隨機產生一段對稱式加密用的key(稱之為Key S好了),並且用憑證內的公鑰加密Key S,送給Server
  4. Server收到加密過的Key S,用自己的私鑰解密,並且回給Client一個ready的訊息
  5. Client開始和Server用Key S做對稱式加密通訊


轉載 from

https://medium.com/@kingapol/3%E5%88%86%E9%90%98%E5%85%A7%E4%BA%86%E8%A7%A3https-595b7d29c16

2018年5月20日 星期日

使用 Vagrant 練習 chef-solo deployment

每次都自己調 server 太煩了,用 chef-solo 調一次以後一直套用比較方便,可以用 Vagrant 練習會快一點

先安裝 VirtualBox 和 Vagrant

https://www.virtualbox.org/wiki/Downloads
https://www.vagrantup.com/downloads.html

Ubuntu 16.04 的 Vagrant box (Vagrant box 就是包好的環境的意思)

https://app.vagrantup.com/ubuntu/boxes/xenial64

```
➜  Codes mkdir vagrant-test
➜  Codes cd vagrant-test
➜  vagrant-test vagrant init
```

在 Vagrantfile 裡設定

```
Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/xenial64"
end
```

然後開啟 Vagrant

```
vagrant up
```

然後就可以 ssh 進去玩了

vagrant ssh

//關閉VM
$ vagrant halt

//暫停VM
$ vagrant suspend

//恢復暫停的VM
$ vagrant resume

//重啓VM
$ vagrant reload


## Chef solo

首先要 init 一個 chef-solo 的 project


檢查 vagrant 的 ssh-config

```
➜  vagrant-test git:(master) ✗ vagrant ssh-config
Host default
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/wayne/Codes/vagrant-test/.vagrant/machines/default/virtualbox/private_key
  IdentitiesOnly yes
  LogLevel FATAL
```

PasswordAuthentication 被設為 no 了所以要嘛去把 local 的 ssh key 加到 vagrant 裡要嘛就把 password 設成 yes,預設 password 是 vagrant


我個人是很懶所以就這樣:

```
ssh-copy-id -i ~/.ssh/id_rsa.pub -p 2222 vagrant@localhost
```
但其實還是有一些其他做法可以參考:

https://github.com/puphpet/puphpet/issues/1253



https://blog.vvtitan.com/2015/10/%E4%BD%BF%E7%94%A8vagrant%E7%B7%B4%E7%BF%92%E4%BD%88%E7%BD%B2%E4%BC%BA%E6%9C%8D%E5%99%A8/
https://medium.com/@brianmayrose/using-vagrant-on-ubuntu-16-04-to-create-a-virtual-machine-c767f6e2d876
https://gist.github.com/nicholasklick/af98d5814d5b8ba6d844


2018年5月16日 星期三

Rails deployment 如何避免 downtime?



有哪些造成 downtime 的可能性?


1. Code 有問題
2. Migration 跑完後 Web Server 還沒 restart
3. Deploy 完後需要重啟 Server
4. Request 沒有被 queue 起來



可能的解決方式:

## 1. Code 有問題

1. 勤勞寫 Test
2. Manually test
3. Code review
4. Staging -> Production

## 2. Migration 跑完後 Web Server 還沒 restart

有篇文章寫得很不錯, cover 了一些之前沒想到的技巧:

https://blog.codeship.com/rails-migrations-zero-downtime/

1. read only method
2. 先讓 AR ignore columns 後再刪除
```
class User
  def self.columns
    super.reject { |c| c.name == "notes" }
  end
end
```
3. renaming column 時可以用 `super || attributes["new_name"]`
```
def first_name
  super || attributes["fname"]
end
```
4. 加 index 時有時會卡住 migration 造成問題,可以考慮 create it concurrently



## 3. Deploy 完後需要重啟 Server

1. 可以先把新的 instances run 起來,然後把 request 切換到新的 instances 後再 shut down 舊的
2. 靠 Load balancer 把 request queue 起來等重啟完再執行


## 4. Request 沒有被 queue 起來

之前就遇過因為 ActionCable and AWS ELB 的各種坑

https://everyday1percent.blogspot.com/2018/04/actioncable-and-aws-elb.html

所以也是有這個可能性,解決方式是要讓 load balancer 確保有 queue request 等 server 恢復時才執行


剩下有想到再補充

2018年5月6日 星期日

Deploy rails to Ubuntu 16.04 with puma and nginx and capistrano



Install Nginx at Ubuntu

https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-16-04


設定Nginx

/etc/nginx/site-availables/myconfig

```
upstream puma {
  server unix:///home/apps/arbitrage/shared/tmp/sockets/puma.sock;
}

server {
 # listen 80 default_server;
 # listen [::]:80 default_server;
  server_name www.yourdomain.com;
  root /home/apps/arbitrage/current/public;
  access_log /home/apps/arbitrage/shared/log/nginx.access.log;
  error_log /home/apps/arbitrage/shared/log/nginx.error.log info;

  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
  }

  try_files $uri/index.html $uri @puma;
  location @puma {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;

    proxy_pass http://puma;
  }

  error_page 500 502 503 504 /500.html;
  client_max_body_size 10M;
  keepalive_timeout 10;
}
```


cd /etc/nginx/site-enabled

sudo ln -nfs /home/username/apps/appname/current/config/nginx.conf /etc/nginx/sites-enabled/appname

sudo service nginx restart



也要記得裝 redis http://everyday1percent.blogspot.com/2017/12/deploy-rails-production-redis.html






https://coderwall.com/p/ttrhow/deploying-rails-app-using-nginx-puma-and-capistrano-3

2018年4月25日 星期三

ActionCable and AWS ELB 的坑



ActionCable old fix

在 puma 前面裝一層 nginx 已經解決 ActionCable 透過 ELB failed 的問題,主要是用 nginx 手動加上 `Connection "Upgrade"` 的 header

```
  location @puma {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Ssl on;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://puma;
  }

  location /cable {
    proxy_redirect     off;
    proxy_set_header   Host $host;
    proxy_set_header   X-Forwarded-Host $host;
    proxy_set_header   X-Forwarded-Server $host;
    proxy_set_header   X-Real-IP        $remote_addr;
    proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
    proxy_buffering    on;
    proxy_http_version 1.1;
    proxy_set_header   Upgrade $http_upgrade;
    proxy_set_header   Connection "Upgrade";
    proxy_set_header   X-Forwarded-Proto https;
    proxy_pass         http://puma;
    gzip off;
  }
```

https://blog.jverkamp.com/2015/07/20/configuring-websockets-behind-an-aws-elb/
https://in1004kyu.github.io/2017/06/14/rails-cable-aws.html
https://unboxed.co/blog/actioncable-on-aws/ (這一個是用 ALB 不過一樣可以參考看看)
https://keithpblog.org/post/rails-5-tutorial-chat-app-can-we-deploy-it/
https://github.com/rubytaiwan/AMA/issues/135


最後決定拿掉,原因:

Quote by CTO

大概就是 aws 的传统 load balancer elb 基本也只支持 http 的网页请求
但是 actioncable wss 是一种 tcp 协议,load balancer 也要支持 tcp 连线方式才行
改了 elb 设定支持 tcp 连线方式,又会让原本 http 的行为有点问题
就是 deploy 时 puma restart load balancer 不会先 queue 住用户连线就会喷 502
然后 aws 比较好的 alb 功能比较强的 load balancer 好像无法调整支持 tcp 连线
但是 alb 可以支持 load balancer 去规划防火墙连线规则挡 ddos
所以前几天我找 aws 技术支持关于挡 ddos 他也是建议我们快点改架构可以用 alb



2017年12月16日 星期六

deploy rails 前如何在 production 環境設好 redis

幾個重點

1. 安裝 redis
2. 根據官方建議做好設定 https://redis.io/topics/quickstart
3. 設防火牆
4. 確定sidekiq 是用你剛剛設定的 port
5. 確定 sidekiq 是用 redis https://github.com/mperham/sidekiq/wiki/Using-Redis
6. 把 sidekiq 加到  systemd
7. 讓 capistrano 重啟 sidekiq




1, 2
```
wget http://download.redis.io/redis-stable.tar.gz
tar xvzf redis-stable.tar.gz
cd redis-stable
make

sudo cp src/redis-server /usr/local/bin/
sudo cp src/redis-cli /usr/local/bin/

sudo mkdir /etc/redis
sudo mkdir /var/redis
sudo cp utils/redis_init_script /etc/init.d/redis_6379
sudo cp redis.conf /etc/redis/6379.conf
sudo mkdir /var/redis/6379
sudo vim /etc/redis/6379.conf
```
編輯:

  • Set daemonize to yes (by default it is set to no).
  • Set the pidfile to /var/run/redis_6379.pid (modify the port if needed).
  • Change the port accordingly. In our example it is not needed as the default port is already 6379.
  • Set your preferred loglevel.
  • Set the logfile to /var/log/redis_6379.log
  • Set the dir to /var/redis/6379 (very important step!)

```
sudo update-rc.d redis_6379 defaults
```



3. 前五步驟 https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-with-ufw-on-ubuntu-16-04

```
sudo vim /etc/default/ufw
# => check ipv6
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 22
```












config/initilaize/sidekiq.rb
```
schedule_file = "config/schedule.yml"

if File.exists?(schedule_file) && Sidekiq.server?
  Sidekiq::Cron::Job.load_from_hash YAML.load_file(schedule_file)
end
```

config/sidekiq.yml
```
---
:concurrency: 4
:queues:
  - critical
  - high
  - default
  - low
  - mailers

```


https://medium.com/@thomasroest/properly-setting-up-redis-and-sidekiq-in-production-on-ubuntu-16-04-f2c4897944b5


2017年11月18日 星期六

Capistrano forward agent


Capistrano forward agent 可以讓我們不用把 server 上的key 加到 github 也能拉 private repo


今天遇到 permission deny 的問題,結果是因為 mac 重開機就清空了 ssh agents ,導致沒有 key 可以 forward ,要永久加到 ssh agent 裡面,要執行

```
ssh-add -K ~/.ssh/id_rsa
```

之後再 deploy 就行了

https://chodounsky.net/2015/07/27/forward-ssh-keys-for-capistrano-deploys/

設定 domain

A record: 把這個 domain 綁到特定 IP
CNAME: 別名,例如 hello.waynechu.com,hello 就是



https://www.oyag.com/9501/websys


Nginx


/etc/nginx/site-availables/myconfig

```
server {
  listen 80;
  server_name www.example.com;
  location / {
    proxy_pass 127.0.0.1:8000;
  }
}
```

cd /etc/nginx/site-enabled

sudo ln -s /etc/nginx/site-availables/myconfig

https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-server-blocks-virtual-hosts-on-ubuntu-16-04

2017年11月17日 星期五

在 Linode 跑 lending bot

Ubuntu 16.04 LTS

先參考裝機筆記 https://everyday1percent.blogspot.hk/2017/10/blog-post.html 把基本的機器安全設定設好


把機器加到github https://help.github.com/articles/connecting-to-github-with-ssh/

安裝 docker https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/#install-using-the-repository

安裝 docker compose https://docs.docker.com/compose/install/

```
sudo docker login
```

server
```
mkdir projects
cd projects
git clone xxxxx
cd xxxxx
sudo docker-compose up -d
```

成功的log
```
Creating lendingbot_nginx_1 ...
Creating lendingbot_nginx_1 ... done
Creating lendingbot_poloniex_1 ...
Creating lendingbot_bitfinex_1 ...
Creating lendingbot_poloniex_1
Creating lendingbot_poloniex_1 ... done
```



測試一下是不是可以連線,進 http://poloniex.yourdomain

通常要等一陣子,但如果有出現 nginx 就是成功了

## 加上 HTTP auth

先進VPS機器裡面生成密碼檔案

bash -c “echo -n ‘USERNAME:’ >> /path/to/htpasswd/subdomain.doamin”
bash -c “openssl passwd -apr1 >> /path/to/htpasswd/subdomain.doamin”

建立好之後,修改 docker-compose.yaml

在 services nginx volumes 下加入
- /path/to/htpasswd:/etc/nginx/htpasswd

重啟 docker 就會有了

2017年10月21日 星期六

deploy nodejs to server using capistrano and nvm and pm2

這給了大概流程

http://jameshuynh.com/nextjs/react/capistrano/nvm/pm2/2017/10/07/deploy-nextjs-app-with-capistrano-3-nvm-and-pm2/


Server 安裝 zsh

不能 sutocomplete 太痛苦了

```
apt-get install zsh
curl -L https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh | sh
```

然後默認zsh


```
chsh -s /bin/zsh
```


遇到問題:

```
$ chsh -s /bin/zsh
You may not change the shell for 'apps'.
$ which zsh
/usr/bin/zsh
$ chsh -s /usr/bin/zsh
You may not change the shell for 'apps'.
```

切換到 root 後跑

```
$ chsh -s /usr/bin/zsh apps
```

解決

http://blog.poetries.top/2016/06/26/Ubuntu%E4%B8%8B%E5%AE%89%E8%A3%9D-Zsh-%E5%8F%8A-Oh-my-zsh/

Host key verification failed.

問題:

```
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
SHA256:qsKeZfZAS3BCLZw6OT1a6I1U9MzfZpEfCZDmY63+VQ8.
Please contact your system administrator.
Add correct host key in /Users/wayne/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /Users/wayne/.ssh/known_hosts:10
ECDSA host key for xxx.xxx.xxx.xxx has changed and you have requested strict checking.
Host key verification failed.
```


試了:


列出現在的

ssh-add -l


ssh-add ~/.ssh/id_rsa


ssh-copy-id username@remote_host

~/.ssh/authorized_keys

最後:

把 xxx.xxx.xxx.xxx 的 key 從 .ssh/known_hosts 刪掉


http://smelon.blog.51cto.com/877877/245405

2017年10月15日 星期日

用 nvm 裝 nodejs


裝 nvm
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.5/install.sh | bash

nvm install v8.7.0

npm install pm2 -g



裝機筆記

## 裝機器

https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-16-04


* Ubuntu 16.04LTS

Local
```
ssh root@HOST
```

Server
```
apt-get update && apt-get upgrade


dpkg-reconfigure tzdata
```

如果 apt-get update 卡住:https://zach-adams.com/2015/01/apt-get-cant-connect-to-security-ubuntu-fix/


## securing-your-server

### 新增 User

Server

```
adduser apps
adduser apps sudo
passwd apps
mkhomedir_helper apps

exit
```

測試登入
Local

```
ssh apps@HOST
```

### 增加 ssh key

Local

```
ssh-copy-id -i ~/.ssh/id_rsa.pub apps@HOST
```
* 如果沒有 ssh key 記得要先 [generate 一組](https://help.github.com/articles/connecting-to-github-with-ssh/)
* 如果沒有 ssh-copy-id 就跑 `brew install ssh-copy-id`


### Disable Password Authentication

Server

```
sudo vim /etc/ssh/sshd_config
```

Set
```
PasswordAuthentication no
```

```
PubkeyAuthentication yes
ChallengeResponseAuthentication no
```


### deploy 前準備

Server
```
sudo apt-get install git
```

Local
```
ssh-add -L
如果沒有就
ssh-add ~/.ssh/id_rsa
```



2017年10月10日 星期二

reddit 上的 rails performance 總結

The Complete Guide to Rails Performance 這本書 https://www.railsspeed.com/ 的總結:

  • Measure. If you have a serious project a cost of NewRelic account is negligible but insights it provides are very valuable. Make sure you measure request queue time, when you have large variance in request processing time (some are slow, some are fast) you may want to switch from Nginx to Haproxy as a front-end.
  • Cache output. With large JSON/HTML responses you'll move from 300ms to sub-10ms. Use Russian doll caching
  • Use conditional GET
  • Use proper DB indexes. If they aren't enough, denormalize in RDBMS or use Shopify's identity_cache. There are gems that suggest what indexes you are missing. Remember that indexes are useful when searching using a prefix of indexed columns, so if you have an index on (name, created_at) it will be used when searching or sorting by name. Read "Use the index Luke" it contains pretty much everything you need to know about them.
  • If you are managing a database yourself and it's PostgreSQL, read the configuration chapter in the docs and change the settings accordingly. Defaults aren't optimized for performance.
  • DB optimization is a huge topic. If some query is unusually slow, make sure execution plan is correct. PostgreSQL optimizer sometimes messes up and uses hash join-table scan instead of nested loop. Increase stats granularity or force it to use nested loop. Read http://a.co/2GF5Sg8 if you want to know more.
  • Avoid N+1, make sure to include related records in queries. In rare cases it's better to use N+1 with Russian doll caching but generally avoiding N+1 is better. There are gems to detect N+1.
  • Play with number of processes and threads per process in your app server. Multi-threading helps with I/O bound tasks (querying a slow database, calling remote servers).
  • Enable out-of-bound GC in your app server, so that GC won't happen during requests. It has minimal impact but still.
  • Off-load long-running tasks (e.g. resizing images and calling external services) to background workers. Use Sidekiq, it's amazing.
  • Don't bother with EventMachine, it sucks.
  • Make a choice on what to do with JS files. Either use CDN to serve third-party libraries individually or bundle them in a separate file.
  • Serve static assets from CDN.


https://www.reddit.com/r/rails/comments/5x0wd2/has_anybody_purchased_the_complete_guide_to_rails/

2017年10月6日 星期五

k8s + docker + google cloud

### Docker

```
docker build -t wayne5540/poloniex-toy .

docker run -p 49160:3000 -d wayne5540/poloniex-toy
```

Go to `http://localhost:49160/`

Tutorails:

* https://nodejs.org/en/docs/guides/nodejs-docker-webapp/
* https://github.com/nodejs/docker-node/blob/master/README.md#how-to-use-this-image
* https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md

Commands:

* list images
  `docker images`
* list running containers
  `docker ps`
* stop container
  `docker stop <CONTAINER_ID>`
* remove container
  `docker rm <CONTAINER_ID>`
* remove imsage
  `docker rmi <IMAGE_ID>`

## Deployment

To google container engine (GKE )Using k8s, on Mac

https://www.sitepoint.com/kubernetes-deploy-node-js-docker-app/

```
brew install kubectl
```

```
docker build -t gcr.io/my-toy-projects/poloniex-toy:v1 .

gcloud docker -- push gcr.io/my-toy-projects/poloniex-toy:v1

kubectl create -f deployment.yml --save-config

kubectl get pods

kubectl expose deployment poloniex-toy-deployment --type="LoadBalancer"

kubectl get services
```

Clean
```
kubectl delete service/hello-world-deployment
kubectl delete deployment/poloniex-toy-deployment
```

docker

* 看 images

docker images

* remove images

docker rmi <IMAGE_ID>


* 建立 image
docker build -t <your username>/node-web-app .

* Run image

$ docker run -p 49160:8080 -d <your username>/node-web-app

In the example above, Docker mapped the 8080 port inside of the container to the port 49160 on your machine.


* node:
https://nodejs.org/en/docs/guides/nodejs-docker-webapp/