# Ubuntu 安裝 R4.5 標準流程 ## 前置作業 * Ubuntu 18.04 LTS 已安裝完畢並能遠端連線進入 * 當前帳號可以使用 sudo 指令 ## 修復舊的 logrotate 的bug ```sh $ curl http://gitlab.tp.rulingcom.com/erictyl/install_r45_on_ubuntu_1804lts_doc/-/raw/master/fix_logrotate.sh | sh ``` ## 建立 rulingcom 帳號(若已是 rulingcom 帳號,前往下一步驟) ```sh $ sudo su # 從當前帳號切換到 root $ adduser rulingcom $ # set the password for rulingcom $ # fill in user information, it's ok to leave all blank $ usermod -aG sudo rulingcom # 讓 rulingcom 可用 sudo $ su - rulingcom $ sudo ls -la /root # 測試 rulingcom sudo 是否可用 $ exit; exit # 第一次 exit 退回 root 帳號,第二次 exit 退回剛登入的帳號 ``` ## 下載裝機script並執行(除了需執行下一步驟的移機外,其他內容不用再執行) ```sh $ wget http://gitlab.tp.rulingcom.com/erictyl/install_r45_on_ubuntu_1804lts_doc/-/raw/master/install_orbit_environment.sh -O install_orbit_environment.sh $ chmod +x install_orbit_environment.sh $ bash install_orbit_environment.sh #請使用要執行網站的user(須為具有sudo權限之帳號)來執行,執行後會需要輸入user密碼 $ source "/etc/profile.d/rvm.sh" ## 以下其他內容均不需執行,可直接進行架站或移機 ``` ## 轉移網站資料 - 1 (把資訊不直接放在command line上,避免資訊存到log中) ```sh $ wget http://gitlab.tp.rulingcom.com/erictyl/install_r45_on_ubuntu_1804lts_doc/-/raw/master/move_site_interactive.sh $ bash -i move_site_interactive.sh ``` ## 轉移網站資料 - 2 (把資訊放在command line) ```sh $ wget http://gitlab.tp.rulingcom.com/erictyl/install_r45_on_ubuntu_1804lts_doc/-/raw/master/move_site.sh # 請依照您的需求替換以下這行的變數成實際的值 $ bash -i move_site.sh $ip $port $user $remote_pass $domain $your_local_password ``` ## 安裝libgmp(Ubuntu 14.04需要) ```sh sudo apt install libgmp-dev ##此套件為nokogiri相依套件 ``` ## 安裝 Nginx 1.23.1及更新openssl(至少保持1.1.1以上) ```sh $ wget http://gitlab.tp.rulingcom.com/erictyl/install_r45_on_ubuntu_1804lts_doc/-/raw/master/install_nginx.sh -O install_nginx.sh $ bash install_nginx.sh # 若要安裝modsecurity WAF(網路應用程式防火牆),則加入參數 --install-modsecurity # $ bash install_nginx.sh --install-modsecurity $ sudo wget http://gitlab.tp.rulingcom.com/erictyl/install_r45_on_ubuntu_1804lts_doc/-/raw/master/orbit_nginx -O /etc/nginx/orbit_sites/xxx_ooo # 建立網站 nginx 設定檔,xxx 為學校縮寫,ooo 為系所、單位縮寫。內容參考附註 nginx 設定檔 ``` ## 設定host IP(避免VM抓不到domain對應的IP) ```sh # sudo vim /etc/hosts 加入以下內容 59.120.142.210 gitlab.tp.rulingcom.com 59.120.142.206 ruling.digital store.tp.rulingcom.com 151.101.1.227 index.rubygems.org rubygems.org 104.192.141.1 bitbucket.org ``` ## 安裝 R4.5 ### 一、建立 ssh key pair ```sh $ cd /home/rulingcom/.ssh # 如果沒有該資料夾則自行建立 `mkdir /home/rulingcom/.ssh`,接著進入 .ssh 資料夾 $ ssh-keygen # 設定 key pair name -> 設定密碼(不設定直接 enter) -> 確認密碼(不設定直接 enter) $ cat ~/.ssh/your_key.pub # 將公鑰轉交給禾綸(注意:不是私鑰) $ # 確認禾綸將公鑰加入 GitLab 後再接續下列指令與步驟二 $ eval "$(ssh-agent -s)" $ ssh-add ~/.ssh/your_private_key ``` ### 二、安裝 R4.5 Web App ```sh $ git clone http://gitlab.tp.rulingcom.com/orbit_chiu1/orbit4-5.git your_site_name $ cd your_site_name $ vim config/mongoid.yml # 所有 orbit_4_5 換成 your_site_name, :wq 存檔離開 $ vim Gemfile # 加井字號註解掉 gem 'sassc-rails', '~>1.3.0' 並拿掉此行 #gem 'sass-rails', '~> 4.0.2' 井字號取消註解 $ gem install nokogiri -v 1.7.0.1 #For Ubuntu 20.04LTS $ bundle install $ RAILS_ENV=production bundle exec rake assets:precompile $ bundle exec unicorn_rails -c config/unicorn.rb -D -E production $ sudo service nginx restart $ # Login the new create site with rulingcom account and choose “Admin Area” to complete the registration of this new created site. ``` ## 開啟crontab的log(獨立顯示) ### Open the file ```sh sudo vim /etc/rsyslog.d/50-default.conf ``` ### Find the line that starts with: #cron.* ```sh uncomment that line, save the file, and restart rsyslog: sudo service rsyslog restart You should now see a cron log file here: /var/log/cron.log ``` ## 設定備份(以備份一週內容為例) ### 一、資料庫備份 ```sh #### 安裝postfix,以避免NO MTA installed. sudo apt-get install -y postfix sudo service postfix start $ sudo crontab -e # 內容如下: 0 3 * * * mongodump -o /home/backup/db/`date "+\%Y\%m\%d"`_db 0 4 * * * rm -fr /home/backup/db/`date --date="1 week ago" "+\%Y\%m\%d"`_db ``` ### 二、R4.5 網站目錄備份 ```sh # 安裝 rsnapshot,如已安裝則直接編輯 /etc/rsnapshot.conf $ sudo apt-get install rsnapshot -y $ sudo vim /etc/rsnapshot.conf # 內容建附註 rsnapshot $ sudo mkdir /home/backup $ sudo mkdir /home/backup/orbit $ sudo chmod 777 /home/backup/orbit $ rsnapshot -t daily # 測試是否設定正確 $ sudo crontab -e # 加入下行內容後,儲存退出 15 4 * * * /usr/bin/rsnapshot daily ``` ```txt # 此為附註 rsnapshot # 注意!該檔使用 tab 而非 space! # find BACKUP LEVELS /INTERVALS part # at this part, remove every lines with `retain` and then add the line below: retain daily 7 # find SNAPSHOT ROOT DIRECTORY part # modify the snapshot dir path snapshot_root /home/backup/orbit # find BACKUP POINTS / SCRIPTS part # add R4.5 site backup backup /home/rulingcom localhost/ ``` ### 三、定期壓縮與刪除 log ```sh $ sudo vim /etc/logrotate.d/orbit # 內容見附註 logrotate $ sudo logrotate -d /etc/logrotate.conf # 確認系統是否有使用 /etc/logrotate.d/orbit $ sudo /usr/sbin/logrotate -f /etc/logrotate.conf #測試執行log壓縮程序,看是否能成功壓縮log ``` ```txt # 附註 logrotate /home/rulingcom/*/*/log/*.log { daily rotate 7 compress missingok notifempty copytruncate postrotate [ ! -f /run/nginx.pid ] || kill -USR1 `cat /run/nginx.pid` endscript } /home/rulingcom/*/*/*/log/*.log { daily rotate 7 compress missingok notifempty copytruncate postrotate [ ! -f /run/nginx.pid ] || kill -USR1 `cat /run/nginx.pid` endscript } /var/log/mongodb/*.log { daily rotate 7 compress missingok notifempty create 644 mongodb mongodb postrotate [ ! -f /var/lib/mongodb/mongod.lock ] || kill -USR1 `cat /var/lib/mongodb/mongod.lock` endscript } ``` ### 四、主機開機網站自動起始 ```sh # 開機網站自動起始 $ sudo vim /etc/init.d/orbit # 內容見附註 orbit $ sudo chmod 755 /etc/init.d/orbit $ update-rc.d orbit defaults $ sudo systemctl start orbit $ sudo systemctl enable mongod.service #ubuntu18.04以上適用(可在系統boot時,自動開啟mongo) $ sudo mv /etc/init.d/mongod /etc/systemd/system/ && sudo systemctl enable mongod.service $ sudo crontab -e #加入以下#內容 # @reboot /bin/bash -l -c "rm -f /tmp/mongodb-27017.sock && chown mongodb:mongodb /var/lib/mongodb/ -R && chown mongodb:mongodb /var/log/mongodb -R && /usr/sbin/service mongod restart && /etc/init.d/orbit restart" ``` ```txt # 附註 orbit 底下#!/bin/bash請務必要加 #!/bin/bash ### BEGIN INIT INFO # Provides: ruling.digital # Required-Start: $network # Required-Stop: # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start orbit daemon at boot time # Description: Start orbit daemon at boot time ### END INIT INFO ORBIT_USER=rulingcom if [ -f "/home/$ORBIT_USER/.rvm/scripts/rvm" ]; then source /home/$ORBIT_USER/.rvm/scripts/rvm rvm use default else if [ -f "/etc/profile.d/rvm.sh" ]; then source /etc/profile.d/rvm.sh elif [ "$1" != "setup" ]; then echo "" echo "-----------------------------------------------------" echo "Orbit server dependencies is missing. Please run setup first." echo "command: service orbit setup" echo "-----------------------------------------------------" echo "" exit 0; fi fi ORBIT_SITES=`pwd` ORBIT_GIT=http://gitlab.tp.rulingcom.com/saurabh/orbit4-5.git NGINX_ORBIT_SITES=/etc/nginx/orbit_sites RAILS_ENV=production sig () { test -s "$ORBIT_ROOT/tmp/pids/unicorn.pid" && kill -$1 `cat $ORBIT_ROOT/tmp/pids/unicorn.pid` } get_orbit_root () { if [ ! -f $NGINX_ORBIT_SITES/$1 ]; then echo "Site $1 not found" && exit 0; fi ORBIT_ROOT=`cat $NGINX_ORBIT_SITES/$1 | grep 'root' | grep -v '#' | xargs | awk '{print $2}'`; ORBIT_ROOT=${ORBIT_ROOT//"/public;"/""}; if [ ! -d $ORBIT_ROOT ]; then echo "Site folder $ORBIT_ROOT not fount"; fi } start_orbit () { sig 0 $ORBIT_ROOT && echo >&2 "$ORBIT_ROOT Already running"; echo "Starting $ORBIT_ROOT"; sudo su -l $ORBIT_USER -c "cd $ORBIT_ROOT && bundle exec unicorn_rails -D -E $RAILS_ENV -c config/unicorn.rb"; } case $1 in start) if [ ! -z "$2" ]; then get_orbit_root $2 start_orbit else for APP in `ls -1 $NGINX_ORBIT_SITES`; do get_orbit_root $APP; start_orbit; done fi exit 0; ;; stop) while [ `whoami` != "root" ]; do if [ ! -z "$2" ]; then read -p "Stop Orbit $2? (y/n) " CONFIRM else read -p "Stop All Orbits? (y/n) " CONFIRM fi case "$CONFIRM" in y|Y ) break;; n|N ) exit 0;; * ) echo "(y/n)";; esac done if [ ! -z "$2" ]; then get_orbit_root $2 echo "Stopping $ORBIT_ROOT" sig QUIT else for APP in `ls -1 $NGINX_ORBIT_SITES`; do get_orbit_root $APP; echo "Stopping $ORBIT_ROOT"; sig QUIT && continue; done fi exit 0; ;; force-stop) while true; do if [ ! -z "$2" ]; then read -p "Stop Orbit $2? (y/n) " CONFIRM else read -p "Stop All Orbits? (y/n) " CONFIRM fi case "$CONFIRM" in y|Y ) break;; n|N ) exit 0;; * ) echo "(y/n)";; esac done if [ ! -z "$2" ]; then get_orbit_root $2 echo "Stopping $ORBIT_ROOT" sig TERM else for APP in `ls -1 $NGINX_ORBIT_SITES`; do get_orbit_root $APP; echo "Stopping $ORBIT_ROOT"; sig TERM && continue; done fi exit 0; ;; restart|reload) if [ ! -z "$2" ]; then get_orbit_root $2 sig USR2 && echo "$ORBIT_ROOT reloaded OK" && exit 0 echo >&2 "Couldn't reload $ORBIT_ROOT, starting instead" start_orbit else for APP in `ls -1 $NGINX_ORBIT_SITES`; do get_orbit_root $APP; sig USR2 && echo "$ORBIT_ROOT reloaded OK" && continue; echo >&2 "Couldn't reload $ORBIT_ROOT, starting instead"; start_orbit; done fi exit 0; ;; create) if [ "$0" == "/etc/init.d/orbit" ]; then echo "Don't use service to create." echo "Use: orbit create $2" exit 0 fi test -s "$NGINX_ORBIT_SITES/$2" && echo "Site $2 already exist." && exit 0 test -s "$ORBIT_SITES/$2" && echo "File $ORBIT_SITES/$2 already exist." && exit 0 while true; do read -p "nginx server name: " SERVER_NAME if [ ! -z "$SERVER_NAME" ]; then break; fi done while true; do read -p "port number: " PORT if [ ! -z "$PORT" ]; then break; fi done while true; do read -p "database name: " DATABASE if [ ! -z "$DATABASE" ]; then break; fi done echo "-----------------------------------------------------" echo "Path: $ORBIT_SITES/$2" echo "Database: $DATABASE" echo http://$SERVER_NAME:$PORT echo "-----------------------------------------------------" while true; do read -p "Create Orbit $2? (y/n) " CONFIRM case "$CONFIRM" in y|Y ) break;; n|N ) exit 0;; * ) echo "(y/n)";; esac done cd ~ sudo wget http://installer.tp.rulingcom.com/nginx4-5.conf sudo cp nginx4-5.conf $NGINX_ORBIT_SITES/$2 sudo rm nginx4-5.conf sudo perl -pi -e "s/{{ORBIT}}/$2/g" $NGINX_ORBIT_SITES/$2 sudo perl -pi -e "s#{{ORBIT_SITES}}#${ORBIT_SITES}#g" $NGINX_ORBIT_SITES/$2 sudo perl -pi -e "s/{{PORT}}/$PORT/g" $NGINX_ORBIT_SITES/$2 sudo perl -pi -e "s/{{SERVER_NAME}}/$SERVER_NAME/g" $NGINX_ORBIT_SITES/$2 sudo service nginx reload sudo su -l $ORBIT_USER -c "cd $ORBIT_SITES && git clone $ORBIT_GIT $2 && cd $2 && bundle" sudo su -l $ORBIT_USER -c "cd $ORBIT_SITES/$2 && perl -pi -e \"s/orbit_4_5/$DATABASE/g\" config/mongoid.yml" sudo su -l $ORBIT_USER -c "cd $ORBIT_SITES/$2 && bundle exec rake assets:precompile RAILS_ENV=production" sudo su -l $ORBIT_USER -c "cd $ORBIT_SITES/$2 && bundle exec unicorn_rails -D -E $RAILS_ENV -c $ORBIT_SITES/$2/config/unicorn.rb" sudo su -l $ORBIT_USER -c "cd $ORBIT_SITES/$2 && bundle exec rake orbit_cron:install" echo "-----------------------------------------------------" echo "$2 is ready" echo "Path: $ORBIT_SITES/$2" echo http://`ifconfig eth0 2>/dev/null|awk '/inet addr:/ {print $2}'|sed 's/addr://'`:$PORT echo "-----------------------------------------------------" exit 0 ;; setup) sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10 sudo echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list sudo apt-get update sudo apt-get -y upgrade sudo apt-get install -y nginx git-core mongodb-org imagemagick curl openssh-server nano sudo mkdir $NGINX_ORBIT_SITES sudo perl -pi -e "s/sites-enabled/orbit_sites/g" /etc/nginx/nginx.conf sudo rm -r /etc/nginx/sites-* sudo apt-get --no-install-recommends --yes install gawk g++ gcc make libc6-dev libreadline6-dev zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 autoconf libgdbm-dev libncurses5-dev automake libtool bison pkg-config libffi-dev sudo su -l $ORBIT_USER -c "\curl -sSL https://get.rvm.io | bash -s stable" sudo su -l $ORBIT_USER -c "rvm install 2.1 --default" echo "gem: --no-ri --no-rdoc" > /home/$ORBIT_USER/.gemrc source /home/$ORBIT_USER/.rvm/scripts/rvm echo "" echo "-----------------------------------------------------" echo "System is ready. You can start creating Orbit servers." echo "command: orbit create Orbit_Folder_Name" echo "-----------------------------------------------------" echo "" exit 0 ;; *) echo >&2 "Usage $0 " exit 1 ;; esac ``` ``` ### 五、網路設定 ​```sh # 開機網站自動起始 $ sudo vim /etc/netplan/50-cloud-init.yaml # 內容見附註 50-cloud-init.yaml 18.04開始設定改這 # $ sudo vim /etc/netplan/00-installer-config.yaml # Ubuntu 20.04LTS # ``` ```txt # 50-cloud-init.yaml # 本範例有兩塊網卡,第一塊是DHCP,第二塊是固定IP # 其中因為子網路遮罩為255.255.255.0 ,所以是 /24 # This file is generated from information provided by the datasource. Changes # to it will not persist across an instance reboot. To disable cloud-init's # network configuration capabilities, write a file # /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following: # network: {config: disabled} network: ethernets: enp0s29u1u1u5: dhcp4: true enp6s0: addresses: - 192.168.1.142/24 gateway4: 192.168.1.1 nameservers: addresses: - 8.8.8.8 search: - rulingcom.com version: 2 ## 六、如果 /etc/init.d/mongod 遺失(適用於ubuntu14.04以上) ​```sh # 建立 mongod service $ sudo vim /etc/init.d/mongod #請查看以下/etc/init.d/mongod之內容 $ sudo chmod +x /etc/init.d/mongod ``` ```txt #此為/etc/init.d/mongod之內容 #!/bin/bash case $1 in start) if [ -f "/var/lib/mongodb/mongod.lock" ]; then exit 0 else self_pid=$$ pid=`ps aux | grep mongod | grep -v 'service' | grep -v 'grep' | grep -v '/etc/init.d' | awk '{print $2}'`; COUNTER=0 for i in $pid do if [ -f "/proc/$i/status" ]; then echo "$i" >> /var/lib/mongodb/mongod.lock; COUNTER=$((COUNTER+1)) fi done if [ $COUNTER == 0 ]; then echo "starting mongo." sudo mongod --config /etc/mongod.conf & exit 0 else echo "mongo is already running." fi fi ;; stop) echo "stoping mongo." if [ -f "/var/lib/mongodb/mongod.lock" ]; then sudo kill -s TERM `cat /var/lib/mongodb/mongod.lock` sudo rm -f /var/lib/mongodb/mongod.lock else pid=`ps aux | grep mongod | grep -v 'service' | grep -v 'grep' | grep -v '/etc/init.d' | awk '{print $2}'`; for i in $pid do kill -s TERM $i done fi ;; restart|reload) echo "stoping mongo." if [ -f "/var/lib/mongodb/mongod.lock" ]; then sudo kill -s TERM `cat /var/lib/mongodb/mongod.lock` sudo rm -f /var/lib/mongodb/mongod.lock else pid=`ps aux | grep mongod | grep -v 'service' | grep -v 'grep' | grep -v '/etc/init.d' | awk '{print $2}'`; for i in $pid do kill -s TERM $i done fi sudo mongod --config /etc/mongod.conf & exit 0 ;; status) if [ -f "/var/lib/mongodb/mongod.lock" ]; then pid=`cat /var/lib/mongodb/mongod.lock` COUNTER=0 ERRORPID=0 for i in $pid do if [ -f "/proc/$i/status" ]; then COUNTER=$((COUNTER+1)) else ERRORPID=1 fi done if [ $ERRORPID == 0 ] && [ $COUNTER != 0 ]; then echo "mongo is already running" else COUNTER=0 pid=`ps aux | grep mongod | grep -v 'service' | grep -v 'grep' | grep -v '/etc/init.d' | awk '{print $2}'`; cat /dev/null > /var/lib/mongodb/mongod.lock; for i in $pid do if [ -f "/proc/$i/status" ]; then echo "$i" >> /var/lib/mongodb/mongod.lock; COUNTER=$((COUNTER+1)) fi done if [ $COUNTER == 0 ]; then echo "mongo is not running." else echo "mongo is already running." fi fi else COUNTER=0 pid=`ps aux | grep mongod | grep -v 'service' | grep -v 'grep' | grep -v '/etc/init.d' | awk '{print $2}'`; for i in $pid do if [ -f "/proc/$i/status" ]; then echo "$i" >> /var/lib/mongodb/mongod.lock; COUNTER=$((COUNTER+1)) fi done if [ $COUNTER == 0 ]; then echo "mongo is not running." else echo "mongo is already running." fi fi esac ```