资讯专栏INFORMATION COLUMN

不正宗 docker 入门教程-使用 docker-compose (3/3)

MorePainMoreGain / 1770人阅读

摘要:看看它里面的镜像是怎么写的还是很有收获的相关不正宗入门教程启动一个容器不正宗入门教程构建一个镜像不正宗入门教程使用博客原文

本章通过一个具体的demo来了解 docker-compose
docker-compose 是做什么的

在构建一个完整的服务时,我们通常启动一个容器, 一旦出现多个容器需要同时启动的时候手打是下下之策, 因为时间一长难免会忘记细节,写脚本也不是不可以,但是大家没有达成共识时脚本也很难维护...

docker-compose 就是来解决这个痛点, 只需要按照统一的格式书写,那么大家生成的容器也都是一致的, 在团队开发的时候扔一个配置好的 docker-compose 能节省很多时间和口水

配置 docker-compose

这是我构建的一个开发环境的容器:dnmp

首先下载下来

git clone https://github.com/gaopengfei123123/dnmp.git && cd dnmp

我们第一件事就是先瞄一眼 .env 文件, 这里设置了很多常量,一会根据个人需求来调整

第二步才是打开 docker-compose.yml 文件, 看后缀都能猜到这是一个配置文件, 另外 docker-compose.yml 是根据缩进来进行分层的,注意书写格式

# docker-compose.yml
# 语法版本( 3 和 2 区别有点大, 比如 3 取消了 volume_from 的相关语法)
version: "3"

networks:
  frontend:
    driver: ${NETWORKS_DRIVER}
  backend:
    driver: ${NETWORKS_DRIVER}


volumes:
  mysql_volume:
    driver: ${VOLUMES_DRIVER}
  redis_volume:
    driver: ${VOLUMES_DRIVER}
  rabbitmq_volume:
    driver: ${VOLUMES_DRIVER}
# 服务编排
services:
  # workspace:
  #   image: tianon/true
  #   container_name: dnmp-www
  #   volumes:
  #     - ./www:/usr/share/nginx/html

# NGINX #############################################
  nginx:
    container_name: dnmp-nginx
    build: 
      context: ./nginx
      args:
          - PHP_UPSTREAM_CONTAINER=${NGINX_PHP_UPSTREAM_CONTAINER}
          - PHP_UPSTREAM_PORT=${NGINX_PHP_UPSTREAM_PORT}
    depends_on:
      - php-fpm
    ports:
      - "${NGINX_HOST_HTTP_PORT}:80"
      - "${NGINX_HOST_HTTPS_PORT}:443"
    volumes:
      # 没必要把配置文件用卷来挂载, 不然就算配置更新了 nginx 也是要重启的

      # 挂载运行代码目录
      - ${APP_CODE_PATH_HOST}:/var/www
      # 挂载日志目录
      - ${NGINX_HOST_LOG_PATH}:/var/log/nginx
    # 使用 networks 取代 links 在同一个网络模式下的服务是互通的
    # 在service 中使用其他的 service 就直接调用 service 名就行, 不用管 ip 地址, docker 会自己维护一套
    networks:
      - frontend
      - backend


# PHP-FPM #############################################
  php-fpm:
    container_name: dnmp-php-fpm
    # 这里的args 是属于 build 下面的,用于构建./php-fpm/Dockerfile 文件中 ARG 参数指定 php 版本
    build: 
      context: ./php-fpm
      args:
        - PHP_VERSION=${PHP_VERSION}
    volumes:
      - ${APP_CODE_PATH_HOST}:/var/www
      - ./php-fpm/php${PHP_VERSION}.ini:/usr/local/etc/php/php.ini
    expose:
      - "9000"
    networks:
      - backend
    
  redis:
    container_name: dnmp-redis
    build:
      context: ./redis
      args:
        - REDIS_SET_PASSWORD=${REDIS_SET_PASSWORD}
    ports:
      - ${REDIS_HOST_PORT}:6379
    volumes:
      # 这里卷挂载的是本地文件
      # - ${DATA_PATH_HOST}/redis:/data
      # 这里创建一个 redis_volume来存放数据
      - redis_volume:/data

# Mysql #############################################
  mysql:
    container_name: dnmp-mysql
    # 镜像来源: https://github.com/docker-library/mysql/blob/fc3e856313423dc2d6a8d74cfd6b678582090fc7/5.7/Dockerfile
    image: mysql:${MYSQL_VERSION}
    volumes:
      # - ${DATA_PATH_HOST}/mysql:/var/lib/mysql
      - mysql_volume:/var/lib/mysql
    # 容器只要停止就会重启
    restart: always
    environment: 
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
    ports:
      - ${MYSQL_HOST_PORT}:3306

接下来看看它的关键词都起着什么作用:

version

这个规定了文件的版本, 既然有 3 就肯定不用 2 啊, 虽然两者没冲突,但是我喜欢, 2 和 3 版本之间有轻微的变动,具体区别你可以在写配置文件时产生的报错信息来体验一下

network
networks:
  frontend:
    driver: ${NETWORKS_DRIVER}
  backend:
    driver: ${NETWORKS_DRIVER}

