在Docker

时间:2017-09-15 18:57:38

标签: ruby-on-rails docker

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

docker-compose.yml中,我已将名称web分配给Rails服务。因此,web是Docker网络中容器的主机名。 Rails容器公开了端口3000.所以我的Nginx反向代理配置如下所示:

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

除了一个问题外,这很有效。从Rails应用程序的角度来看,所有请求都是web:3000。由于Rails会根据请求的主机名和端口生成内部网址,因此我最终会在回复中找到web:3000的网址。

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

<%= 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. E.g. 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:

0 个答案:

没有答案