[英]Docker container running apache always exposing port 80
我有一個運行 Apache 的 Docker 映像,並且我已將 Apache(通過httpd.conf )配置為偵聽端口8080
。
Listen 8080
當我構建我的映像並運行它時,我能夠通過端口8080
成功連接到我的網站,所以此時一切似乎都很好。
docker build -t my/apache:8080 .
docker run --name "MyWebsite" -p 8080:8080 -v ~/dir:/mnt/dir -d -t my/apache:8080
但是,當我使用docker ps
列出正在運行的容器時,我發現由於某種原因,端口80
也已暴露。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
23c4e1f0ea66 my/apache:8080 "/docker-entrypoint.…" 12 minutes ago Up 12 minutes 80/tcp, 0.0.0.0:8080->8080/tcp MyWebsite
當我打開正在運行的容器並搜索“Listen 80”的實例時,除了我添加到httpd.conf的“Listen 8080”實例之外,沒有任何顯示。
docker exec -it 23c4e1f0ea66 /bin/bash
grep -ri "Listen 80"
我的 Dockerfile 只包含一個EXPOSE
聲明 - EXPOSE 8080
。 但是,我不相信這實際上會公開端口,而是更多地作為一種記錄在運行使用圖像的容器時應該公開哪個端口的方式。
我怎樣才能知道什么時候暴露端口80
,最重要的是,我怎樣才能阻止它被暴露?
FROM httpd:2.4
COPY httpd.conf /usr/local/apache2/conf/
COPY docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["apache"]
### Apache (proxies to MapProxy).
EXPOSE 8080
#!/bin/bash
set -e
if [ "$1" = 'apache' ]; then
echo "Starting Apache"
httpd-foreground
fi
exec "$@"
ServerRoot "/usr/local/apache2"
Listen 8080
LoadModule mpm_event_module modules/mod_mpm_event.so
LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authn_core_module modules/mod_authn_core.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule access_compat_module modules/mod_access_compat.so
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule reqtimeout_module modules/mod_reqtimeout.so
LoadModule filter_module modules/mod_filter.so
LoadModule mime_module modules/mod_mime.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule env_module modules/mod_env.so
LoadModule headers_module modules/mod_headers.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule version_module modules/mod_version.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule unixd_module modules/mod_unixd.so
LoadModule status_module modules/mod_status.so
LoadModule autoindex_module modules/mod_autoindex.so
<IfModule !mpm_prefork_module>
</IfModule>
<IfModule mpm_prefork_module>
</IfModule>
LoadModule dir_module modules/mod_dir.so
LoadModule alias_module modules/mod_alias.so
<IfModule unixd_module>
User daemon
Group daemon
</IfModule>
ServerAdmin applicationdelivery@landmark.co.uk
ServerName mapproxy.gcs.lmkcloud.net:8080
DocumentRoot "/usr/local/apache2/htdocs"
ErrorLog /proc/self/fd/2
LogLevel warn
<IfModule log_config_module>
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
<IfModule logio_module>
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
</IfModule>
CustomLog /proc/self/fd/1 common
</IfModule>
<IfModule mime_module>
TypesConfig conf/mime.types
AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz
</IfModule>
<IfModule ssl_module>
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
</IfModule>
ProxyPreserveHost On
ProxyPass / http://example.com:8001/ retry=1 acquire=3000 timeout=20 Keepalive=On
ProxyPassReverse / http://example.com:8001/
端口 80 由父 Dockerfile 為httpd:2.4
圖像公開 -
https://github.com/docker-library/httpd/blob/75e85910d1d9954ea0709960c61517376fc9b254/2.4/Dockerfile
EXPOSE
語句最終會在docker ps
為您提供輸出。 但是,它僅暴露給容器網絡,並且不允許通過定義的端口與同一網絡外部的容器或主機進行通信。 要允許這種情況發生,您需要發布端口。
例子 -
docker run -dit --expose 8008 httpd:2.4
輸出 -
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d628b537aded httpd:2.4 "httpd-foreground" 3 seconds ago Up 2 seconds 80/tcp, 8008/tcp objective_dewdney
這會暴露容器端口。 參數--expose
等於在 Dockerfile 中使用EXPOSE
的語句。
現在讓我們嘗試發布端口 -
docker run -dit -p 8009 httpd:2.4
輸出 -
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2c8c93a78e97 httpd:2.4 "httpd-foreground" 2 seconds ago Up 2 seconds 80/tcp, 0.0.0.0:32768->8009/tcp keen_swirles
請參閱0.0.0.0:32768
,它現在已發布到具有隨機臨時端口(即 32768)的主機。您也可以將其發布到特定主機端口。
例子 -
docker run -dit -p 8009:8009 httpd:2.4
輸出 -
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1023df9822e5 httpd:2.4 "httpd-foreground" 2 seconds ago Up 2 seconds 80/tcp, 0.0.0.0:8009->8009/tcp fervent_almeida
簡而言之,現在無法從父 Dockerfile 中取消暴露端口 80。 您當然可以公開更多端口。
這是一個懸而未決的問題——
https://github.com/moby/moby/issues/2210
https://github.com/moby/moby/issues/3465
將@BMitch 評論添加到我認為正確的答案中,因為容器可以在同一網絡中相互通信,而不管暴露的端口 -
根據@BMitch -
EXPOSE 只是文檔/元數據。 它不會改變容器相互通信的方式。 docker ps 只是讓您知道圖像創建者記錄的端口可以發布但尚未發布(因為地圖沒有主機端)。 除非您的代碼或用戶堅持此文檔與您的環境相匹配,否則此處無需更改。 為此,您必須重建上游映像。
在DockerHub 頁面上有關於如何執行此操作的提示。 必須通過 Dockerfile 獲取備用配置文件並將其添加到容器中。
首先獲取配置文件的副本:
docker run --rm httpd:2.4 cat /usr/local/apache2/conf/httpd.conf > my-httpd.conf
然后編輯my-httpd.conf
文件,修改端口:
Listen 8080
最后在 Dockerfile 中添加復制指令:
COPY ./my-httpd.conf /usr/local/apache2/conf/httpd.conf
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.