使用 Docker 做正确的事情

使用 Docker 做正确的事情

原文:https://medium.com/hackernoon/making-right-things-using-docker-7296cf0f6c6e

在本文中,我想展示如何使用 docker 进行开发测试。为了表明现在是从开发切换到工程,从单栈切换到全栈的时候了。当然,全栈不仅仅是前端和后端,它也是环境。docker 是一个很好的工具。

还有一些想法认为在不久的将来全栈将包含和机器学习 。我将展示在这个领域使用 docker 是多么容易。

码头工人哲学

Docker 容器是一个开源软件开发平台。它的主要好处是将应用程序打包在“容器”中,允许它们在任何运行 Linux 操作系统(OS)的系统之间移植。

可以把 Docker 容器看作是虚拟化的另一种形式。虚拟机(VM)允许将一个硬件分割成不同的 VM(或虚拟化),以便不同的用户可以共享硬件能力,并显示为独立的服务器或机器。Docker 容器将操作系统虚拟化,将其分成虚拟化的隔间来运行容器应用程序。

这种方法允许将代码片段放入更小的、易于移植的片段中,这些片段可以在任何运行 Linux 的地方运行。这是一种使应用程序更加分散的方式,并将它们分解成特定的功能。

容器映像是一个轻量级的、独立的、可执行的软件包,包含了运行它所需的一切:代码、运行时、系统工具、系统库、设置。基于 Linux 和 Windows 的应用程序都可以使用容器化软件,无论环境如何,容器化软件都可以运行。容器将软件从其周围环境中隔离出来,例如开发和阶段环境之间的差异,并有助于减少在同一基础设施上运行不同软件的团队之间的冲突。

docker 安装后,它使用命令行工作:

