如何在一个Docker容器在Ubuntu 14.04运行Nginx

本教程介绍了如何在Docker容器部署Nginx的。 由集装化的Nginx,我们减少了系统管理员的开销。我们将不再需要通过的软件包管理器来管理Nginx的或从源代码编译它。Docker容器使我们能够简单地更换整个容器时,Nginx的一个新版本发布。我们只需要保持Nginx的配置文件,我们的内容。

介绍

本教程介绍如何在Docker容器中部署Nginx。 通过容器化Nginx,我们减少了我们的sysadmin开销。我们将不再需要通过包管理器来管理Nginx,或者从源代码构建它。 Docker容器允许我们在发布新版本的Nginx时简单地替换整个容器。我们只需要维护Nginx配置文件和我们的内容。 Nginx自称为:
nginx [engine x]是一个HTTP和反向代理服务器,邮件代理服务器和一个通用的TCP代理服务器,最初由Igor Sysoev编写。
在实践中,许多系统管理员使用Nginx来提供Web内容,从平面文件网站到NodeJS中的上游API。在本教程中,我们将提供一个基本的网页,所以我们可以专注于使用Docker容器配置Nginx。 Docker容器是一种相对较旧的操作实践的流行形式:容器化。容器化与虚拟化的不同之处在于,虚拟化抽象出了硬件,而容器化也抽象出了基本操作系统。实际上,这意味着我们可以采取一个应用程序(或一组应用程序),并将它们包装在一个容器(或容器)中,使它们模块化,可移植,可组合和轻量级。 这种可移植性意味着您可以在各种各样的操作系统上安装Docker引擎(也称为Docker Core,甚至只是Docker),任何人编写的任何功能容器都可以在其上运行。 如果您想了解更多关于Docker,你可以检查出的入门教程Docker 。 为了本文的目的,我们将在Ubuntu 14.04上安装Docker Engine。 我们将安装Ubuntu的当前稳定版本的Docker,这是1.8.1。 本教程针对的是Docker新手的Nginx用户。如果你只想使用裸命令来设置Nginx容器,可以执行第1步,然后跳转到第5步。 如果你想逐步建立你的容器,并了解端口映射和分离模式,请按照整个教程。

先决条件

要集装Nginx,请完成以下操作: Docker1.8.1依靠一些相当新的内核特性,所以一定要确保内核在3.10或以上。 一个清新的形象将运行一个相当新的内核,但如果你需要检查,只是运行uname -r
uname -r
我们提供了从下面一个新鲜的Ubuntu 14.04Droplet,这比3.10的输出,所以你不应该有什么可担心的,除非你在运行这个旧的图像
3.13.0-57-generic

第1步 - 安装Docker

Docker托管一个启动脚本,以使Docker在您的机器上运行。我们可以简单地运行命令:
sudo curl -sSL https://get.docker.com/ | sh
一般情况下,你应该从互联网到shell不是管随机脚本( | sh ),因为它们可以几乎可以做任何事情。 看看get.docker.com如果你想知道你让自己成什么样。 一旦这完成,你会看到安装的版本,如下所示(您的读数可能更新;这是罚款)和一些说明作为非root /无sudo运行。我们正在使用sudo用户运行这个教程,所以为了本教程的目的,不需要担心这个。
    Client:
     Version:      1.8.3
     API version:  1.20
     Go version:   go1.4.2
     Git commit:   f4bf5c7
     Built:        Mon Oct 12 05:37:18 UTC 2015
     OS/Arch:      linux/amd64

    Server:
     Version:      1.8.3
     API version:  1.20
     Go version:   go1.4.2
     Git commit:   f4bf5c7
     Built:        Mon Oct 12 05:37:18 UTC 2015
     OS/Arch:      linux/amd64
