Rails 项目部署
服务器和域名的购买,可自行google解决。
表达惯例:
#
开头代表该命令使用 root 权限执行。
$
开头代表改命令使用 ruby 用户权限执行。
从 root 切换至 ruby 用户,使用 su - ruby
,-
的作用可以确保 ruby 用户的环境变量的正确加载。
如果命令中有xxx
,请替换为自己的项目名称。
服务器搭建环境
本地执行:
$ ssh root@yourserver_ip
输入密码确保登录成功
准备工作
更新源,并安装必需的用户
# apt-get update
# apt-get install -y git-core curl zlib1g-dev build-essential libssl-dev \
libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev \
libcurl4-openssl-dev python-software-properties libffi-dev imagemagick libmagickwand-dev
创建新用户 ruby
# adduser ruby(不要使用 useradd)
随便输入一个复杂密码即可,因为后续我们只使用ruby
用户的sshkey
登录方式。
在 ruby 用户下安装Rbenv + ruby
# su - ruby
Ruby
的安装推荐使用Rbenv
,Rvm
我使用Rbenv
https://github.com/rbenv/rbenv
$ git clone git@github.com:rbenv/rbenv.git ~/.rbenv
$ git clone git@github.com:rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
$ git clone git@github.com:AndorChen/rbenv-china-mirror.git ~/.rbenv/plugins/rbenv-china-mirror
$ echo 'export path="$home/.rbenv/bin:$path"' >> ~/.bashrc
$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc
$ echo 'source ~/.bashrc' >> ~/.bash_profile
$ source ~/.bash_profile
$ rbenv install 3.0.1
$ rbenv global 3.0.1
$ rbenv rehash
安装 Rails 依赖 gem 和 bundler
$ gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/
$ gem update --system
$ gem install bundler
$ bundle config mirror.https://rubygems.org https://gems.ruby-china.com
准备发布目录
# chown ruby:ruby /home/ruby
准备免密登录
$ ssh-keygen
$ vim ~/.ssh/authorized_keys (然后复制本机的 id_rsa.pub 内容写入。)
然后本地新开终端窗口,测试输入:
(本地执行)
$ ssh ruby@yourserver_ip
这里一定要成功免密登录,如果有问题请自行 google 解决。
准备 github clone 权限
$ cat ~/.ssh/id_rsa.pub
将输出的内容复制到 github 仓库中 deploy key 里,保证发布环境主机能 clone 你的仓库。
github 选择账户 ->
settings
->SSH and GPG keys
->New SSH key
当然在测试之前你还需要设置 git 的 username 和 useremail:
$ git config --global user.name "example"
$ git config --global user.email example@163.com
然后测试确保能够克隆代码
准备 postgresql
# apt update
# apt install -y postgresql postgresql-contrib
# apt install -y postgresql libpq-dev
然后运行 sudo -u postgres psql -c "SELECT version();"
会输出相关版本信息,例如:
PostgreSQL 12.2 (Ubuntu 12.2-4) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 9.3.0-8ubuntu1) 9.3.0, 64-bit
postgresql_user 设置(最简单的就是把 /etc/postgresql/xxx(版本号)/main/pg_hba.conf
里面的 MD5 与 peer 统一改为 trust)
然后修改 postgres 用户的密码,改成 database.yml 文件中一样的。
然后重启下:# service postgresql restart
安装 Nodejs (用来编译 assets 使用)
# curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
如果你需要另外的 Node.js 版本,例如12.x
,将setup_14.x
修改为setup_12.x
。
# apt install nodejs
现在切换到本地,
首先你的config/puma.rb
最简单应该长这样:
port 3000
if ENV['RAILS_ENV'] == 'production'
app_root = '/home/ruby/xxx/shared'
pidfile "#{app_root}/tmp/pids/puma.pid"
state_path "#{app_root}/tmp/pids/puma.state"
bind "unix://#{app_root}/tmp/sockets/puma.sock"
activate_control_app "unix://#{app_root}/tmp/sockets/pumactl.sock"
daemonize true
workers 2
threads 8, 16
prune_bundler
stdout_redirect "#{app_root}/log/puma_access.log", "#{app_root}/log/puma_error.log", true
else
plugin :tmp_restart
end
然后你的config/deploy/production.rb
最简单应该长这样:
set :domain, '服务器ip或者域名'
set :deploy_to, '/home/ruby/xxx'
set :repository, '你的仓库地址'
set :branch, 'master'
set :user, 'ruby'
然后在本地终端执行:$ mina deploy
,静等执行完毕,根据提示,需要你修改服务器上的application.yml
和database.yml
。
(服务器执行)
$ vim /home/ruby/xxx/shared/config/application.yml
$ vim /home/ruby/xxx/shared/config/database.yml
第一次搞部署肯定会有很多问题,可以先进行一次冒烟测试,
(本地执行)
$ mina first_deploy
如果一切正常,进入正式发布流程:
(本地执行)
$ mina deploy
每个人发布时都可能会遇到问题,需要自己 google 去解决。
发布成功之后,开始配置nginx
。
# echo "deb http://nginx.org/packages/mainline/ubuntu `lsb_release -cs` nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
# curl -o /tmp/nginx_signing.key https://nginx.org/keys/nginx_signing.key
# mv /tmp/nginx_signing.key /etc/apt/trusted.gpg.d/nginx_signing.asc
# apt update
# apt install nginx
nginx -v
保证 nginx 版本大于
1.20.1
在 /etc/nginx/conf.d/
创建 xxx.conf
,
里面的内容最简单可以长这样:
upstream xxx {
server unix:///home/ruby/xxx/shared/tmp/sockets/puma.sock fail_timeout=0;
}
server {
listen 80;
server_name domain.com;
root /home/ruby/xxx/current/public;
location ^~ /packs/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
location /cable {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://xxx;
}
location ~ ^/(uploads)/ {
expires max;
break;
}
try_files $uri/index.html $uri @xxx;
location @xxx{
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_redirect off;
proxy_pass http://xxx;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 20M;
keepalive_timeout 10;
}
# nginx -s reload (重启 nginx)
本地浏览器打开http://yourserverdomain
来检查是否发布成功。
服务器安全
采用 ufw
来作为防火墙,简单而不失安全。
ufw 配置,打开22
,80
,443
端口。
# ufw allow 22/tcp
# ufw allow 80/tcp
# ufw allow 433/tcp
# ufw enable
这样可以防止大部分的入侵。
https ssl 支持
这里直接抄作业,看大佬文章 https://ruby-china.org/topics/31983