介绍
本教程展示了如何在 Docker 容器中部署 Nginx。
通过容器化 Nginx,我们削减了我们的 sysadmin overhead. 我们将不再需要通过包管理器管理 Nginx 或从源头构建它. Docker 容器允许我们在发布新的 Nginx 版本时简单地更换整个容器。
Nginx 将自己描述为:
nginx [engine x] 是一个 HTTP 和反向代理服务器,邮件代理服务器和通用 TCP 代理服务器,最初由 Igor Sysoev 撰写。
在实践中,许多 sysadmins 使用 Nginx 来服务 Web 内容,从平面文件网站到 NodeJS 上的上游 API。
Docker 容器是相对较旧的操作实践的一种流行的形式:集装箱化.集装箱化不同于虚拟化,即虚拟化抽象了硬件,而集装箱化抽象了基础操作系统。
这种可移植性意味着您可以在各种操作系统上安装Docker Engine(也称为Docker Core,甚至仅是Docker),任何由任何人编写的功能容器都会在其上运行。
如果您想了解更多关于Docker的信息,您可以参阅 介绍的Docker教程 。
对于本文的目的,我们将在Ubuntu 14.04上安装Docker Engine。
我们将安装目前为Ubuntu的稳定版本Docker,即1.8.1。
本教程针对的是新的Docker的Nginx用户,如果您只需要为设置您的Nginx容器的裸体命令,您可以执行步骤1,然后跳到步骤5。
如果您想逐步建立您的容器,并了解端口绘制和分离模式,请遵循整个教程。
前提条件
要集装 Nginx,请填写下列内容:
- 设置 Ubuntu 14.04 服务器,最好使用 SSH 密钥用于安全 *设置 sudo 用户
- 验证您的内核版本
Docker 1.8.1 依靠一些最近的内核功能,所以请确保内核处于 3.10或更高水平。
1uname -r
我们已经包括了下面一个新鲜的Ubuntu 14.04 Droplet的输出,它超过了3.10,所以你不应该担心任何事情,除非你在 较老的图像上运行此功能。
1[secondary_label Output]
23.13.0-57-generic
步骤 1 - 安装 Docker
Docker 主持一个启动脚本,让 Docker 在您的机器上运行,我们可以简单地运行命令:
1sudo curl -sSL https://get.docker.com/ | sh
<$>[注]
一般来说,你不应该将随机脚本从互联网引导到你的壳( Átha sh
),因为它们几乎可以做任何事情。
一旦完成,您将看到如下所示的安装版本(您的阅读可能更新的;这很好)和一些指示运行作为非根 / 没有 sudo。
1[secondary_label Output]
2 Client:
3 Version: 1.8.3
4 API version: 1.20
5 Go version: go1.4.2
6 Git commit: f4bf5c7
7 Built: Mon Oct 12 05:37:18 UTC 2015
8 OS/Arch: linux/amd64
9
10 Server:
11 Version: 1.8.3
12 API version: 1.20
13 Go version: go1.4.2
14 Git commit: f4bf5c7
15 Built: Mon Oct 12 05:37:18 UTC 2015
16 OS/Arch: linux/amd64
可选:运行Hello-world
容器,确保一切按预期工作。
1sudo docker run hello-world
你应该看到类似于下面所示的输出。
1[secondary_label Output]
2 $ docker run hello-world
3 Unable to find image 'hello-world:latest' locally
4 latest: Pulling from library/hello-world
5 535020c3e8ad: Pull complete
6 af340544ed62: Already exists
7 library/hello-world:latest: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
8 Digest: sha256:d5fbd996e6562438f7ea5389d7da867fe58e04d581810e230df4cc073271ea52
9 Status: Downloaded newer image for hello-world:latest
10
11 Hello from Docker.
12 This message shows that your installation appears to be working correctly.
13
14 To generate this message, Docker took the following steps:
15 1. The Docker client contacted the Docker daemon.
16 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
17 3. The Docker daemon created a new container from that image which runs the
18 executable that produces the output you are currently reading.
19 4. The Docker daemon streamed that output to the Docker client, which sent it
20 to your terminal.
21
22 To try something more ambitious, you can run an Ubuntu container with:
23 $ docker run -it ubuntu bash
24
25 Share images, automate workflows, and more with a free Docker Hub account:
26 https://hub.docker.com
27
28 For more examples and ideas, visit:
29 https://docs.docker.com/userguide/
有了这个完整,我们可以深入到Docker的基本知识。
(可选)步骤 2 — 审查集装箱基础:运行,列表,删除
本节说明如何运行基本容器,然后删除它. 如果您已经知道如何使用 Docker 一般,并且想跳过 Nginx 部分,请转到步骤 5。
我们已经安装了 Docker 客户端作为 Docker 安装的一部分,因此我们可以访问命令行工具,允许我们与容器进行交互。
如果我们执行以下命令;
1sudo docker ps -a
您应该获得类似于以下的输出;
1[secondary_label Output]
2 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3 a3b149c3ddea hello-world "/hello" 3 minutes ago Exited (0) 3 minutes ago nostalgic_hopper
我们可以看到关于我们的集装箱的一些基本信息。
您会注意到它有一个荒谬的名称,如nostalgic_hopper
;如果您在创建容器时没有指定一个,这些名称会自动生成。
我们还可以看到你好,世界
的示例容器在3分钟前运行并在3分钟前退出。
如果我们用这个命令重新运行此容器(用自己的容器名称取代nostalgic_hopper
):
1sudo docker start nostalgic_hopper
然后运行命令来列出容器:
1sudo docker ps -a
我们现在应该看到,集装箱最近运行了;
1[secondary_label Output]
2CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3a3b149c3ddea hello-world "/hello" 4 minutes ago Exited (0) 9 seconds ago nostalgic_hopper
默认情况下,Docker容器运行其分配的命令,然后退出。
一些容器将设置为运行任务列表并完成,而其他则将无限期运行。
现在我们已经通过了一些Docker的基本知识,让我们删除你好世界
的图像,因为我们不会再需要它(请记住用你的容器名称代替nostalgic_hopper
,或者使用你的容器ID)。
1sudo docker rm nostalgic_hopper
接下来我们将开始使用 Nginx。
(可选)步骤 3 – 学习如何暴露端口
在本节中,我们将下载 Nginx Docker 图像,并向您展示如何运行容器,以便它作为网页服务器可公开访问。
默认情况下,容器无法从互联网访问,所以我们需要将容器的 internal 端口绘制到 Droplet 的端口。
首先,我们会得到 Nginx 图像。
<$>[注] 步骤5包含部署整个容器的最后命令,所以如果你不太关心实施细节,你可以直接跳过那里。
运行以下命令来获取 Nginx Docker 图像:
1sudo docker pull nginx
Docker会缓存这些,所以当我们运行容器时,我们不需要每次下载容器图像。
Docker 维护了一个名为 Dockerhub的网站,这是一个公共存储库的 Docker 文件(包括官方和用户提交的图像)。
让我们用这个命令启动我们的 Nginx Docker 容器:
1sudo docker run --name docker-nginx -p 80:80 nginx
run
是创建新容器 的命令 *--name
旗帜是我们如何指定容器的名称(如果左空为我们分配,如 nostalgic_hopper 从步骤 2)-p
指定了我们以-p local-machine-port:internal-container-port
的格式暴露的端口。
把你的 Droplet 的 IP 地址插入到网页浏览器中,你应该看到 Nginx 的欢迎来到 nginx!
页面。
在您的壳会话中,您还会注意到当您向您的服务器发送请求时, Nginx 日志正在更新,因为我们正在互动地运行我们的容器。
让我们打破快捷键CTRL+C
,回到我们的壳会话。
如果你现在试图加载页面,你会得到一个连接拒绝
页面. 这是因为我们关闭了我们的容器。
1sudo docker ps -a
你应该看到一些类似于下面显示的输出。
1[secondary_label Output]
2CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
305012ab02ca1 nginx "nginx -g 'daemon off" 57 seconds ago Exited (0) 47 seconds ago docker-nginx
我们可以看到我们的Docker容器已经离开了。
如果我们需要将 Nginx 附加到容器图像中才能工作,那么在下一步我们将向您展示如何分离容器以使其独立运行。
使用此命令删除现有docker-nginx
容器:
1sudo docker rm docker-nginx
在下一步中,我们将向您展示如何在独立模式下运行它。
(可选)步骤4 – 学习如何在独立模式下运行
使用此命令创建一个新的、分离的 Nginx 容器:
1sudo docker run --name docker-nginx -p 80:80 -d nginx
我们添加了d
旗,以便在背景中运行此容器。
输出应该只是新容器的ID。
如果我们运行列表命令:
1sudo docker ps
我们将在前所未见的输出中看到几件事情。
1[secondary_label Output]
2CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3b91f3ce26553 nginx "nginx -g 'daemon off" About a minute ago Up About a minute 0.0.0.0:80->80/tcp, 443/tcp docker-nginx
我们可以看到,而不是退出(0) X 分钟前
我们现在有约一分钟
,我们也可以看到端口绘制。
如果我们在浏览器中再次访问我们的服务器的IP地址,我们将能够再次看到欢迎到nginx!
页面,这次它在背景中运行,因为我们指定了d
旗帜,该旗帜告诉Docker以独立模式运行此容器。
现在我们有一个在单独的容器中运行的 Nginx 实例!
然而,它还不够有用,因为我们无法编辑配置文件,并且容器无法访问我们的网站文件。
停止容器,运行以下命令:
1sudo docker stop docker-nginx
现在容器已经停止(如果你想确定的话,你可以用sudo docker ps -a
检查),我们可以通过运行以下命令去除它;
1sudo docker rm docker-nginx
现在我们将进入我们的容器的最终版本,并快速停止生成自定义网站文件。
步骤 5 — 构建一个在 Nginx 上服务的网页
在此步骤中,我们将为我们的网站创建一个自定义索引页面. 此设置允许我们在(过渡)容器之外托管永久性网站内容。
让我们在我们的主目录中创建一个新的网站内容目录,并通过运行下面的命令移动到它。
1mkdir -p ~/docker-nginx/html
2cd ~/docker-nginx/html
现在让我们创建一个HTML文件(我们会显示Vim的命令,但你可以使用任何你喜欢的文本编辑器)。
1vim index.html
点击i
进入插入模式. 粘贴下面的内容(或放心添加自己的HTML标记)。
1<html>
2 <head>
3 <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" integrity="sha256-MfvZlkHCEqatNoGiOXveE8FIwMzZg4W85qfrfIFBfYc= sha512-dTfge/zgoMYpP7QbHy4gWMEGsbsdZeCXz7irItjcC3sPUFtf0kuFbDz/ixG7ArTxmDjLXDmezHubeNikyKGVyQ==" crossorigin="anonymous">
4 <title>Docker nginx Tutorial</title>
5 </head>
6 <body>
7 <div class="container">
8 <h1>Hello Digital Ocean</h1>
9 <p>This nginx page is brought to you by Docker and Digital Ocean</p>
10 </div>
11 </body>
12</html>
如果你熟悉HTML,你会发现这是一个超级基本的网页. 我们已经包含了一个<link>
标签,指向一个CDN for Bootstrap(一个CSS框架,让你的网页收集了响应式风格)。
我们现在可以通过按ESC
来保存这个文件,然后按:wq
和ENTER
:
- write (
w
) 告訴 Vim 將變更寫入檔案 停止 (q
) 告訴 Vim 退出
我们现在有一个简单的索引页面来取代默认的Nginx定位页面。
步骤 6 – 将容器连接到本地文件系统
我们将启动我们的 Nginx 容器,以便通过端口 80 在互联网上访问,并将其连接到服务器上的网站内容。
关于卷的背景信息;即,链接到您的容器的永久服务器内容:
Docker 允许我们将我们虚拟机的本地文件系统中的目录链接到我们的容器。
在我们的情况下,因为我们想要服务器网页,我们需要给我们的容器的文件来渲染。
我们可以将文件复制到容器中作为Dockerfile的一部分,或者在事实发生后复制到容器中,但这两种方法都会使我们的网站在容器内部处于静态状态。使用Docker的数据量功能,我们可以创建Droplet的文件系统和容器的文件系统之间的象征链接,这使我们能够编辑现有的网页文件并将新文件添加到目录中,我们的容器将自动访问它们。
Nginx 容器默认设置为在 `/usr/share/nginx/html 搜索索引页面,所以在我们的新 Docker 容器中,我们需要让它在该位置访问我们的文件。
** 创建链接:**
要做到这一点,我们使用‘-v’旗帜将文件夹从本地机器(~/docker-nginx/html')绘制到容器中的相对路径(
/usr/share/nginx/html').
我们可以通过执行以下命令来实现这一点:
1sudo docker run --name docker-nginx -p 80:80 -d -v ~/docker-nginx/html:/usr/share/nginx/html nginx
我们可以看到,新的附加到命令 -v ~/docker-nginx/html:/usr/share/nginx/html
是我们的卷链接。
-v
指明我们正在链接一个卷- 左边的部分是我们虚拟机上的文件/目录的位置(
~/docker-nginx/html
) - 右边的部分是我们在我们的容器中链接的位置(
/usr/share/nginx/html
)
运行该命令后,如果您现在将浏览器指向您的 DigitalOcean Droplet 的 IP 地址,您应该看到 Hello Digital Ocean 的第一个标题(或您在步骤 5 中创建的任何网页)。
如果你对其他 Nginx 默认设置感到满意,你已经设置好了。
您可以将更多内容上传到 ~/docker-nginx/html/
目录,并将添加到您的现场网站。
例如,如果我们修改我们的索引文件,如果我们重新加载我们的浏览器窗口,我们将能够看到它在实时更新. 如果我们想要这样,我们可以构建一个完整的网站从平板的HTML文件。
(可选)步骤 7 — 使用您自己的 Nginx 配置文件
本节是为想要使用自己的 Nginx 配置文件与他们的 Nginx 容器的先进用户。如果您没有想要使用的自定义配置文件,请跳过此步骤。
让我们回到一个目录,所以我们不会写到我们的公共HTML目录:
1cd ~/docker-nginx
如果您想查看默认 config 文件,只需使用 Docker 复制命令来复制它:
1sudo docker cp docker-nginx:/etc/nginx/conf.d/default.conf default.conf
由于我们将为 Nginx 使用自定义.conf 文件,我们将需要重建容器。
首先,停止容器:
1sudo docker stop docker-nginx
用它去除:
1sudo docker rm docker-nginx
现在你可以本地编辑默认文件(为新目录提供服务,或使用proxy_pass
将流量转移到另一个应用程序/容器,就像你在正常的 Nginx 安装时一样)。
一旦您保存了自定义配置文件,是时候创建 Nginx 容器了. 只需添加第二个 -v
旗帜,以提供适当的路径,以便为新鲜的 Nginx 容器提供适当的链接,从您自己的配置文件中运行。
1sudo docker run --name docker-nginx -p 80:80 -v ~/docker-nginx/html:/usr/share/nginx/html -v ~/docker-nginx/default.conf:/etc/nginx/conf.d/default.conf -d nginx
此命令还会继续在自定义网站页面中链接到容器。
请注意,如果您在启动容器后对配置文件进行任何更改,则需要使用docker restart
命令重新启动容器,因为如果其配置文件被更改, Nginx 不会热重新加载:
1sudo docker restart docker-nginx
结论
您现在有一个运行 Nginx 容器,服务于自定义网页。
从这里开始,我们建议您阅读 Docker 的 容器链接,如果您想了解如何将容器连接在一起,以便使用 Nginx 作为服务其他基于容器的 Web 应用程序的反向代理。
如果您想管理一组容器,例如应用容器、数据库容器和这个 Nginx 容器,请查看 Docker Compose。