${NETWORKS_DRIVER} 是从 .env 文件中取的值, 下面的同理

这一块就相当于执行 docker network create -d bridge frontend && docker network create -d bridge backend
在本地持久化的建立一个网络配置,稍后方便容器进行连接, 当然这里也不止是一个 driver 参数,具体配置情况还是参考docker network inspect dnmp_frontend 来看一下

没有设置名字的配置当需要名字的时候会 {当前docker-compose.yml文件名}_{key} 这种格式

有了 network 配置就极大的简化了老版的 --links 命令, 只要属于同一个 network 就能互相访问到, 而不是每新增一个服务就要把原来的服务都 link 一遍

volume
volumes:
  mysql_volume:
    driver: ${VOLUMES_DRIVER}
  redis_volume:
    driver: ${VOLUMES_DRIVER}
  rabbitmq_volume:
    driver: ${VOLUMES_DRIVER}

network 部分一样, 持久化的创建几个 volume, 相当于命令 docker network create mysql_volume等等

这算是 v3 的一个新特性, 在 v2 的时候, 为了共享数据大家会创建一个什么镜像都不继承的image, 所有容器的 volume 都会和它连接, 现在有了 volume 就没必要这么搞了

service

这个是本章的重点, 我们来看下面的例子中的注释, 按序号来

services:

  #1 创建一个服务叫做nginx服务
  nginx:
    #2 为了显得个性化一点,我们指定这个容器的名字叫做 dnmp-nginx
    container_name: dnmp-nginx
    #3 标明这个服务的 Dockerfile 的地址,用相对路径方便项目迁移
    build: 
      #3.1 相当于命令: 
      # docker build ./nginx -t dnmp-nginx 
      #     --build-arg PHP_UPSTREAM_CONTAINER=xxx 
      #     --build-arg PHP_UPSTREAM_PORT=zzz
      context: ./nginx
      #3.2 这里 ${NGINX_PHP_UPSTREAM_PORT} 的值是从 .env 文件中取的, args 属于构建时传入的参数
      args:
          - PHP_UPSTREAM_CONTAINER=${NGINX_PHP_UPSTREAM_CONTAINER}
          - PHP_UPSTREAM_PORT=${NGINX_PHP_UPSTREAM_PORT}
    #4  在启动这个容器之前先启动 php-fpm 这个容器 
    depends_on:
      - php-fpm
    #5 将本地端口和容器端口绑定, 本地哪个端口就看 .env 里怎么写的
    ports:
      - "${NGINX_HOST_HTTP_PORT}:80"
      - "${NGINX_HOST_HTTPS_PORT}:443"
    
    #6 设置需要挂载的卷, 这里时将本地目录和容器绑定, 也可以像 services.redis 那样和创建好的卷绑定 
    volumes:
      # 没必要把配置文件用卷来挂载, 不然就算配置更新了 nginx 也是要重启的

      # 挂载运行代码目录
      - ${APP_CODE_PATH_HOST}:/var/www
      # 挂载日志目录
      - ${NGINX_HOST_LOG_PATH}:/var/log/nginx
    # 使用 networks 取代 links 在同一个网络模式下的服务是互通的
    # 在service 中使用其他的 service 就直接调用 service 名就行, 不用管 ip 地址, docker 会自己维护一套
    
    #7 设置容器从属的网络, 同一个网络下可互相访问
    networks:
      - frontend
      - backend

在上文的 #3 步骤看其他的service也有直接使用image的, 这是直接从远程获取镜像的方式

配置文件写完了, 我们看下nginx的构建文件

# in file ./nginx/Dockerfile

#1 选择继承的镜像
FROM nginx:1.13.1-alpine
#2 各种标签
LABEL maintainer="GPF <5173180@qq.com>"

#3 容器中执行命令, 且把本地的配置文件添加进去
#https://yeasy.gitbooks.io/docker_practice/content/image/build.html
RUN mkdir -p /etc/nginx/cert 
    && mkdir -p /etc/nginx/conf.d 
    && mkdir -p /etc/nginx/sites

COPY ./nginx.conf /etc/ngixn/nginx.conf
COPY ./conf.d/ /etc/nginx/conf.d/
COPY ./cert/ /etc/nginx/cert/

COPY ./sites /etc/nginx/sites/


#4 这里也是设置构建参数, 不过相同 key 值会被 docker-compose 中的给覆盖掉
ARG PHP_UPSTREAM_CONTAINER=php-fpm
ARG PHP_UPSTREAM_PORT=9000
#5 ${PHP_UPSTREAM_CONTAINER} 就在构建时的参数使用方式
RUN echo "upstream php-upstream { server ${PHP_UPSTREAM_CONTAINER}:${PHP_UPSTREAM_PORT}; }" > /etc/nginx/conf.d/upstream.conf

#6 设置挂载的目录, 该目录下文件变化不会影响到容器
VOLUME ["/var/log/nginx", "/var/www"]

#7 设置目录运行时所处在容器中的目录地址
WORKDIR /usr/share/nginx/html

#5 就是显示了在 nginx 容器中怎么去访问 php-fpm 这个容器, 直接调用 service 名称就行

这里需要注意的时 ARGENV 的区别, 参考这篇文章: Docker中 Arg 和 Env 的区别

启动docker-compse

在配置好 .env 文件和 docker-compose.yml 配置文件后就可以启动它了, 命令也很简单,在同级目录下运行:

docker-compose up -d

它会自动创建volumenetworkservices, 而且相关的运行参数都是按着配置文件来的, 这样一来每个完整docker-compose.yml中的service就相当于时一个整体,每个服务又属于各自的容器,这样操控是不是节省了很多代码呢?

查看这些容器的运行状况也很是简单

docker-compose ps
# 或者使用更方便的一个工具: ctop , github地址: https://github.com/bcicen/ctop

可操控单一容器一样, 但是它会把这一组容器都囊括了进去,操控起来只需要知道操控哪个服务,而一些参数就写在配置文件当中已经默认添加了

一些常用的命令:

# 终止整个服务集合
docker-compose stop

# 终止指定的服务 (这有个点就是启动的时候会先启动 depond_on 中的容器,关闭的时候不会影响到 depond_on 中的)
docker-compose stop nginx

# 查看容器的输出日志
docker-compose logs -f [services...]

# 构建镜像时不使用缓存(能避免很多因为缓存造成的问题)
docker-compose build --no-cache --force-rm

# 移除指定的容器
docker-compose rm nginx
本来熟悉命令的最好方式就是 用->犯错->排错->用 这种循环, 有什么不懂的 谷歌bing 都能查到, 直接 docker-compose --help 也能猜出命令的大概作用, 这里就不细说了

还有个很不错的 docker-compose 项目就是 laradock, dnmp 就是仿照着它写的, 不过网络不好的情况下别运行 laradock, 它现在做的太臃肿了。。。。 看看它里面的镜像是怎么写的还是很有收获的

相关

不正宗 Docker 入门教程-启动一个容器(1/3)

不正宗 Docker 入门教程-构建一个镜像(2/3)

不正宗 Docker 入门教程-使用 Docker-Compose (3/3)

博客原文

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/27375.html

相关文章

  • 正宗 docker 入门教程-启动一个容器(1/3)

    摘要:从命名上就知道这是一篇简单粗暴的新手入门教程,为什么要简单粗暴我认为有自学能力的人帮他入门就够了,不能自学的一时半会儿也教不会,不符合入门教程的初衷,建议出门左拐去找找视频教程本章目标大概了解是个什么玩意知道常用的指令参数能启动一个容器不然 从命名上就知道这是一篇简单粗暴的docker新手入门教程, 为什么要简单粗暴? 我认为有自学能力的人帮他入门就够了, 不能自学的一时半会儿也教不会...

    YorkChen 评论0 收藏0
  • 慕课网_《Docker入门》学习总结

    摘要:时间年月日星期六说明本文部分内容均来自慕课网。必填用于执行命令,当执行完毕后,将产生一个新的文件层。可选指定此镜像启动时默认执行命令。可选用于指定需要暴露的网络端口号。可选向镜像中挂载一个卷组。 时间:2017年09月16日星期六说明:本文部分内容均来自慕课网。@慕课网:http://www.imooc.com 教学源码:无 学习源码:无 第一章:课程简介 1-1 课程介绍 Docke...

    CoorChice 评论0 收藏0
  • docker-compose安装及简单入门

    摘要:编排一组容器的启停的工具,直接在官方仓库下载二进制文件。启动多任务只需多增加一个指定该容器暴露的端口号用启动,用查看启动成功关闭一组服务注意要在文件所在的目录执行该命令才可关闭对应的容器会停止并删除容器,网络等入门到此结束 docker-compose 编排一组容器的启停的工具,直接在官方github仓库下载二进制文件。 安装 1. 下载docker-compose sudo curl...

    honmaple 评论0 收藏0
  • EOS开发教程-Docker构建EOS环境

    摘要:确认安装成功并且服务启动之后,再继续进行下一步。适用于开发者的定制环境,其中包含编译智能合约需要的相关工具和依赖库。由于我们是开发者,因此我们选用这个。此时也可以通过的请求,直接访问查询分享一个开发视频教程,密码 由于EOS的版本在不断的更新迭代,本地编译最新版本的方式更新比较繁琐,而且容易出问题。 因此,我们推荐使用Docker容器的方式配置EOS本地测试环境,这样方便维护升级,而且...

    omgdog 评论0 收藏0
  • Docker 入门(二):从实例来看 Dockerfile 和 Compose

    摘要:安装完成后,可以用以下命令查看下版本信息。另外,如果要删除刚运行的两个容器,可以总结本文从数据持久化开始说起,浅谈了和并附送如何用这两种方式分别搭建环境,并在对比中展示了它们各自的特点。 上一文中提到,每次对容器做了改动,如果不把它 commit 成新的镜像,在删除容器后,数据也会丢失,有没有什么更好的办法来保存数据呢?使用数据卷就可以解决这个问题。 另外,相对于用 commit 容器...

    xingqiba 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<