本地localhost多项目如何配置自定义域名访问Docker容器
完全可以实现,核心是用统一Apache反向代理做流量入口,配合本地域名解析,不需要给每个项目分配不同宿主机端口,就能实现和XAMPP虚拟主机完全一致的自定义域名访问效果。
1. 配置本地域名解析
把你需要的自定义域名全部指向本地IP:
- Windows系统:编辑
C:\Windows\System32\drivers\etc\hosts文件 - Mac/Linux系统:编辑
/etc/hosts文件
添加以下内容,后续新增项目直接追加对应域名即可:
127.0.0.1 project-a.test 127.0.0.1 project-b.test
2. 创建跨容器共享网络
所有项目容器和反向代理容器需要在同一个Docker网络下才能互相通信,执行以下命令创建共享网络:
docker network create vhost-net
3. 部署统一Apache反向代理(核心入口)
单独新建一个目录(比如命名为docker-proxy)存放代理配置,这个代理会统一监听宿主机80/443端口,根据访问域名转发请求到对应项目容器。
3.1 新建代理的docker-compose.yml
version: "3" services: proxy: image: httpd:2.4 container_name: docker-vhost-proxy ports: - "80:80" - "443:443" volumes: - ./httpd.conf:/usr/local/apache2/conf/httpd.conf - ./httpd-vhosts.conf:/usr/local/apache2/conf/extra/httpd-vhosts.conf restart: always networks: - vhost-net networks: vhost-net: external: true
3.2 生成并修改代理的httpd.conf
在docker-proxy目录下执行以下命令,从官方Apache镜像拷贝默认配置文件:
docker run --rm httpd:2.4 cat /usr/local/apache2/conf/httpd.conf > httpd.conf
打开生成的httpd.conf文件,找到以下4行配置,删除行首的#注释符,开启代理和虚拟主机功能:
#LoadModule proxy_module modules/mod_proxy.so #LoadModule proxy_http_module modules/mod_proxy_http.so #LoadModule vhost_alias_module modules/mod_vhost_alias.so #Include conf/extra/httpd-vhosts.conf
3.3 新建代理的虚拟主机配置httpd-vhosts.conf
在docker-proxy目录下新建httpd-vhosts.conf,配置域名转发规则,容器之间直接用容器名作为访问地址即可:
<VirtualHost *:80> ServerName project-a.test ProxyPass / http://simplephp56:80/ ProxyPassReverse / http://simplephp56:80/ </VirtualHost> <VirtualHost *:80> ServerName project-b.test # 替换为你项目B的web容器名,容器内部Apache默认监听80端口 ProxyPass / http://project-b-web:80/ ProxyPassReverse / http://project-b-web:80/ </VirtualHost>
后续新增项目只需要追加对应VirtualHost段即可。
3.4 启动代理服务
在docker-proxy目录下执行:
docker-compose up -d
4. 改造现有项目配置
以你的项目A为例,需要修改3个配置文件,不需要再映射80/443端口到宿主机,避免端口冲突。
4.1 修改docker-compose.yml
version: "3" services: web: container_name: simplephp56 build: context: . dockerfile: ${DOCKER_FILE} ports: # 仅保留你需要的非Web端口,删除80/443的端口映射 - "25:25" volumes: - "${WORKING_DIR}:/var/www/html" restart: always # 加入共享网络 networks: - vhost-net networks: vhost-net: external: true
4.2 修改.env文件
删除不再需要的端口配置:
DOCKER_FILE=Dockerfile56 WORKING_DIR=./code
4.3 修改Apache虚拟主机配置000-default.conf
注意容器内部Apache始终监听80端口,和宿主机映射端口无关,同时补充目录权限避免403错误:
<VirtualHost *:80> ServerAdmin webmaster@simplephp56.com ServerName project-a.test DocumentRoot /var/www/html <Directory /var/www/html> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
4.4 原有Dockerfile56不需要任何修改,直接复用即可
4.5 重启项目A容器
在项目A目录下执行:
docker-compose up -d --build
5. 访问验证
直接在浏览器访问http://project-a.test即可打开项目A,访问http://project-b.test即可打开项目B,不需要加任何端口号。
后续新增并行开发的项目,只需要3步:
- 在本地hosts文件追加新域名指向127.0.0.1
- 新项目的docker-compose.yml加入
vhost-net共享网络,不要映射80/443端口到宿主机,项目内部Apache虚拟主机配置对应自己的域名 - 在反向代理的
httpd-vhosts.conf中追加对应域名的转发规则,执行docker restart docker-vhost-proxy重启代理即可
你之前的配置无法实现域名访问主要是两个原因:
- 错误将Apache虚拟主机的监听端口设置为宿主机映射端口(8000),容器内部服务的监听端口和宿主机映射端口是独立的,该配置从未生效
- 没有统一的入口层做域名转发,即使本地域名解析到127.0.0.1,80端口也没有对应服务处理请求,自然无法访问
内容的提问来源于stack exchange,提问作者lnwMaN

