在 Mac 上用 hosts 文件进行 Docker 开发
为 Docker、docker-compose 和容器网络配置 hosts 文件。将服务映射到本地域名,简化 Mac 开发。
Sleezr Team

无需终端,管理 hosts 文件
Sleezr 让您在 Windows、macOS 和 Linux 上可视化管理环境,支持自动 DNS 刷新和备份。
一次性购买
目录
- 如何在 Docker 中使用 hosts 文件
- 理解 Docker 网络基础
- Docker Desktop 网络架构
- 容器间通信
- 为 Docker 服务设置自定义域名
- 基础 hosts 文件配置
- 多服务使用标准端口
- 子域名的通配符域名
- Docker Compose 多服务架构
- 微服务设置
- Docker 内服务发现
- 高级 Docker 网络模式
- 自定义 Docker 网络
- 外部网络
- Host 网络模式(仅 Linux)
- 端口管理策略
- 避免端口冲突
- 标准端口与反向代理
- Docker 与本地 HTTPS
- 为 Docker 服务生成 SSL 证书
- 在 Docker 中配置 HTTPS
- Traefik 自动 HTTPS
- 组织 Docker 的 hosts 文件条目
- 按项目组织
- 按环境组织
- Docker Compose 覆盖模式
- 开发覆盖
- 多个 Compose 文件
- Docker hosts 文件问题排查
- 自定义域名无法访问容器
- 端口已被占用
- DNS 解析问题
- 容器间通信失败
- Docker hosts 文件管理最佳实践
- 1. 使用一致的命名规范
- 2. 记录端口映射
- Local Development
- 3. 版本控制 hosts 文件模板
- 4. 使用环境特定域名
- 5. 自动化 hosts 文件更新
- 与开发工具集成
- 热重载与卷挂载
- 数据库访问
- 调试工具
- 结论
- 参考资料
Docker 通过提供隔离、可复现的环境革新了本地开发。然而,通过自定义域名访问容器需要协调 Docker 网络与 Mac 的 hosts 文件。本指南将展示如何将 hosts 文件管理与 Docker、docker-compose 和容器网络无缝集成。
如何在 Docker 中使用 hosts 文件
要在 Mac 上通过自定义域名访问 Docker 容器,请在 /etc/hosts 中将域名映射到 `127.0.0.1`,并发布容器端口(例如 `-p 8080:80`),因为 Docker Desktop 在 localhost 上暴露容器。在容器内部访问宿主机服务时,请使用 `host.docker.internal`,无需修改 hosts 文件。
理解 Docker 网络基础
在配置 hosts 文件之前,需了解 macOS 上 Docker 网络的工作原理。
Docker Desktop 网络架构
Mac 上的 Docker Desktop 在 Linux VM 内运行容器。使用 -p 或 docker-compose 中的 ports: 映射端口时,Docker 会在容器网络与 Mac 的 localhost 之间建立桥接。
services:
web:
image: nginx:alpine
ports:
- "8080:80" # Host:Container这意味着:
- Mac 的 8080 端口映射到容器的 80 端口
- 可通过
localhost:8080或127.0.0.1:8080访问 - 要使用自定义域名,需在 hosts 文件中添加指向 127.0.0.1 的条目
容器间通信
同一 Docker 网络内的容器可通过 docker-compose.yml 中定义的服务名通信,无需修改 hosts 文件:
services:
web:
image: nginx:alpine
depends_on:
- api
api:
image: node:18
expose:
- "3000"web 容器可通过 http://api:3000 访问 API,无需任何 hosts 文件配置。
为 Docker 服务设置自定义域名
基础 hosts 文件配置
最简单的方式是为每个 Docker 服务映射自定义域名:
# /etc/hosts
127.0.0.1 api.docker.test
127.0.0.1 frontend.docker.test
127.0.0.1 admin.docker.test在 docker-compose.yml 中:
version: '3.8'
services:
api:
image: node:18
ports:
- "3001:3000"
frontend:
image: nginx:alpine
ports:
- "3002:80"
admin:
image: nginx:alpine
ports:
- "3003:80"访问服务:
http://api.docker.test:3001http://frontend.docker.test:3002http://admin.docker.test:3003
多服务使用标准端口
若偏好标准端口(80、443),每个端口只能运行一个服务,使用不同域名:
# /etc/hosts
127.0.0.1 api.docker.test
127.0.0.1 frontend.docker.testservices:
api:
image: node:18
ports:
- "80:3000" # 通过 api.docker.test:80 访问
frontend:
image: nginx:alpine
ports:
- "8080:80" # frontend 使用不同端口子域名的通配符域名
对动态子域名的应用,使用 dnsmasq 配置通配符 DNS:
# Install dnsmasq
brew install dnsmasq
# Configure wildcard for .docker.test
echo "address=/.docker.test/127.0.0.1" >> /usr/local/etc/dnsmasq.conf
# Create resolver
sudo mkdir -p /etc/resolver
echo "nameserver 127.0.0.1" | sudo tee /etc/resolver/docker.test
# Start dnsmasq
sudo brew services start dnsmasq现在任何 *.docker.test 域名都会自动解析到 localhost!
Docker Compose 多服务架构
微服务设置
复杂多服务应用示例:
version: '3.8'
services:
# Backend API
api:
build: ./api
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://db:5432/myapp
depends_on:
- db
# Frontend Application
frontend:
build: ./frontend
ports:
- "3001:3000"
environment:
- API_URL=http://api:3000
# Admin Panel
admin:
build: ./admin
ports:
- "3002:3000"
# Database
db:
image: postgres:15
environment:
POSTGRES_DB: myapp
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
volumes:
- postgres_data:/var/lib/postgresql/data
# Redis Cache
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
postgres_data:hosts 文件配置:
# /etc/hosts
# Docker Services
127.0.0.1 api.docker.test
127.0.0.1 frontend.docker.test
127.0.0.1 admin.docker.testDocker 内服务发现
容器通过服务名互相发现。frontend 容器可调用 http://api:3000,因为 Docker 内部 DNS 将 api 解析为容器 IP。
从 Mac 外部访问时,使用 hosts 文件条目和映射端口。
高级 Docker 网络模式
自定义 Docker 网络
为不同环境创建隔离网络:
version: '3.8'
networks:
frontend_network:
driver: bridge
backend_network:
driver: bridge
services:
frontend:
image: nginx:alpine
networks:
- frontend_network
ports:
- "80:80"
api:
image: node:18
networks:
- backend_network
- frontend_network
ports:
- "3000:3000"api 服务可从两个网络访问,frontend 仅通过共享网络看到 API。
外部网络
将容器连接到现有网络:
services:
web:
image: nginx:alpine
networks:
- existing_network
networks:
existing_network:
external: trueHost 网络模式(仅 Linux)
在 Linux 上可使用 host 网络模式。macOS 不直接支持,但可通过端口映射达到类似效果。
端口管理策略
避免端口冲突
运行多个 Docker 项目时,端口冲突很常见。策略:
1. 使用不同端口范围
# Project A
services:
web:
ports:
- "8000:80"
# Project B
services:
web:
ports:
- "8001:80"2. 使用环境变量
services:
web:
ports:
- "\$\{WEB_PORT:-8080}:80"# .env file
WEB_PORT=90003. 动态端口分配
services:
web:
ports:
- "0:80" # Docker 分配随机端口查看分配的端口:docker ps 或 docker-compose ps
标准端口与反向代理
使用反向代理(Traefik、Nginx)按域名路由:
version: '3.8'
services:
traefik:
image: traefik:v2.10
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
api:
image: node:18
labels:
- "traefik.http.routers.api.rule=Host(`api.docker.test`)"
- "traefik.http.services.api.loadbalancer.server.port=3000"
frontend:
image: nginx:alpine
labels:
- "traefik.http.routers.frontend.rule=Host(`frontend.docker.test`)"配合 hosts 文件条目,所有服务可通过各自域名在 80 端口访问。
Docker 与本地 HTTPS
为 Docker 服务生成 SSL 证书
使用 mkcert 创建受信任证书:
# Install mkcert
brew install mkcert
mkcert -install
# Create certificate for Docker services
mkcert api.docker.test frontend.docker.test "*.docker.test"在 Docker 中配置 HTTPS
services:
nginx:
image: nginx:alpine
ports:
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./api.docker.test.pem:/etc/nginx/ssl/cert.pem
- ./api.docker.test-key.pem:/etc/nginx/ssl/key.pemTraefik 自动 HTTPS
Traefik 可自动处理 HTTPS:
services:
traefik:
image: traefik:v2.10
command:
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./certs:/certs组织 Docker 的 hosts 文件条目
按项目组织
按项目分组条目:
# ===================
# DOCKER PROJECT: E-commerce Platform
# ===================
127.0.0.1 shop.docker.test
127.0.0.1 api.shop.docker.test
127.0.0.1 admin.shop.docker.test
# ===================
# DOCKER PROJECT: Blog Platform
# ===================
127.0.0.1 blog.docker.test
127.0.0.1 cms.blog.docker.test按环境组织
按环境分离:
# ===================
# DOCKER: Development
# ===================
127.0.0.1 dev-api.docker.test
127.0.0.1 dev-frontend.docker.test
# ===================
# DOCKER: Staging
# ===================
127.0.0.1 staging-api.docker.test
127.0.0.1 staging-frontend.docker.testDocker Compose 覆盖模式
开发覆盖
使用 docker-compose.override.yml 做本地开发:
# docker-compose.yml (base)
version: '3.8'
services:
api:
image: node:18
ports:
- "3000:3000"
# docker-compose.override.yml (local, gitignored)
version: '3.8'
services:
api:
volumes:
- ./src:/app/src # Hot reload
environment:
- NODE_ENV=development多个 Compose 文件
# Development
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up
# Production-like
docker-compose -f docker-compose.yml -f docker-compose.prod.yml upDocker hosts 文件问题排查
自定义域名无法访问容器
问题:域名能解析但连接被拒绝。
解决:
docker ps 应显示 0.0.0.0:PORT->...docker-compose psping api.docker.test 应解析到 127.0.0.1端口已被占用
问题:Error: bind: address already in use
解决:
lsof -i :8080docker stop <container>DNS 解析问题
问题:域名无法解析。
解决:
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder容器间通信失败
问题:服务无法互相访问。
解决:
docker network inspect <network>depends_on 顺序Docker hosts 文件管理最佳实践
1. 使用一致的命名规范
# Good: Project-based naming
api.projectname.test
frontend.projectname.test
# Avoid: Generic names
api.test
web.test2. 记录端口映射
在 README 中包含端口文档:
## Local Development
- API: http://api.project.test:3000
- Frontend: http://frontend.project.test:8080
- Admin: http://admin.project.test:30013. 版本控制 hosts 文件模板
在项目中创建 hosts.example:
# hosts.example
127.0.0.1 api.project.test
127.0.0.1 frontend.project.test4. 使用环境特定域名
# Development
dev-api.project.test
# Staging
staging-api.project.test
# Local
local-api.project.test5. 自动化 hosts 文件更新
创建脚本将 docker-compose 服务与 hosts 文件同步:
#!/bin/bash
# sync-docker-hosts.sh
SERVICES=$(docker-compose config --services)
for service in $SERVICES; do
PORT=$(docker-compose config | grep -A 5 "$service:" | grep -oP 'd+:d+' | head -1 | cut -d: -f1)
echo "127.0.0.1 $service.docker.test" >> /tmp/docker-hosts
done与开发工具集成
热重载与卷挂载
services:
api:
build: ./api
volumes:
- ./api/src:/app/src # Hot reload
ports:
- "3000:3000"通过 api.docker.test:3000 访问,代码自动重载。
数据库访问
services:
db:
image: postgres:15
ports:
- "5432:5432" # Expose for external tools从 Mac 使用 localhost:5432 连接,或在 hosts 文件中添加 db.docker.test。
调试工具
services:
api:
image: node:18
ports:
- "3000:3000"
- "9229:9229" # Node.js debugger通过 api.docker.test:9229 附加调试器。
结论
有效管理 Docker 的 hosts 文件需要同时理解 Docker 网络和 macOS DNS 解析。遵循本指南中的模式,你可以:
- 将容器服务映射到易记的域名
- 避免多项目间的端口冲突
- 保持清晰、有序的 hosts 文件配置
- 简化 Docker 开发工作流
记得使用 .test 域名避免冲突、记录端口映射,并利用 Sleezr 等工具高效管理 hosts 条目。正确配置后,Docker 与 hosts 文件可无缝协作,打造高效的本地开发环境。
对使用 Docker 的团队,可考虑 Sleezr(€4.99)分享 hosts 配置、保持环境一致并消除手动编辑负担。Sleezr 可轻松导出、导入并在全团队同步 hosts 条目。
参考资料
常见问题
如何通过自定义域名访问 Docker 容器?
在 docker-compose.yml 中将容器端口映射到主机端口,然后在 hosts 文件中添加指向 127.0.0.1 的条目。使用 .test 域名避免冲突。
每个 Docker 容器都需要修改 hosts 文件吗?
仅当你需要自定义域名时。同一 Docker 网络内的容器可通过服务名互相访问,无需修改 hosts 文件。
Docker 网络如何与 hosts 文件交互?
hosts 文件只影响 Mac 的 DNS 解析。Docker 容器使用自己的内部 DNS 和网络。通过映射主机端口,可用 hosts 文件条目访问容器。
在 Mac 上 Docker 能用 .local 域名吗?
不推荐。.local 域名与 macOS Bonjour 冲突。改用 .test 或 .localhost 以获得更好性能和兼容性。
如何与团队分享 Docker hosts 文件配置?
导出 hosts 文件条目并纳入项目文档。Sleezr 等工具可轻松在团队成员间分享和同步 hosts 文件配置。
相关文章
在 Mac 上编辑 hosts 文件:Terminal vs GUI(2026)
如何在 macOS 上无误编辑 /etc/hosts?Terminal(sudo nano)与 GUI 对比。2 分钟内解决 permission denied 和 DNS 缓存问题。
Sleezr Team
Mac 刷新 DNS 缓存:命令与版本对照(2026)
复制可直接使用的 macOS 刷新 DNS 命令,适用于 Tahoe、Sequoia、Sonoma、Ventura 及旧版本。含验证步骤与浏览器缓存清理。
Sleezr Team
hosts 文件完全指南:原理、位置与用法(2026)
一份关于 hosts 文件的完整指南:它是什么、在 Windows/Mac/Linux 上的位置、语法、常见用途与故障排查。
Sleezr Team
如何刷新 DNS 缓存(Windows、Mac、Linux 与 Chrome)
在 Windows、Mac、Linux 和 Chrome 上刷新或清除 DNS 缓存的方法。复制适合你系统的命令,了解刷新 DNS 的作用以及是否安全。
Sleezr Team
SwitchHosts vs Sleezr:2026 hosts 管理器对比
对比 SwitchHosts 与 Sleezr 的桌面 hosts 文件管理:功能、界面、DNS 刷新、备份、协作与定价。
Sleezr Team