使用Docker-Compose创建一个包含客户端与服务端的应用


【编者的话】这篇教程会对Docker-Compose进行简短的介绍,之后读者会使用Docker创建第一个客户端/服务器端应用程序。


本文考虑到读者了解了Docker的基础知识。如果没有,我建议你阅读我的第一篇文章来学习Docker并创建你的第一个应用程序。

什么是Docker-Compose?

Docker-Compose是Docker提供的工具。简而言之,这个工具是用于解决项目中的架构问题的。

正如你在上一篇文章中可能已经注意到,我们创建了一个简单的程序,它在启动时显示“Docker is magic!”。

实际上,当你真正开发时,你很少会只创建一个独立程序(一个不依赖于任何其他服务的程序,例如数据库)。

但是,你如何得知是否需要Docker-Compose?这非常简单 - 如果您的应用程序需要运行多个服务,那么你就需要Docker-Compose。例如,如果你创建的网站需要连接到你的数据库以对用户进行身份验证(此处为2个服务,网站和数据库)。

Docker-Compose可以让你使用单个命令来启动所有服务。

Docker和Docker-Compose之间的区别

Docker用于管理应用程序的单个容器(服务)。

Docker-Compose用于同时管理同一个应用程序下的多个容器。这个工具提供与Docker相同的功能,但允许你管理更复杂的应用程序。
1.png

Docker(单个容器)VS Docker-Compose(多个容器)

一个典型的用例

这个工具可以变得非常强大,并允许你非常快速地部署拥有复杂架构的应用程序。接下来我会给你一个具体的案例,来证明你需要它。

想象一下,你需要创建一个应用。

这个应用包含两个网站,第一个允许商店只需点击几下就可以创建他们的在线商店。第二个是用于客户售后支持。这两个站点与同一个数据库进行交互。

随着业务增长,你的服务器不够用了。因此,你决定将整个软件迁移到另一台计算机。

不幸的是,你没有使用Docker-Compose。因此,你将不得不一个接一个地迁移和重新配置你的服务。

如果你使用过Docker-Compose,只需几个命令就可以在新服务器上部署整个架构。你现在要做的就是进行一些配置并进行数据库的备份以完成迁移。

现在开始使用Docker-Compose创建你的第一个客户端/服务器端应用程序

你已经知道Docker-Compose是用来干什么了,现在是时候创建你的第一个客户端/服务器端应用程序了!

本教程的目的是用Python创建一个显示一句话的小型网站(服务器)。再由Python创建的程序(客户端)请求服务端,最终这个程序将会显示这句话。


注意:您需要在计算机上安装Docker并且已经掌握了基础知识。如果不是这种情况,请您阅读我之前的文章

1. 创建项目

在计算机上创建一个文件夹。它的根目录下必须包含以下文件和文件夹:
  • 一个'docker-compose.yml'文件(Docker-Compose文件,其中包含创建不同服务的必要指令)。
  • 'server'文件夹(此文件夹将包含服务器的配置文件)。
  • 'client'文件夹(此文件夹将包含客户端的配置文件)。


通常你应该有这样的文件夹架构:
.
├── client/
├── docker-compose.yml
└── server/
2 directories, 1 file

2. 创建你的服务器

为了开始重温Docker的基础知识,我们将从创建服务器开始。

2a. 创建文件

进入server文件夹,并创建以下文件:
  • 一个'server.py'文件(包含服务器代码的Python文件)。
  • 'index.html'文件(包含要显示的句子的html文件)。
  • “Dockerfile”文件(Docker文件,包含创建服务器环境的必要指令)。


'server /'文件夹下应包含下列文件:
.├── Dockerfile
├── index.html
└── server.py
0 directories, 3 files

2b. 编辑Python文件

将以下代码添加到'server.py'文件中:
#!/usr/bin/env python3

# 导入Python系统库
# 这些库用来创建网页服务器
# 你无需安装任何特殊的包,这些库是python自带的
import http.server
import socketserver

# 这个变量用于处理客户端发来的请求
handler = http.server.SimpleHTTPRequestHandler

# 这里我们定义了将服务端运行在端口1234
# 记住这些信息,我们之后将在docker-compose中用到
with socketserver.TCPServer(("", 1234), handler) as httpd:
# 这个指令将会使服务端长久运行以接受客户端的请求
httpd.serve_forever()

2c. 编辑Html文件

你可以把下面这句话添加到‘index.html’文件中:
Docker-Compose is magic!

服务器启动时将共享此文件,并显示这句话。

2d. 编辑Docker文件

在这里,我们将创建一个基本的Dockerfile,负责执行Python文件。我们将使用官方镜像的python环境。
# dockerfile必须以import基础镜像开头
# 我们使用关键词 FROM 来做这件事
# 在我们的实例中,我们引入Python镜像(从dockerhub)
# 所以这里写下python以及版本latest
FROM python:latest

# 为了运行我们的python代码,我们需要引入'server.py' 和 'index.html' 文件.
# 我们使用关键词 ADD 来做这件事
# 记住,第一个server.py是主机上文件的名称
# 第二个'/server/'是在镜像里用来存放文件的位置
# 这里我们将文件都放在镜像里的server文件夹下面
ADD server.py /server/
ADD index.html /server/

