如何设置 docker 和 nginx 进行本地开发

Sam*_*Sam 3 nginx docker docker-compose

语境

\n

我正在尝试构建一个本地开发环境,并且正在努力让它发挥作用。我希望 docker 和 docker compose 将 nginx 作为反向代理和 postgresql 数据库运行

\n

项目结构

\n
my-app/\n\xe2\x94\x9c\xe2\x94\x80 server/ (fastify node server)\n\xe2\x94\x9c\xe2\x94\x80 client/ (sveltekit dev server)\n\xe2\x94\x9c\xe2\x94\x80 nginx/\n\xe2\x94\x82  \xe2\x94\x9c\xe2\x94\x80 Dockerfile\n\xe2\x94\x82  \xe2\x94\x9c\xe2\x94\x80 default.conf\n\xe2\x94\x9c\xe2\x94\x80 docker-compose.yml\n
Run Code Online (Sandbox Code Playgroud)\n

我希望唯一的先决条件是 Node、git 和 docker。我能够克隆项目,启动 docker compose,然后分别启动两个项目

\n

先前的研究

\n

我已经阅读了 nginx 初学者指南和几篇 nginx 文档,但我发现他们的文档相当难以理解。我还找到了一些指南,这些指南让我的客户端和服务器在 docker 容器内运行,并在 docker compose 中设置为单独的服务。这不是最终目标,但不幸的是我也没有让这些发挥作用。

\n

这个问题似乎很接近,我发现它很有帮助。但它\xe2\x80\x99s仍然无法工作。

\n

首先,我只是想让一切在 http://localhost:4000 上正常工作,以消除一些复杂性

\n

这是迄今为止我最好的尝试:

\n
\n    ##########################\n    # docker-compose.yml\n    ##########################\n    \n    version: \'3.9\'\n    services:\n      reverse-proxy:\n        build: ./nginx\n        ports:\n          - 8080:8080\n    \n    ##########################\n    # nginx/Dockerfile\n    ##########################\n    FROM nginx:1.21.3\n    COPY ./default.conf /etc/nginx/conf.d/default.conf/\n    \n    ##########################\n    # nginx/default.conf\n    ##########################\n    \n    server {\n      listen 8080;\n    \n      location / {\n        proxy_pass http://host.docker.internal:8080;\n      }\n    \n      location /api/ {\n        proxy_pass http://host.docker.internal:3000;\n      }\n    }\n
Run Code Online (Sandbox Code Playgroud)\n

通过此设置,我可以点击 http://localhost:3000/api/ 并从服务器获取 json 响应,但是当我尝试点击 http://localhost:8080/api/ 时,我得到标准的 nginx 502响应和 nginx 未成功到达我的节点服务器。nginx 日志给我这个错误:

\n
     2021/11/16 12:38:39 [error] 34#34: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.19.0.1, server: , request: "GET /api/ HTTP/1.1", upstream: "http://192.168.65.2:3000/api/", host: "localhost:8080"\n
Run Code Online (Sandbox Code Playgroud)\n

我不知道上面的IP地址来自哪里,但是如果我在本地点击http://192.168.65.2:3000/api/,那么浏览器就会不停地旋转。

\n

最终目标

\n

我正在寻找一个配置正确docker-compose.yml且相对简单的 nginx 文件,以便映射到默认值。HTTPS 和自定义 URL 确实是后来的问题。目前,我只想能够在 docker 容器内访问 nginx 反向代理,并正确路由到两个本地运行的节点服务器(一台是 API 服务器,一台是 sveltekit 开发服务器 - 都不在 docker 容器内)。

\n

预先感谢您的任何帮助!

\n

编辑(在 Robert-Jan Kuyper 建议的更改后)

\n

我现在基本上是这样运行的:

\n
##########################\n# docker-compose.yml\n##########################\n\nversion: \'3.8\'\nservices:\n  nginx:\n    image: nginx:1.19.4\n    depends_on:\n      - api\n    volumes:\n      - ./nginx/default.local.conf:/etc/nginx/conf.d/default.conf\n    ports:\n      - \'8080:8080\'\n  api:\n    build: ./api\n    hostname: api\n    command: node src/app.js\n    volumes:\n      - ./server/src:/app/src\n\n\n##########################\n# nginx/default.conf\n##########################\n\nupstream api_server {\n    server api:3000;\n}\n\nserver {\n  listen 8080;\n\n  location /api/ {\n    proxy_pass http://api_server;\n  }\n}\n\n##########################\n# api/Dockerfile\n##########################\n\nFROM node:16.9.0\n\n# docker workdir\nWORKDIR /home/usr/app\n\n# copy files\nCOPY . .\n\n# build the app\nRUN npm ci\n\n# expose at port 3000\nEXPOSE 3000\n\n\nCMD ["node", "src/app.js"]\n
Run Code Online (Sandbox Code Playgroud)\n

不幸的是,它仍然失败:

\n
[error] 29#29: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.1, server: , request: "GET /api/ HTTP/1.1", upstream: "http://172.18.0.2:3000/api/", host: "localhost:8080"\n
Run Code Online (Sandbox Code Playgroud)\n

Rob*_*per 5

您必须记住以下几点:

  1. Docker compose 默认使用服务名称作为容器间网络的主机名
  2. Nginx需要先了解上游
  3. 您不需要在 Dockerfile 中使用 Nginx,docker-compose.yml而是直接使用它。并将您的配置文件安装到容器中。
  4. 您需要对前端和后端进行 dockerize 以将它们连接到 nginx
  5. 始终在Docker 容器0.0.0.0127.0.0.1或内部公开,请参阅此答案localhost

我使用 nginx、docker 和 docker-compose 的示例存储库: https: //gitlab.com/datails/api

例子default.conf

upstream api_server {
    server api:3000;
}

upstream frontend {
    server frontend:3000;
}

server {
    listen 80;

    location /api {
        proxy_pass http://api_server;
    }

    location / {           
        proxy_pass http://frontend/;
    }
}
Run Code Online (Sandbox Code Playgroud)

例子docker-compose.yml

version: '3.8'
services:
  nginx:
    image: nginx:1.19.4
    depends_on:
      - server
      - frontend
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
    ports:
      - '8080:80'
Run Code Online (Sandbox Code Playgroud)

然后确保您的前端已经 Docker 化并frontend在 docker-compose 中作为服务调用,如下所示:

version: '3.8'
services:    
  nginx:
    image: nginx:1.19.4
    depends_on:
      - server
      - frontend
    volumes:
      - ./default.conf:/etc/nginx/conf.d/default.conf
    ports:
      - '8080:80'

  frontend:
    build: ./frontend
    command: npm run start
    volumes:
      - ./frontend/src:/home/usr/app/src

  api:
    build: ./api
    command: npm run start
    volumes:
      - ./api/src:/home/usr/app/src
Run Code Online (Sandbox Code Playgroud)

请注意,您不需要端口,因为您使用容器间通信。