在上面一篇文章中,分享過如何搭建和使用dnmp,今天分享如何修改dnmp中PHP容器的端口映射功能。php
在PHP容器中,安裝了一個swoole擴展,啓動了一個server,端口是9501。在安裝dnmp中,docker配置中將9501給暴露出來了,按理來講,啓動服務以後宿主機就能夠正常訪問了,可是提示以下信息。
nginx
而後嘗試去telnet端口號,卻發現是測試不通。docker
✘ ert@192 ~ telnet 127.0.0.1 9501 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Connection closed by foreign host.
第一步,檢測PHP容器內的9501端口是否正常啓動。發現端口是正常啓動的,接下來,看看是否是映射問題。shell
/www # netstat -anp | grep 9501 tcp 0 0 0.0.0.0:9501 0.0.0.0:* LISTEN 69511/tools.Master
第二步,查看docker的PHP容器端口映射有哪些。api
✘ ert@192 ~ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 68a39b4d38ff dnmp_php "docker-php-entrypoi…" 23 hours ago Up 23 hours 0.0.0.0:9000->9000/tcp, 9501/tcp php ert@192 ~
發現端口暴露有9000和9501,可是發現9501和9000的卻不同。猜測多是9501沒有給映射出來。接下來,查看docker-compose.yml的端口設置狀況,查看到以下代碼:swoole
php: build: context: ./services/php args: PHP_VERSION: php:${PHP_VERSION}-fpm-alpine CONTAINER_PACKAGE_URL: ${CONTAINER_PACKAGE_URL} PHP_EXTENSIONS: ${PHP_EXTENSIONS} TZ: "$TZ" container_name: php expose: - 9501 extra_hosts: - "www.site1.com:172.17.0.1" volumes: - ${SOURCE_DIR}:/www/:rw - ${PHP_PHP_CONF_FILE}:/usr/local/etc/php/php.ini:ro - ${PHP_FPM_CONF_FILE}:/usr/local/etc/php-fpm.d/www.conf:rw - ${PHP_LOG_DIR}:/var/log/php - ${DATA_DIR}/composer:/tmp/composer restart: always cap_add: - SYS_PTRACE networks: - default
發現expose設置了9501。因而便查看了一下docker的expose配置項說明。文檔以下:cookie
EXPOSE 指令是聲明運行時容器提供服務端口,這只是一個聲明,在運行時並不會由於這個聲明應用就會開啓這個端口的服務。在 Dockerfile 中寫入這樣的聲明有兩個好處,composer
a.一個是幫助鏡像使用者理解這個鏡像服務的守護端口,以方便配置映射;tcp
b.另外一個用處則是在運行時使用隨機端口映射時,也就是 docker run -P 時,會自動隨機映射 EXPOSE 的端口。php-fpm
要將 EXPOSE 和在運行時使用 -p <宿主端口>:<容器端口> 區分開來。-p,是映射宿主端口和容器端口,換句話說,就是將容器的對應端口服務公開給外界訪問,而 EXPOSE 僅僅是聲明容器打算使用什麼端口而已,並不會自動在宿主進行端口映射。
總結: docker配置文件中的expose並非真正的將宿主機的端口和PHP容器的端口作映射。
經過上面的分析,發現是實際沒作映射,接下來,咱們直接修改一下配置文件,從新安裝docker容器便可。
第一步:修改以下兩個配置文件,一個是.env文件,一個是docker-compose.yml文件。
// .env # 這裏就是須要作映射的端口,多配置便可避免後期須要使用。 PHP_HOST_PORT=9000 PHP_HYPERF1_PORT=9501 PHP_HYPERF2_PORT=9502 PHP_HYPERF3_PORT=9503
// docker-compose.yml php: build: context: ./services/php args: PHP_VERSION: php:${PHP_VERSION}-fpm-alpine CONTAINER_PACKAGE_URL: ${CONTAINER_PACKAGE_URL} PHP_EXTENSIONS: ${PHP_EXTENSIONS} TZ: "$TZ" container_name: php ports: # 這裏的${xxx}和.env文件一一對應。 - "${PHP_HOST_PORT}:9000" - "${PHP_HYPERF1_PORT}:9501" - "${PHP_HYPERF2_PORT}:9502" - "${PHP_HYPERF3_PORT}:9503" extra_hosts: - "www.site1.com:172.17.0.1" volumes: - ${SOURCE_DIR}:/www/:rw - ${PHP_PHP_CONF_FILE}:/usr/local/etc/php/php.ini:ro - ${PHP_FPM_CONF_FILE}:/usr/local/etc/php-fpm.d/www.conf:rw - ${PHP_LOG_DIR}:/var/log/php - ${DATA_DIR}/composer:/tmp/composer restart: always cap_add: - SYS_PTRACE networks: - default
第二步:刪除以前的PHP重啓端口
docker stop 68a39b4d38ff && docker rm 68a39b4d38ff
第三步:從新啓動PHP容器。
docker-compose up php
此時,就從新啓動了一個PHP容器了,而且容器的端口也作好映射了。
ert@192 ~ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 68a39b4d38ff dnmp_php "docker-php-entrypoi…" 23 hours ago Up 23 hours 0.0.0.0:9000->9000/tcp, 0.0.0.0:9501-9503->9501-9503/tcp php
此時,咱們啓動PHP容器對應的9501端口服務。訪問,結果以下:
這說明咱們的端口映射成功了。接下來,咱們進入NGINX容器配置一個反向代理,直接經過域名訪問對應的端口。
upstream travelApi { # 這裏的php直接寫PHP容器的名稱便可。 發現協程127.0.0.1是不行的,由於訪問的是容器內部的端口, 若是不經過容器訪問,則直接宿主機的IP,可是IP可能會變更,則寫容器名比較合適。 server php:9501; } server { listen 80; server_name travel_api.com; location / { proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict"; proxy_pass http://travelApi; } }
將對應的域名寫入到宿主機的host文件,進行訪問,效果以下:
說明咱們的反向代理也配置成功了。
1.docker中的expose不是作端口映射,而僅僅是聲明端口。
2.容器之間監聽端口,建議使用容器名稱,如NGINX中的反向代理配置。