如何用Docker Compose实现容器互联及在Windows 10中整合多容器至Ubuntu容器
问题一:Ubuntu系统中运行Docker Compose并让服务容器彼此互联
首先,咱们得先确保Docker和Docker Compose已经安装到位:
安装Docker
在Ubuntu终端执行以下命令:# 更新软件包索引 sudo apt update # 安装依赖包 sudo apt install -y apt-transport-https ca-certificates curl software-properties-common # 添加Docker官方GPG密钥 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg # 添加Docker软件源 echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # 安装Docker Engine sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io # 验证安装 sudo docker run hello-world安装Docker Compose
可以通过apt直接安装(版本可能不是最新),或者用curl下载最新版本:# 方式一:apt安装 sudo apt install -y docker-compose # 方式二:下载最新稳定版(替换v2.20.2为当前最新版本号) sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose # 验证安装 docker-compose --version编写docker-compose.yml实现服务互联
Docker Compose默认会为你的项目创建一个专属的桥接网络,同一compose文件中的所有服务都会加入这个网络,并且可以直接通过服务名称作为主机名互相访问。举个简单的例子,比如定义一个web服务和一个db服务:
version: '3.8' services: web: image: nginx:alpine ports: - "80:80" db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: example运行并验证互联
在docker-compose.yml所在目录执行:# 后台启动服务 docker-compose up -d # 进入web容器,ping db服务 docker-compose exec web ping db你会发现ping能成功,说明两个容器已经互联了。
问题二:Windows 10下用Docker Compose整合多服务容器(附单容器方案提醒)
首先得纠正一个常见的误解:Docker的最佳实践是一个容器只运行一个进程,把nginx、php-fpm、mysql等都塞进一个Ubuntu 16.04容器里会导致容器臃肿、难以维护、日志混乱等问题。更合理的做法是用Docker Compose分别定义每个服务容器,让它们通过默认网络互联。
推荐方案:多容器协同(符合Docker最佳实践)
下面是一个整合nginx、php-fpm、mysql、nodejs、composer的docker-compose.yml示例:
version: '3.8' services: nginx: image: nginx:1.20-alpine ports: - "80:80" volumes: - ./nginx/conf.d:/etc/nginx/conf.d - ./www:/var/www/html depends_on: - php-fpm php-fpm: image: php:7.4-fpm-alpine volumes: - ./www:/var/www/html depends_on: - mysql mysql: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: your_root_password MYSQL_DATABASE: your_db_name MYSQL_USER: your_db_user MYSQL_PASSWORD: your_db_password volumes: - mysql_data:/var/lib/mysql nodejs: image: node:16-alpine volumes: - ./node_app:/app working_dir: /app command: ["npm", "run", "start"] composer: image: composer:latest volumes: - ./www:/app working_dir: /app command: ["install"] volumes: mysql_data:
使用说明:
- 在Windows 10的Docker for Windows中,确保已经启用了WSL 2后端(性能更好)。
- 创建对应的目录(比如nginx/conf.d、www、node_app),并配置nginx的反向代理指向php-fpm服务(nginx配置里用
php-fpm:9000作为地址)。 - 执行
docker-compose up -d启动所有服务,各个服务之间可以通过服务名互相访问(比如php-fpm容器里可以用mysql作为主机名连接数据库)。
如果你坚持要将所有服务塞进一个Ubuntu 16.04容器(不推荐)
这种情况下需要自定义Docker镜像,编写Dockerfile来安装所有需要的软件:
- 创建Dockerfile:
FROM ubuntu:16.04 # 更新源并安装依赖 RUN apt update && apt install -y nginx php-fpm mysql-server nodejs npm composer # 配置各个服务的启动脚本(需要处理多进程启动,比如用supervisor) RUN apt install -y supervisor COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf # 暴露端口 EXPOSE 80 3306 3000 # 启动supervisor管理所有进程 CMD ["/usr/bin/supervisord"]
- 编写supervisord.conf配置文件,管理各个服务的进程:
[supervisord] nodaemon=true [program:nginx] command=/usr/sbin/nginx -g "daemon off;" autostart=true autorestart=true [program:php-fpm] command=/usr/sbin/php-fpm7.0 -F autostart=true autorestart=true [program:mysql] command=/usr/sbin/mysqld_safe autostart=true autorestart=true [program:nodejs] command=npm run start directory=/app autostart=true autorestart=true
- 然后在docker-compose.yml中使用这个自定义镜像:
version: '3.8' services: ubuntu-all-in-one: build: . ports: - "80:80" - "3306:3306" - "3000:3000" volumes: - ./www:/var/www/html - ./node_app:/app - mysql_data:/var/lib/mysql volumes: mysql_data:
但再次提醒:这种单容器方案违反Docker设计原则,后续维护(比如升级某个服务、排查问题)会非常麻烦,强烈建议使用多容器协同方案。
内容的提问来源于stack exchange,提问作者Kalen Nguyen




