一部、Ansibleで自動化したりしていますが、
さらっと追加したい場合に確認しながら設定するのは手間なので、手順をメモしておきます。
また、Capistranoだとrvmが使えなかったり、CentOS7だとnode v18が使えなかったり
rvmのgpgでエラーになったりとか、色々あったので、現象も含め残しておきます。

ユーザー作成

用途
・CapistranoでSSHログイン
・Gitリポジトリからソースを取得
・Unicorn起動

# useradd -g nginx -G users railsapp

# id railsapp
uid=1002(railsapp) gid=490(nginx) groups=490(nginx),100(users)

# ll /home/ | grep railsapp
drwx------ 2 railsapp nginx  62  1月 29 10:29 railsapp

Nginxを使うので、メインはnginxグループ。
SSHログインはusersグループで制限しているので追加しています。(環境に合わせて設定)

パーミッション変更

# chmod 750 /home/railsapp
# ll /home/ | grep railsapp
drwxr-x--- 5 railsapp nginx 140  1月 29 10:54 railsapp

Nginxからアクセスできるようにパーミッションを変更しています。

メール転送

cronの標準出力(エラー等)はメールで来るので、転送するように設定しておきます。

# vi /etc/aliases
railsapp:	warning【受信するメールアドレス】
# newaliases

SSH鍵設置

作成する場合

# su - railsapp
$ ssh-keygen -t rsa -b 4096
Enter file in which to save the key (/home/railsapp/.ssh/id_rsa): (空のままEnter)
Enter passphrase (empty for no passphrase): (空のままEnter)
Enter same passphrase again: (空のままEnter)

$ cd .ssh/
$ ln -s id_rsa.pub authorized_keys

$ cat id_rsa
※秘密鍵。接続元PCの~/.ssh/以下等に保存して利用

$ cat id_rsa.pub
※公開鍵。保存しなくてもOKだけど、同じ鍵を使う場合に利用。Gitリポジトリにも登録

$ exit

既存の鍵を設置する場合

# su - railsapp
$ chmod 700 .ssh/
$ ls -la | grep .ssh
drwx------  2 railsapp nginx    6  1月 29 10:39 .ssh

$ cd .ssh/
$ vi id_rsa
※既存の秘密鍵をコピペして保存(SSHログインするだけなら不要だけど、Gitリポジトリにアクセスする為)

$ vi id_rsa.pub
※既存の秘密鍵をコピペして保存

$ chmod 600 id_rsa 
$ ln -s id_rsa.pub authorized_keys
$ ll
lrwxrwxrwx 1 railsapp nginx   10  1月 29 10:47 authorized_keys -> id_rsa.pub
-rw------- 1 railsapp nginx 3243  1月 29 10:41 id_rsa
-rw-r--r-- 1 railsapp nginx  757  1月 29 10:45 id_rsa.pub

$ exit

疎通確認

ssh config設定しておくと楽なので、おすすめ。
踏み台経由の接続とかも設定しておけば一発でできます。

.ssh/config

# ssh railsapp@servername.example.com -p 22 -i ~/.ssh/servername_railsapp/id_rsa
Host servername_railsapp
  Hostname servername.example.com
  Port 22
  User railsapp
  IdentityFile ~/.ssh/servername_railsapp/id_rsa
% chmod 600 ~/.ssh/servername_railsapp/id_rsa 

% ssh servername_railsapp
[railsapp@servername ~]$ exit

rvm/Rubyインストール

rvmはユーザーに入れて、他のユーザーに影響しないようにしています。

# yum -y install libffi-devel readline-devel ruby sqlite-devel graphviz

bundle install時にsudoのパスワードを求められるやつを先に入れておきます。
(sudo許可していないので)
graphvizは使用しているので追加していますので、必要な場合のみでOK。

rvmインストール

RVM: Ruby Version Manager – Installing RVM

# su - railsapp
$ gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
gpg: 有効なOpenPGPデータが見つかりません。
gpg:         処理数の合計: 0

公式通りにkeyserver指定すると下記エラーになりました。下記を参考にubuntuのを使用。

Fresh Install gpg keys fail – needs ipv4 prepended · Issue #5004 · rvm/rvm

$ gpg --keyserver keyserver.ubuntu.com --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
gpg: 絶対的に信用する鍵が見つかりません
gpg:         処理数の合計: 2
gpg:           インポート: 2  (RSA: 2)
$ \curl -sSL https://get.rvm.io | bash
👉  Donate: https://opencollective.com/rvm/donate

$ source ~/.rvm/scripts/rvm
$ rvm -v
rvm 1.29.12-next (master) by Michal Papis, Piotr Kuczynski, Wayne E. Seguin [https://rvm.io]

Rubyインストール

$ rvm list known
[ruby-]3.0[.5]
[ruby-]3.1[.3]
[ruby-]3[.2.0]
ruby-head

使用しているRubyのバージョンをインストール

$ rvm install 3.0.0
$ ruby -v
ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c5) [x86_64-linux]

