丹哥的技術培養皿

A blogging framework for hackers.

RubyKaigi 2018 心得

| Comments

2018 RubyKaigi 參加心得

場地

今年的場地在仙台的國際會議中心,一樣是一個品質很好,水準很高的會議中心。其中的 Main Hall 的容量達到了 1000 個座位之多。 難怪,第一天 KeyNote 的時候,就感覺為什麼非常擁擠,大家都在找空位坐,那時候還以為只有三四百人而已,沒想到第三天的時候公布今年的 RubyKaigi 2018 達到了 1017 人之多。 是歷年來參加者最多的一場 RubyKaigi 。真的是辦得很盛大。

議程

第一天:

第一天的 KeyNote 是由 Matz 桑主講,題目是「箴言」 大概圍繞在的議題是,命名的重要性,以及還是要每年幽默一次,說, 每一年都有人在說 Ruby 要死了 Ruby is going to dead every year 接著我就選聽了一場跟 crypto currency 有關的題目, bancor: Token economy made with Ruby - RubyKaigi 2018 大意是說國外有人做了一個 protocal 是用來計算當 based on Ehtereum 乙太坊架構的 Token 之間要做交換的話,因為涉及到 Gas (乙太坊執行 smart contract 的必要花費) 或轉換費率的重重計算,所以有人就做了一個 protocal & API 。這個 talk 就是在講利用 Ruby 實作了這個 Protocal ,作用就是可以用在兩種不同價值的 token 的交換時的轉換 API 。

接著去聽了 Stripe 這家公司裡面有三個人去做了一個 Type System 用來辨識 Ruby 的 codebase 裡面的 type 的狀態。 A practical type system for Ruby at Stripe. - RubyKaigi 2018 今年有蠻多 talk 都圍繞在 Type 型別的辨識跟處理。 應該是我的眼界還不夠大,接觸的語言不夠多,所以其實不太懂為什麼辨識 Type 那麼重要。而每一年的 Ruby Commiter VS World 的時候也常常會討論 ~爭辯~ 動態型別還是靜態型別比較好。

然後再去聽了一場用 Ruby 來開發 Command Line Tool 的 Library :TTY TTY - Ruby alchemist’s secret potion - RubyKaigi 2018 覺得是蠻酷炫的,作者設計了很多小工具小 Library ,在 Command Line 的環境介面當中多了一些視覺化的體驗。 例如 Spin , status bar , 打勾打叉符號的等等。 吃完下午中場休息的點心

去聽了一場 資料 ETL (Extract , Transform , Load ) 的 Talk 是一個法國人來講,命名成 Kiba (牙),因為他認為處理資料,就像咬住一個東西一樣。 (笑) Kiba 2 - Past, present & future of data processing with Ruby - RubyKaigi 2018

第一天的最後一場是聽了 Hanami 的作者又再說了一次 Hanami. 的整體架構,說明為什麼要採用這樣的架構。 Slides 超多,有200多頁, 就是圍繞在他所設計的 framework 架構。 Architecture of hanami applications // Speaker Deck 作者蠻酷的,說他是從 Moscow 飛到東京,再搭新幹線到仙台。 這是他第二次到日本,他還是很喜歡日本。

接著第一天最後就是 Lightening Talk 了。 2018 RubyKaigi - lightening Talk 因為我第一天其實有點在發燒,頭痛得不得了,所以 Lightening Talk. 總長度超過了一個小時讓我很痛苦。
除了 Lulalala 介紹 Rib (一個改良版的 irb 工具 ) 讓我印象深刻之外, 還有五倍的蒼時介紹他的 tamashi IOT 軟體, 還有一個人不知道為啥要 5 分鐘做一個 todo list 的 APP 還有一個 commiter 又來幽默每年 ruby 都會 dead 的話題,原因就是因為每年的聖誕節都會出新的版本,但是人力不足以維護所有舊的版本,所以每年其實都有舊的版本會 EOL (end of life)
其他的我已經有點忘記了。

第二天

