Docker - 绑定到 0.0.0.0:4000 失败:端口已被占用。

284

我是第一次使用Docker,我正在尝试实现这个操作 - https://docs.docker.com/get-started/part2/#tag-the-image

在某个阶段,我尝试使用以下命令连接本地主机 -

$ curl http://localhost:4000

显示了这个错误 -

curl: (7) Failed to connect to localhost port 4000: Connection refused

然而,我通过以下代码解决了这个问题 -

$ docker-machine ip default
$ curl http://192.168.99.100:4000

之后一切都进行得很好,但在最后一部分,我试图按照教程使用以下代码运行应用程序...

$ docker run -p 4000:80 anibar/get-started:part1

但是,我遇到了这个错误

C:\Program Files\Docker Toolbox\docker.exe: Error response from daemon: driver failed programming external connectivity on endpoint goofy_bohr (63f5691ef18ad6d6389ef52c56198389c7a627e5fa4a79133d6bbf13953a7c98): Bind for 0.0.0.0:4000 failed: port is already allocated.
27个回答

8

docker ps 命令可以列出 Docker 中正在运行的容器。找到正在使用所需端口的容器并记录其 PID。

使用以下命令停止并删除该容器:

docker stop PID
docker rm PID

现在运行docker-compose up,你的服务应该会运行,因为你已经释放了所需的端口。

6

对于使用docker-compose遇到此问题的用户们。当你有多个项目(即在不同文件夹中)具有类似服务的时候,你需要在每个其他项目中运行docker-compose stop


5

针对Windows系统:

我终止了Docker使用的所有进程,并在“服务”中重新启动了Docker服务。现在我的容器正常工作。

这是关于Docker仍然占用端口,即使你此时并没有使用它。


这是我在2023年在Windows 11上工作的修复方法。 - jnchaba

4

在我的情况下,没有需要终止的进程。

更新 Docker 解决了这个问题。


4
可能是由于在docker-compose.ymldocker-compose.override.yml中均指定了相同的端口,或者同时使用环境变量和显式指定相同的端口导致冲突。
我有一个docker-compose.yml文件,其中容器的端口是使用环境变量指定的,并且有一个docker-compose.override.yml文件,其中一个相同的端口是显式指定的。显然,Docker 尝试在同一容器上打开两个端口 。docker container ls -a未列出任何容器,因为该容器无法启动并且无法列出端口。

我也遇到了类似的问题,但是有所不同——docker-compose.yml明确指定了端口,而docker-compose.override.yml则有一个不同的显式设置,以及一个环境变量告诉应用程序使用新端口。通过在docker-compose.yml文件中注释掉ports,解决了问题,因为我们只在本地使用docker-compose(即:使用override文件)。在docker-compose.override.yml中为应用程序定义的环境变量从未被使用,因为应用程序从未启动——对于我们来说,这似乎只是两个compose文件中ports设置不匹配的问题。 - vacri

3
对我来说,容器未能正常显示运行状态,因此没有任何东西使用端口9010(在我的情况下),但是Docker仍在抱怨。
我不想重置我的Docker(对于Windows),所以我所做的只是:
1.删除网络(我知道以前有一个容器正在使用与问题端口(9010)相同的网络 docker network ls docker network rm blabla(或id) 2.实际上我使用了一个新网络而不是旧的(有错误的)网络,但这应该不是必需的 3.重新启动Docker 这是唯一适合我的方法。我无法解释为什么,但某种程度上“旧”网络仍然绑定在该端口(9010)上,Docker继续“阻止”它(关于它的抱怨)。

这真帮了我一个大忙!我的一个容器一直在抱怨端口已经被分配并运行,但在我的 Mac 上运行 lsof 没有显示任何正在使用的端口。我不得不向下滚动到这个答案,最终发现需要删除的网络。之后重新启动容器就成功了! - Jeff Chew

2

对我来说,问题在于重复映射同一端口

由于一个参数化的docker run命令,最终变成了这样的形式:

docker run -p 4000:80 -p 4000:80 anibar/get-started:part1

注意端口4000上的双重映射。

在这种情况下,日志不够详细,因为它没有说明我是双重映射的原因,以及docker run命令返回失败后端口不再绑定


1
谢谢你的回答。我有一个很长的Docker命令字符串,我没有意识到我在开头和结尾都放了-p选项。 - Husniddin Qurbonboyev

2

在Linux上,您可以运行sudo netstat -tulpn命令查看当前正在监听哪个端口。然后,您可以选择配置该进程或Docker容器绑定到不同的端口以避免冲突。


1

如何停止Docker进程

让Docker自己停止 <- 安全快捷

这是停止容器和所有无法停止的进程的最佳方法:让Docker来完成任务。


前往Docker设置 > 资源。更改任何资源并单击应用和重启。


Docker 会停止自身及其每个进程,即使是其他常用命令(如 kill)或其他人建议的更加猛烈的命令(如 rm)也无法杀死最顽固的进程。

我之前遇到过类似的问题,同事们给出的好方法都不起作用。每当我的团队中有人问我这个问题时,我都会分享这个安全技巧。

Error response from daemon: driver failed programming external connectivity on endpoint foobar
Bind for 0.0.0.0:8000 failed: port is already allocated

希望这可以帮到你!

在弄清楚这个问题之前,我尝试了几乎所有的方法。重启电脑、重启 Docker、docker compose downkill,甚至删除一些容器和文件。改变资源以触发 Docker 重启是最好的解决方法!哈哈 - NamsanCode

1

停止容器对我也没有用。我在 docker-compose.yml 中更改了端口。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接