nginx、git、ssl 环境都搭建好后,重头戏 docker 部分开始了。
Alibaba Cloud Linux 是基于 CentOS 的,所以可以使用阿里云自己的 CentOS docker 仓库来安装
yum update -y yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum install docker-ce -y
验证 docker 是否安装成功
查看 docker 版本
docker version
查看 docker 详情
docker info
出现以上截图说明安装成功,此时已默认安装 docker compose 工具,无需再单独安装 docker-compose 软件。
鉴于国内网络问题,后续拉取 Docker 镜像十分缓慢,可以使用阿里云的免费镜像加速器
获取到加速器地址后,按提示修改 docker 配置
vim /etc/docker/daemon.json { "registry-mirrors": ["{your_address}"] }
如果将个人镜像托管在阿里云的容器镜像服务上,需要配置 docker 客户端的登录授权信息,
vim /etc/docker/config.json {"auths":{"registry.cn-hangzhou.aliyuncs.com":{"auth":"{auth_string}"}},"stackOrchestrator":"swarm"}
auth_string 是阿里云容器镜像服务里设置的登录用户名和密码的组合字符串的base64结果,例如 base64(张三:123456)
设置开机自启动Docker,立即启动Docker
systemctl enable docker systemctl start docker
以上基础环境搭建完毕后,需要实现下图的架构
在 nginx 的安装目录中创建如下目录结构
-/usr/share/nginx/www -- . -- .. ---- docker(架构核心配置) ------ logs(所有项目的日志,映射到容器里) -------- mysql(mysql 全局日志) -------- redis(redis 全局日志) -------- project-1(项目1日志) ---------- nginx (项目1 的 nginx 日志) ---------- php (项目1 的 php 日志) ------ prod(生产环境的配置,配置文件存储在宿主机上,会映射到容器里,通过修改宿主机文件,直接在容器中生效) -------- mysql(mysql 容器的配置) -------- nginx(容器 nginx 配置,各容器项目使用单独的配置文件) -------- php(容器 php 配置,各容器项目使用对应版本的配置文件) -------- redis(容器 redis 配置) -------- docker-compose.yaml (docker-compose 配置文件) ---- project-1(项目1,如 blog 等) ------ web(web代码) ------ api(接口代码)
一份示例的 docker-compose 文件如下:
version: "3" services: mysql: image: mysql:5.7 # 可以修改为自己托管的镜像 privileged: true container_name: mysql restart: always ports: - "3306:3306" # 将宿主机的 3306 端口映射到容器内的 3306 端口,实现直接访问宿主机 volumes: - ./mysql/mysql.cnf:/etc/mysql/conf.d/mysql.cnf:rw # 挂载到宿主机的配置文件 - /data/mysql/:/var/lib/mysql/:rw # 挂载到宿主机的数据文件 - ../logs/mysql/:/var/log/mysql/:rw # 挂载到宿主机的日志文件 environment: MYSQL_ROOT_PASSWORD: "" # 容器内mysql的root密码 TZ: "Asia/Shanghai" networks: - default #各容器所在网络名称 redis: image: redis:6.2.6 privileged: true container_name: redis restart: always ports: - "6379:6379" volumes: - ./redis/redis.conf:/etc/redis.conf:rw - /data/redis/:/data/:rw - ../logs/redis/:/var/log/redis/:rw entrypoint: ["redis-server", "/etc/redis.conf"] environment: TZ: "Asia/Shanghai" networks: - default blog: # 具体的项目 image: nginx-php-fpm:8.1 privileged: true container_name: blog restart: always ports: - "8081:80" # 将宿主机的 8081端口映射到容器内的 80 端口,宿主机的 8081 端口,由宿主机上的 nginx 做代理转发,参考《在阿里云服务器ECS上搭建SSL+Git+Docker环境(二)》 volumes: - ./php/8.1/php.ini:/etc/php/8.1/fpm/php.ini:rw # 自定义的 php 配置 - ./php/8.1/ # 自定义的 php 配置 - ../../blog/:/usr/share/nginx/html/:rw # 项目代码挂载 - ./nginx/conf.d/blog/:/etc/nginx/conf.d/:rw # 项目的nginx配置 - ../logs/blog/nginx/:/var/log/nginx/:rw # 项目的nginx日志 - ../logs/blog/php/:/var/log/php/:rw # 项目的php日志 networks: - default networks: default:
进入 docker-compose.yaml 文件所在目录,执行如下命令,创建并启动所有容器
docker compose up -d
参数说明:
up:默认启动 docker-compose.yaml 的 yaml 文件
-d 后台运行
-f 指定 yaml 文件(例如:-f docker-compose-xxx.yaml)
查看容器启动情况
docker ps
这里可以看到 docker-compose.yaml 文件中配置的容器都正常启动,显示了宿主机和容器的端口映射情况。
需要注意的是,容器中的运行程序的用户和组,如mysql、redis的用户及组,需要在宿主机中存在相同的uid和gid,否则会存在宿主机与容器用户、组权限不一致,导致容器无法访问宿主机文件的问题。在了解了容器中用户及组的id后,可以手动在宿主机中添加对应的用户和组。
这些容器被 docker 管理在同一个局域网内,可以查看整个 docker 网络情况
docker network ls
其中 name 为 prod_default 的就是 docker-compose.yaml 文件中配置的 default 网络名称(默认网络名称是 docker-compose.yaml 文件所在目录名+自定义网络名称)
查看网络中的容器情况
docker network inspect prod_default [ { "Name": "prod_default", "Id": "xxx", "Created": "2024-09-13T22:06:48.692997797+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "172.18.0.0/16", "Gateway": "172.18.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "xx": { "Name": "redis", "EndpointID": "xx", "MacAddress": "02:42:ac:12:00:02", "IPv4Address": "172.18.0.2/16", "IPv6Address": "" }, "xx": { "Name": "mysql", "EndpointID": "xx", "MacAddress": "02:42:ac:12:00:05", "IPv4Address": "172.18.0.5/16", "IPv6Address": "" }, "xx": { "Name": "blog", "EndpointID": "xx", "MacAddress": "02:42:ac:12:00:03", "IPv4Address": "172.18.0.3/16", "IPv6Address": "" } }, "Options": {}, "Labels": { "com.docker.compose.network": "default", "com.docker.compose.project": "prod", "com.docker.compose.version": "2.27.0" } } ]
容器间的网络通信,可以直接使用 docker 网络中的 ip地址,也可以直接使用容器名称,比如 PHP 访问 MySQL,在 PHP 项目配置文件 .env 中配置如下
DB_HOST=mysql # 使用容器名或 docker 网络中容器的ip DB_PORT=3306 DB_DATABASE=blog DB_USERNAME=xxx DB_PASSWORD=xxx