AzureのVMでRedmine構築
前回はAWSでRedmineを構築しましたが今回はAzureのVMサービスでRedmineを構築してみました。手順自体は前回とそんな変更ないです。GitからRedmineのソースをcloneしてくるようにしたくらいです。AzureのVMはAWSほど気軽に使える値段でないので少しコスト面で怖い部分もありますが、これから徐々に慣れていきたいところです。
リストアが試せていないので時間あるときに試してみたいです。
*仮想マシンを復活させるだけなのでスムーズなはず。。。
大枠の手順は以下の通り
Ⅰ.OSイメージ作成
Ⅱ.OSイメージ更新
Ⅲ.Redmine構築
Ⅳ.仮想マシンのバックアップ
◆作業手順
Ⅰ.OSイメージ作成
#1.初期設定 #1-1.日本語化 $ sudo sed -i.bak -e "s%http://us.archive.ubuntu.com/ubuntu/%http://ftp.jaist.ac.jp/pub/Linux/ubuntu/%g" /etc/apt/sources.list $ sudo apt-get -y install language-pack-ja-base language-pack-ja ibus-mozc $ sudo localectl set-locale LANG=ja_JP.UTF-8 LANGUAGE="ja_JP:ja" $ source /etc/default/locale $ echo $LANG ja_JP.UTF-8 #1-2.タイムロケール変更 $ sudo timedatectl set-timezone Asia/Tokyo $ timedatectl #1-3.ソフトウェアアップデート $ sudo apt-get update $ sudo apt-get -y upgrade #1-4.ディストリビューションアップデート $ sudo apt-get -y update $ sudo apt-get dist-upgrade #1-5.デフォルトエディタ変更 $ sudo update-alternatives --config editor alternative editor (/usr/bin/editor を提供) には 4 個の選択肢があります。 選択肢 パス 優先度 状態 ------------------------------------------------------------ * 0 /bin/nano 40 自動モード 1 /bin/ed -100 手動モード 2 /bin/nano 40 手動モード 3 /usr/bin/vim.basic 30 手動モード 4 /usr/bin/vim.tiny 15 手動モード 現在の選択 [*] を保持するには、さもなければ選択肢の番号のキーを押してく ださい: 4 update-alternatives: /usr/bin/editor (editor) を提供するためにマニュアルモードで /usr/bin/vim.tiny を使います $ sudo apt -y remove nano #1-6.ホームディレクトリのアクセス権限設定 $ sudo chmod 750 $HOME [sudo] password for ope_user: $ ls -ld $HOME drwxr-x--- 3 ope_user ope_user 4096 11月 21 11:42 /home/ope_user $ sudo sed -i "s/DIR_MODE=0755/DIR_MODE=0750/g" /etc/adduser.conf #2.SSH関連設定 #2-1.sshlogin用ユーザ追加 $ sudo adduser ssh_user ユーザー `ssh_user' を追加しています... 新しいグループ `ssh_user' (1001) を追加しています... 新しいユーザー `ssh_user' (1001) をグループ `ssh_user' に追加しています... ホームディレクトリ `/home/ssh_user' を作成しています... `/etc/skel' からファイルをコピーしています... 新しい UNIX パスワードを入力してください: 新しい UNIX パスワードを再入力してください: passwd: password updated successfully Changing the user information for ssh_user Enter the new value, or press ENTER for the default Full Name []: Room Number []: Work Phone []: Home Phone []: Other []: 以上で正しいですか? [Y/n] Y #2-2.sshログイン可能ユーザ限定 $ echo "AllowGroups sshlogin" | sudo tee -a /etc/ssh/sshd_config AllowGroups sshlogin $ sudo addgroup sshlogin グループ `sshlogin' (GID 1002) を追加しています... 完了。 $ sudo gpasswd -a ssh_user sshlogin Adding user ssh_user to group sshlogin #2-3.ssh_config修正 $ sudo vi /etc/ssh/sshd_config ------------------------------- ※PermitRootLogin noを追記しその上をコメントアウト # Authentication: LoginGraceTime 120 #PermitRootLogin without-password PermitRootLogin no StrictModes yes #2-4.ssh再起動 $ sudo sshd -t $ sudo service ssh restart #2-5.ssh用証明書作成 #TeraTermでKey作成後にWinSCP等でpubファイルアップロード後に以下のコマンド実行 $ mkdir .ssh $ chmod 700 .ssh $ mv id_rsa.pub .ssh/authorized_keys #2-6.sshd_config編集 $ su - ope_user $ sudo sed -i -e "s/#PubkeyAuthentication/PubkeyAuthentication/g" /etc/ssh/sshd_config $ sudo sed -i -e "s/PasswordAuthentication yes/PasswordAuthentication no/g" /etc/ssh/sshd_config $ sudo reboot #3.ネットワーク関連防御設定 #3-1.パケットソースフィルタリング及び偽装IPのログ排出 $ sudo vi /etc/sysctl.conf ----------------------------------- ※IP偽装保護(コメントアウト解除) # Uncomment the next two lines to enable Spoof protection (reverse-path filter) # Turn on Source Address Verification in all interfaces to # prevent some spoofing attacks net.ipv4.conf.default.rp_filter=1 net.ipv4.conf.all.rp_filter=1 ※SYN攻撃ブロック(コメントアウト解除、下3行追加) # Uncomment the next line to enable TCP/IP SYN cookies # See http://lwn.net/Articles/277146/ # Note: This may impact IPv6 TCP sessions too net.ipv4.tcp_syncookies=1 net.ipv4.tcp_max_syn_backlog = 2048 net.ipv4.tcp_synack_retries = 2 net.ipv4.tcp_syn_retries = 5 ※リダイレクト送信無視 # Do not accept ICMP redirects (prevent MITM attacks) net.ipv4.conf.all.accept_redirects = 0 net.ipv6.conf.all.accept_redirects = 0 ※ソースパケットルーティング禁止 # Do not accept IP source route packets (we are not a router) net.ipv4.conf.all.accept_source_route = 0 net.ipv6.conf.all.accept_source_route = 0 net.ipv4.conf.default.accept_source_route = 0 net.ipv6.conf.default.accept_source_route = 0 ※ Martiansのログ(コメント解除) # Log Martian Packets net.ipv4.conf.all.log_martians = 1 # ICMPブロードキャストリクエストを無視(追記) net.ipv4.icmp_echo_ignore_broadcasts = 1 # ICMPリダイレクトを無視(追記) net.ipv4.conf.all.accept_redirects = 0 net.ipv6.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv6.conf.default.accept_redirects = 0 ----------------------------------- $ sudo sysctl --system * Applying /etc/sysctl.d/10-console-messages.conf ... ~中略~ net.ipv6.conf.lo.disable_ipv6 = 1 #3-2.ファイアウォールの設定 #ポリシー設定(外部からのパケットはSSH、http、httpsのみを許可) $ sudo ufw default deny デフォルトの incoming ポリシーは 'deny' に変更しました (適用したい内容に基づいて必ずルールを更新してください) $ sudo ufw default allow outgoing デフォルトの outgoing ポリシーは 'allow' に変更しました (適用したい内容に基づいて必ずルールを更新してください) $ sudo ufw logging low ログ取得を有効にしました $ sudo ufw allow ssh ルールを追加しました ルールを追加しました (v6) $ sudo ufw allow http ルールをアップデートしました ルールをアップデートしました(v6) $ sudo ufw allow https ルールをアップデートしました ルールをアップデートしました(v6) $ sudo ufw enable Command may disrupt existing ssh connections. Proceed with operation (y|n)? y ファイアウォールはアクティブかつシステムの起動時に有効化されます。 #4.監視系ツール類インストール #4-1.ntp設定 $ sudo apt -y install ntp $ sudo vi /etc/ntp.conf ------------------------------------ # Use Ubuntu's ntp server as a fallback. #pool ntp.ubuntu.com server ntp1.jst.mfeed.ad.jp server ntp2.jst.mfeed.ad.jp server ntp3.jst.mfeed.ad.jp ------------------------------------ $ sudo /etc/init.d/ntp restart $ sudo ntpq -p $ date #4-2.logwatchインストール ・インストール $ sudo mkdir /var/cache/logwatch $ sudo chmod 700 /var/cache/logwatch ※GUIが出てくるので[サテライト]を選ぶ) ※後は全部Enterで $ sudo apt-get -y install logwatch パッケージリストを読み込んでいます... 完了 依存関係ツリーを作成しています ~中略~ logwatch (7.4.0+svn20130529rev144-1ubuntu1) を設定しています ... libc-bin (2.19-0ubuntu6.6) のトリガを処理しています ... $ sudo which postfix /usr/sbin/postfix #sendgrid送信確認 $ curl --request POST \ --url https://api.sendgrid.com/v3/mail/send \ --header 'Authorization: Bearer YOURTOKEN' \ --header 'Content-Type: application/json' \ --data '{"personalizations": [{"to": [{"email": "youremailadress"}]}],"from": {"email": "example@example.com"},"subject": "Hello, World!","content": [{"type": "text/plain", "value": "Heya!"}]}' #設定ファイル準備 $ sudo vi /etc/postfix/main.cf ※すべて削除して追記 ------------------------- # SendGrid APIkey Settings smtp_sasl_auth_enable = yes smtp_sasl_password_maps = hash:/etc/postfix/smtp_apikey_sendgrid smtp_sasl_security_options = noanonymous smtp_sasl_tls_security_options = noanonymous smtp_tls_security_level = encrypt header_size_limit = 4096000 relayhost = [smtp.sendgrid.net]:587 ------------------------- $ echo "[smtp.sendgrid.net]:587 apikey:YOURETOKEN" | sudo tee -a /etc/postfix/smtp_apikey_sendgrid $ sudo chmod 600 /etc/postfix/smtp_apikey_sendgrid #postfix再起動 $ sudo postmap /etc/postfix/smtp_apikey_sendgrid $ sudo service postfix restart #aliasesの編集 $ echo "root: yourmailadress" | sudo tee -a /etc/aliases $ sudo newaliases #設定ファイル準備 $ sudo cp -p /usr/share/logwatch/default.conf/logwatch.conf /etc/logwatch/logwatch.conf $ sudo cp /usr/share/logwatch/default.conf/services/* /etc/logwatch/conf/services/ $ sudo vi /etc/logwatch/logwatch.conf $ sudo shutdown -r now #送信テスト $ sudo logwatch -range today $ sudo logwatch -range today --output mail #4-3.SNMPインストール ・インストール $ sudo apt -y install snmpd snmp ・設定ファイル編集 $ sudo vi /etc/snmp/snmpd.conf ------------------------------- ※外部からの接続許可 #Listen for connections from the local system only #agentAddress udp:127.0.0.1:161 ←コメントアウト # Listen for connections on all interfaces (both IPv4 *and* IPv6) agentAddress udp:161 ←コメント解除し後半udp6を削除 ※コミュニティ設定 # rocommunity public default -V systemonly ←コメントアウト # rocommunity6 is for IPv6 # rocommunity6 public default -V systemonly ←コメントアウト # Full access from an example network rocommunity dev-com localhost ←追記 rocommunity dev-com YOURIPADRESS ←追記 ------------------------------- #5.セキュリティ関連ソフトインストール #5-1.chkrootkitインストール #インストール $ sudo apt -y install chkrootkit #5-2.Fail2Banインストール $ sudo apt -y install fail2ban $ cd /etc/fail2ban $ sudo cp jail.conf jail.local $ sudo systemctl restart fail2ban.service $ sudo systemctl enable fail2ban.service $ cd #5-3.改ざん検知ツールインストール(指定フォルダを決定後に再設定必要) $ sudo apt -y install aide #設定ファイル編集 $ sudo vi /etc/aide/aide.conf ※最終行に追記(除外ディレクトリ設定) ----------------------------------- #exclude dir !/var/agentx/* !/var/backups/* !/var/cache/* !/var/crash/* !/var/lib/* !/var/log/* !/var/mail/* !/var/snap/* !/var/spool/* !/var/tmp/* !/root !/home !/mnt ----------------------------------- #初期DB作成(※少し時間がかかる) $ sudo aideinit Running aide --init... ~略~ End timestamp: 2019-08-10 17:35:26 +0900 (run time: 4m 47s) $ sudo cp -p /var/lib/aide/aide.db.new /var/lib/aide/aide.db #5-4.Clamavインストール $ sudo apt -y install clamav-base clamav-daemon clamav-freshclam #設定変更 $ sudo rm /var/log/clamav/freshclam.log $ sudo touch /var/log/clamav/freshclam.log $ sudo chown clamav:clamav /var/log/clamav/freshclam.log $ sudo vi /etc/logrotate.d/clamav-freshclam ------------------------------ create 640 clamav adm ↓ create 640 clamav clamav ------------------------------ $ sudo chmod 744 /etc/clamav/freshclam.conf $ sudo vi /etc/clamav/freshclam.conf ------------------------------- # Check for new database 24 times a day Checks 24 DatabaseMirror db.local.clamav.net DatabaseMirror database.clamav.net # added DatabaseMirror db.jp.clamav.net DatabaseMirror db.us.clamav.net ------------------------------- $ sudo vi /etc/clamav/clamd.conf ------------------------------- #User clamav #ユーザをコメントアウト MaxScanSize 100M MaxFileSize 4096M #25Mから書替 MaxRecursion 16 MaxFiles 10000 ------------------------------- $ sudo sed -i -e "s/^NotifyClamd/#NotifyClamd/g" /etc/clamav/freshclam.conf #サービス再起動 $ sudo /etc/init.d/clamav-freshclam restart [ ok ] Restarting clamav-freshclam (via systemctl): clamav-freshclam.service. #スクリプト作成 $ sudo mkdir /var/log/clamav/virus $ sudo chown clamav:clamav /var/log/clamav/virus $ sudo touch /etc/cron.daily/clamav $ sudo chmod 755 /etc/cron.daily/clamav $ sudo vi /etc/cron.daily/clamav ----------------------------------- #!/bin/sh echo ========================================= date clamscan / \ --infected \ --recursive \ --log=/var/log/clamav/clamav.log \ --move=/var/log/clamav/virus \ --exclude-dir=^/boot \ --exclude-dir=^/sys \ --exclude-dir=^/proc \ --exclude-dir=^/dev \ --exclude-dir=^/var/log/clamav if [ $? = 0 ]; then echo "ウイルス未検出." cat /var/log/clamav/clamav.log | mail -s "Clamav scan OK." root else echo "ウイルス検出!!" cat /var/log/clamav/clamav.log | mail -s "Clamav scan NG!" root fi ----------------------------------- #6.ログ削除 $ sudo find /var/log/ -type f -name \* -exec cp -f /dev/null {} \; $ history -c $ sudo shutdown -h now
Ⅱ.OSイメージ更新・ドメイン取得
1.イメージの作成
①[Azure Portal] に移動して、VM イメージを管理します。 [仮想マシン] を検索して選択します。
一覧で VM を選択します。
②VM の [仮想マシン] ページの上部のメニューで、 [キャプチャ] を選択します。
③[イメージの作成] ページが表示されます。
④[名前] で、あらかじめ設定されている名前を受け入れるか、イメージに使用する名前を入力します。
⑤[リソース グループ] で、 [新規作成] を選択して名前を入力するか、使用するリソースグループをドロップダウンリストから選択します。
⑥イメージが作成された後にソース VM を削除する場合、 [イメージの作成後、この仮想マシンを自動的に削除します] を選択します。
いずれかの 可用性ゾーンでイメージを使用する機能が必要な場合、 [Zone resiliency (ゾーンの回復性)] に [オン] を選択します。
⑦[作成] を選択してイメージを作成します。
2.イメージ展開後の注意
①イメージギャラリーからイメージを選択
②VMの作成でVMを作成する
③VM展開後にsudo可能ユーザのパスワードのリセットを行う必要がある
3.ドメイン設定
①freenomでドメインを取得する
②VMのIPアドレスをAzureDNSのAレコードに登録する
Ⅲ.Redmine構築
#1.BlobStorageのマウント
$ export AZUREFILES_RGN="VirtualMachineExamination"
$ export AZUREFILES_SA="YOURSTORAGEACCOUNT"
$ export AZUREFILES_FSN="YOURFILESTORAGENAME"
$ export AZUREFILES_MNT="/mnt/$AZUREFILES_SA/$AZUREFILES_FSN"
$ curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
$ az login
#接続用スクリプト
$ vi azurefilesconnect.sh
---------------------------
#! /bin/bash
resourceGroupName=$AZUREFILES_RGN
storageAccountName=$AZUREFILES_SA
# This command assumes you have logged in with az login
httpEndpoint=$(az storage account show \
--resource-group $resourceGroupName \
--name $storageAccountName \
--query "primaryEndpoints.file" | tr -d '"')
smbPath=$(echo $httpEndpoint | cut -c7-$(expr length $httpEndpoint))
fileHost=$(echo $smbPath | tr -d "/")
nc -zvw3 $fileHost 445
---------------------------
$ chmod a+x azurefilesconnect.sh
$ ./azurefilesconnect.sh
Connection to XXXX.file.core.windows.net 445 port [tcp/microsoft-ds] succeeded!
#マウント用スクリプト
$ vi azurefilesmount.sh
---------------------------
#! /bin/bash
resourceGroupName=$AZUREFILES_RGN
storageAccountName=$AZUREFILES_SA
fileShareName=$AZUREFILES_FSN
mntPath="/mnt/$storageAccountName/$fileShareName"
sudo mkdir -p $mntPath
if [ ! -d "/etc/smbcredentials" ]; then
sudo mkdir "/etc/smbcredentials"
fi
storageAccountKey=$(az storage account keys list \
--resource-group $resourceGroupName \
--account-name $storageAccountName \
--query "[0].value" | tr -d '"')
smbCredentialFile="/etc/smbcredentials/$storageAccountName.cred"
if [ ! -f $smbCredentialFile ]; then
echo "username=$storageAccountName" | sudo tee $smbCredentialFile > /dev/null
echo "password=$storageAccountKey" | sudo tee -a $smbCredentialFile > /dev/null
else
echo "The credential file $smbCredentialFile already exists, and was not modified."
fi
sudo chmod 600 $smbCredentialFile
# This command assumes you have logged in with az login
httpEndpoint=$(az storage account show \
--resource-group $resourceGroupName \
--name $storageAccountName \
--query "primaryEndpoints.file" | tr -d '"')
smbPath=$(echo $httpEndpoint | cut -c7-$(expr length $httpEndpoint))$fileShareName
if [ -z "$(grep $smbPath\ $mntPath /etc/fstab)" ]; then
echo "$smbPath $mntPath cifs nofail,vers=3.0,file_mode=0666,dir_mode=0777,credentials=$smbCredentialFile,serverino" | sudo tee -a /etc/fstab > /dev/null
else
echo "/etc/fstab was not modified to avoid conflicting entries as this Azure file share was already present. You may want to double check /etc/fstab to ensure the configuration is as desired."
fi
sudo mount -a
---------------------------
$ chmod a+x azurefilesmount.sh
$ ./azurefilesmount.sh
#2.PostgresSQLインストール(dbサーバ
#2-1.インストール
$ sudo apt-get update
$ sudo apt-get -y install postgresql postgresql-contrib
$ sudo systemctl enable postgresql
$ sudo systemctl list-unit-files | grep postgres
$ psql --version
psql (PostgreSQL) 12.6 (Ubuntu 12.6-0ubuntu0.20.04.1)
#2-2.管理ユーザ追加
$ sudo -u postgres psql
=# ALTER ROLE postgres PASSWORD 'YOURPASSWORD';
ALTER ROLE
=# SELECT * FROM pg_shadow;
$ sudo -u postgres createuser -P redmine
Enter password for new role:YOURPASSWORD
Enter it again:YOURPASSWORD
#2-3.DB作成
$ sudo -u postgres createdb -E UTF-8 -l ja_JP.UTF-8 -O redmine -T template0 redmine
$ psql -U redmine -h localhost -d redmine
Password for user redmine:YOURPASSWORD
redmine-> \l
$ sudo systemctl stop postgresql
$ sudo systemctl start postgresql
$ psql -U redmine -h localhost -d redmine
#3.Redmineインストール
#3-1.ネットワークセキュリティグループ設定
あらかじめAzureポータルでネットワークセキュリティグループにてhttpとhttpsをオープンする
#3-2.nginxインストール
$ sudo apt -y install nginx
$ nginx -v
nginx version: nginx/1.18.0 (Ubuntu)
#3-3.Let'sEncrypt設定
$ sudo apt -y install certbot python3-certbot-nginx
$ sudo certbot --nginx -d YOURDOMAIN -d *.YOURDOMAIN
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel):YOURMAILADRESS
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
~略~
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel:A
~略~
(Y)es/(N)o:Y
~略~
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
#3-4.nginx設定ファイル修正
$ sudo vi /etc/nginx/conf.d/local.conf
------------------------------
upstream unicorn-unix-domain-socket {
server unix:/var/www/redmine/tmp/sockets/unicorn.sock fail_timeout=0;
}
server {
listen 80; # httpへのアクセスをhttpsへリダイレクトする
listen [::]:80;
server_name YOURDOMAIN;
if ($http_x_forwarded_proto != https) {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl on;
if ($host != "YOURDOMAIN"){
return 444;
}
server_name YOURDOMAIN;
index index.html index.htm index.php;
client_max_body_size 1024M;
ssl_stapling on;
ssl_stapling_verify on;
ssl_certificate /etc/letsencrypt/live/YOURDOMAIN/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/YOURDOMAIN/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
location / {
root /var/www/redmine;
access_log /var/log/nginx/redmine_access.log;
error_log /var/log/nginx/redmine_error.log;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://unicorn-unix-domain-socket;
}
}
------------------------------
#3-5.Rubyほか必要ツール類インストール
$ cd
$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
$ echo 'export PATH=~/.rbenv/bin:$PATH' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile
$ rbenv --version
rbenv 1.1.2-44-gd604acb
$ sudo apt -y install build-essential
$ sudo apt -y install git build-essential libssl-dev libpq-dev
$ sudo apt -y install zlib1g-dev libxslt1-dev libreadline-dev libcurl4-openssl-dev
$ sudo apt -y install imagemagick libmagick++-dev
$ rbenv install 2.6.7
$ rbenv versions
$ rbenv global 2.6.7
$ ruby -v
ruby 2.6.7p197 (2021-04-05 revision 67941) [x86_64-linux]
#3-6.Redmine導入
$ cd /var/www
$ sudo git clone https://github.com/redmine/redmine.git redmine
$ sudo chown -R ope_user redmine/
$ cd redmine
$ cp config/database.yml.example config/database.yml
$ sudo vi config/database.yml
---------------------------------------
# PostgreSQL configuration example
production:
adapter: postgresql
database: redmine
host: localhost
username: redmine
password: YOURPASSWORD
encoding: utf8
pool: 5
development:
adapter: postgresql
database: redmine
host: localhost
username: redmine
password: YOURPASSWORD
encoding: utf8
pool: 5
---------------------------------------
$ vi config/configuration.yml
--------------------------------------------
default:
email_delivery:
delivery_method: :smtp
smtp_settings:
address: "smtp.sendgrid.net"
port: 587
domain: "smtp.sendgrid.net"
authentication: :login
user_name: apikey
password: YOURPASSWORD
attachments_storage_path: /mnt/YOURSTORAGEACCOUNT/YOURFILESTORAGENAME
--------------------------------------------
#3-7.unicorn関連設定
$ vi Gemfile
※最後尾に追加
------------------
#Unicorn
gem "unicorn"
------------------
$ gem install rubygems-update
Fetching rubygems-update-3.2.16.gem
~中略~
Done installing documentation for rubygems-update after 170 seconds
1 gem installed
$ update_rubygems
$ gem install bundler
$ gem install daemon_controller rack passenger
$ bundle update
$ bundle install --path vendor/bundler --without development test
$ bundle exec rake generate_secret_token
$ bundle exec rake db:migrate RAILS_ENV=production
#3-8.設定ファイル編集
#unicornファイル
$ vi config/unicorn.rb
--------------------------------------------
# Railsのルートパスを求める。(RAILS_ROOT/config/unicorn.rbに配置している場合。)
rails_root = File.expand_path('../../', __FILE__)
# RAILS_ENVを求める。(RAILS_ENV毎に挙動を変更したい場合に使用。今回は使用しません。)
# rails_env = ENV['RAILS_ENV'] || "development"
# 追記に記載してます。入れた方がいいです。
ENV['BUNDLE_GEMFILE'] = rails_root + "/Gemfile"
# Unicornは複数のワーカーで起動するのでワーカー数を定義
# サーバーのメモリなどによって変更すること。
worker_processes 2
# 指定しなくても良い。
# Unicornの起動コマンドを実行するディレクトリを指定します。
# (記載しておけば他のディレクトリでこのファイルを叩けなくなる。)
working_directory rails_root
# 接続タイムアウト時間
timeout 30
# Unicornのエラーログと通常ログの位置を指定。
stderr_path File.expand_path('../../log/unicorn_stderr.log', __FILE__)
stdout_path File.expand_path('../../log/unicorn_stdout.log', __FILE__)
# Nginxで使用する場合は以下の設定を行う(※このパスをNginx側で設定したパスと揃えておく必要があります)。
listen File.expand_path('../../tmp/sockets/unicorn.sock', __FILE__)
# とりあえず起動して動作確認をしたい場合は以下の設定を行う。
#listen 8080
# ※「backlog」や「tcp_nopush」の設定もあるけど、よくわかって無い。
# プロセスの停止などに必要なPIDファイルの保存先を指定。
pid File.expand_path('../../tmp/pids/unicorn.pid', __FILE__)
# 基本的には`true`を指定する。Unicornの再起動時にダウンタイムなしで再起動が行われる。
preload_app true
# 効果なしとの記事を見たので、コメントアウト。
# GC.respond_to?(:copy_on_write_friendly=) and GC.copy_on_write_friendly = true
# USR2シグナルを受けると古いプロセスを止める。
# 後述するが、記述しておくとNginxと連携する時に良いことがある。
before_fork do |server, worker|
defined?(ActiveRecord::Base) and
ActiveRecord::Base.connection.disconnect!
old_pid = "#{server.config[:pid]}.oldbin"
if old_pid != server.pid
begin
sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
Process.kill(sig, File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
end
end
end
after_fork do |server, worker|
defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
end
--------------------------------------------
$ bundle exec rails generate task unicorn
#unicorn起動コマンド
$ vi lib/tasks/unicorn.rake
----------------------------
namespace :unicorn do
desc "Start unicorn for production env."
task(:start) do
config_path = "/var/www/redmine/config/unicorn.rb"
sh "unicorn_rails -c #{config_path} -E production -D"
end
desc "Stop unicorn"
task(:stop) { unicorn_signal :QUIT }
desc "Restart unicorn with USR2"
task(:restart) { unicorn_signal :USR2 }
desc "Increment number of worker processes"
task(:increment) { unicorn_signal :TTIN }
desc "Decrement number of worker processes"
task(:decrement) { unicorn_signal :TTOU }
desc "Unicorn pstree (depends on pstree command)"
task(:pstree) do
sh "pstree '#{unicorn_pid}'"
end
def unicorn_signal signal
Process.kill signal, unicorn_pid
end
def unicorn_pid
begin
File.read("/var/www/redmine/tmp/pids/unicorn.pid").to_i
rescue Errno::ENOENT
raise "Unicorn doesn't seem to be running"
end
end
end
----------------------------
#unicorn自動起動設定
$ sudo vi /etc/init.d/unicorn
--------------------------------------------
#!/bin/sh
# chkconfig: 345 90 20
# description: Redmine
# processname: unicorn_redmine
RAILS_ENV=production
SERVICE=redmine
USER=ope_user
RAILS_ROOT_DIR="/var/www/redmine"
PID=${RAILS_ROOT_DIR}/tmp/pids/unicorn.pid
UNICORN_CONF=${RAILS_ROOT_DIR}/config/unicorn.rb
UNICORN_ALIVE=`ps aux|grep '${UNICORN_CONF}'|grep -v grep|wc -l`
start()
{
if [ $UNICORN_ALIVE = 0 ]; then
rm -f $PID
fi
if [ -e ${PID} ]; then
echo "${SERVICE} already started"
exit 1
fi
echo "start ${SERVICE}"
sudo su -l ${USER} -c "cd ${RAILS_ROOT_DIR} && bundle exec unicorn_rails -c ${UNICORN_CONF} -D"
}
stop()
{
if [ ! -e ${PID} ]; then
echo "${SERVICE} not started"
exit 1
fi
echo "stop ${SERVICE}"
kill -QUIT `cat ${PID}`
}
force_stop()
{
if [ ! -e ${PID} ]; then
echo "${SERVICE} not started"
exit 1
fi
echo "stop ${SERVICE}"
kill -INT `cat ${PID}`
}
reload()
{
if [ ! -e ${PID} ]; then
echo "${SERVICE} not started"
start
exit 0
fi
echo "reload ${SERVICE}"
kill -USR2 `cat ${PID}`
}
restart()
{
if [ -e ${PID} ]; then
stop
sleep 3
fi
start
}
case "$1" in
start)
start
;;
stop)
stop
;;
force-stop)
force_stop
;;
reload)
reload
;;
restart)
restart
;;
*)
echo "Syntax Error: release [start|stop|force-stop|reload|restart]"
;;
esac
--------------------------------------------
$ sudo chmod 755 /etc/init.d/unicorn
#サービス設定ファイル
$ sudo vi /lib/systemd/system/unicorn.service
--------------------------------------------
[Unit]
Description=Unicorn Server
After=postgresql.service
[Service]
WorkingDirectory=/var/www/redmine
Environment=RAILS_ENV=production
SyslogIdentifier=unicorn
PIDFile=/var/www/redmine/tmp/pids/unicorn.pid
ExecStart=/home/ope_user/.rbenv/shims/bundle exec "unicorn_rails -c config/unicorn.rb -E production -D"
ExecStop=/usr/bin/kill -QUIT $MAINPID
ExecReload=/bin/kill -USR2 $MAINPID
[Install]
WantedBy=multi-user.target
--------------------------------------------
$ sudo chmod 755 /lib/systemd/system/unicorn.service
$ sudo ln -s /lib/systemd/system/unicorn.service /etc/systemd/system/multi-user.target.wants/unicorn.service
$ sudo systemctl start unicorn.service
$ sudo systemctl stop unicorn.service
$ sudo systemctl enabled unicorn.service
~エラーが出るが無視しても問題なし~
$ sudo service nginx restart
$ sudo reboot
#4.リマインダーおよびプラグイン関連
#リマインダー
$ crontab -e
-----------------------------
# m h dom mon dow command
30 6 * * * cd /var/www/redmine ; bundle exec rake redmine:send_reminders days=3 RAILS_ENV=production
-----------------------------
#プラグインは未導入(検討中)
redmine issue templates
redmine checklists
redmine issue badge
redmine issues tree
redmine absolute dates
redmine work time
redmine slack
view_customize
Ⅳ.仮想マシンのバックアップ
Azureの仮想マシンバックアップの機能を使用する。
※注意点としてリストア後はVMのsudo可能ユーザのパスワードリセットを行う必要がある
1.バックアップ
①バックアップおよびサイトの回復で「作成」を行う
②RecoveryServiceコンテナーの作成で必要事項を入力しコンテナーを作成する
③RecoveryContainerで[+バックアップ]を選択する
④バックアップの目標で[バックアップ]をクリックする
⑤バックアップの構成でバックアップポリシーを作成して、そのバックアップポリシーを選択する
⑥PolicyDetailsの内容を確認する。(自分の意図した設定となっているかを確認する)
⑦[バックアップの有効化]でジョブをデプロイする
◆参照サイト
・Azure関連
・PostgresSQLインストール
・nginxインストール
・Redmine
今回はGitでインストールしているので今後のマイナーバージョンアップの場合は
git pull origin masterで更新が反映できるようになるので少しは楽になるかなぁと。
で、今回色々とやってみて、ことのほかAzureファイル共有のパフォーマンスが
S3と比べて悪くはなかったのでDockerを使ってマウントしてみて
Postgreの永続化ファイルと添付ファイル分をAzureファイル共有に逃がせばもしかしたら
色々と楽できるのではないかと思った次第。
ほかにAzureADと連携させてみても面白そうですな。次回はDockerのネタで色々と試してみようかと思います。
コメント