如何在使用Docker时更改nginx的端口

28

我是一名 Docker 初学者,第一件事就是下载了 nginx 并尝试将其挂载在 80:80 端口,但 Apache 已经占据了这个位置。

docker container run --publish 80:80 nginx

我尝试像这样运行 docker container run --publish 3000:3000 nginx ,使用端口号3000,但它不起作用。它也没有记录任何东西,我可以参考。

5个回答

51

被接受的答案并不会改变nginx实际启动的端口。

如果您想要更改容器内nginx启动的端口,您需要修改容器内的/etc/nginx/nginx.conf文件。

例如,要使用9080端口启动:

Dockerfile

FROM nginx:1.17-alpine
COPY <your static content> /usr/share/nginx/html
COPY nginx.conf /etc/nginx/
EXPOSE 9080
CMD ["nginx", "-g", "daemon off;"]

nginx.conf

# on alpine, copy to /etc/nginx/nginx.conf
user                            root;
worker_processes                auto;

error_log                       /var/log/nginx/error.log warn;

events {
    worker_connections          1024;
}

http {
    include                     /etc/nginx/mime.types;
    default_type                application/octet-stream;
    sendfile                    off;
    access_log                  off;
    keepalive_timeout           3000;
    server {
        listen                  9080;
        root                    /usr/share/nginx/html;
        index                   index.html;
        server_name             localhost;
        client_max_body_size    16m;
    }
}

现在要从您的计算机访问服务器:
docker build . -t my-app
docker run -p 3333:9080 my-app

在浏览器中输入localhost:3333,即可查看您的内容。

可能有一种方法可以包含默认的nginx.conf,并仅覆盖server.listen = PORT属性,但我对nginx配置不太熟悉,所以我只是覆盖了整个默认配置。


你的 nginx 是从哪里来的,它又是用来做什么的? - PositiveGuy
1
@PositiveGuy nginx.conf 是一个配置文件,您可以将其保存在源代码控制下 - 在 Dockerfile 中,您可以指示 Docker 将 nginx.conf 文件从源代码目录复制到路径 /etc/nginx/nginx.conf 的 nginx 容器中,因为这是 nginx 寻找配置的默认位置。换句话说,nginx.conf 与您的 Dockerfile 处于同一级别。 - mancini0
也许不要使用root用户。您还可以使用已经非root的nginx镜像,例如nginxinc/nginx-unprivileged。 - tuxErrante
4
为了使本文保持最新,NGINX 新版本将 nginx.conf 文件移至 /etc/nginx/conf.d/default.conf 路径。因此,复制自定义的 nginx.conf 文件应该像这样:COPY ["default.conf", "/etc/nginx/conf.d/default.conf"]。假设用户只想覆盖默认文件而不添加其他文件。 - Thanos

26

当您开始使用Docker时,您可能会在DockerHub上找到有关镜像的有用信息。例如,对于nginx,您可以在如何公开端口的部分中找到相关信息。

您只需使用:

docker run --publish 3000:80 nginx

你的localhost的3000端口将被转发到80端口,这是nginx镜像用于等待http连接的端口。

我还建议你阅读这些官方文档关于Docker中网络的内容。


7

您说您是一个初学者,首先我要提到的是,nginx镜像的默认配置(我假设您使用的是标准镜像)是监听端口80
这就是为什么您无法映射到容器内部的端口3000,因为没有进程监听此端口。

现在如果我理解正确,并且考虑到您正在使用docker的nginx 我猜您想能够配置容器的端口(而不是主机端口,因为这很显然)。

@mancini0 开始了一个好的方向,但我将展示如何以更动态的方式完成它。

我们将使用envsubst命令,该命令用于替换shell格式字符串中的环境变量。
这个命令可以在官方nginx镜像和alpine版本中使用。

现在来看解决方案。

第一步
编写nginx配置模板文件 - 我们称之为:site.template:

server {
    listen       ${PORT};
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
}

注意PORT占位符。

第二步 - 使用docker-compose
将其挂载到/etc/nginx/conf.d目录中,然后执行envsubst命令,以模板作为default.conf的参考,该文件将用于在容器内设置端口配置:

web:
  image: nginx:alpine
  volumes:
   - ./site.template:/etc/nginx/conf.d/site.template
  ports:
   - "3000:8080"
  environment:
   - PORT=8080
  command: /bin/sh -c "envsubst < /etc/nginx/conf.d/site.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"

请注意:
1. 在此之后,您需要执行nginx守护进程。
2. 我使用的是/bin/sh而不是/bin/bash,因为我的基础镜像是alpine。


步骤#2(另一种选项) - 内联docker run
如果出于某种原因您不想使用docker-compose,则可以使用以下bash脚本:

#!/usr/bin/env bash

##### Variables #####
PORT=8080 #Or $1 if you pass it from command line
TEMPLATE_DIR=$(pwd)/site.template
TEMPLATE_REMOTE_DIR=/etc/nginx/conf.d/site.template
IMAGE_NAME=nginx:alpine

echo "Starting nginx on port: $PORT ..."

##### The docker command #####
docker run -p 3000:$PORT -v $TEMPLATE_DIR:$TEMPLATE_REMOTE_DIR $IMAGE_NAME \
/bin/sh -c "envsubst < $TEMPLATE_REMOTE_DIR > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"

(*) 你也可以使用CMD命令将其写入Dockerfile中,但我不建议这样做。


你能不能在 Dockerfile 中使用 "ENV NGINX_PORT 8080" 来暴露端口? - tuxErrante
EXPOSE指令并不会实际发布端口,它只是一种文档形式,用于构建镜像的人和运行容器的人之间的交流,以表明哪些端口应该被发布。 - RtmY
我写的是 ENV 而不是 EXPOSE。 - tuxErrante
抱歉(: 我认为将其添加到docker-compose.yaml中(就像我所做的那样)比在镜像中硬编码更灵活。 - RtmY

5
你可以使用nginx.conf来更改端口。
nginx.conf将包含所有与nginx相关的配置。这里的默认端口为80,我们可以按如下方式更改它。
nginx.conf
server {
  listen 3000;

  location / {
    root /usr/share/nginx/html;
    index index.html index.htm;
    try_files $uri $uri/ /index.html =404;
  }

  include /etc/nginx/extra-conf.d/*.conf;
}

在 DockerFile 中添加一行:
COPY ./nginx.conf /etc/nginx/conf.d/default.conf

1
请解释一下你的帖子如何提供任何新的帮助。其他答案似乎指向相同的方向,但提供了更多的信息和解释。你更喜欢哪个答案? - FrankM
2
如果我们使用DockerFile,那么这是一个直截了当的答案。 - Sushanth

-1
docker run -e NGINX_PORT=8080 nginx:latest -d 

该页面


2
这是不准确的,也行不通:你链接的页面明确提到需要一些模板才能获取NGINX_PORT变量并在这些模板中进行替换。 - Clorichel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接