Docker Web 和 API 拒绝连接
Docker web and apis refusing connection
我是 docker 的新手。我创建了一个 docker-compose,它有 1 个主应用程序 (laravel) 站点和 2 个 API。
我正在尝试从 laravel 站点访问 API,但不断收到:
cURL error 7: Failed to connect to 0.0.0.0 port 8082: Connection refused (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)
我的docker-compose.yml是:
version: '3'
services:
web:
image: nginx:1.10
volumes:
- ./vhost.conf:/etc/nginx/conf.d/default.conf
ports:
- "8080:80"
depends_on:
- app
restart: always
app:
build: . #run the dockerfile to install whatever
env_file: .env
volumes:
- ./:/var/www
depends_on:
- database
web-api2:
image: nginx:1.10
volumes:
- ../api/api2/vhost.conf:/etc/nginx/conf.d/default.conf
ports:
- "8081:81"
depends_on:
- app-api2
app-api2:
build: . #run the dockerfile to install whatever
env_file: .env
volumes:
- ../api/api2:/var/www
depends_on:
- database
web-api1:
image: nginx:1.10
volumes:
- ../api/api1/vhost.conf:/etc/nginx/conf.d/default.conf
ports:
- "8082:82"
depends_on:
- app-api1
app-api1:
build: . #run the dockerfile to install whatever
env_file: ../api/api1/.env
volumes:
- ../api/api1:/var/www
depends_on:
- database
database:
image: mysql:5.7
environment:
- "MYSQL_ROOT_PASSWORD=IAmSoSecure"
- "MYSQL_DATABASE=my_app"
ports:
- "33061:3306"
volumes:
- my_app:/var/lib/mysql
restart: always
volumes:
wildfire:
我研究了 docker 网络,但我的尝试失败了。我有一个网络设置,并尝试使用子网但没有成功:
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
我也尝试访问我启用的端口:
"Ports": {
"443/tcp": null,
"80/tcp": null,
"82/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "8082"
}
]
},
我像往常一样通过 Guzzle 请求呼叫:
$client = new Client();
$res = $client->get('127.0.0.1:8082/accounts');
dd($res->getBody()->getContents());
我尝试了不同的 IP,但找不到正确的 IP。
我目前的 vhost.conf 是:
server {
listen 80;
index index.php server.php;
root /var/www/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
index index.html server.php index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 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;
include fastcgi_params;
include /etc/nginx/mime.types;
}
location ~ /\.(?!well-known).* {
deny all;
}
location ~ \.css {
add_header Content-Type text/css;
}
location ~ \.js {
add_header Content-Type application/x-javascript;
}
}
在您的 docker compose 上,您启动了 3 个 nginx:web、web-api2 和 web-api1.
根据你写的,web-api2 在端口 81 上监听,web-api1 在端口 82 上监听。
如果您想从 web 中的应用程序访问 api,您需要使用:
http://web-api2:81/...
http://web-api1:82/...
请注意,从您的 本地计算机,您将使用 http://localhost:8081
和 http://localhost:8082
将端口 8081 映射到网络上的 81-api2 和网络上的 8082 到 82-api1.
在 docker compose 创建的默认网络上,每个由 orchestrator 管理的容器都可以通过它的服务名称访问,该名称恰好与 docker-compose.yaml
文件中给定的名称相同。因此,在您的情况下,同一网络上的每个容器都可能达到 app-api2
作为您的问题详细信息:
http://app-api2:82/accounts
要从您的容器中使用 127.0.0.1
获得更完整的答案,这意味着您正在尝试访问容器本身内的服务并监听,在您的情况下,82
。由于您在同一个容器中没有其他可执行文件 运行 并在该端口上侦听您正确接收 Connection refused
.
了解您并不严格需要为同一网络上的其他容器公开 docker-compose.yaml
文件中的端口可能对您也很有用交流。公开的端口使您能够从主机发出请求(实际上您会使用 127.0.0.1
)。
如果出于某种原因你确实想使用容器的 IP 地址在容器之间进行通信,那么你可以使用 docker inspect <container name>
找到特定容器的当前 IP。但是请注意,此 IP 是临时的,每次启动容器时都可能会更改。
为了解决这个问题,我将我正在查看的 url 更改为:
$client = new Client();
$res = $client->get('**http://web-api2:82/accounts**');
dd($res->getBody()->getContents());
为了最佳实践,我还将端口号更改为 8082。这也反映在我的 docker-compose.yml 中:
web 8080:8080
web-api1 8081:8081
web-api2 8082:8082
感谢大家的回答!
我是 docker 的新手。我创建了一个 docker-compose,它有 1 个主应用程序 (laravel) 站点和 2 个 API。
我正在尝试从 laravel 站点访问 API,但不断收到:
cURL error 7: Failed to connect to 0.0.0.0 port 8082: Connection refused (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)
我的docker-compose.yml是:
version: '3'
services:
web:
image: nginx:1.10
volumes:
- ./vhost.conf:/etc/nginx/conf.d/default.conf
ports:
- "8080:80"
depends_on:
- app
restart: always
app:
build: . #run the dockerfile to install whatever
env_file: .env
volumes:
- ./:/var/www
depends_on:
- database
web-api2:
image: nginx:1.10
volumes:
- ../api/api2/vhost.conf:/etc/nginx/conf.d/default.conf
ports:
- "8081:81"
depends_on:
- app-api2
app-api2:
build: . #run the dockerfile to install whatever
env_file: .env
volumes:
- ../api/api2:/var/www
depends_on:
- database
web-api1:
image: nginx:1.10
volumes:
- ../api/api1/vhost.conf:/etc/nginx/conf.d/default.conf
ports:
- "8082:82"
depends_on:
- app-api1
app-api1:
build: . #run the dockerfile to install whatever
env_file: ../api/api1/.env
volumes:
- ../api/api1:/var/www
depends_on:
- database
database:
image: mysql:5.7
environment:
- "MYSQL_ROOT_PASSWORD=IAmSoSecure"
- "MYSQL_DATABASE=my_app"
ports:
- "33061:3306"
volumes:
- my_app:/var/lib/mysql
restart: always
volumes:
wildfire:
我研究了 docker 网络,但我的尝试失败了。我有一个网络设置,并尝试使用子网但没有成功:
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
我也尝试访问我启用的端口:
"Ports": {
"443/tcp": null,
"80/tcp": null,
"82/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "8082"
}
]
},
我像往常一样通过 Guzzle 请求呼叫:
$client = new Client();
$res = $client->get('127.0.0.1:8082/accounts');
dd($res->getBody()->getContents());
我尝试了不同的 IP,但找不到正确的 IP。
我目前的 vhost.conf 是:
server {
listen 80;
index index.php server.php;
root /var/www/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
index index.html server.php index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 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;
include fastcgi_params;
include /etc/nginx/mime.types;
}
location ~ /\.(?!well-known).* {
deny all;
}
location ~ \.css {
add_header Content-Type text/css;
}
location ~ \.js {
add_header Content-Type application/x-javascript;
}
}
在您的 docker compose 上,您启动了 3 个 nginx:web、web-api2 和 web-api1.
根据你写的,web-api2 在端口 81 上监听,web-api1 在端口 82 上监听。
如果您想从 web 中的应用程序访问 api,您需要使用:
http://web-api2:81/...
http://web-api1:82/...
请注意,从您的 本地计算机,您将使用 http://localhost:8081
和 http://localhost:8082
将端口 8081 映射到网络上的 81-api2 和网络上的 8082 到 82-api1.
在 docker compose 创建的默认网络上,每个由 orchestrator 管理的容器都可以通过它的服务名称访问,该名称恰好与 docker-compose.yaml
文件中给定的名称相同。因此,在您的情况下,同一网络上的每个容器都可能达到 app-api2
作为您的问题详细信息:
http://app-api2:82/accounts
要从您的容器中使用 127.0.0.1
获得更完整的答案,这意味着您正在尝试访问容器本身内的服务并监听,在您的情况下,82
。由于您在同一个容器中没有其他可执行文件 运行 并在该端口上侦听您正确接收 Connection refused
.
了解您并不严格需要为同一网络上的其他容器公开 docker-compose.yaml
文件中的端口可能对您也很有用交流。公开的端口使您能够从主机发出请求(实际上您会使用 127.0.0.1
)。
如果出于某种原因你确实想使用容器的 IP 地址在容器之间进行通信,那么你可以使用 docker inspect <container name>
找到特定容器的当前 IP。但是请注意,此 IP 是临时的,每次启动容器时都可能会更改。
为了解决这个问题,我将我正在查看的 url 更改为:
$client = new Client();
$res = $client->get('**http://web-api2:82/accounts**');
dd($res->getBody()->getContents());
为了最佳实践,我还将端口号更改为 8082。这也反映在我的 docker-compose.yml 中:
web 8080:8080
web-api1 8081:8081
web-api2 8082:8082
感谢大家的回答!