可选:运行hello-world容器,以确保一切都在按预期工作。
sudo docker run hello-world
您应该看到类似下面显示的输出。
    $ docker run hello-world
    Unable to find image 'hello-world:latest' locally
    latest: Pulling from library/hello-world
    535020c3e8ad: Pull complete
    af340544ed62: Already exists
    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.
    Digest: sha256:d5fbd996e6562438f7ea5389d7da867fe58e04d581810e230df4cc073271ea52
    Status: Downloaded newer image for hello-world:latest

    Hello from Docker.
    This message shows that your installation appears to be working correctly.

    To generate this message, Docker took the following steps:
     1. The Docker client contacted the Docker daemon.
     2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
     3. The Docker daemon created a new container from that image which runs the
        executable that produces the output you are currently reading.
     4. The Docker daemon streamed that output to the Docker client, which sent it
        to your terminal.

    To try something more ambitious, you can run an Ubuntu container with:
     $ docker run -it ubuntu bash

    Share images, automate workflows, and more with a free Docker Hub account:
     https://hub.docker.com

    For more examples and ideas, visit:
     https://docs.docker.com/userguide/
有了这个完整的,我们能够深入了解Docker的基础知识。

(可选)第2步 - 查看容器基础:运行,列出,删除

本节介绍如何运行基本容器,然后将其删除。如果你已经知道如何使用Docker,并且想跳到Nginx部分,请转到第5步。 我们已经安装了Docker客户端作为Docker安装的一部分,所以我们可以访问命令行工具,让我们与我们的容器交互。 如果我们运行以下命令;
sudo docker ps -a
你应该得到类似下面的输出:
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
    a3b149c3ddea        hello-world         "/hello"            3 minutes ago      Exited (0) 3 minutes ago                       nostalgic_hopper
我们可以看到有关我们的容器的一些基本信息。 你会注意到它像一个荒谬的名字nostalgic_hopper ;如果在创建容器时未指定这些名称,则会自动生成这些名称。 我们还可以看到,该hello-world例如容器运行3分钟前和退出3分钟前。 如果我们用这个命令再次运行此容器(更换nostalgic_hopper用自己的容器名称):
sudo docker start nostalgic_hopper
然后运行命令以列出容器:
sudo docker ps -a
我们现在应该看到容器最近运行了;
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
a3b149c3ddea        hello-world         "/hello"            4 minutes ago      Exited (0) 9 seconds ago                       nostalgic_hopper
默认情况下,Docker容器运行他们分配的命令,然后退出。 一些容器将设置为运行任务列表并完成,而其他容器将无限期运行。 现在,我们已经通过一些基本的Docker走了,我们删除了hello-world的形象,因为我们将不会再需要它(记得要更换nostalgic_hopper与容器名称,或使用你的容器ID)。
sudo docker rm nostalgic_hopper
接下来,我们将开始使用Nginx。

(可选)第3步 - 学习如何公开端口

在本节中,我们将下载Nginx Docker映像,并向您展示如何运行容器,以便作为Web服务器公开访问。 默认情况下容器不能从Internet访问,所以我们需要容器的内部端口映射到Droplet的端口。这是本节会教你! 首先,虽然,我们将获得Nginx图像。 第5步包含部署完整容器的最终命令,所以如果你不过分关注实现细节,你可以直接跳过那里。 运行以下命令获取Nginx Docker镜像:
sudo docker pull nginx
这将下载容器的所有必需组件。 Docker将缓存这些,所以当我们运行容器时,我们不需要每次下载容器图像。 Docker维护一个网站名为Dockerhub ,Docker的文件的公共仓库(包括官方和用户提交的图片)。我们下载的镜像是官方的Nginx镜像,这使我们无需建立自己的镜像。 让我们用这个命令启动我们的Nginx Docker容器:
sudo docker run --name docker-nginx -p 80:80 nginx
  • run是创建一个新的容器命令
  • --name标志是我们如何指定容器的名称(如果留空一个分配给我们,像nostalgic_hopper第2步)
  • -p指定我们在格式暴露的端口-p local-machine-port:internal-container-port 。在这种情况下,我们将容器中的端口80映射到服务器上的端口80
  • nginx是上dockerhub图像的名称(我们之前与拉命令下载这一点,但是如果图像丢失Docker将自动执行此)