有很多参数和选项。我们将主要用 构建图像运行execRM和 [rmi](https://docs.docker.com/engine/reference/commandline/rmi/) 。

使用 YEPS 将 node.js 应用程序归档

可以从 node 官方文档文章开始:dockering a node . js web app

要使用 docker 容器,您需要从 docker hub 获取图像,或者使用 Dockerfile 和 [docker build](https://docs.docker.com/engine/reference/commandline/build/) 命令创建自己的图像。让我们使用 node.js 和 [YEPS 框架](https://yeps.info/)创建自己的映像

我在 github 上创建了库,所以你可以获得源代码:

git clone https://github.com/evheniy/yeps-docker-example.gitcd yeps-docker-example

**Dockerfile :**

**FROM** node:latest# Create app directory
**RUN** mkdir -p /usr/src/app
**WORKDIR** /usr/src/app# Install app dependencies
**COPY** package.json /usr/src/app/
**RUN** npm install# Bundle app source
**COPY** . /usr/src/app**EXPOSE** 3000**CMD** [ "**npm**", "**start**" ]

要创建自己的图像,您需要使用中的从现有图像扩展它。该图像扩展了 docker hub 上的原始节点图像的最新版本。****

之后,我们需要在容器中创建工作目录。使用 node.js 有一个很好的做法,即复制 package.json 并在复制所有其他文件之前安装所有依赖项。所以我复制它并运行 npm install 命令来获取所有依赖项。在我将所有文件复制到容器后。

**EXPOSE 命令使 docker 容器监听端口。而 CMD 命令运行我们的服务器。**

**只能有一个 CMD 命令。这是 docker 的理念— 每个容器一个流程。**

建成后,我们可以在 docker 中心或自己的私人图像库存储我们的图像。但我不会在这篇文章中描述。

要构建它,请运行:

docker build -t yeps .

我在 README.md 文件中描述了如何处理该图像的所有示例和命令。选项 -t 为图像创建名称,在我们的例子中是 yeps

要运行容器:

docker run -p 3000:3000 --name yeps -d yeps

选项 -p 将端口从主机映射到容器端口,选项 -d 将其作为服务运行。打开 http://localhost:3000/ 看到工作节点应用。

有很多命令可以阻止它。简单的就是docker stop。要检查集装箱 id ,运行 docker ps -a 。如果你运行 docker image ls 你可以找到图像: nodeyeps 。并使用 docker 镜像 rm 将其删除。但是还有其他方法来覆盖和移除图像:

docker rm -f yeps

交互模式

Docker 帮助处理图像,但不构建自己的图像。在 docker hub 上,你可以找到很多有趣的官方和非官方图片。你可以扩展它来制作自己的新图像,或者只是出于某些原因运行它。

一个有趣的例子是测试。在 node.js 的官方 docker hub 页面上,有许多不同 node.js 版本的图片。这对测试很有用。例如,我将展示如何测试任何 node.js 应用程序。再来试试 YEPS 框架。首先我们应该从 github 获取代码:

git clone https://github.com/evheniy/yeps.git
cd yeps

在我们需要使用任何节点版本运行 npm 测试命令之后,如下所示:

docker run -it --rm -v "$PWD":/www -w /www **node:8** /bin/bash -c "node -v && npm -v && npm i && npm t"

这里我们使用 node:8 image 运行 docker image(我使用最新的 8 版本,你可以指定任何其他版本)。 -it 参数有助于在交互模式下运行它,并在完成后清除所有数据我们放入 — rm 参数。如何从旧的容器和图像中清理光盘,我将在教程中描述。

命令 -v 帮助将当前目录映射到 /www-w 命令是 cd 命令的模拟(改变目录),它帮助在这个目录中运行我们的命令。

我们运行 node.js 命令node-v&&NPM-v&&NPM I&&NPM t,使用标志 -c

如果您需要使用 node.js 7 运行相同的命令,只需更改节点的 docker 映像:

docker run -it --rm -v "$PWD":/www -w /www **node:7** /bin/bash -c "**node -v && npm -v && npm i && npm t**"

你可以在 docker hub 上找到来自官方资料库的所有节点图片。但是作为一个好的实践,如果你看到有基于 alpine linux 的映像,最好使用它们来减少磁盘空间。因此,如果我们需要使用最新的节点版本测试我们的应用程序,只需运行即可(在 alpine linux 中,我们需要使用 /bin/sh 而不是 bash ):

docker run -it --rm -v "$PWD":/www -w /www **node:alpine** **/bin/sh** -c "**node -v && npm -v && npm i && npm t**"

数据库即服务

为了测试不同数据库的 YEPS 包,我使用了 docker。比如 [yeps-redis](https://github.com/evheniy/yeps-redis) 。为了运行和停止测试,我在 package.json 的脚本部分添加了命令:

"**db:start**": "docker run -d --name redis -p 6379:6379 redis:latest",    "**db:stop**": "docker rm -f redis"

同样适用于 [yeps-mysql](https://github.com/evheniy/yeps-mysql) :

"**db:start**": "docker run -d --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=yeps mysql:latest", "**db:stop**": "docker rm -f mysql"

这里使用 -e 选项我设置环境变量,如用户和密码。

而对于[yeps-mongose](https://github.com/evheniy/yeps-mongoose):

"**db:start**": "docker run -d --name mongo -p 27017:27017 mongo",    "**db:stop**": "docker rm -f mongo"

当我使用 [TravisCI](https://travis-ci.org/) 进行测试时,使用 docker 作为服务很容易,因为 TravisCI 基于 docker。只需注册存储库并创建 .travis.yml 就像我为yeps-mongose:****

**sudo: required
language: node_js
node_js:
  - "7"
  - "8"
**services:
  - docker**
before_install:
  - npm install
script:
  - docker version
  - node --version
  - npm --version
  - npm run lint
  - npm run test
  - npm run report** 

**如果您需要使用私有 CI 服务,您可以使用 [Jenkins](https://jenkins.io/) 或 [TeamCity](https://www.jetbrains.com/teamcity/) 。詹金斯在 docker hub 上有官方资源库,你可以在那里找到如何运行它的文档。例如:**

**docker run --name jenkins -p 8080:8080 -d jenkins**

**要访问管理员界面,您需要获得管理员密码。当我们用 -d 选项运行我们的容器时,我们只能从/var/Jenkins _ home/secrets/initial admin password中获得它:**

**docker exec jenkins **cat /var/jenkins_home/secrets/initialAdminPassword****

**这里我使用 exec 命令。它有助于在运行容器中运行类似于"cat/var/Jenkins _ home/secrets/initialAdminPassword "的命令。**

**并命令“docker RM-f Jenkins”将其停止。**

团队合作也差不多。但是这里我们需要运行主进程(服务器)并在单独的容器中构建代理。

但是首先,我们需要创建目录来存储我们的配置和日志:

**mkdir teamcity
cd teamcity**

**要启动 [TeamCity 服务器](https://hub.docker.com/r/jetbrains/teamcity-server/) 只需运行:**

**docker run -it --name teamcity-server-instance  -v "$PWD"/datadir:/data/teamcity_server/datadir -v "$PWD"/logs:/opt/teamcity/logs -p 8111:8111 -d jetbrains/teamcity-server**

**对于 [构建代理](https://hub.docker.com/r/jetbrains/teamcity-agent/) 几乎相同(在免费版本中,我们只能使用 3 个构建代理):**

**docker run -it -d -e SERVER_URL="teamcity-server-instance:8111" -v "$PWD"/**agent1**:/data/teamcity_agent/conf --link teamcity-server-instance:teamcity-server-instance --privileged jetbrains/teamcity-agentdocker run -it -d -e SERVER_URL="teamcity-server-instance:8111" -v "$PWD"/**agent2**:/data/teamcity_agent/conf --link teamcity-server-instance:teamcity-server-instance --privileged jetbrains/teamcity-agentdocker run -it -d -e SERVER_URL="teamcity-server-instance:8111" -v "$PWD"/**agent3**:/data/teamcity_agent/conf --link teamcity-server-instance:teamcity-server-instance --privileged jetbrains/teamcity-agent**

**我为每个代理指定了不同的名称和目录。如您所见,我将服务器和代理的目录映射到本地目录 teamcity 。**

Docker 撰写

**如果您需要构建和运行单个映像,Docker 是个好东西。但是在大多数真正的应用程序中,你需要同时处理不同的东西。数据库、集群模式下的实例、微服务…以及[Docker compose](https://docs.docker.com/compose/)是这方面的完美工具。**

Compose 是一个定义和运行多容器 Docker 应用程序的工具。使用 Compose,您可以使用 YAML 文件来配置应用程序的服务。然后,只需一个命令,您就可以从您的配置中创建并启动所有服务。要了解更多关于 Compose 的所有特性,请参见特性列表。

Compose 具有用于管理应用程序整个生命周期的命令:

  • 启动、停止和重建服务
  • 查看运行服务的状态
  • 流式传输正在运行的服务的日志输出
  • 在服务上运行一次性命令

**让我们为我们的 TeamCity 集群创建一个组合版本— docker-compose.yml :**

**version: '2'
services:
  **server**:
    restart: unless-stopped
    **image**: jetbrains/teamcity-server
    **ports**:
      - "8111:8111"
    **volumes**:
      - "./server/datadir:/data/teamcity_server/datadir"
      - "./server/logs:/opt/teamcity/logs"
  **agent1**:
    restart: unless-stopped
    **image**: jetbrains/teamcity-agent
    **links**:
      - "server:server"
    **environment**:
      SERVER_URL: server:8111
    **volumes**:
      - "./**agent1**:/data/teamcity_agent/conf"
  **agent2**:
    restart: unless-stopped
    **image**: jetbrains/teamcity-agent
    **links**:
      - "server:server"
    **environment**:
      SERVER_URL: server:8111
    **volumes**:
      - "./**agent2**:/data/teamcity_agent/conf"
  **agent3**:
    restart: unless-stopped
    **image**: jetbrains/teamcity-agent
    **links**:
      - "server:server"
    **environment**:
      SERVER_URL: server:8111
    **volumes**:
      - "./**agent3**:/data/teamcity_agent/conf"**

**我们使用几乎相同的参数(端口映像),但有一些特定的更新。**

**要开始编写,只需运行 docker-compose up 或将其作为服务运行:**

**docker-compose up -d**

并停止:

**docker-compose stop**

把所有东西都拿下来(用卷):

**docker-compose down --volumes**

或者,如果您想要删除 docker 图像:

**docker-compose down --rmi all**

**让我们用 node.js 实例集群和作为负载平衡器的 nginx 来更新我们之前的 node.js YEPS 示例。**

我创建了一个 github 库,所以只需克隆它:

**git clone [https://github.com/evheniy/yeps-docker-compose-example.git](https://github.com/evheniy/yeps-docker-compose-example.git)
cd [yeps-docker-compose-example](https://github.com/evheniy/yeps-docker-compose-example.git)docker-compose up -d**

在这个例子中,我们有 docker-compose.yml 和两个目录: nginx节点。您可以打开链接并检查每个文件。我使用了与前面的合成示例相同的想法。但是这次我为 nginx 构建了自己的映像:

**# Set nginx base image
**FROM** nginx:latest

# Copy custom configuration file from the current directory
**COPY** nginx.conf /etc/nginx/nginx.conf**

对于节点 I,使用现有的 Dockerfile

**DockerDocker compose 即使使用微服务架构,也能真正帮助开发和测试真正的现代应用。但是你不仅可以用它来开发。接下来我将向您展示如何使用它进行数据科学实验。**

机器学习

同样的想法不仅对开发有用,我指的是计算机科学。它对数据科学很有用。在 docker 容器中运行机器学习实验也是一个不错的选择。

**为了我在机器学习中的实验,我基于[python anaconda](https://hub.docker.com/r/continuumio/anaconda3/)创建了 github 库。**

要使用这个容器,只需克隆 git 存储库并构建映像:

**$ git clone https://github.com/evheniy/python-docker.git
$ cd python-docker**

**由于我经常使用 node.jsnpm ,我在 package.json [脚本部分](https://github.com/evheniy/python-docker/blob/master/package.json) 中创建了命令,并在 [README.md](https://github.com/evheniy/python-docker) 文件中进行了描述。**

**所以对于 build 只需运行 npm 运行 builddocker build -t python ”。并开始: npm start 或“docker run—name python-p 8888:8888-v $ PWD/python:/opt/notebooks-d python”。在这里,我使用参数 -d 进行恶魔化处理,使用参数 -v 映射当前目录,并在停止容器后保存我的所有数据。**

**并使用密码 root 打开 http://localhost:8888 。**

**您可以使用 jupyter 笔记本的 web UI 找到一些示例,并运行任何示例 plot_face_recognition :**

**Docker 有助于在任何地方使用相同的环境( python 、 [scikit-learn](http://scikit-learn.org/stable/) 、[SkPy](https://pypi.python.org/pypi)……)工作。完成后,需要使用 npm 运行停止停止容器,并使用 npm 运行 rm 清洁圆盘空间。**

**清洁**

Docker 使得将应用程序和服务封装在容器中变得容易,这样你就可以在任何地方运行它们。然而,当您使用 Docker 时,也很容易积累大量未使用的图像、容器和数据卷,从而使输出混乱并消耗磁盘空间。

Docker 没有提供直接的清理命令,但是它提供了从命令行清理系统所需的所有工具。在本教程中,你可以找到一些命令的快速参考,这些命令有助于通过删除未使用的 Docker 映像、容器和卷来释放磁盘空间并保持系统有序。

我将在这里提供一些有用的命令:

**所有图像列表:**

**docker image ls**

**运行容器:**

**docker ps -a**

**一行停止并移除所有容器:**

**docker rm -f $(docker ps -a -q)**

**并删除所有图像:**

**docker rmi -f $(docker images -q)**

**删除所有悬空卷:**

**docker volume rm $(docker volume ls -f dangling=true -q)**

**结论**

在本教程中,我展示了一些使用 docker 的有用例子和命令。有许多其他的组合和标志可以与每一个一起使用。要获得更多信息,你可以阅读 docker 文档,我建议你完成 T2 的 Udemy 课程。

**Docker 可以帮助研究和测试新工具、数据库、机器学习和大数据工具,如 [Hadoop](http://hadoop.apache.org/) 和 [Apache Spark](https://spark.apache.org/) 。您可以在本地运行它,并在停止后保持您的电脑干净。**

**正如我之前所说,docker 是一个用于开发测试的伟大工具。在生产中,您将使用 devops 帮助来配置 web 服务,如 AWS 。所以有了 docker,你现在可以使用任何东西,让我们 devops 关心生产。**


本站为非盈利网站,作品由网友提供上传,如无意中有侵犯您的版权,请联系删除