实战篇笔记-山竹记账后端(五)


书接上回,报错翻译过来就是

!无法加载应用程序: 参数错误: 生产环境缺少 secret_key_base,请使用 “bin/rails credentials:edit “设置该字符串。

如何管理密钥

对称加密

master.key + keys => encrypted
密钥 + 加密内容 => 密文

encrypted + master.key => keys
密文 + 密钥 => 解密内容

Rails 读取 keys

打开控制台 bin/rails console

输入 Rails.application.credentials.config

可以查看到 keys (这些 keys 即加密内容,不能泄露)

~/r/mangosteen-rails # ❯❯❯ bin/rails console
irb(main):001:0> Rails.application.credentials.config
=> 
{:secret_key_base=>                                                                                     
  "0b20f2b6b8dc0f440f4b0f22ebc74aec8c9156276728d5bcd2e96c3625aaeb4346ed94e6b507f647462cca583009e656e5486ece31d0f405506bec3af02605c"} 

Rails 写入 keys

  1. 删除 config 目录下 的 credentials.yml.enc 和 master.key 文件(如果之前执行过下面操作就会生成这两个文件)

  2. 输入命令 EDITOR="code --wait" bin/rails credentials:edit,会生成一个 master.key 文件 和 xxxxx.credentials.yml 文件,将 keys 记录在 xxxxx.credentials.yml 文件,保存关闭编辑器,这个 xxxxx.credentials.yml 文件会自动销毁,可以通过前面Rails 读取 keys的方法来读取

Adding config/master.key to store the encryption key: abf694bcb7a2f9973efbab9b0ebfe409

Save this in a password manager your team can access.

If you lose the key, no one, including you, can access anything encrypted with it.

      create  config/master.key

File encrypted and saved.

Rails 多环境密钥

开发环境密钥

命令:EDITOR="code --wait" bin/rails credentials:edit

产物:config/master.key、config/credentials.yml.enc

生产环境密钥

命令:EDITOR="code --wait" rails credentials:edit --environment production

产物:config/credentials/production.key、config/credentials/production.yml.enc

解决 Missing secret_key_base for ‘production’ environment

  1. 修改 bin/setup_post.host,把 secret_key_base 写到环境变量
# 添加了这个 -e RAILS_MASTER_KEY=$RAILS_MASTER_KEY
docker run -e RAILS_MASTER_KEY=$RAILS_MASTER_KEY -d -p 3000:3000 --network=network1  --name=$container_name mangosteen:$version
  1. 读取开发环境的 secret_key_base,可以通过前面Rails 读取 keys的方法来读取,也可以通过前面Rails 写入 keys的方法来重新获取一个,把这个 secret_key_base 的值复制下来

  2. 设置生产环境的 secret_key_base

    1. 输入命令:EDITOR="code --wait" rails credentials:edit --environment production

    2. 在生成的 xxxxx.production.yml 写入 secret_key_base: 刚刚复制的开发环境secret_key_base,关闭编辑页会自动销毁这个文件

  3. 重新生成开发环境的 secret_key_base,防止生产环境 secret_key_base 泄露

  4. 输入命令 bin/pack_for_host.sh 重新打包

  5. 复制 config/credentials/production.key 内容

  6. 宿主机执行 RAILS_MASTER_KEY=xxxxxxxxxxxxxxx mangosteen_deploy/setup_host.sh(这里 RAILS_MASTER_KEY 是步骤 1 命名的,xxxxxxxxxxxxxxx 就是上面步骤 6 复制的内容)

  7. 浏览器访问 http://localhost:3000/,页面出现 {"message":"Welcome!"} 即部署成功了

但是访问 http://localhost:3000/api/v1/items 还是失败,原因是还没有配置生产环境数据库

配置生产环境数据库

  1. 修改 config/database.yml
production:
  <<: *default
  database: mangosteen_production
  username: mangosteen
  password: <%= ENV["DB_PASSWORD"] %>
  host: <%= ENV["DB_HOST"] %>
  # <%= ENV["DB_PASSWORD"] %> <%= ENV["DB_HOST"] %> 使用环境变量
  1. 修改 bin/setup_host.sh
# 添加了 -e DB_HOST=$DB_HOST -e DB_PASSWORD=$DB_PASSWORD
docker run -e DB_HOST=$DB_HOST -e DB_PASSWORD=$DB_PASSWORD -e RAILS_MASTER_KEY=$RAILS_MASTER_KEY -d -p 3000:3000 --network=network1 --name=$container_name mangosteen:$version
  1. 执行上面解决 Missing secret_key_base for ‘production’ environment 的步骤2/3/4/5/6

  2. 宿主机执行 DB_HOST=db-for-mangosteen DB_PASSWORD=123456 RAILS_MASTER_KEY=xxxxxxxxxxxxxxx mangosteen_deploy/setup_host.sh(举一反三理解DB_HOST、DB_PASSWORD)

  3. 宿主机执行 docker exec -it mangosteen-prod-1 bin/rails db:create db:migrate 创建和迁移数据库(mangosteen-prod-1 也可以改成容器 id)

  4. 浏览器访问 http://localhost:3000/api/v1/items,页面出现 "resources":[],"pager":{"page":null,"per_page":100,"count":0}} 即访问接口成功了

为什么不用 curl http://localhost:3000/ -vcurl http://localhost:3000/api/v1/items -v
这里其实正常是可以 curl 出来的,就很奇怪我的出不来,一直卡在返回那里,尝试 curl 百度和本地的其它端口也是成功的,说明 curl 没问题,但是浏览器访问也是成功的,说明接口也没问题,so I don’t understand why …


谨慎操作:如何删除生产环境数据库

  1. 宿主机执行 docker exec -it mangosteen-prod-1 bash 进入容器内部

  2. 输入 DISABLE_DATABASE_ENVIRONMENT_CHECK=1 bin/rails db:drop


文章作者: April-cl
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 April-cl !
  目录