这就是我们需要得到Nginx!将Droplet的IP地址粘贴到Web浏览器中,您应该看到Nginx的“Welcome to nginx!”页。 你还会注意到在你的shell会话中,当你向服务器发出请求时,Nginx的日志正在被更新,因为我们以交互方式运行我们的容器。 让我们打破快捷键CTRL+C要回我们的shell会话。 如果您尝试立即加载网页,则会收到“连接被拒绝”页面。这是因为我们关闭了我们的容器。我们可以用这个命令验证:
sudo docker ps -a
您应该看到类似于下面所示的输出。
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
05012ab02ca1        nginx               "nginx -g 'daemon off"   57 seconds ago      Exited (0) 47 seconds ago                       docker-nginx
我们可以看到我们的Docker容器已经退出。 如果我们需要附加到容器图像以使其工作,Nginx将不是非常有用,因此在下一步中,我们将向您展示如何分离容器以允许它独立运行。 删除现有的docker-nginx用这个命令容器:
sudo docker rm docker-nginx
在下一步中,我们将向您展示如何以独立模式运行它。

(可选)第4步 - 学习如何以独立模式运行

使用此命令创建一个新的,分离的Nginx容器:
sudo docker run --name docker-nginx -p 80:80 -d nginx
我们添加了-d标志在后台运行此容器。 输出应该只是新容器的ID。 如果我们运行list命令:
sudo docker ps
我们将在我们以前没有见过的输出中看到一些东西。
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                         NAMES
b91f3ce26553        nginx               "nginx -g 'daemon off"   About a minute ago   Up About a minute   0.0.0.0:80->80/tcp, 443/tcp   docker-nginx
我们可以看到,而不是Exited (0) X minutes ago我们现在已经Up About a minute ,我们还可以看到端口映射。 如果我们在浏览器中再次访问我们的服务器的IP地址,我们将能够看到“欢迎使用nginx!页面。这一次,它的背景,因为我们指定的运行-d标志,告诉Docker运行在独立模式下,该容器中。 现在我们有一个运行的Nginx实例在一个独立的容器中! 这还不够有用,但是,因为我们不能编辑配置文件,容器没有访问任何我们的网站文件。 通过运行以下命令停止容器:
sudo docker stop docker-nginx
现在,容器被停止(你可以用sudo docker ps -a如果你想确定),我们可以通过运行以下命令将其删除;
sudo docker rm docker-nginx
现在,我们将到达容器的最终版本,快速停止生成自定义网站文件。

第5步 - 构建一个网页服务于Nginx

在此步骤中,我们将为我们的网站创建自定义索引页。此设置允许我们拥有托管在(临时)容器之外的永久网站内容。 让我们在我们的主目录中为我们的网站内容创建一个新目录,并通过运行下面所示的命令移动到它。
mkdir -p ~/docker-nginx/html
cd ~/docker-nginx/html
现在让我们创建一个HTML文件(我们显示Vim的命令,但你可以使用任何你喜欢的文本编辑器)。
vim index.html
按Enter键插入模式i 。粘贴到下面显示的内容(或随意添加您自己的HTML标记)。
<html>
  <head>
    <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">
    <title>Docker nginx Tutorial</title>
  </head>
  <body>
    <div class="container">
      <h1>Hello Digital Ocean</h1>
      <p>This nginx page is brought to you by Docker and Digital Ocean</p>
    </div>
  </body>
</html>
如果你熟悉HTML,你会看到这是一个超级基本的网页。我们提供了一个<link>是指向一个CDN为引导(一个CSS框架,让你的网页的响应样式的集合)标签。 你可以阅读更多关于引导 。 我们可以按现在保存此文件ESC ,然后:wqENTER
  • 写( w )告诉Vim将更改写入文件
  • 退出( q )告诉Vim退出
