docker-compose使用

介绍

我们平时使用docker的时候,可以需要启动很多服务(容器),编写很多Dockerfile,例如 docker run mysql, docker run redis, docker run nginx等等。

服务少了还好,手动一个一个启动就是了。但是服务一旦多了,并且服务之前还有依赖(比如启动微服务前先得启动网关吧,启动网关前先得启动nacos,nacos配置又在mysql,得先启动mysql。),就比较麻烦了。

那么docker-compose就是为此而生的。它是用于定义和运行多容器Docker应用程序的工具。以一个ocker-compose.yml文件来配置所有的服务。

docker-compose里的两个概念:

1 服务(service):一个应用容器实例,比如一个nginx实例,一个mysql实例。

2 项目(project):由一组关联的应用容器组成的一个完整业务单元,在docker-compose.yml文件中定义。

不用compose例子

假设我们要启动容器mysql, redis, nacos, gateway.jar, biz.jar,需要依次执行

1 mysql容器

build mysql Dockerfile:

# 基础镜像
FROM mysql:5.7
# author
MAINTAINER tenny

# 执行sql脚本
ADD ./db/*.sql  /docker-entrypoint-initdb.d/

启动mysql

docker run --name mysql -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/logs:/logs -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7

2 redis容器

build redis Dockerfile:

# 基础镜像
FROM redis
# author
MAINTAINER tenny

# 挂载目录
VOLUME /home/redis
# 创建目录
RUN mkdir -p /home/redis
# 指定路径
WORKDIR /home/redis
# 复制conf文件到路径
COPY ./conf/redis.conf /home/redis/redis.conf

启动redis

docker run --name redis -p 6379:6379 -v /home/redis/conf/redis.conf:/home/redis/redis.conf -v /home/redis/data:/data -d redis:6.0.8 redis-server /home/redis/redis.conf

3 nacos容器

build nacos Dockerfile:

# 基础镜像
FROM nacos/nacos-server
# author
MAINTAINER tenny

# 复制conf文件到路径
COPY ./conf/application.properties /home/nacos/conf/application.properties

启动nacos

docker run --name nacos -p 8848:8848 -v /home/nacos/logs/:/home/nacos/logs -v /home/nacos/conf/application.properties:/home/nacos/conf/application.properties --env MODE=standalone -d nacos/nacos-server 

4 gateway容器

build gateway Dockerfile:

# 基础镜像
FROM  openjdk:8-jre
# author
MAINTAINER tenny

# 挂载目录
VOLUME /home/gateway
# 创建目录
RUN mkdir -p /home/gateway
# 指定路径
WORKDIR /home/gateway
# 复制jar文件到路径
COPY ./jar/gateway.jar /home/gateway/gateway.jar
# 启动网关服务
ENTRYPOINT ["java","-jar","-Dspring.profiles.active=stage","gateway.jar"]

启动gateway

docker run --name gateway -p 8080:8080 -v /home/gateway/jar:/home/gateway -d gateway

5 biz容器

build biz Dockerfile:

# 基础镜像
FROM  openjdk:8-jre
# author
MAINTAINER tenny

# 挂载目录
VOLUME /home/biz
# 创建目录
RUN mkdir -p /home/biz
# 指定路径
WORKDIR /home/biz
# 复制jar文件到路径
COPY ./biz/jar/microservice-biz.jar /home/biz/microservice-biz.jar
# 启动系统服务
ENTRYPOINT ["java","-jar","-Dspring.profiles.active=stage","microservice-biz.jar"]

启动biz

docker run --name microservice-biz -p 8081:8081 -v /home/microservice/biz/jar:/home/biz -d biz

问题提出

其实容器不多,就这样一个一个编排启动也没什么。不过这里有几个值得改进的地方:

1 我们得执行很多次docker run

2 容器启动顺序是有要求的,比如要先启动mysql 才能启动nacos,先启动redis nacos才能启动gateway,先启动mysql redis nacos才能启动biz等等

3 容器宕机重启可能会导致ip变化,那么在nacos里的相关配置(例如mysql和redis的ip)可能就得改,当然可以把ip写死,但这样做不方便移植

接下来使用compose改进这三点。

使用compose例子

1 安装docker-compose

下载

curl -SL https://github.com/docker/compose/releases/download/v2.14.2/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose

授权

chmod +x /usr/local/bin/docker-compose

测试

docker-compose --version

卸载:

rm /usr/local/bin/docker-compose

2 编写docker-compose.yml

创建文件夹DockerCompose, 编写docker-compose.yml文件:

version : '3.8'
services:
  compose-mysql:
    container_name: compose-mysql
    image: mysql:5.7
    build:
      context: ./mysql
    ports:
      - "3306:3306"
    volumes:
      - ./mysql/conf:/etc/mysql/conf.d
      - ./mysql/logs:/logs
      - ./mysql/data:/var/lib/mysql
    command: [
          'mysqld',
          '--innodb-buffer-pool-size=80M',
          '--character-set-server=utf8mb4',
          '--collation-server=utf8mb4_unicode_ci',
          '--default-time-zone=+8:00',
          '--lower-case-table-names=1'
        ]
    environment:
      MYSQL_DATABASE: 'test'
      MYSQL_ROOT_PASSWORD: 123456
    networks:
      - tenny-net
  compose-redis:
    container_name: compose-redis
    image: redis
    build:
      context: ./redis
    ports:
      - "6379:6379"
    volumes:
      - ./redis/conf/redis.conf:/home/redis/redis.conf
      - ./redis/data:/data
    command: redis-server /home/redis/redis.conf
  compose-nacos:
    container_name: compose-nacos
    image: nacos/nacos-server
    build:
      context: ./nacos
    environment:
      - MODE=standalone
    volumes:
      - ./nacos/logs/:/home/nacos/logs
      - ./nacos/conf/application.properties:/home/nacos/conf/application.properties
    ports:
      - "8848:8848"
    depends_on:
      - compose-mysql
    networks:
      - tenny-net
  compose-gateway:
    container_name: compose-gateway
    build:
      context: ./gateway
      dockerfile: dockerfile
    ports:
      - "8080:8080"
    volumes:
      - ./gateway/jar:/home/gateway
    depends_on:
      - compose-redis
    links:
      - compose-redis
    networks:
      - tenny-net
  compose-microservice-biz:
    container_name: compose-microservice-biz
    build:
      context: ./microservice/biz/
      dockerfile: dockerfile
    ports:
      - "8081:8081"
    volumes:
      - ./microservice/biz/jar:/home/biz
    depends_on:
      - compose-redis
      - compose-mysql
    links:
      - compose-redis
      - compose-mysql
    networks:
      - tenny-net
networks:
  tenny-net:
    name: tenny-net
    driver: bridge

配置项说明:

  • version:描述Compose文件的版本信息,当前最新版本为3.8,对应的Docker版本为19.03.0+,可以去官网查看 https://docs.docker.com/compose/compose-file/compose-file-v3/

    Compose文件版本.png

  • services:定义服务,可以多个,每个服务中定义了创建容器时所需的镜像、参数、依赖等

  • container_name: 容器名

  • image: 镜像名称标签,创建容器时所需的镜像名称标签或者镜像ID。如果镜像在本地不存在,会去远程拉取。

  • build: 构建容器, 基于指定的镜像或者基于Dockerfile文件构建。此例基于Dockerfile。

  • context: Dockerfile文件的绝对路径,或者相对路径(相对于docker-compose.yml文件所在目录),或者远程Git仓库的URL。

  • ports: 暴露端口。格式:左边宿主机端口:右边容器端口

  • volumes:数据卷,用于实现目录挂载

  • command:容器启动后默认执行命令

  • environment: 环境变量

  • networks: 所属网络。引用networks下的条目

  • depends_on: 容器依赖,启动时会先检查所依赖容器是否启动,若没有则先启动依赖容器,再启动本容器

  • links: 链接到其他容器中,这样通过容器名如compose-mysql就能访问到mysql容器。此例中不需要,因为已经设置同一网络。

  • networkds:定义网络,可以多个,根据DNS server让相同网络中的容器可以直接通过容器名称进行通信

DockerCompose目录结构

DockerCompose目录.png

DockerCompose目录详细1.png

DockerCompose目录详细2.png

3 修改业务ip配置

修改nacos地址为容器名

spring:
  config:
    activate:
      on-profile: stage
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: compose-nacos:8848
        namespace: 9373d87d-6bbc-4f5c-a6f6-f928f9623281
      config:
        # 配置中心地址
        server-addr: compose-nacos:8848
        namespace: 9373d87d-6bbc-4f5c-a6f6-f928f9623281

修改mysql redis的ip为相应容器名

spring:
  datasource:
    url: jdbc:mysql://compose-mysql:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
spring:
  redis:
    host: compose-redis

4 启动容器

到docker-compose.yml所在目录执行

docker-compose up -d

该命令会启动docker-compose.yml配置里的所有容器。

ps: 后续如果更新了业务代码,只需要上传jar包到指定目录,执行docker-compose restart compose-microservice-biz即可。

问题解决

这样,就解决了上面提到的三个改进问题:

1 只需执行一个命令就可以启动多个容器

2 容器之间依赖配置好后,不会再有启动顺序问题

3 容器之间通过容器名联系,不再固定ip。不用担心容器重启ip变换的问题,并且移植到另一台服务器也用修改ip。

常用命令

最后列出常用命令

pull 拉取镜像

docker-compose pull

只拉取某一个

docker-compose pull compose-mysql

up 启动容器

docker-compose up -d

只启动单个

docker-compose up compose-mysql -d

logs 查看日志

docker-compose logs

查看某一个容器日志并跟踪

docker-compose logs -f compose-gateway

exec 进入容器

docker-compose exec compose-redis bash

restart 重启容器

docker-compose restart

重启某一个

docker-compose restart compose-mysql

stop 停止容器

docker-compose stop

停止某一个

docker-compose stop compose-gateway

ps 列出容器

docker-compose ps

images 查看镜像

docker-compose images

rm 删除(停止状态)容器

docker-compose rm

down 停止并删除

docker-compose down

总结

首先提出多个docker容器的启停的重复性和可能存在的顺序问题,引出docker-compose。

然后举例说明单独启动多个docker容器的不便之处,再使用docker-compose改进这些问题,统一管理,一键部署,一键停止。

感谢阅读。

posted @ 2023-01-08 15:38  淘气小饼干  阅读(588)  评论(1编辑  收藏  举报