$ exit

node/Yarnインストール

nvmを使いたい所ですが、Capistrano経由のyarn installに失敗するので断念。
(オプションとかで回避する方法もなさそう)

cap production deploy
00:30 yarn:install
      01 yarn install --production
      01 /usr/bin/env: yarn: そのようなファイルやディレクトリはありません

yarn入れてもダメ

yarn -v
1.22.19

cap production deploy
00:30 yarn:install
      01 yarn install --production
      01 /usr/bin/env: node
      01 : そのようなファイルやディレクトリはありません

また、CentOS7で、node v18を入れるとエラーになるので、その前のLTSのv16を使います。
nodeのv18を使ったらエラーになった(CentOS7) – ITのプロへ

nvm ls-remote | grep "Latest LTS"
         v4.9.1   (Latest LTS: Argon)
        v6.17.1   (Latest LTS: Boron)
        v8.17.0   (Latest LTS: Carbon)
       v10.24.1   (Latest LTS: Dubnium)
      v12.22.12   (Latest LTS: Erbium)
       v14.21.2   (Latest LTS: Fermium)
       v16.19.0   (Latest LTS: Gallium)
       v18.13.0   (Latest LTS: Hydrogen)

デフォルトではyumにない。

# yum install nodejs
パッケージ nodejs は利用できません。
エラー: 何もしません

nodeインストール

v16の場合は「setup_16.x」を実行

# curl -fsSL https://rpm.nodesource.com/setup_16.x | sudo bash -
## Run `sudo yum install -y nodejs` to install Node.js 16.x and npm.
## You may run dnf if yum is not available:
     sudo dnf install -y nodejs
## You may also need development tools to build native addons:
     sudo yum install gcc-c++ make
## To install the Yarn package manager, run:
     curl -sL https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/yarn.repo
     sudo yum install yarn
# yum install -y nodejs
インストール:
  nodejs.x86_64 2:16.19.0-1nodesource                                                                                                                           

完了しました!

# node -v
v16.19.0
# npm -v
8.19.3

Yarnインストール

# npm install -g yarn
added 1 package, and audited 2 packages in 687ms

# yarn -v
1.22.19

DB・ユーザー作成

DBはMySQL(MariaDB含む)がインストール済みの前提です。

パスワード生成 (Passwords Generator)で作るか、下記コマンドで作成。

CentOS # yum install expect
Mac % brew install expect

# mkpasswd -l 8 -s 0
※オプション:-l 長さ、-s 記号等の数
# mysql
CREATE DATABASE railsapp_production;
CREATE USER 'railsapp'@'%' IDENTIFIED BY '【DBのパスワード】';
GRANT ALL PRIVILEGES ON railsapp_production.* TO 'railsapp'@'%';
exit

# mysql -u railsapp -p railsapp_production
Enter password: 【DBのパスワード】
exit

環境変数設定

# su - railsapp
$ vi ~/.bashrc
### START ###
export RAILS_ENV="production"
export SECRET_KEY_BASE="【rails secretで作成した値(環境毎に固定)】"
export DATABASE_URL="mysql2://railsapp:【DBのパスワード】@localhost/railsapp_production"
### END ###

DATABASE_URLはconfig/database.ymlで設定しています。

production:
  <<: *default
  url: <%= ENV['DATABASE_URL'] %>
export LOG_LEVEL="info" # "debug"

LOG_LEVELはconfig/environments/production.rbで設定しています。

  config.log_level = ENV['LOG_LEVEL'].present? ? ENV['LOG_LEVEL'].to_sym : :info

その他、ENVで定義している値をセット。私の場合は、/config/settings/production.ymlで定義しているもののうち環境により変更が必要なものを設定しています。

export ENV_NAME=""
export BASE_DOMAIN="example.com"
export BASE_IMAGE_URL="https://example.com"
export REDIRECT_WHITELIST="['https://front.example.com/*']"
export MAILER_FROM_EMAIL="noreply@example.com"
export EXCEPTION_NOTIFIER_EMAIL=1
export EXCEPTION_NOTIFIER_EMAIL_SENDER="noreply@example.com"
export EXCEPTION_NOTIFIER_EMAIL_RECIPIENTS="['warning@example.com']"
export EXCEPTION_NOTIFIER_SLACK=1
export EXCEPTION_NOTIFIER_SLACK_WEBHOOK_URL="https://hooks.slack.com/services/xxxxxxxx"

反映

$ source ~/.bashrc

念の為、メール送信テスト

$ echo "test" | mail -s "test for `hostname`" -r noreply@example.com warning@example.com

Nginx設定追加