我们现在有一个简单的索引页面来替换默认的Nginx着陆页。

第6步 - 将容器链接到本地文件系统

在这一节中,我们将把它们放在一起。我们将启动Nginx容器,以便通过端口80在Internet上访问它,我们将它连接到我们在服务器上的网站内容。 关于卷的背景信息; 也就是说,从您的容器链接到永久服务器内容: Docker允许我们将目录从我们的虚拟机的本地文件系统链接到我们的容器。 在我们的例子中,由于我们想要服务器网页,我们需要给我们的容器渲染的文件。 我们可以将文件复制到容器中作为Dockerfile的一部分,或者在事实之后将它们复制到容器中,但是这两种方法都使我们的网站在容器内处于静态。通过使用Docker的数据卷功能,我们可以在Droplet的文件系统和容器的文件系统之间创建一个符号链接。这允许我们编辑我们现有的网页文件,并添加新的目录,我们的容器将自动访问它们。如果您想了解更多关于Docker和卷检查了数据量的文档 。 nginx的容器设置在默认情况下寻找一个索引页面/usr/share/nginx/html ,所以在我们的新泊坞容器,我们需要给它在该位置访问我们的文件。 制作链接: 要做到这一点,我们使用-v标志一个文件夹从本地机器(MAP ~/docker-nginx/html )在容器(相对路径/usr/share/nginx/html )。 我们可以通过运行以下命令来完成此任务:
sudo 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
运行命令,如果现在你的浏览器指向你DigitalOceanDroplet的IP地址后,你应该看到你好数字海洋 (或任何网页,您在第5步中创建)的第一个标题。 如果你对其他Nginx默认值感到满意,你就全部设置好了。 您可以上传更多的内容到~/docker-nginx/html/目录下,它会被添加到现有的网站。 例如,如果我们修改我们的索引文件,并且如果我们重新加载我们的浏览器窗口,我们将能够看到它实时更新。如果我们想要,我们可以用这种方式构建一个整个网站的平面HTML文件。例如,如果我们增加了一个about.html页面,我们可以在访问它http:// your_server_ip /about.html而不需要与容器进行交互。

(可选)第7步 - 使用您自己的Nginx配置文件

此部分适用于想要使用自己的Nginx配置文件及其Nginx容器的高级用户。如果您没有要使用的自定义配置文件,请跳过此步骤。 让我们回到一个目录,所以我们不写入我们的公共HTML目录:
cd ~/docker-nginx
如果你想看看默认的配置文件,只需使用Docker copy命令复制它:
sudo docker cp docker-nginx:/etc/nginx/conf.d/default.conf default.conf
因为我们将要使用自定义.conf为Nginx的文件,我们需要重建的容器。 首先停止容器:
sudo docker stop docker-nginx
将其删除:
sudo docker rm docker-nginx
现在你可以在本地编辑默认的文件(服务于一个新的目录,或使用proxy_pass的流量转发到另一个应用程序/容器像你有定期的Nginx安装)。 您可以阅读我们的Nginx的配置文件Nginx的配置文件向导 。 一旦你保存你的自定义配置文件,是时候制作Nginx容器。只需添加第二个-v用适当的路径标志,给人耳目一新的Nginx容器的相应链接,以从自己的配置文件运行。
sudo 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的确实,如果其配置文件被更改不热重装:
sudo docker restart docker-nginx

结论

你现在有一个运行Nginx容器服务自定义网页。 从这里,我们建议在Docker的阅读了容器链接 ,如果你想了解使用Nginx的用作向其他基于容器的Web应用程序反向代理的目的联在一起的容器。 如果你想管理一组容器,比如一个应用程序容器,数据库容器,这种容器的Nginx的,看看Docker Compose