在Docker中使用/ etc / hosts

时间:2019-03-30 21:57:34

标签: apache docker containers

在我的Mac上,我将vagrant与Ubuntu和apache一起运行,并且在我的apache的各种代码存储库中都有虚拟主机条目。在OSX方面,我为每个虚拟主机条目创建/ etc / hosts条目。

我正在尝试使用docker达到相同的效果,但是我正在努力找出它,而不必在访问应用程序时指定端口号,而我不想这样做。例如:我的/ etc / hosts中有127.0.0.1 dockertest.com,然后可以在http://dockertest.com:8080进行访问。我希望不指定端口就可以直接转到http://dockertest.com。我该如何实现?我知道端口号不能在/ etc / hosts文件中使用,所以我正在寻找一种方法来模拟可能的效果。我需要能够同时运行多个docker应用程序,因为某些代码库相互通信,并且每个代码库都需要具有自己唯一的主机名,因此我不认为只需在端口中将端口设置为80:80 docker-compose文件将起作用,因为每个应用都将(尝试)在127.0.0.1:80上运行。

对于上下文,我遵循this tutorial在docker上运行apache,php和mysql。我的所有文件都与该站点上显示的完全相同。

更新

以下502 Bad Gateway文件出现docker-compose.yml nginx错误。

version: "3.3"
services:
  php:
    build: './php/'
    networks:
      - backend
    volumes:
      - ./public_html/:/var/www/html/
  apache:
    build: './apache/'
    depends_on:
      - php
      - mysql
    networks:
      - frontend
      - backend
    volumes:
      - ./public_html/:/var/www/html/
    environment:
      - VIRTUAL_PORT=3000
      - VIRTUAL_HOST=dockertest.com
  mysql:
    image: mysql:5.6.40
    networks:
      - backend
    environment:
      - MYSQL_ROOT_PASSWORD=rootpassword
  nginx-proxy:
    image: jwilder/nginx-proxy
    ports:
      - 80:80
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
networks:
  frontend:
  backend:

更新2

解决了“ 502 Bad Gateway”错误,这是更新的docker-compose.yml文件。我必须将nginx-proxy添加到我引用的网络之一。我的问题尚未完全解决,但我确实有一部分可以解决。对于阅读本文以寻求解决方案的任何人,我创建了另一个问题here,以防止这个问题变得太长。

version: "3.3"
services:
  php:
    build: './php/'
    networks:
      - backend
    volumes:
      - ./public_html/:/var/www/html/
  apache:
    build: './apache/'
    depends_on:
      - php
      - mysql
    networks:
      - frontend
      - backend
    volumes:
      - ./public_html/:/var/www/html/
    environment:
      - VIRTUAL_HOST=dockertest.com
  mysql:
    image: mysql:5.6.40
    networks:
      - backend
    environment:
      - MYSQL_ROOT_PASSWORD=rootpassword
  nginx-proxy:
    image: jwilder/nginx-proxy
    networks:
      - backend
    ports:
      - 80:80
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
networks:
  frontend:
  backend:

3 个答案:

答案 0 :(得分:1)

您可以使用jwilder/nginx-proxy,它是由其他容器的环境变量自动配置的反向代理,因此您无需手动编写nginx代理配置。同样根据要求,它允许使用特定端口将请求转发到。

# docker-compose.yml

version: '3.3'

services:

  lamp:
    environment:
      VIRTUAL_HOST: some_domain.dev
      VIRTUAL_PORT: 9999
    image: my_lamp_image

  app:
    environment:
      VIRTUAL_HOST: another_domain.dev
      VIRTUAL_PORT: 3000
    image: my_app_image

  nginx-proxy:
    image: jwilder/nginx-proxy
    ports:
      - 80:80
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
# /etc/hosts

127.0.0.1 some_domain.dev
127.0.0.1 another_domain.dev

jwilder/nginx-proxy具有ssl,uwsgi,fastcgi等许多更好的功能,也可以在生产中使用。也有“ {伴侣””添加项,例如let's encrypt sslman in the middle proxy

答案 1 :(得分:0)

看起来您的apache服务器运行在容器内的端口80上。如果您想在您的/ etc / hosts条目中使用dockertest.com在外部,那么您也必须在外部使用端口80。

  1. 为dockertest.com域创建/etc/hosts条目
  2. 如果您使用docker,请使用-p 80:80运行它,或者如果您使用docker-compose
ports:
  - "80:80"

答案 2 :(得分:0)

一种可能性是将所有应用程序设置在各自的容器中,然后通过docker network进行连接。

为了访问所有容器,我建议将nginx Web服务器容器作为反向代理添加到网络中,然后可以将其绑定到计算机的端口80。

然后您可以为每个应用分别定义location或定义一个通用位置,如

# sample.conf
server {
  listen 80 default_server;
  server_name ~ (?<docker_host_name>.+);
  location ~ {
    # for actual request forwarding
    proxy_pass                         http://$docker_host_name$1$is_args$args;
    # some stuff I figured out I have to use in order for service to work properly
    proxy_set_header                   Upgrade $http_upgrade;
    proxy_set_header                   Connection 'upgrade';
    proxy_http_version                 1.1;
    proxy_cache_bypass                 $http_upgrade;
    proxy_set_header Host              $host;
    proxy_set_header X-Real-IP         $remote_addr;
    proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }
}

此配置必须内联放置在原始/etc/nginx/nginx.conf中,或者放置在http配置块内的单独文件中。

重启nginx服务或容器后(取决于容器设置),您应该能够访问docker网络内部的所有服务,并且所有服务都应该能够相互通信而不会出现问题。

当然,您仍然必须将条目保留在hosts文件中,因此您的计算机知道它必须在本地处理请求。

编辑:

原始配置(可能)没有执行应做的工作。 因此,我想出了一个新版本,应该可以完成工作:

# sample.conf
server {
  listen 80 default_server;
  location ~ {
    # for actual request forwarding
    proxy_pass                         http://$host$1$is_args$args;
    # some stuff I figured out I have to use in order for service to work properly
    proxy_set_header                   Upgrade $http_upgrade;
    proxy_set_header                   Connection 'upgrade';
    proxy_http_version                 1.1;
    proxy_cache_bypass                 $http_upgrade;
    proxy_set_header Host              $host;
    proxy_set_header X-Real-IP         $remote_addr;
    proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }
}

使用此配置,nginx服务器将监听端口80上的所有传入请求,并将它们转发到网络内部的适当容器。 您也不必自己配置主机解析度,因为docker容器名称还代表容器的主机(名称)。

希望这对您有用。