欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-02-22 11:33:53
...

以前一直使用 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

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

微信公众号:
Dockerfile 与 Compose 环境搭建学习笔记(一)

参考资料:
- https://yeasy.gitbooks.io/docker_practice/content/