如何使用Docker运行Nginx

818 阅读3分钟

NGINX是一个流行的开源软件,用于网络服务、反向代理、缓存、负载平衡、媒体流等。它还可以作为电子邮件(IMAP、POP3和SMTP)的代理服务器以及HTTP、TCP和UDP服务器的反向代理和负载平衡器。Nginx现在相当流行,在许多大流量网站上使用。在本教程中,我们将学习如何使用[Docker]在容器中运行Nginx。我们将解决如何下载和运行镜像,从该镜像中创建几个容器,了解前台与后台任务,并查看如何检查日志。


镜像与容器

  • 镜像是一个你想运行的应用程序
  • 容器作为一个进程运行的镜像的一个实例
  • 可以有很多容器通过同一个镜像运行。
  • Docker Hub是镜像的主要注册中心,位于hub.docker.com。

启动一个容器

我们可以使用下面的命令启动一个新的容器。

docker container run --publish 80:80 nginx

你可能会在终端看到一些与此类似的输出。

$ docker container run --publish 80:80 nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Configuration complete; ready for start up

Docker Dashboard也会显示正在运行的容器。

nginx docker container running

打开浏览器[访问http://localhost,我们应该看到一个Nginx网络服务器正在愉快地提供默认的网页。

nginx web page via docker

在终端中,我们也会看到浏览器从网络服务器发出请求的一些日志。

172.17.0.1 - - [28/Sep/2020:15:10:03 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36" "-"

它是如何工作的

docker container run -publish 80:80 nginx

当上面的命令被触发时,Docker引擎会采取一系列的步骤。

  1. 从Docker Hub下载Nginx镜像,如果本地缓存中没有的话
  2. 从Nginx镜像中启动一个新的容器
  3. 在主机IP上打开80端口
  4. 将主机流量80端口路由到容器IP 80端口

在分离模式下运行

我们之所以能够直接看到容器的日志输出,是因为该容器是在前台运行的。很多时候,你只是想让容器在后台运行。这就是所谓的分离模式。首先,我们需要停止运行中的容器。我们可以这样做,首先用docker ps找到容器的id或名称,然后用docker stop命令来停止它。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
902affce585b        nginx               "/docker-entrypoint.…"   2 hours ago         Up 2 hours          0.0.0.0:80->80/tcp   sharp_hoover

根据上面的输出,我们可以用以下两种方法中的任何一种来停止该容器。

  • docker stop sharp_hoover
  • docker stop 902affce585b

现在让我们再次运行该镜像,创建一个全新的、以分离模式运行的容器。注意-detach标志的使用。

$ docker container run --publish 80:80 --detach nginx

Detach告诉Docker在后台运行该容器,在这种情况下,向终端的唯一输出是唯一的容器ID。每次你运行一个新的容器,你都会得到一个新的唯一ID。让我们用[docker container ls]再看一下运行中的容器。

$ docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
d62595efbb6c        nginx               "/docker-entrypoint.…"   4 minutes ago       Up 4 minutes        0.0.0.0:80->80/tcp   quizzical_hermann

我们在后台运行的新Nginx容器的名字是quizzical_hermann

我们可以用docker container stop来停止该容器,只需输入容器ID的前几个字符。

$ docker container stop d62
d62

列举容器

在过去,你可以用docker ps来显示容器。现在更合适的方法是使用docker container ls来列出容器。当列出我们的容器时,我们没有看到任何容器。

$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

这是因为如果一个容器没有运行,它将不会被显示出来。要看到所有的容器,即使是那些没有运行的,你需要添加**-a**标志。

$ docker container ls -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
d62595efbb6c        nginx               "/docker-entrypoint.…"   14 minutes ago      Exited (0) 4 minutes ago                        quizzical_hermann
902affce585b        nginx               "/docker-entrypoint.…"   2 hours ago         Exited (0) 16 minutes ago                       sharp_hoover

现在我们看到了这两个容器。如果你在创建过程中没有为容器指定一个名字,这些有趣的名字就会自动创建。就像容器的每个ID都是唯一的一样,名称也需要是唯一的。Docker从一个开源的形容词列表和著名的科学家黑客中随机生成名字。那么,我们怎样才能给容器起一个自己的名字呢?我们可以通过指定-name标志来做到这一点。

$ docker container run --publish 80:80 --detach --name my_nginx_server nginx
4402b968a91567195e690ca4c5c7d79525c5823f640ff0d2cceb6ee045d2a8d6

$ docker container ls -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS                NAMES
4402b968a915        nginx               "/docker-entrypoint.…"   8 seconds ago       Up 7 seconds                0.0.0.0:80->80/tcp   my_nginx_server
d62595efbb6c        nginx               "/docker-entrypoint.…"   19 minutes ago      Exited (0) 10 minutes ago                        quizzical_hermann
902affce585b        nginx               "/docker-entrypoint.…"   2 hours ago         Exited (0) 21 minutes ago                        sharp_hoover


在分离模式下查看容器日志

如果一个容器在后台运行,我们不会在终端看到任何日志的输出。如果我们想看这些日志,我们可以用[docker container logs]命令来做。

$ docker container logs my_nginx_server
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
172.17.0.1 - - [28/Sep/2020:17:18:38 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36" "-"
172.17.0.1 - - [28/Sep/2020:17:18:39 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36" "-"

使用容器工作

下面是你在使用容器时需要熟悉的命令。

$ docker container

Usage:  docker container COMMAND

Manage containers

Commands:
  attach      Attach local standard input, output, and error streams to a running container
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  exec        Run a command in a running container
  export      Export a container's filesystem as a tar archive
  inspect     Display detailed information on one or more containers
  kill        Kill one or more running containers
  logs        Fetch the logs of a container
  ls          List containers
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  prune       Remove all stopped containers
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  run         Run a command in a new container
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  wait        Block until one or more containers stop, then print their exit codes

Run 'docker container COMMAND --help' for more information on a command.


移除容器

在这一点上,我们总共有3个容器。一个正在运行,另外两个是空闲的。让我们试着一次就把它们全部删除。

$ docker container rm 440 d62 902
d62
902
Error response from daemon: You cannot remove a running container 4402b968a91567195e690ca4c5c7d79525c5823f640ff0d2cceb6ee045d2a8d6. Stop the container before attempting removal or force remove

其中两个容器被删除了,然而,我们可以从错误信息中看到,如果不先停止运行中的容器或者强制删除,就不能删除它。这里我们使用-f标志来强制删除正在运行的容器。

$ docker container rm 440 -f
440

最后,我们再一次列出所有容器,我们可以看到我们的docker游乐场是干净的。

$ docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

总结

我们了解了一些使用Nginx和Docker的基本命令。