我目前正在切换到 docker 部署方案。nginx 是原来就已经安装在服务器的主机环境中,通过将 docker 容器中的 puma 的端口暴露在主机中,可以实现 Rails 程序跑起来。但是静态文件这部分,public/目录怎么让 nginx 能访问到呢?
我看到 homeland 是由于就一个 Rails 应用,它是直接在 Rails 应用的容器中安装了 nginx,这样就可以直接访问到同一个容器中的文件。但是我这个服务器,由于有多个网站在运行,我后续打算将每一个 Rails 应用都采用 docker 容器来运行,它们共用一个 nginx 服务(后面有可能采主机的 nginx 或者是 docker 容器的 nginx 服务)。
所以 nginx 怎么样可以访问每个容器中 Rails 应用的 public 目录呢,以便配置/assets
等静态资源 url?
我在 docker-compose.yml 中配置了:
volumes:
- ./data/public:/home/app/ntwebsite/public
docker-compose run app
后,然后发现主机中这个 data/public 目录是空的了。然后我在主机的 data/public 创建一个文件,通过 docker exec 进入到 container 中的 public 目录查看,发现有刚才创建的文件,public 目录中本来存在的文件都没有了。
是有这个问题,挂载时的内容会以宿主机为准,若挂载时宿主机的/data/public 是空的,那么/home/app/ntwebsite/public 也是空的。之后在容器中从新编译静态文件到 public 目录,就能在宿主机看到文件了
之后在容器中从新编译静态文件到 public 目录,就能在宿主机看到文件了
这样太麻烦了啊。有其它办法吗?
怎么样让这个关系反过来呢?我挂载时宿主机故意不存在/data/public 这个目录都解决不了问题。
你的意思是在 Rails 应用开启服务静态文件的功能,
# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
config.public_file_server.enabled = true
然后通过配置你提示的这个Reverse Proxy with Caching
来曲线解决问题?
考虑到在一个容器版本里, public
内容不会变的情况下,比较 tricky 的实现思路我想到两种:
在启动容器的时候调用 docker cp
指令将 public
复制到宿主机中。
docker-compose.yml
使用 volumes:
,利用 docker 创建空的 named volume
时会自动复制对应 path 文件到宿主机 volume 的特性,通过 /var/lib/docker/volumes/{volume名称}/_data
访问 volume 数据。但是这要求更新镜像版本时删除这个 volume。
总的来说,比如 docker-compose
就没有原生对 pre script
的支持,坑多不好用就是了。