【问题标题】:Docker Nginx PHP Laravel curl failed to connect to api.localhost port 80. Connection refusedDocker Nginx PHP Laravel curl 无法连接到 api.localhost 端口 80。连接被拒绝
【发布时间】:2021-06-19 05:57:58
【问题描述】:

我是 docker for Windows 的新手,并且有这个设置,其中 2 个 repos 有自己的 docker-compose.yml 文件。一个是API,一个是APP。

APIdocker-compose.yml

version: '3'

networks:
    my_network:
        name: my_network
        ipam:
            config:
                - subnet: 172.23.0.0/24
services:
    my_api:
        build:
            context: .
            dockerfile: .docker/site.dockerfile
        container_name: my_api
        ports:
            - 127.0.12.9:80:80
        volumes:
            - ./:/var/www/html
        networks:
            my_network:
                aliases:
                    - "api.localhost"
    webserver:
        image: nginx:alpine
        container_name: webserver_my_api
        restart: unless-stopped
        tty: true
        ports:
            - 127.0.12.10:80:80
            - 127.0.12.10:443:443
        volumes:
            - ./:/var/www/html
            - ./.docker/nginx/conf.d/:/etc/nginx/conf.d/
        networks:
            - my_network

APPdocker-compose.yml

version: '3'

networks:
    my_network:
        external: true
services:
    my_app:
        build:
            context: .
            dockerfile: .docker/site.dockerfile
        container_name: my_app
        ports:
            - 127.0.12.11:80:80
        volumes:
            - ./:/var/www/html
        networks:
            my_network:
                aliases:
                    - "app.localhost"
    webserver:
        image: nginx:alpine
        container_name: webserver_my_app
        restart: unless-stopped
        tty: true
        ports:
            - 127.0.12.12:80:80
            - 127.0.12.12:443:443
        volumes:
            - ./:/var/www/html
            - ./.docker/nginx/conf.d/:/etc/nginx/conf.d/
        networks:
            - my_network

每个都有自己的 docker 文件。

API和APP都有相同的.docker/site.dockerfile

FROM php:7.4-fpm

USER root

WORKDIR /var/www/html

# just a bunch of RUN commands to install PHP dependencies

EXPOSE 9000
CMD ["php-fpm"]

用于 API 的 Nginx 配置 .docker/nginx/conf.d/app.conf

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

然后是 APP 的 Nginx conf .docker/nginx/conf.d/app.conf

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

之后,我在我的 Windows 主机文件中添加了这些行。

127.0.12.10     api.localhost
127.0.12.12     app.localhost

http://api.localhost 和 http://app.localhost 都可以在我的网络浏览器上运行。但是,当APP向API发出curl请求时,出现以下错误。