# 这里我介绍一下关键词 WORKDIR 
# 这个关键词将会改变你镜像的工作目录
# 这里我们将 '/server/' 作为根目录(所有的指令都会在工作目录执行).
WORKDIR /server/

3. 创建客户端

3a. 创建文件

进入‘client’ 文件夹,创建以下文件:
  • 一个'client.py'文件(将包含客户端代码的Python文件)。
  • 一个 “Dockerfile”文件(Docker文件,其中包含创建客户端环境的必要指令)。


'client /'文件夹结构如下:
.
├── client.py
└── Dockerfile
0 directories, 2 files

3b. 编辑Python文件

将以下代码添加到 ‘client.py’ 文件:
#!/usr/bin/env python3

# 引入python库
# 这个库用于从服务器端下载index.html
# 无需下载特殊的python库,这个库包含于python之中
import urllib.request

# 这个变量包含了 'http://localhost:1234/'的请求
#什么是 'http://localhost:1234'?
# localhost: 意味着服务器在本地
# 1234: 记得我们定义服务器的端口是1234么
fp = urllib.request.urlopen("http://localhost:1234/")

# 'encodedContent' 对应的是从服务器拿到的编码的内容 ('index.html').
# 'decodedContent' 对应的是从将服务器拿到的内容进行解码 (也是我们需要显示的内容).
encodedContent = fp.read()
decodedContent = encodedContent.decode("utf8")

# 打印解码的内容: 'index.html'.
print(decodedContent)

# 关闭与服务器的连接
fp.close()

此代码将允许您获取服务器网页的内容并显示它。

3c. 编辑Docker文件

# 与server的Dockerfile一样
FROM python:latest

# 与server的dockerfile一样
# 将主机文件 'client.py' 移到镜像中的 '/client/' 文件夹下.
ADD client.py /client/

# 这里我们将'/client/' 作为工作目录
WORKDIR /client/

4. 回到Docker-Compose

你可能已经注意到,我们创建了两个不同的项目,服务器和客户端,都使用Dockerfile。

现在编辑根目录底下的'docker-compose.yml'文件。
# Docker-Compose文件必须以版本号开始
# 我们使用3作为最新版本
version: "3"

# 你需要知道Docker-Compose是用来管理服务的
# 1 服务 = 1 容器
# 例如,一个服务可能是服务端,客户端,或者数据库...
# 我们使用关键词service来定义服务
services:
# 我们需要创建两个服务:客户端,服务端
# 第一个服务(容器):服务端
# 这里你可以使用任意关键词
# 你可以定义这个服务对应于什么业务
# 我们使用关键词server来定义服务端
server:
# 关键词build是用来定义用于创建镜像的Dockerfile的位置
# 这里的 'server/' 对用于server目录,它包含了需要使用的dockefile
build: server/

# command用于定义镜像被创建后运行的指令
# 这个指令将会运行 "python ./server.py"。
command: python ./server.py

# 记得我们在 'server/server.py' 将服务端运行在1234 端口.
# 如果我们想从电脑上访问这个端口(容器之外)
# 我们需要将这个端口映射到容器之外
# 使用关键词ports可以实现这个目标
# 它的语法如下 [我们机器上的端口]:[容器的端口]
# 以下配置会把容器的端口1234映射到主机的端口1234上
ports:
  - 1234:1234

# 第二个服务(容器):客户端
# 我们使用关键词 'client' 作为客户端
client:
# 这里 'client/' 对应于容器内的包含Dockerfile的路径
build: client/

# 容器镜像创建之后会执行 "python ./client.py".
command: python ./client.py

# 关键词 'network_mode'用于定义网络模式
# 这里我们定义容器可以访问主机的localhost
network_mode: host

# 关键词 'depends_on' 这个服务是否需要依赖于其他服务创建以后再开始创建
# 这里我们希望服务端的服务先运行起来之后在运行客户端
depends_on:
  - server

5. 构建Docker-Compose

设置Docker-Compose后,需要构建客户端/服务器应用程序。此步骤对应于“docker build”命令,但应用于多个不同的服务。
$ docker-compose build

6. 运行Docker-Compose

你的Docker-Compose已经构建成功!现在是时候开始吧!这个步骤对应于“docker run”命令,但应用于不同的服务。
$ docker-compose up

您会在终端中看到“Docker-Compose is magic!”


注意:如教程中所示,您的“服务器”服务使用计算机的端口1234来分发其内容。如果您打开计算机上的“http:// localhost:1234/”页面,您应该会看到‘Docker-Compose is magic!’。
代码地址:https://github.com/gael-thomas ... ample

Docker一些常用的命令

停止并删除由“docker-compose up”创建的容器以及镜像 :
$ docker-compose down

显示服务输出的日志(例如:'docker-compose logs -f client'):
$ docker-compose logs -f [service name]

列出所有的容器:
$ docker-compose ps

对正在运行的容器执行指令(例如:'docker-compose exec server ls'会在server服务的容器中执行ls操作):
$ docker-compose exec [service name] [command]

列出所有的镜像:
$ docker-compose images

原文链接:A beginner’s guide to Docker — how to create a client/server side with docker-compose

==============================================================================
译者介绍:Grace,程序员,研究生毕业于SUNY at Stony Brook,目前供职于Linktime Cloud Company,对大数据技术以及数据可视化技术感兴趣。

0 个评论

要回复文章请先登录注册