簡體   English   中英

運行 apache 的 Docker 容器總是暴露端口 80

[英]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 "$@"

HTTP 配置

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM