docker - 如何为本地开发设置 docker 和 nginx
问题描述
语境
我正在尝试建立一个本地开发环境,但我正在努力让它发挥作用。我希望 docker 和 docker compose 将 nginx 作为反向代理和 postgresql 数据库运行
项目结构
my-app/
├─ server/ (fastify node server)
├─ client/ (sveltekit dev server)
├─ nginx/
│ ├─ Dockerfile
│ ├─ default.conf
├─ docker-compose.yml
我希望唯一的先决条件是 Node、git 和 docker。我能够克隆项目,启动 docker compose,然后分别启动两个项目
先前的研究
我已经阅读了 nginx 初学者指南和几篇 nginx 文档,但我发现他们的文档相当难以接近。我还找到了一些指南,它们让我的客户端和服务器在 docker 容器中运行,并在 docker compose 中设置为单独的服务。这不是最终目标,但不幸的是我也没有让那些工作。
这个问题似乎很接近,我发现它很有帮助。但它仍然无法正常工作。
首先,我只是想让一切都在 http://localhost:4000 上运行,以消除一些复杂性
这是我迄今为止最好的尝试:
##########################
# docker-compose.yml
##########################
version: '3.9'
services:
reverse-proxy:
build: ./nginx
ports:
- 8080:8080
##########################
# nginx/Dockerfile
##########################
FROM nginx:1.21.3
COPY ./default.conf /etc/nginx/conf.d/default.conf/
##########################
# nginx/default.conf
##########################
server {
listen 8080;
location / {
proxy_pass http://host.docker.internal:8080;
}
location /api/ {
proxy_pass http://host.docker.internal:3000;
}
}
有了这个设置,我可以点击 http://localhost:3000/api/ 并从服务器获取我的 json 响应,但是当我尝试点击 http://localhost:8080/api/ 时,我得到标准的 nginx 502响应和 nginx 没有成功到达我的节点服务器。nginx 日志给了我这个错误:
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"
我不知道上面的 IP 地址是从哪里来的,但是如果我在本地点击http://192.168.65.2:3000/api/,那么浏览器就会不停地旋转。
最终目标
目前,我正在寻找一个正确配置docker-compose.yml
且相对简单的 nginx 文件,该文件被映射到默认值。HTTPS 和自定义 URL 确实是后来的问题。现在,我只想能够在 docker 容器中访问我的 nginx 反向代理,并正确路由到我的两个本地运行的节点服务器(一个是 API 服务器,一个是 sveltekit 开发服务器 - 不在 docker 容器内)。
预先感谢您的任何帮助!
编辑(Robert-Jan Kuyper 建议的更改后)
我现在基本上是这样运行的:
##########################
# docker-compose.yml
##########################
version: '3.8'
services:
nginx:
image: nginx:1.19.4
depends_on:
- api
volumes:
- ./nginx/default.local.conf:/etc/nginx/conf.d/default.conf
ports:
- '8080:8080'
api:
build: ./api
hostname: api
command: node src/app.js
volumes:
- ./server/src:/app/src
##########################
# nginx/default.conf
##########################
upstream api_server {
server api:3000;
}
server {
listen 8080;
location /api/ {
proxy_pass http://api_server;
}
}
##########################
# api/Dockerfile
##########################
FROM node:16.9.0
# docker workdir
WORKDIR /home/usr/app
# copy files
COPY . .
# build the app
RUN npm ci
# expose at port 3000
EXPOSE 3000
CMD ["node", "src/app.js"]
不幸的是,它仍然失败:
[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"
解决方案
您必须记住以下几点:
- Docker compose 默认使用服务名作为容器间网络的主机名
- Nginx 需要先了解上游
- 您不需要在 Dockerfile 中使用 Nginx,而是直接使用它
docker-compose.yml
。并将您的配置文件安装到容器中。 - 您需要将前端和后端 dockerize 以将它们连接到 nginx
- 始终在您的 docker 容器中
0.0.0.0
而不是127.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/;
}
}
例子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'
然后确保你的前端 dockerized 并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
请注意,您不需要端口,因为您使用容器间通信。
推荐阅读
- jms - 在 Spring jms 监听器中捕获提交异常
- python - 如何查看 keras 层的变量槽的值
- python - 具有不对称误差惩罚的分类交叉熵
- bookdown - gt::opt_row_striping 在 rmarkdown 中可以,在 bookdown 中不行
- java - 从java运行maven命令
- firefox - 如何在 Firefox 中修复绿色文本和缺失字符
- tensorflow - 区分 RNN 模型与非 RNN 模型 TFLite
- azure-devops - Azure 存储库 - 仅在构建通过时才通知 PR 审阅者
- python - 使用 rhino python 脚本时无法快照和存储
- python - 将列中的行类别除以相同类别但不同日期的值