一大早就錯過 KeyNote Q_Q 10:30去聽了一場作者研究如何在現今時代我們雖然利用了諸多不同的工具或套件幫忙處理網路世界的資料,但是這些每一樣的工具,能否都用 Ruby 實作或是有相同一樣功能的替代品呢? 覺得作者對 Ruby 真的蠻有愛的!也因為有他的研究,所以讓我知道,真的每一種功能(大概除了 RDBMS之外)幾乎都有人用 Ruby 實作過。 而且大家很愛詬病的效能問題,作者也做了很多的BenchMark,希望可以證明其實並沒有慢多少。 算是一個蠻特別的 Talk 。 http://rubykaigi.org/2018/presentations/wyhaines.html#jun01 用完餐後,繼續接著下午的議程 選聽了一個講述升級 gem 的 know how trick Journey of a complex gem upgrade - RubyKaigi 2018 這是由 Shopify 的工程師來分享的。 他提出了一個方法是:在 Gemfile 裡面設計 variable 去控制要不要採用新的版本的 Gem,接著,他還要去改 test code base 裡面先去宣告讓採用新版本gem 的 code 測試 allow failed . ( i.e. 就是故意要先讓他pass). 接著就可以去繼續開發新功能 & 把那些 test failed 的 test case 標記出來,整理到 excel 表去,設計改善專案時程,發給不同的團隊去啟動修正 test failed 之處,然後他說用excel 表整理一個大表,然後有標記了紅色綠色的底色,可以像是一種 Gaminification (遊戲化的象徵)讓過程可以比較像競賽一樣有趣。 他說通常要順利升級所有的 gem version 都要耗時 6 months to 1 year. 聽了之後覺得也是一個蠻新的做法。

接著聽了一場 mruby & mruby/c 的實作,是日文講者 Firmware programming with mruby/c - RubyKaigi 2018 很特別的地方是,講者的專案是跟 獺祭的酒廠 旭酒造合作 他幫酒廠的製程設計了監控溫度、濕度、空氣中的co2 等等屬性的 IOT 裝置。並且會把數據傳送到手機的 APP 上。 他分享了採用哪一種 micro processor 比較好,以及採用了 mruby/c 會遇到哪些問題,以及解法等等。

看到他做了這樣的東西,就讓我覺得 ruby 可以實作應用的場合真的蠻多的。

最後就去聽了一場講 web socket 的應用 One cable to rule them all - RubyKaigi 2018 先是揶揄了一下 Rails 5 的 action cable 雖然有設計了 web-socket & sub/pub 功能。 但是實際上好像很少有人敢用在 production 環境。 原因是效能太差,以及實際上在 publish 的時候好像還會掉訊息,所以可靠度也太差。 於是作者就介紹了自己以 Ruby 也是實做出來的另一個 web socket 工具 叫做 anycable . 但是因為實際使用的情境跟經驗太少,所以我也有點聽不懂。

第三天

一大早,又錯過了 KeyNote Q_Q 據說是在講如何 parallel run ruby 以便達到效能提升 x倍的一個 talk , 看 twitter 內是驚嘆連連,但我想應該是適用在某種 compute intensive 的條件下吧。 因為作者說,不適用 rails . 哈哈

第三天只有聽了下面這幾個talk Deep into Ruby Code Coverage - RubyKaigi 2018 在講述作者開發了一個 Gem. 可以用來標記 test code 對實作的 coverage 範圍 尤其是那種 if else then 的測試,甚至可以標記到有些 test case 沒有設計到測試不同 condition 的結果。 以及聽了一場 JRuby 9.2 and Rails 5.x - RubyKaigi 2018 基本上就是在講 JRuby 上到 9.2 了,然後改善了哪些東西 以及講一點點關於使用 JRuby 在 Rails 5.x 上的狀況 作者有show 了一些圖表去顯示效能,但除了某個 update column 的情境是 JRuby 比較厲害之外,其他其實並沒有顯著的優化。

接著最後一場就是很特別的一個 Trick 2018 contest 大賞發表。文章稍後下面另外獨立寫一段。

特別之處

Pair Programming

