简介

在实际的开发环境或者生产环境,容器往往都不是独立运行的,经常需要多个容器一起运行,此时,如果继续使用 run 命令启动容器,就会非常不便,在这种情况下,docker-compose 是一个不错的选择,使用 docker-compose 可以实现简单的容器编排,本文就来看看 docker-compose 的使用。

前面没有介绍到两个重要的知识点,我这里简单介绍一下:

  • 数据卷

    • 数据卷可以绕过拷贝系统,在多个容器之间、容器和宿主机之间共享目录或者文件,数据卷绕过了拷贝系统,可以达到本地磁盘 I/O 性能。
    docker run -itd --name nginx -v /Users/sang/blog/docker/docker/:/usr/share/nginx/html/ -p 80:80 bc26f1ed35cf
    
  • 网络

    • docker容器是相互隔离的,但是在使用中需要访问另一个容器的服务需要通过虚拟网络进行连接,如:

    有两个容器,一个 nginx 容器,另一个 ubuntu ,我启动 nginx 容器,但是并不分配端口映射,然后再启动 ubuntu ,通过容器连接,在 ubuntu 中访问 nginx

一般情况下,如果需要部署多个容器,我们都是通过docker-compose进行单机容器编排,分布式是使用k8s进行部署的,所以,作为开发人员,前面介绍的这些docker内容已经可以满足我们日常开发的使用了。

docker-compose安装

  • windows/mac

    • 安装docker for desktop 会安装好docker-compose的
  • linux

    curl -L https://github.com/docker/compose/releases/download/1.8.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
    chmod +x /usr/local/bin/docker-compose
    docker-compose -v
    

编写示例

version: "3"
services:
  nginx:
    # docker镜像,先拉取本地,再拉取云端
    image: nginx:${NGINX_VERSION}
    # 容器名称
    container_name: web
    # 端口映射
    ports:
      - "${NGINX_HTTP_HOST_PORT}:80"
    # 数据挂载 宿主机:docker 此处可以写相对路径
    volumes:
      - ${SOURCE_DIR}:/var/www/html/:rw
    # 重启策略
    # no是默认的重启策略,在任何情况下都不会重启容器。 
    # 指定为always时,容器总是重新启动。 
    restart: always
    # 注意:如果服务之间是在同个networks之下的话就可以通过 服务名:port 来访问链接
    networks:
      - default

  php72:
    # build用context指定的dockerfile创建
    build:
      context: .
      # 传入dockerfile里面的参数,注意与context同级,在dockerfile里面通过ARG接收
      args:
      - PHP_VERSION: ${PHP72_VERSION}
    # 指定容器名称
    container_name: php72
    # 链接到另一个服务中的容器 SERVICE:ALIAS
    # 在当前的web服务的容器中可以通过链接的db服务的别名database访问db容器中的数据库应用
    # 如果没有指定别名,则可直接使用服务名访问。
    links:
      - db:database

    # 链接到docker-compose.yml 外部的容器
    external_links:
      - redis_1
      - project_db_1:mysql
      - project_db_1:postgresq

    # 使用该参数,container内的root拥有真正的root权限。
    # 否则,container内的root只是外部的一个普通用户权限。
    privileged: true
    # 容器名称
    container_name: php72
    # 启动时必须等mysql服务启动好
    depends_on:
      - mysql
    cap_add:
      - SYS_PTRACE
    networks:
      - default


  mysql:
    image: mysql:${MYSQL_VERSION}
    ports:
      - "${MYSQL_HOST_PORT}:3306"
    volumes:
      - ${MYSQL_CONF_FILE}:/etc/mysql/conf.d/mysql.cnf:ro
      - ${MYSQL_DATA_DIR}:/var/lib/mysql/:rw
    restart: always
    networks:
      - default
    #  环境变量传入dockerfile里面的变量
    # 与args不同environment定义的变量在容器内部也可以反问
    environment:
      MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD}"

  redis:
    image: redis:${REDIS_VERSION}
    ports:
      - "${REDIS_HOST_PORT}:6379"
    volumes:
      - ${REDIS_CONF_FILE}:/etc/redis.conf:ro
    restart: always
    entrypoint: ["redis-server", "/etc/redis.conf"]
    networks:
      - default

# 指定其为同个docker网络
# docker network ls来查看
# 同一网络下,可以通过服务名来互联
networks:
  default:
  • 变量来自同目录下的.env文件
  • php通过同级目录的dockerfile来构建
  • 镜像改了之后要通过docker-compose build --no-cache 来重新构建一下

常用命令

  • ps:列出所有运行容器
docker-compose ps
  • logs:查看服务日志输出
docker-compose logs
  • port:打印绑定的公共端口,下面命令可以输出 eureka 服务 8761 端口所绑定的公共端口
docker-compose port eureka 8761
  • build:构建或者重新构建服务
docker-compose build
  • start:启动指定服务已存在的容器
docker-compose start eureka
  • stop:停止已运行的服务的容器
docker-compose stop eureka
  • rm:删除指定服务的容器
docker-compose rm eureka
  • up:构建、启动容器
docker-compose up
  • kill:通过发送 SIGKILL 信号来停止指定服务的容器
docker-compose kill eureka
  • pull:下载服务镜像
  • scale:设置指定服务运气容器的个数,以 service=num 形式指定
docker-compose scale user=3 movie=3
  • run:在一个服务上执行一个命令
docker-compose run 容器名 bash
  1. 通过docker-compose编排的的容器是没有容器自己的ip,因为他们共用一个或多个network,可以通过docker network ls来查看,可以通过服务名来链接网络,docker network inspect <container id>可以查看对应网络的配置。
  2. 通过docker-compose build的dockerfile一定要有CMD [ "/bin/bash" ]等执行命令,才能通过docker-compose up起来

来源:

  1. docker-compose