パスやドメインは環境に合わせて変更してください。
Unicornで、UNIXソケットで接続するように設定しています。
pem(SSL証明書)は、Let’s Encryptでワイルドカードで作成してあるので、
それを使用しています。

# vi /etc/nginx/conf.d/z_railsapp.conf
### START ###
upstream railsapp {
    server unix:/home/railsapp/app/current/tmp/sockets/unicorn.sock;
}

server {
    listen       80;
    listen       [::]:80;
    server_name  railsapp.nightonly.com *.railsapp.nightonly.com;

    # SSL redirect
    return 301 https://$host$request_uri;

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;

    access_log /var/log/nginx/railsapp_access.log 'addhost'; # or 'main'
    error_log  /var/log/nginx/railsapp_error.log;
}

server {
    listen       443 ssl http2;
    listen       [::]:443 ssl;
    server_name  railsapp.nightonly.com *.railsapp.nightonly.com;

    ssl_certificate     /etc/letsencrypt/live/nightonly.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/nightonly.com/privkey.pem;
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout 10m;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:MEDIUM:!aNULL:!MD5:!SEED:!IDEA:!3DES:!RC4:!DH;
    ssl_prefer_server_ciphers on;
    add_header Strict-Transport-Security "max-age=31536000";

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;

    access_log /var/log/nginx/railsapp_ssl_access.log 'addhost'; # or 'main'
    error_log  /var/log/nginx/railsapp_ssl_error.log;

    # Application settings
    root /usr/share/nginx/html;
    error_page 400 403 404 422 /404.html;
    error_page 408 500 502 504 /500.html;
    error_page 503 /503.html;
    location = /503.html {
    }

    # Front access
    location / {
        proxy_set_header    Host                $http_host;
        proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
        proxy_set_header    X-Forwarded-Host    $host;
        proxy_set_header    X-Forwarded-Proto   $scheme;
        proxy_set_header    X-Real-IP           $remote_addr;
        proxy_redirect      off;
        proxy_pass          http://railsapp;
    }

    # Action Cable access
    location /cable {
        proxy_set_header    Host                $http_host;
        proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
        proxy_set_header    X-Forwarded-Host    $host;
        proxy_set_header    X-Forwarded-Proto   $scheme;
        proxy_set_header    X-Real-IP           $remote_addr;
        proxy_redirect      off;

        proxy_http_version  1.1;
        proxy_set_header    Upgrade             websocket;
        proxy_set_header    Connection          Upgrade;

        proxy_pass          http://railsapp;
    }

    # Admin access control
    location /admin {
        include /etc/nginx/conf.d/allow-ip.inc;
        deny all;

        proxy_set_header    Host                $http_host;
        proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
        proxy_set_header    X-Forwarded-Host    $host;
        proxy_set_header    X-Forwarded-Proto   $scheme;
        proxy_set_header    X-Real-IP           $remote_addr;
        proxy_redirect      off;
        proxy_pass          http://railsapp;
    }
}
### END ###
# nginx -t -c /etc/nginx/nginx.conf
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

# systemctl restart nginx

DNS設定 → 使っているDNSサーバーに設定したドメインを追加
動作確認 → 設定したドメインにアクセスしてみる。https://ドメイン

Ansibleを使っているので、下記と同じパスにpushして完成 → 次回、構築時は自動でできる!
https://dev.azure.com/nightonly/vagrant-ansible-origin/_git/vagrant-ansible-centos7?path=/ansible/roles/nginx/templates/etc/nginx/conf.d/z_front.conf&version=GBrails_master

ログローテート

時間経過と共にログが増え続けて行くので、ローテートするように設定しました。
下記は、毎日切り替えて、90日分残す設定。
Railsは-USR1を送らないとファイル名変えても書き込み先が変わらない。

# vi /etc/logrotate.d/railsapp
### START ###
/home/railsapp/app/current/log/*.log {
    daily
    rotate 90
    missingok
    sharedscripts
    postrotate
        pid=/home/railsapp/app/current/tmp/pids/unicorn.pid
        test -s $pid && kill -USR1 "$(cat $pid)"
    endscript
}
### END ###

下記も含めAnsibleにpushして完成 → 次回、構築時は自動でできる!

ansible/roles/nginx/tasks/main.yml

- name: cd /etc/logrotate.d; cp /vagrant/ansible/roles/nginx/templates/etc/logrotate.d/railsapp ./; chmod 644 railsapp; chown root:root railsapp
  template: src="templates/etc/logrotate.d/railsapp" dest="/etc/logrotate.d/" mode=644 owner=root group=root backup=no

続きはこちら

Capistranoを設定して安全にデプロイできるようにする

CentOS7にCapistranoでデプロイしたRailsアプリが動く環境を作る” に対して3件のコメントがあります。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です