在Docker上运行Rails时,URL会生成错误的主机和端口

我有一些与Docker Compose粘合在一起的服务。 主要的服务是在自己的容器中的Rails应用程序。 它位于一个Nginx代理的后面,也在它自己的容器中。 (其他服务也在Nginx之后,但这不重要。)

docker-compose.yml ,我将名称web分配给了Rails服务。 因此, web是Dockernetworking中的容器的主机名。 Rails容器公开端口3000.所以我的Nginx反向代理configuration看起来像这样:

 location / { proxy_pass http://web:3000; } 

除了一个问题,这个工作很好。 从Rails应用程序的angular度来看,所有的请求都是web:3000 。 因为Rails根据请求的主机名和端口生成内部URL,所以在响应中我最终得到了web:3000 URL。

例如,如果我把它放在一个模板中:

 <%= link_to 'Admin', admin_url %> 

我得到这在呈现的HTML:

 <a href="http://web:3000/admin">Admin</a> 

我明白为什么会发生这种情况,但我不确定解决问题的最佳做法。 如果我可以避免的话,我宁愿不把一个端口和主机名硬编码到Rails代码中。

这似乎是一个普遍的问题与Docker和Rails,所以我猜别人遇到了它。 想法?

编辑。 我解决了部分问题,让Nginx把原来的主机名传递给Rails,像这样:

 location / { proxy_set_header Host $host; proxy_pass http://web:3000; } 

但是,Rails仍然没有看到外部端口或协议( http vs https )。

编辑2.根据评论的要求,这里是docker-compose.yml

 version: "3.2" services: proxy: image: nginx ports: # For flexibility, I'd like to be able to set whatever host-side # port I want. Eg 5000:80. - 80:80 - 443:443 volumes: - ssl-certs:/ssl-certs - ssl-webroot:/ssl-webroot - type: bind source: ./nginx.conf target: /etc/nginx/nginx.conf read_only: true certbot: image: certbot/certbot command: --version volumes: - ssl-certs:/etc/letsencrypt - ssl-webroot:/ssl-webroot web: build: ./rails volumes: - gems:/gems environment: - GEM_HOME=/gems - MYSQL_DOCKER_HOST - MYSQL_USER=root - MYSQL_PASSWORD - MYSQL_DEVELOPMENT_DB=myapp_dev - MYSQL_TEST_DB=myapp_test volumes: gems: ssl-certs: ssl-webroot: