Dockerfile 与 Compose 环境搭建学习笔记(一)

以前一直使用 Vagrant 作为自己的开发环境,并且在上家公司也推行大家采用 Vagrant 作为开发环境,保障公司使用的是同一套开发环境。随着docker的流行,越来越多的人在docker上运行自己的项目,利用docker也非常方便模拟各种线上集群,相比虚拟机效率会更高,不管是搭建还是运行。

网络上关于docker搭建环境的资料非常之多了,但自己一直没有进行过实践。纸上得来终觉浅,只有自己动过手之后,才能对相关的概念更熟悉。花了将近2天时间折腾,终于算是把docker的开发环境搭建好了,对他的很多概念也又了更深入的认识。整理一下整个过程,方便以后查漏补缺。

下面就来开启docker之旅吧,打算利用docker完成以下任务:

  • 基础的环境搭建:MySQL、Redis、Nginx;
  • 搭建PHP、Golang的开发环境;
  • 搭建MySQL、Redis的主从;
  • 探索一下如何监控docker中的进程。

涉及的命令介绍

这仅仅是操作笔记,不涉及 Docker 原理什么之类的知识,重点是如何应用。为了后续理解方便,先把用到的相关命令在这里进行整体介绍。

查找镜像

➜ ~/home/dockerenv >docker search mysql

上面这个命令就是查找 mysql 镜像。对应的可以将 mysql 替换成其它想要查找的镜像名称。该命令常用选项是: -s。可以设置搜索条件:多少个start以上的镜像。

➜ ~/home/dockerenv >docker search -s 100 mysql

搜索有100个以上start的 mysql 镜像。

获取镜像

docker pull centos7

这个命令会把镜像克隆到本地,就像:git clone 一样的效果。关于什么是镜像、容器之类的概念不在我的讲解范畴了。

查看与删除镜像

➜ ~/home/dockerenv >docker image ls

会列出当前所有的本地安装了的镜像。看到了有哪些镜像,有时候一个镜像我们用不到了,想把它干掉,为硬盘腾腾位置,可以用下面的命令:

➜ ~/home/dockerenv >docker rmi 0d16d0a97dd1 # 编号是 image id

创建镜像 - Dockerfile

docker的镜像可以从官方直接拉取,也可也通过 Dockerfile 进行定制,写好 Dockerfile 文件后,可以执行下面的命令运行镜像。

➜ ~/home/dockerenv >docker build -t nginx:1.14.0 .

这里的结尾有个 . 它表示上下文,而不是说 Dockerfile 的路径。举例来说,在 Dockerfile 中常常用 Copy 指令,它拷贝的文件必须要在这个上下文中。

Dockerfile的主要作用是:自己根据基础镜像,重新定制镜像,而不是直接从官方仓库拿现成的使用。

具体含义可以看这里:

https://yeasy.gitbooks.io/docker_practice/content/image/build.html

启动容器

➜ ~/home/dockerenv >docker run -it --rm php:7 bash

上面的命令会启动一个容器,并且分配一个伪终端,退出后容器就会被删除。

➜ ~/home/dockerenv >docker run -d -p 9000:9000 php:7

这个命令会在后台运行一个容器,此容器不会因为退出就被删除,可以重复进行start、stop操作。

上面两种容器启动的操作方式,在我的文章中其实不会出现,我的环境是基于docker-compose + Dockerfile 来搭建的。因为根据最佳实践:一个容器内部只包含一个进程,像上面我需要安装:PHP/Golang/Redis/Nginx/Mysql等,就算不算主从也需要启动5个容器,每次这样启动都要累死,还不说需要管理容器之间的互联。因此我使用Compose来定义和运行多个 Docker 容器的应用。

查看容器信息

➜ ~/home/dockerenv >docker inspect a49dfb2e6f45 # image id

通过该命令可以看到容器的完整信息,我用这个命令主要是在进行容器互联的时候,检查容器的网络与IP相关的情况。

进入容器

➜ ~/home/dockerenv >docker exec -it e8d740a6ac7a bash # image id

上面的命令可以进入容器,让你感觉像是 ssh 到了远程机器一样的感觉。

停止、启动

➜ ~/home/dockerenv >docker stop a49dfb2e6f45 # image id

如果容器是在后台启动,可以通过该方式停止容器。停止后可以使用下面的命令启动容器:

➜ ~/home/dockerenv >docker start a49dfb2e6f45 # image id

查看与删除容器

容器也可以像镜像一样进行查看

➜ ~/home/dockerenv >docker ps

上面的命令只会显示启动了的镜像,如果要查看所有镜像,可以添加 -a 选项。 如果某个容器不需要了,可以使用下面的命令进行删除:

➜ ~/home/dockerenv >docker rm 0d848bc87fe7  # image id

容器的删除并不会影响镜像,镜像可以继续用来启动新的容器。并且如果依赖某个镜像创建的容器没有被删除,该镜像是不能直接删除的,需要先删除容器后才能继续删除镜像。

Compose 中的启动与停止

针对docker compose启动与停止用到下面的命令,个人感觉这就是批量操作,毕竟容器太多,一个一个操作太麻烦,容易遗漏等等问题。

批量启动:

➜ ~/home/dockerenv >docker-compose up -d

虽然该命令并不是单纯的启动容器,它非常强大,将尝试自动完成包括构建镜像,(重新)创建服务,启动服务,并关联服务相关容器的一系列操作。

如果已经创建完了,也可以用下面的命令来启动已经创建的容器。

➜ ~/home/dockerenv >docker-compose start

如果想要停止容器可以使用下面的命令:

➜ ~/home/dockerenv >docker-compose stop

当然这些命令的运行,要在 docker-compose.yml 文件所在的目录下运行,否则它也不知道该启动或关闭哪些容器。

基本用到的命令大概就是上面这些,接下来先说说 docker-compose.yml 文件的编写。

Docker Compose构建环境

Docker Compose 可以把多个容器方便的管理起来,也就是所谓的编排技术。

编排技术的核心是 docker-compose.yml 这个模版文件。它定义了容器集群里每一个容器的镜像、数据卷挂载路径、端口、网络等。

以接下来要构建的环境来说明下,下面我将要搭建一个php7的开发环境,需要Nginx/PHP-FPM/MySQL/Redis进行配合。那么需要启动4个容器。对应的也需要4个镜像。整个环境的目录结构如下:

├── README.md
├── docker-compose.yml
├── logs
│   └── nginx
├── mysql
│   ├── conf
│   └── data
├── nginx
│   ├── Dockerfile
│   ├── conf
│   └── src
├── php7
│   ├── Dockerfile
│   ├── docker-compose.yml
│   ├── etc
│   ├── extensions
│   └── src
├── redis
│   ├── Dockerfile
│   ├── conf
│   ├── data
│   └── src
├── start.sh
├── stop.sh
└── www
└── abc

我的MySQL是直接使用的官方提供的镜像资源,而Redis/Nginx/PHP为了做定制化,我采用Dockerfile进行自定义。接下来按照每一个独立的服务分别进行一下说明。

MySQL服务

dev.mysql.srv:
  image: mysql:5.7.22
volumes:
    - ./mysql/data:/var/lib/mysql
- ./mysql/conf:/etc/mysql/conf.d
  ports:
    - "3307:3306"
  restart: always
  environment:
    MYSQL_ROOT_PASSWORD: 123123
  networks:
    - default
  • image:是制定依赖的镜像,这里是Docker提供的镜像资源;
  • volumes:数据卷所挂载路径设置,主要是MySQL的数据保存的路径设置与配置文件的设置。它的主要作用是持久化数据,避免容器销毁后内部数据丢失;
  • ports:暴露到宿主机的端口。这个没什么太多说的,就是为了可以在宿主机访问到容器内部的服务;
  • restart:该命令是设置容器如果在某种情况下(非认为)退出了,容器重启的策略;
  • environment:设置镜像的环境变量,你可以进入镜像通过:echo $MYSQL_ROOT_PASSWORD查看其值;
  • networks:设置网络,让所有的容器在一个网络中,方便容器互联互通。

这里还有一个点需要注意,dev.mysql.srv ,是我为mysql服务取的名字。取一个好的名字,非常便于后续容器互联的使用,比如这个名字,如果php代码需要填写mysql的host。我则可以直接使用它。

其它服务

剩下的三种服务配置方式基本上大同小异。我放在一起说明。

dev.nginx.srv:
  image: lei_nginx:1.14.0
  build: ./nginx
  volumes:
    - ./nginx/conf:/home/work/app/nginx/conf
- ./www:/home/work/www
  ports:
    - "80:8080"
- "443:443"
  restart: always
  networks:
    - default
  depends_on:
- dev.php-fpm.srv
dev.redis.srv:
  image: lei_redis:3.2.11
  build: ./redis
  volumes:
    - ./redis/conf:/home/work/app/redis/conf
- ./redis/data:/home/work/app/redis/data
  ports:
- "6379:6379"
  restart: always
  networks:
- default
dev.php-fpm.srv:
  image: lei_php:7.2.6
  build: ./php7
  volumes:
    - ./php7/etc:/home/work/app/php/etc
    - ./www:/home/work/www
  ports:
    - "9000:9000"
  restart: always
  networks:
    - default

这里与MySQL最大的一个区别是多了一个 build 选项。这就是上面说到的这三个镜像都是我用Dockerfile定制的有关。你可以在对应的 build 指定的目录下看到 Dockerfile 这个文件。

另外一个需要注意的地方是Nginx中配置的 depends_on 选项,他的作用是指定依赖,因为Nginx中我配置了php-fpm。所以它启动前要确保php-fpm已经启动后,他才能正常的启动。

启动

为了减少太多概念的东西,你可以先直接从github拉取这部分配置,然后运行

➜ ~/home/dockerenv >./start.sh
Starting dockerenv_dev.php-fpm.srv_1 ... done
Starting dockerenv_dev.redis.srv_1   ... done
Starting dockerenv_dev.mysql.srv_1   ... done
Creating dockerenv_dev.nginx.srv_1   ... done

如果你是第一次运行 start.sh ,他还会去docker hub上拉取镜像,以及根据Dockerfile来定制镜像。所以会有非常多的输出信息。

然后访问:http://localhost 。应该就能够看到 phpinfo() 输出的信息。

总结

经过自己的熟悉,对基本的docker命令,以及docker的三个基础概念:仓库、镜像、容器有了充分的认识。利用 docker compose 搭建一个环境后,对于容器的互联也有了更深刻的体会,并且经过这种一个容器运行一个进程的方式,对系统也有了一些更深的认识。在利用Dockerfile定制镜像的过程中,通过反复的 build 镜像,对理解容器的分层、如何确保镜像体积更小方面有了相当多的实践,特别是在ENTRYPOINT的设置上,认识到了docker的启动流程。

由于篇幅限制,把 Dockerfile 的内容在拆出一篇来进行说明,以及把遇到的一些问题也进行一些整理。

我的docker环境:

https://github.com/helei112g/docker-env

以后换机装换机,再也不担心了

微信公众号:

参考资料:

  • https://yeasy.gitbooks.io/docker_practice/content/

本文分享自微信公众号 - 大愚Talk(dayuTalk)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-06-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java帮帮-微信公众号-技术文章全总结

三个技巧,将Docker镜像体积减小90%【面试+工作】

在构建Docker容器时,应该尽量想办法获得体积更小的镜像,因为传输和部署体积较小的镜像速度更快。

18010
来自专栏康怀帅的专栏

Docker 实践遇到的问题(持续更新)

本文列举了使用 Docker 过程中遇到的问题。 时区 基于 Debian 的镜像通过设置 环境变量 改变时区,在 Dockerfile 中增加 ENV 或在启...

46950
来自专栏架构师小秘圈

\bdocker容器极简教程

一,小王对于容器的困惑 小王刚开始学习Docker的时候,找资料在网上看到最多的是Docker的好处。比如: 1、Docker 容器的启动可以在秒级实现,这相比...

42550
来自专栏IT米粉

Docker 常用基础命令

最近开始进攻Docker,已经将自己的电脑上的服务端软件逐一移到Docker上,包括tomcat、nginx、rabbitmq、redis等,并通过简单的脚本进...

403120
来自专栏云计算教程系列

如何在Ubuntu 14.04上使用Docker数据卷

在本文中,我们将介绍Docker数据卷的概念:它们是什么,它们有用的原因,不同类型的卷,如何使用它们以及何时使用它们。我们还将通过docker命令行工具介绍如何...

13830
来自专栏农夫安全

Docker安装与简单使用

至于Docker是什么,和他的一些功能简介,请自行百度. 如果还是不了解,你就当他是一个可以给你渗透的就行了 安装Docker: 我用的是ubuntu...

38640
来自专栏友弟技术工作室

使用 Dockerfile 定制镜像

最近公司项目上线原因,一直加班。没有时间更新文章。隔壁部门需要我提供sdk的打包的支持,所以一直在学习docker。原文 ? 从刚才的 docker commi...

48970
来自专栏散尽浮华

Docker容器学习梳理--容器间网络通信设置(Pipework和Open vSwitch)

自从Docker容器出现以来,容器的网络通信就一直是被关注的焦点,也是生产环境的迫切需求。容器的网络通信又可以分为两大方面:单主机容器上的相互通信,和跨主机的容...

1.4K110
来自专栏云计算教程系列

如何在Ubuntu 16.04上使用dry管理和监控Docker容器

dry是一个简单但广泛的终端应用程序,用于与Docker容器及其映像交互。使用dry会删除执行常规Docker Engine命令时所涉及的重复,并且还提供了更原...

15560
来自专栏快乐八哥

Docker Hub工作流程-Docker for Web Developers(6)

在Github上创建项目仓库 和创建其他Github项目一样,在Github创建一个仓库,然后在仓库里面增加一个dockerfile,然后提交并推送到Githu...

21970

扫码关注云+社区

领取腾讯云代金券