记账app_4_本地部署实践
Contents
1 部署思路与宿主机部署流程
1.1 部署思路
-
后端部署思路
- 上传Dockerfile
-
上传源代码
-
用Dockerfile构建运行环境
-
在运行环境里运行源代码
-
使用Nginx做转发,优势如下
- 负载均衡:可以用多个应用去服务用户
-
0宕机时间:新旧应用负载均衡,最终新应用完全替代旧应用,实现应用的不停机更新
-
前端部署思路
-
将代码中的路径替换成CDN路径
-
上传打包好的CSS和JS代码到CDN
-
将html文件上传到后端服务器
-
使用Nginx处理html文件请求
-
1.2 本地部署实践
- 思路
- 本地采用docker部署,首先在linux中打包代码(Rails源代码及Dockerfile)并拷贝到宿主机环境,之后在宿主机中运行docker命令,构建ruby运行容器,最终在宿主机的docker启动项目即可
1.2.0 添加首页
-
添加跟路由,替换rails自带的欢迎页
config/routes.rb
1 2 3 4 5 6
Rails.application.routes.draw do get '/', to 'home#index' namespace :api do ... end end
-
生成对应的controller:
bin/rails g controller home index
app/controllers/home_controller.rb
1 2 3 4 5
class HomeController < ApplicationController def index render json: { message: 'Welcome' } end end
-
1.2.1 打包
-
将docker开发环境中的rails代码选择性地拷贝到公共目录,供宿主机访问
-
bin目录下创建
pack_for_host.sh
文件
|
|
- 为此文件添加可执行权限:
chmod +x bin/pack_for_host.sh
1.2.2 Dockerfile
-
准备ruby运行容器的dockerfile,供宿主机构建容器用
config/host.Dockerfile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
# 基于ruby3.0.0镜像构建ruby运行环境的容器 FROM ruby:3.0.0 # 设置rails环境变量为production ENV RAILS_ENV production RUN mkdir /mangosteen # 配置bundle源 RUN bundle config mirror.https://rubygems.org https://gems.ruby-china.com WORKDIR /mangosteen # 将源代码放入当前工作目录中(ADD会自动解压缩tar包) ADD mangosteen-*.tar.gz ./ # 安装依赖(先配置 安装时排除开发和测试环境的依赖) RUN bundle config set --local without 'development test' RUN bundle install # bundle exec rails server 是专门用在开发环境的 # 生产环境用puma # 只在docker exec或start时自动执行,build时不执行 ENTRYPOINT bundle exec puma
1.2.3 宿主机项目构建与运行
-
构建部署容器的命令
bin/setup_host.sh
1 2 3 4 5 6 7 8 9 10 11 12
DB_PASSWORD=123456 container_name=mangosteen-prod-1 version=$(cat mangosteen_deploy/version) echo 'docker build ...' docker build mangosteen_deploy -t mangosteen:$version echo 'docker run ...' docker run -d -p 3000:3000 --network=network1 -e DB_PASSWORD=$DB_PASSWORD --name=$container_name mangosteen:$version echo 'docker exec ...' # 创建数据库 同步数据表 docker exec -it $container_name bin/rails db:create db:migrate echo 'DONE'
-
为此文件添加可执行权限:
chmod +x bin/setup_host.sh
1.2.4 部署流程
-
在容器中执行:
bin/pack_for_host.sh
-
将宿主机的oh-my-env目录下,可以看到mangosteen_deploy文件
|
|
-
在此目录下执行(用zsh或bash):
mangosteen_deploy/setup_host.sh
-
构建完成后在docker desktop会发现多了一个容器,但是启动失败了,失败原因:
docker logs containerID
-
如果是rails报错missing ‘secret_base_key’,说明我们部署的过程是没有问题的
-
不适用于M1芯片的系统,会遇到了glibc版本不对的问题
2 密钥管理
2.1 基本思路
-
web应用中经常会做一些对称加密,例如JWT和Session ID的加密解密
-
这些keys不可以存在github中,也不要存在自己电脑中传来传去,都不是安全的
-
所以rails为我们提供了master.key,master.key相当于加解密的钥匙,rails会对密钥们基于master.key二次加密
-
我们需要将密钥们写入临时文件,经
master.key
加密后生成credentials.yml.enc(encrypted)
,随即销毁临时文件,只有这两个文件同时存在时,rails才会将真正的密钥们解密出来
|
|
- 可以将加密后的.enc文件放到git中,注意一定要将master.key排除出git(rails帮忙了)
2.2 生产环境master.key
-
rails生成或编辑keys:
-
bin/rails credentials:edit
,默认使用vim编辑 -
EDITOR="code --wait" bin/rails credentials:edit
,指定使用vscode编辑
-
-
执行后,在config下生成
master.key
与credentials.yml.enc
,同时会打开一个临时文件,存储着所有的密钥,关闭即销毁
|
|
-
关闭后,
credentials.yml.enc
文件会自动更新 -
rails读keys:
-
打开rails控制台:
bin/rails c
-
输入代码:
Rails.application.credentials.secret_key_base
或者Rails.application.credentials.config
-
|
|
2.3 多环境密钥
-
开发环境的master.key可以随意,只要保证生产环境的production.key只有负责部署的最高权限那个人能访问就可以避免安全问题
-
rails生成并编辑生产环境的keys,注意默认并没有生成
secret_key_base
,需要手动添加EDITOR="code --wait" rails credentials:edit --environment production
-
执行后,在config/credentials下创建了
production.key
和对应的production.yml.enc
-
rails读生产环境的keys:
-
打开rails生产环境控制台:
RAILS_ENV=production bin/rails c
-
输入代码:
Rails.application.credentials.secret_key_base
或者Rails.application.credentials.config
-
2.4 总结
-
开发环境
-
使用master.key和credentials.yml.enc
-
master.key一定ignore
-
如果.enc被ignore,那就多人公用master.key
-
如果.enc不被ignore,那就把密钥直接拷贝给每个人,每个人创建自己的master.key
-
-
生产环境
-
使用production.key和production.yml.enc
-
.env不要ignore
-
production.key一定ignore,内容写到部署机的环境变量中
-
2.5 解决Missing secret_key_base的报错
-
添加生产环境的production.key(步骤见上文)
-
更改setup_host,在执行docker run的时候添加环境变量占位符
|
|
- 每次在宿主机执行构建脚本前,加上production.key
|
|
3 配置生产环境数据库
config/database.yml
|
|
- 再次更改setup_host,在执行docker run的时候添加环境变量占位符
|
|
- 创建生产环境数据库
|
|
- 每次在宿主机执行构建脚本前,加上production.key、DB_HOST和DB_PASSWORD值
|
|
Author gsemir
LastMod 2022-05-18