今年 Dekai 巨人外人 Jonan 在會場架設了錄影直播設備,也邀請了一些 Developer 其中還包括了 Matz !! 做一些 Kata 的 Pair Programming ! 然後放到 Twitch 上直播。 真的是蠻特別的~ Jonan Show - Pair Programming

Ruby Trick 2018

所謂的 Ruby Trick 的全名是 Transcendental Ruby Imbroglio Contest for rubyKaigi Reference Github 意思就是如何用 Ruby 寫出廢code ,雖然名為廢 code ,但是實際上參加者每一個都是絕世高手啊!如果不是對 Ruby 有透徹的了解的話,基本上是不可能有能力寫出這些作品的。

印象最深的有三個: 一個是執行後 redner 出了很類似 3D 動畫的聖誕樹 11-tompng 另一個是用最少的 code 寫出了一個 IRB 的環境。 12-jan 還有一個是執行後, Ruby 會在 console 開始逐個 byte 印出,然後會螺旋狀像貪食蛇一樣的像漩渦一樣的往中心繞進去。 最話顯示在畫面上的就是 source code ! 超神奇的。02-mame

推薦大家上 Reference Github Repo 找到那些參加者的 folder 執行看看

人數最多&贊助商最多

今年人數達到了 1017 人 贊助商來到了 71 家 今年有好幾家前兩年都沒有來參加的贊助商,可見規模是逐漸擴大了,而採用 Ruby 語言甚至願意贊助,參加擺攤位以及招募 Ruby 工程師的氣氛也是相當濃厚。

2019 RubyKaigi

明年要移到九州 - 福岡 舉辦囉。 時間就定在 2019-04-18 ~ 2019-04-20 感覺是一個適合賞櫻花的日子呢。

Octopress Multi Dev Env Setting Step

| Comments

如何在不同的電腦上面重新安裝已經發布過的 Octopress

[Deploy] 在其他電腦部署己存在的 octopress

1
2
3
4
5
6
7
8
git clone -b source git@github.com:dangjlin/dangjlin.github.com.git dangjlin.github.io
cd dangjlin.github.io
echo "2.5.1" >> .ruby-version
gem install bundler
bundle install          (才能使用 rake new_post['xxx'] 指令)
git clone git@github.com:dangjlin/dangjlin.github.com.git _deploy
rake generate
rake deploy

[Deploy] 同步不同電腦的 octopress

