【问题标题】:Can't call my Laravel API from the Node.js container but I can call it from Postman无法从 Node.js 容器调用我的 Laravel API,但我可以从 Postman 调用它
【发布时间】:2021-08-19 01:40:09
【问题描述】:

我有以下 4 个容器:

  1. 用于 Laravel API 后端的 php-fpm
  2. Next.js 前端的 node.js 容器
  3. nginx 容器
  4. mysql 容器

我可以调用 Laravel API 并使用 http://localhost:8088/api/products 从 Postman 获取正确的 JSON 数据,但是当我从 Node 容器尝试时,我得到了 FetchError: request to http://localhost:8088/api/ failed, reason: connect ECONNREFUSED 10.0.238.3:8088。我不确定是 nginx 配置问题,还是 docker-compose.yml 配置问题。 我还尝试使用其他几个选项从节点容器调用 API(它们都不起作用):

  1. http://php:8088/api/products
  2. http://localhost:8088/api/products
  3. http://php:9000/api/products - 给出不同的错误:FetchError: request to http://php:9000/api/products/ failed, reason: read ECONNRESET

这是docker-compose.yml

networks:
    laravel:
        driver: bridge

services:
    nginx:
        image: nginx:stable-alpine
        container_name: nginx
        ports:
            - "8088:80"
        volumes:
            - ./laravel-app:/var/www/html 
            - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
        
        depends_on:
            - php
            - mysql           
            - node             
        networks:
            - laravel
            
    mysql:
        image: mysql
        container_name: mysql
        restart: unless-stopped
        tty: true
        ports:
            - "4306:3306"
        volumes:
            - ./mysql:/var/lib/mysql
        environment:
            MYSQL_DATABASE: laravel          
            MYSQL_ROOT_PASSWORD: password
            SERVICE_TAGS: dev
            SERVICE_NAME: mysql            
        networks:
            - laravel
                     
    
    php:
        build:
            context: .
            dockerfile: Dockerfile
        container_name: php
        volumes:
            - ./laravel-app:/var/www/html
        ports:
            - "9000:9000"
        networks:
            - laravel

    node:
        build:
            context: ./nextjs
            dockerfile: Dockerfile
        container_name: next
        
        volumes:
            - ./nextjs:/var/www/html
        ports:
            - "3000:3000"
            - "49153:49153"

        networks:
            - laravel

这是 nginx default.conf 文件:

server {
    listen 80;
    index index.php index.html;
    server_name localhost;
    error_log /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /var/www/html/public;
    
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    
    location ~ \.php$ {        
        try_files $uri = 404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
    
}

【问题讨论】:

标签: docker nginx


【解决方案1】:

如果你想从 node 服务访问你的 Laravel API,你必须使用 http://nginx/your_api_endpoint

Nginx 在这里充当反向代理,它获取端口 80 (listen 80;) 上的流量并将其重定向到您的 Laravel 容器 (fastcgi_pass php:9000;)。

所以你的目标不是 Laravel 容器本身,而是 nginx。

如果其他一切正常,http://nginx/api/products/ 应该可以工作。

【讨论】:

  • 我不敢相信,之前我用错误的端口尝试了http://nginx:8088/api/products/(甚至没有把它放在帖子的列表中)。现在可以了!谢谢!
  • 没问题。仅供参考,如果它不适用于端口,那是因为当您在容器中时,您在私有网络中(您在 docker-compose.yml 中声明的 laravel)。映射到80的端口8088,这里就是说“将主机端口8088映射到容器内的80”。简而言之,这样做是为了从主机(您的机器)访问容器......但是在节点容器内,您不在主机网络中。或者,http://nginx:80/api/products/ 也应该有效。
  • 谢谢,我可以再问你一件事吗?我是在看了一篇关于如何创建使用 Laravel 开发网站的环境的教程后制作了这个 docker-compose.yml 文件,但这里 Laravel 只是 API,实际页面是 node 容器上的 Next.js 文件,是有没有办法让 nginx 服务于前端,而不是直接从他们的主机访问?正如您现在所看到的,它映射 3000:3000,所以我直接从主机访问我的网站,而不是从 nginx 作为代理(就像我使用 Laravel API 一样)
  • 可能是的,但如果只是为了开发目的,它可能会过于复杂。您可以将一个端口从您的 nginx 容器(比如说 3000)映射到容器内的另一个端口,然后创建一个监听该端口并将流量重定向到您的节点容器的虚拟主机,在您的下一个应用程序监听的端口上(例如你用 php 做了,但没有所有的 try_files 东西......)。在没有换行符的有限大小的评论中很难解释:p 但如果你只是在试验,你真的不需要它……但有可能是的。
  • 这个想法是从你的节点容器中删除映射"3000:3000"(因为你不会从你的主机访问它)(顺便说一句,你也可以从你的php容器中删除"9000:9000",因为...... . 好吧,您也没有从您的主机访问它)。然后你将“一个端口”(不管是哪个端口)添加到你的 nginx 容器("xxxx":"8888"),这样你就可以在浏览器中输入localhost:xxxx 并访问你的应用程序。之后,创建一个新的服务器块,监听 8888 端口并执行fastcgi_pass node:3000;。如果你只是用这些小解释来做,做得好:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-06
  • 1970-01-01
  • 2013-02-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多