cURL error 7: Failed to connect to api.localhost port 80: Connection refused (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for http://api.localhost

当我执行docker network inspect my_network 时,两者都驻留在同一个网络中。

"Containers": {
    "0d77c5cc22c36f8086eb8e5d580562354c4c6b3c7bdd962e0f8cebfa7a3d844b": {
        "Name": "my_api",
        "EndpointID": "93bb1cd93ccd09b7c1fd2de3e074525b2fc98919eba0cf2cc96c2112d4e1e1b5",
        "MacAddress": "02:42:ac:17:00:09",
        "IPv4Address": "172.23.0.9/24",
        "IPv6Address": ""
    },
    "53432448ea91677c643d2f1ff206dcfdc6209741ba9951da342756f752672ab8": {
        "Name": "webserver_my_app",
        "EndpointID": "09ec9ae65461bcc42a750fb0a4fee8305b299c1ad2f1b8e16c65902119489b0d",
        "MacAddress": "02:42:ac:17:00:03",
        "IPv4Address": "172.23.0.3/24",
        "IPv6Address": ""
    },
    "55c2fef084b249a7b3537c641c7101276d9130c6d81d77b21e88206bd10001ec": {
        "Name": "webserver_my_api",
        "EndpointID": "ad1d3b1bedd140a26aec05de276f6f5edc0631b22fa2e77595f5bdf63d9eabca",
        "MacAddress": "02:42:ac:17:00:08",
        "IPv4Address": "172.23.0.8/24",
        "IPv6Address": ""
    },
    "dedfe7f75ef76e913b4483708b9920b7d94f8d4931db74e9831cc86194113d75": {
        "Name": "my_app",
        "EndpointID": "80f2c8e1b83817dda62c682f9ed8e098d8cd3cf4c6d05b3af145e58660368779",
        "MacAddress": "02:42:ac:17:00:05",
        "IPv4Address": "172.23.0.5/24",
        "IPv6Address": ""
    }
},

我也可以通过邮递员提出请求,没有任何问题。就是APP在API上做一个curl的时候。

我错过了什么?

谢谢

编辑:

添加了来自docker ps 命令的截图

【问题讨论】:

    标签: laravel docker nginx curl docker-compose


    【解决方案1】:

    经过数小时的反复试验,我终于找到了答案。

    在我的例子中,我没有使用别名api.localhost,而是使用容器上设置的 IPv4。

    为了获得 IPv4,我运行了docker network inspect my_network,它给了我这个列表。

    "Containers": {
        "0d77c5cc22c36f8086eb8e5d580562354c4c6b3c7bdd962e0f8cebfa7a3d844b": {
            "Name": "my_api",
            "EndpointID": "93bb1cd93ccd09b7c1fd2de3e074525b2fc98919eba0cf2cc96c2112d4e1e1b5",
            "MacAddress": "02:42:ac:17:00:09",
            "IPv4Address": "172.23.0.9/24",
            "IPv6Address": ""
        },
        "53432448ea91677c643d2f1ff206dcfdc6209741ba9951da342756f752672ab8": {
            "Name": "webserver_my_app",
            "EndpointID": "09ec9ae65461bcc42a750fb0a4fee8305b299c1ad2f1b8e16c65902119489b0d",
            "MacAddress": "02:42:ac:17:00:03",
            "IPv4Address": "172.23.0.3/24",
            "IPv6Address": ""
        },
        "55c2fef084b249a7b3537c641c7101276d9130c6d81d77b21e88206bd10001ec": {
            "Name": "webserver_my_api",
            "EndpointID": "ad1d3b1bedd140a26aec05de276f6f5edc0631b22fa2e77595f5bdf63d9eabca",
            "MacAddress": "02:42:ac:17:00:08",
            "IPv4Address": "172.23.0.8/24",
            "IPv6Address": ""
        },
        "dedfe7f75ef76e913b4483708b9920b7d94f8d4931db74e9831cc86194113d75": {
            "Name": "my_app",
            "EndpointID": "80f2c8e1b83817dda62c682f9ed8e098d8cd3cf4c6d05b3af145e58660368779",
            "MacAddress": "02:42:ac:17:00:05",
            "IPv4Address": "172.23.0.5/24",
            "IPv6Address": ""
        }
    },
    

    由于webserver_my_api 是我的nginx 容器,我使用它的IP 地址172.23.0.8。然后我在我的应用程序上运行curl_setopt($cURLConnection, CURLOPT_URL, 'http://172.23.0.8');,它现在可以工作了!!!

    虽然这个解决方案有效,但我仍然不认为它是实际的解决方案。这样做的问题是,当我重新启动容器时,这些 IP 地址会发生变化。

    对此有什么长期解决方案吗?另外,我还是想用api.localhost而不是IP地址。

    谢谢

    【讨论】:

      【解决方案2】:

      当您将端口与 IP 地址绑定时(例如:127.0.12.12:80:80),您会限制与该特定地址的连接。更多here

      【讨论】:

      • 我必须分配 IP 的原因是在我的本地计算机上运行多个网站时在我的 Windows 主机文件中设置它。如果我不分配 IP,那么它将默认为 http://localhost:<some_port_here>
      • 我明白了。但这不会改变工作方式。
      • 我可以知道应用程序还需要什么才能对 api 端点进行休息调用吗?我确实尝试了您的建议,但仍然无法正常工作。
      猜你喜欢
      • 1970-01-01
      • 2018-08-09
      • 2017-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多