在阿里云服务器ECS上搭建SSL+Git+Docker环境(四)

服务器   2024-09-26 11:17   392   0  

nginx、git、ssl 环境都搭建好后,重头戏 docker 部分开始了。

一、安装 docker 并修改配置

1、安装 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 软件。

2、镜像加速

鉴于国内网络问题,后续拉取 Docker 镜像十分缓慢,可以使用阿里云的免费镜像加速器

获取到加速器地址后,按提示修改 docker 配置

vim /etc/docker/daemon.json
{
    "registry-mirrors": ["{your_address}"]
}

 

3、授权管理

如果将个人镜像托管在阿里云的容器镜像服务上,需要配置 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


二、搭建基于 docker 容器的项目架构

1、总体架构图

以上基础环境搭建完毕后,需要实现下图的架构

6328_g4nd_3948.png

2、架构目录

在 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(接口代码)


3、配置 docker-compose

一份示例的 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:


4、创建并启动容器

进入 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后,可以手动在宿主机中添加对应的用户和组。


5、容器网络访问

这些容器被 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