1
2
3
git pull origin source      ( 同步 source 的 branch
cd _deploy
git pull origin master      ( 同步 _deploy 目錄的內容

ps1: master branch 只存在 deploy 目錄內 ps2: deploy 目錄內一定要有一個 CNAME file ,這樣才可以使用自訂的 domain name 所以 rakefile 裡面在做 deploy 的時候,會自動 copy 一個 CNAME file from source branch to _deploy 目錄

如何使用 Mina & Puma & Nginx 部署 Rails - Deploy Rails App With Mina & Puma & Nginx

| Comments

從provision VM 到自動安裝軟體、到使用 mina 自動化部署 Rails App

provision 一台新 ubuntu server

自動裝機 script , 分兩段:

1- 第一段自動裝軟體 , curl -L https://gist.githubusercontent.com/dangjlin/2dd09f80d114e54b54be89ce8b9c6336/raw/d94cfd5eb92905c45899cb41a86c64b9f868efb5/init_install.sh | sh

gist file: (https://gist.github.com/dangjlin/2dd09f80d114e54b54be89ce8b9c6336)[https://gist.github.com/dangjlin/2dd09f80d114e54b54be89ce8b9c6336]

很重要的是: 裝完之後需手動 source ~/.bashrc 重新載入環境變數 才可以再繼續run 第二段

2- 一段自動裝 rbenv & 安裝 ruby 2.3.0 curl -L https://gist.githubusercontent.com/dangjlin/f57d8713352bfc8b0d35c31327658790/raw/efe262d3c030fa32d479b2eb9d852b41edc736d8/rbenv_init.sh | sh

gist file: (https://gist.github.com/dangjlin/f57d8713352bfc8b0d35c31327658790)[https://gist.github.com/dangjlin/f57d8713352bfc8b0d35c31327658790]

如果VPS都永遠在 AWS 或 Digital Ocean or Linode , 建議裝好之後自己 create 一個 image file, 以後就用這個image 去 provision new server

接著我會使用 chef-solo , knife-solo 自動安裝

cookbook 準備了 user , nginx, postgres sql 等自動安裝及自動設定 config template.

補充 knife-solo 的安裝 (摘錄 from Gogojimmy 網頁說明 在我們的本機,我們先安裝好knife,針對我們所使用的是Chef-Solo,因此我們要安裝的是Knife-Solo gem install knife-solo 裝好了knife-solo以後,讓我們使用knife solo init 來開啟一個新專案 knife solo init knife-solo-demo 再來我們進行下一步之前我們先產生一個chef的設定檔 knife configure -r . --defaults

在 knife-solo-demo/node 目錄裡面要 create 一個 xx.xx.xx.xx.json 檔案 這個就是待會 knife-solo 會參照的檔案

往下設定 config 之前請先完成這幾個動作

  1. 把local端的 ~/.ssh/id_rsa.pub 檔案 copy 到server端的 ~/.ssh/authorized_keys 裡面
  2. 把server端的 ~/.ssh/id_rsa.pub 檔案登記到 github 上面,這樣server 端才可以到github拉檔案

啟動 knife-solo ,使其對 server 端開啟自動 chef 的自動化腳本安裝

這邊有兩種情境 一種就是一般的 ssh 登入的方式,例如 digital ocean , linode 之類的 這種就照原本knife-solo的做法就可以 knife solo bootstrap server-user-name@xx.xx.xx.xx

一種就是 AWS 那種要登入到 ec2 instance 的時候,我們的 local 的環境要有一把 xxxx.pem 檔案的私鑰 這一種就要打這個指令才有辦法讓 knife-solo 去免帳號密碼 遠端驅動 server site 執行 chef-solo solo bootstrap xx.xx.xx.xx(server_ip) --ssh-user ubuntu -i ~/.ssh/your-pem-file-name.pem --node-name xx.xxx.xx.xx

接著請手動調整下列三個 config file

nginx config file, put it in the site-enable/default file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
upstream app {
    # Path to Puma SOCK file, as defined previously
    server unix:/home/ubuntu/site/app/app-name/current/shared/sockets/puma.sock fail_timeout=0;
}

server {
    listen 80;
    server_name localhost;

    root /home/ubuntu/site/app/app-name/current/public;

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

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

    error_page 500 502 503 504 /500.html;
    client_max_body_size 4G;
    keepalive_timeout 10;
}

puma config file in config/puma_production.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
environment 'production'
threads 2, 64
workers 2   #depends on how many cores of server CPU

application_path = File.expand_path('..', __dir__)
directory application_path

pidfile "#{application_path}/shared/pids/puma.pid"
state_path "#{application_path}/shared/sockets/puma.state"
stdout_redirect "#{application_path}/shared/log/puma.stdout.log", "#{application_path}/shared/log/puma.stderr.log"
bind "unix://#{application_path}/shared/sockets/puma.sock"
activate_control_app "unix://#{application_path}/shared/sockets/pumactl.sock"

daemonize true
preload_app!

Mina Setup 步驟執行之後注意事項

有三件事情要做: 1- 因為有兩個 config 檔案我們是做 symbolic link 到 shared folder “ shared/config ” 目錄裡面 所以記得要server 上手動增加 database.yml , secret.yml 檔案 2- 另外還有環境變數也記得手動到server去增加,以利後續 Rails production server 要讀取&啟動 3- 在 postgresql 手動 create production 的 database.

mina config file in config/deploy.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
require 'mina/bundler'
require 'mina/rails'
require 'mina/git'
require 'mina/rbenv'
require 'mina/puma'

# Basic settings:
#   domain       - The hostname to SSH to.
#   deploy_to    - Path to deploy into.
#   repository   - Git repo to clone from. (needed by mina/git)
#   branch       - Branch name to deploy. (needed by mina/git)

set :application_name, 'production_app'
set :domain, '192.168.99.99'
set :user, 'ubuntu' # Username in the server to SSH to.
set :deploy_to, "/home/#{fetch(:user)}/site/app/#{fetch(:application_name)}"
set :repository, 'git@github.com:abcdefg/xyz.git'
set :branch, 'master'
set :rbenv_path, "$HOME/.rbenv"
set :database, 'name_of_production'

# shared dirs and files will be symlinked into the app-folder by the 'deploy:link_shared_paths' step.
set :shared_files, fetch(:shared_files, []).push('config/database.yml', 'config/secrets.yml')
set :shared_dirs, fetch(:shared_dirs, []).push('shared/log', 'tmp/cache', 'shared/pids', 'shared/sockets', 'public', 'vendor')

# This task is the environment that is loaded for all remote run commands, such as
# `mina deploy` or `mina rake`.
task :environment do
    invoke :'rbenv:load'
end

task :setup do

end

desc "Deploys the current version to the server."
task :deploy do
  deploy do
    # Put things that will set up an empty directory into a fully set-up
    # instance of your project.
    invoke :'git:clone'
    invoke :'deploy:link_shared_paths'
    invoke :'bundle:install'
    invoke :'rails:db_migrate'
    invoke :'rails:assets_precompile'
    invoke :'deploy:cleanup'

    on :launch do
        in_path(fetch(:current_path)) do
        command %{mkdir -p tmp/}
        command %{touch tmp/restart.txt}
        invoke :'puma_restart'
        end
    end
  end
  # you can use `run :local` to run tasks on local machine before of after the deploy scripts
  # run(:local){ say 'done' }
end

task puma_restart: :environment do
  puma_pid = "#{fetch(:current_path)}/shared/pids/puma.pid"
  command %[
    if [ -e '#{puma_pid}' ]; then
      bundle exec pumactl -F config/puma_production.rb stop
      bundle exec pumactl -F config/puma_production.rb start
    else
      bundle exec pumactl -F config/puma_production.rb start
    fi
  ]
end

# For help in making your deploy script, see the Mina documentation:
#  - https://github.com/mina-deploy/mina/tree/master/docs

參考網站: (http://gogojimmy.net/2013/06/01/Chef-Solo-Basic-with-Vagrant/)[http://gogojimmy.net/2013/06/01/Chef-Solo-Basic-with-Vagrant/] (https://ruchee.com/notes/2016/deploy_rails_use_ubuntu_nginx_puma_mina.html)[https://ruchee.com/notes/2016/deploy_rails_use_ubuntu_nginx_puma_mina.html]

如何寫出clean Code 的參考資料

| Comments

如何設計好的程式架構跟安排,寫出clean code

這是在臉書上徵詢請教大大的筆記資料

thanks TaiAn suggestions:

Leetcode 主要還是演算法 如果是 OO (Objective Oriented) 的話, 0. Confident Ruby 1. Practical Object oriented design in ruby 2. Implementation pattern 3. The art of readable code

我記得後三本都有中文。如果不是 ruby 的話,第 0 本可以省略。也有人推薦 code complete 2,但是實在很厚,語氣也有點教條。

https://sourcemaking.com/refactoring

thanks Scott Tsai suggestions:

  1. 閱讀某篇 coding style 規範 (e.g. Google 的) 思考辯證其中規則 (e.g. 命名,變數長度與可見範圍)
  2. 閱讀某高品質的 open source 專案的程式,或可從 http://aosabook.org/en/index.html 找個目標。 500 lines or less 的程式也頗適合。

附註:Leetcode 只求解出演算法題目,會鼓勵實作快速、執行也夠快的程式碼,與寫出 “clean code” 的目標應是背道而馳。

thank unknow friend

一本聖經叫clean code

thanks Jason

裝rubocop,養成每次git commit 之前跑檢查,把檢查出的錯誤堅持修掉,然後隨經驗的累積調整 rubocop 的設定

Rails Using AWS SES Send Mail Service

| Comments

Ruby on Rails 如何使用AWS SES 的寄送MAIL服務

網站可以 send mail 了 , 感謝 AWS SES service.

有幾個小坑要注意一下:

  1. 使用 devise gem 時, initializers 目錄裡面的 devise.rb 這一行請不要亂打,AWS會驗證是不是已 verified domain , 否則會拒絕,不讓你寄信. config.mailer_sender = ‘service@aaa.bbb.ccc

  2. username & password 要在 SES 的管理頁面 「SMTP Settings」那邊有一個 create SMTP credentials ,才可以產生 SMTP 的 user & password , 不是自己跑去 IAM 生一組。

  3. 測試的時候,請先在SES 管理頁面,左邊有一個 「Email Addresses」先把要測試的收信的 mail address 打進去並且經過驗證,否則填入未經驗證的收信信箱,測試的時候SES也不讓你寄。

  4. 其餘的話就是在 environment/production.rb 把下面內容設定好

config.action_mailer.delivery_method = :smtp config.action_mailer.default_url_options = { :host => ‘http://aaa.bbb.ccc/’}

config.action_mailer.smtp_settings = { :address => ‘email-smtp.us-west-2.amazonaws.com’, :port => 465, :authentication => :login, :user_name => ENV[‘AWS_SES_USER’], :password => ENV[‘AWS_SES_PASS’], :domain => “aaa.bbb.ccc”, :ssl => true, :tls => true, :enable_starttls_auto => true }

  1. 確定沒問題之後,要離開 sandbox 到正式環境使用時,就在SES的介面填申請表,AWS會審核開通。

Redmine 串 AWS S3 遇到的問題 Hack Workaround

| Comments

整個安裝的步驟,請參考 sdlong 大的文章:

但是一直做到要把 file upload 串到 AWS S3 的時候,我們使用了 gem redmine_s3

其中 bundle install 的時候會有一個 error 說重複命名的問題 然後就開始追 code , 發現是 htmlentities 這個 gem 命名 inodot 變數的時候跟另外一個gem 的命名重複了 雖然人家 htmlentities 在 4.3.4 的時候修正了變數命名重複的問題, BUT 偏偏 redmine_3 的 dependency 又只能綁到 4.3.1 作者有回應說,我沒辦法綁到 4.3.4喔 因為 bulabulabula (省略一百字)

我剛好想到一個方式去 hack 這件事情 預設的 gemfile 會使用 bundler 去讀 rubygems.org 上面的檔案 所以所有的 code & dependency 都會依照 rubygems.org 上面的code所記載的內容運行

我想到我能做的是,我 clone 一份 htmlentities 4.3.1 的 code 回來自己的 github 然後把 lib/htmlentities/mappings/expanded.rb 檔案裡面的重複的 inotod 刪掉~ push 到自己的github.

然後我在 gemfile 裡面去指定 gem ‘htmlentities’ 的路徑是要去找我的 github 這樣被裝到 system library 的 code 就會被改正的了!

` gem “htmlentities”, github: “dangjlin/htmlentities”, branch: “fix-inodot-problem”

Rails 串 Stripe 付款的寫 Code 幾個步驟(摘要)

| Comments

Rails & Stripe

先摘要筆記下來,細節有機會再來補. 好好的付款動作,為什麼要跟註冊頁面綁在一起啊~ 然後這個註冊頁面還要跟 multi-tenancy design 綁在一起。 難度上升十倍. 範例也弄太難了吧~ (昏倒狀態) 筆記一下串 Stripe 第三方付款要做哪些動作.

  1. 設計 view , 定義好 class
  2. 設計 javascript , 該綁定的 , 該防止user誤觸的 ,該跳 error的
  3. 設定 secret key 放到 environment variable 或丟去變數管理
  4. 寫 model method , 付款動作
  5. 寫 controller , 創造 instance variable , call method , redirect .
  6. 檢查 strong parameter , 有 whitelist 的話要加上去

Bitnami Wordpress Apache Subdomain Virtual Host 設定

| Comments

bitnami wordpress apache subdomain & virtual host 設定

因為最近要把一個本來住在別的地方還是以 windows server 為 base 的 wordpress 搬家到 AWS 為了省去還要自己安裝 php , mysql , wordpress , 搞各種設定檔很麻煩的過繁瑣事務 看到 AWS 上面有 bitnami 出的 AMI 檔裡面已經有了基本的 LAMP + Wordpress. 很開心的就用了,結果是個小惡夢

對熟悉的人來說可能還好,但我太久沒有設定 apache 了,明明印象當中 subdomain 就是放到 virtual host 檔案裡面指定好目錄就好啦,但因為這個 AMI 是 Bitnami 綁了 wordpress 包出來的,他把 apache 的設定檔變成了一層包一層

然後又因為我是綁了 wordpress 的關係,現在有幾個設定檔可以設定呢?

/opt/bitnami/apache2/conf/httpd.conf /opt/bitnami/apache2/conf/bitnami/bitnami.conf /opt/bitnami/apache2/conf/bitnami/httpd.conf (這個這次不用改 可以忽視他) /opt/bitnami/apache2/conf/bitnami/bitnami-apps-prefix.conf /opt/bitnami/apache2/conf/bitnami/bitnami-apps-vhosts.conf

你以為這樣就沒了嗎?在 bitnami 所謂的 apps 裡面還有 apache 要讀的設定檔勒 /opt/bitnami/apps/wordpress/conf/httpd-app.conf /opt/bitnami/apps/wordpress/conf/httpd-prefix.conf /opt/bitnami/apps/wordpress/conf/httpd-vhosts.conf

我的情境是這樣 我的主網站放置的地方是 www.example.com /opt/bitnami/apps/wordpress/htdocs/MAINSITE 副站放置的地方是 /opt/bitnami/apps/wordpress/htdocs/OTHER-A /opt/bitnami/apps/wordpress/htdocs/OTHER-B

所以怎麼做?

bitnami apache wordpress virtual host 修改步驟

1.打開 /opt/bitnami/apache2/conf/bitnami/bitnami.conf 把下面這行註解掉

1
# Include "/opt/bitnami/apps/wordpress/conf/httpd-prefix.conf"

2.apache 本來會把主站的根目錄指去這裡 /opt/bitnami/apps/wordpress/htdocs/ 因為我們註解掉了之後, 他所謂的 prefix 模式就沒了,所以他變成去讀這個檔案 /opt/bitnami/apache2/conf/bitnami/bitnami.conf 裡面寫的根目錄路徑 /opt/bitnami/apache2/htdocs 所以我要把他換掉 換成 /opt/bitnami/apps/wordpress/htdocs/MAINSITE

3.然後去打開這個檔案 /opt/bitnami/apache2/conf/bitnami/bitnami-apps-vhosts.conf 加上下面這一行

1
 Include "/opt/bitnami/apps/wordpress/conf/httpd-vhosts.conf"

4.最後,就是我們要編輯 subdomain 副站的目的地了 打開 /opt/bitnami/apps/wordpress/conf/httpd-vhosts.conf 把 subdomain 放進去。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<VirtualHost *:80>
  ServerName Other-A.example.com
  DocumentRoot "/opt/bitnami/apps/wordpress/htdocs/OTHER-A"
  <Directory "/opt/bitnami/apps/wordpress/htdocs/OTHER-A">
    Options FollowSymLinks MultiViews
    LanguagePriority en
    ForceLanguagePriority Prefer Fallback

    AllowOverride All
    <IfVersion < 2.3 >
      Order allow,deny
      Allow from all
    </IfVersion>
    <IfVersion >= 2.3 >
      Require all granted
    </IfVersion>
  </Directory>
</VirtualHost>

Other B 一樣啦,就不寫了。 另外 DNS 那邊也要把 subdomain 的 cname給設定好喔!

以下是官網上的wiki document

How To Create A Virtual Host? Using a Virtual Host allows you to access an application at (for example) http://SERVER-IP/ or http://APPNAME.SERVER-IP instead of http://SERVER-IP/APPNAME.

This example shows how to configure WordPress to be accessible from http://wordpress.example.com. Follow these steps:

Comment out the line that includes the prefix configuration file in the /opt/bitnami/apache2/conf/bitnami/bitnami-apps-prefix.conf file:

# Include “/opt/bitnami/apps/wordpress/conf/httpd-prefix.conf” Include the virtual host configuration file for WordPress in the /opt/bitnami/apache2/conf/bitnami/bitnami-apps-vhosts.conf file:

Include “/opt/bitnami/apps/wordpress/conf/httpd-vhosts.conf” Update the URL in the application if necessary.

Restart the Apache server:

sudo /opt/bitnami/ctlscript.sh restart apache

AWS SES ( Simple Email Service) 服務使用

| Comments

很快地做一個筆記

  1. AWS SES 服務目前只有三個 Region (美東 Virginia , 美西 Orggan , 愛爾蘭) 可以用,但是不用擔心,我們開在不同Region的ec2是可調用的 (像我的主機放在東京,上面跑 wordpress ,去呼叫美東的 smtp server 是OK的。

  2. 要使用 AWS SES 服務有幾個動作要做

  3. 你要發出去的 sender 要經過驗證,其實這個很簡單,就是去登記 sender mail address 然後去這個mail 收信點驗證LINK
  4. 如果是要認證整個 domain 也可以,就是 dns 那邊要做驗證。
  5. 很重要!你要記得去 support center 開一張票,申請 ses mail service increase limitation. 這個很簡單就是幾個問題勾一勾(主要就是問你有沒有讀過使用規定,會不會遵守不寄發垃圾信的規定,會不會處理退信) 以及文字說明為什麼要增加 limitation , 我很簡單寫了需要啟用的原因是 電子商務網站註冊及寄發系統通知使用(當然是要用英文寫) , 其實這封mail 不只是增加 limitation 更是把服務從 sandbox 移到 production 啟用的重要步驟。
  6. 在 SES裡面 create 一組 IAM User,這個時候會產生一組 user name & password 很重要,請記錄下來。 這是後面要拿去 wordpress 做 smtp authentication 用的! 我一開始傻傻的拿 key id 跟 secret key 去當作帳號密碼一直認證不過~後來才知道是要在 SES 產生一組 user name & password , key and secret key 應該是 for REST API 調用的時候要寫到 code裡面的。

  7. 還有一個小坑, 我在 wordpress 那邊設定 sender email 舉例: “ Daniel@gmail.com ” , 但是我在 SES裡面認證過的是 ” daniel@gmail.com “ , 只是因為第一個字母的大小寫不一樣,這樣也會寄信失敗,要注意要一模一樣喔!

其實還有很多別的選擇啦,例如使用 mailchimp , mailgun 等等的 SaaS service. 未來有機會再來比較。

如何在windows 裡面自動定時螢幕截圖存檔 (Command Line)

| Comments

目前每天都讓 aws 上面 windows server 自動十二點半開機,然後一點啟動模型下單程式,收盤前會下單,機器兩點關機。 為了要做一個紀錄,我希望可以在每天收盤之後,讓電腦拍一下螢幕快照做歷史紀錄,否則每天自動關機,都沒有留下紀錄,到時候要回來追蹤的時候都毫無辦法。

很幸運的,老早就有人把windows裡面要做的動作,做成command line tool ,我們要使用 nircmd 這個小軟體 然後指令如下,下面這個是官方舉的例子,意思是 Save 10 screenshots in a loop, and wait 60 seconds between the screenshot save calls. The filenames of the screenshot will contain the time and date of the saved screenshot.

1
nircmd.exe loop 10 60000 savescreenshot c:\temp\scr~$currdate.MM_dd_yyyy$-~$currtime.HH_mm_ss$.png

但因為我只需要在收盤之後把畫面拍下來,然後放到 dropbox 的目錄裡面,這樣一同步之後,我在家裡就可以看到當天的數據紀錄了。我們來改一點點參數,變成這樣:

1
nircmd.exe savescreenshot c:\dropbox\Hmodel_~$currdate.yyyy_MM_dd$-~$currtime.HH_mm_ss$.png