玩转dnmp之端口配置篇
文章簡(jiǎn)介
在上面一篇文章中,分享過(guò)如何搭建和使用dnmp,今天分享如何修改dnmp中PHP容器的端口映射功能。
問(wèn)題歸納
在PHP容器中,安裝了一個(gè)swoole擴(kuò)展,啟動(dòng)了一個(gè)server,端口是9501。在安裝dnmp中,docker配置中將9501給暴露出來(lái)了,按理來(lái)說(shuō),啟動(dòng)服務(wù)之后宿主機(jī)就可以正常訪問(wèn)了,但是提示如下信息。
然后嘗試去telnet端口號(hào),卻發(fā)現(xiàn)是測(cè)試不通。
 ? ert@192 ? ~ ? telnet 127.0.0.1 9501
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Connection closed by foreign host.
問(wèn)題排查
第一步,檢測(cè)PHP容器內(nèi)的9501端口是否正常啟動(dòng)。發(fā)現(xiàn)端口是正常啟動(dòng)的,接下來(lái),看看是不是映射問(wèn)題。
/www # netstat -anp | grep 9501
tcp        0      0 0.0.0.0:9501            0.0.0.0:*               LISTEN      69511/tools.Master
第二步,查看docker的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, 9501/tcp   php
 ert@192 ? ~ ? 
發(fā)現(xiàn)端口暴露有9000和9501,但是發(fā)現(xiàn)9501和9000的卻不一樣。猜想可能是9501沒(méi)有給映射出來(lái)。接下來(lái),查看docker-compose.yml的端口設(shè)置情況,查看到如下代碼:
  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
發(fā)現(xiàn)expose設(shè)置了9501。于是便查看了一下docker的expose配置項(xiàng)說(shuō)明。文檔如下:
EXPOSE 指令是聲明運(yùn)行時(shí)容器提供服務(wù)端口,這只是一個(gè)聲明,在運(yùn)行時(shí)并不會(huì)因?yàn)檫@個(gè)聲明應(yīng)用就會(huì)開啟這個(gè)端口的服務(wù)。在 Dockerfile 中寫入這樣的聲明有兩個(gè)好處,
a.一個(gè)是幫助鏡像使用者理解這個(gè)鏡像服務(wù)的守護(hù)端口,以方便配置映射;
b.另一個(gè)用處則是在運(yùn)行時(shí)使用隨機(jī)端口映射時(shí),也就是 docker run -P 時(shí),會(huì)自動(dòng)隨機(jī)映射 EXPOSE 的端口。
要將 EXPOSE 和在運(yùn)行時(shí)使用 -p <宿主端口>:<容器端口> 區(qū)分開來(lái)。-p,是映射宿主端口和容器端口,換句話說(shuō),就是將容器的對(duì)應(yīng)端口服務(wù)公開給外界訪問(wèn),而 EXPOSE 僅僅是聲明容器打算使用什么端口而已,并不會(huì)自動(dòng)在宿主進(jìn)行端口映射。
總結(jié): docker配置文件中的expose并不是真正的將宿主機(jī)的端口和PHP容器的端口做映射。
問(wèn)題解決
通過(guò)上面的分析,發(fā)現(xiàn)是實(shí)際沒(méi)做映射,接下來(lái),我們直接修改一下配置文件,重新安裝docker容器即可。
第一步:修改如下兩個(gè)配置文件,一個(gè)是.env文件,一個(gè)是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文件一一對(duì)應(yīng)。
      - "${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
第三步:重新啟動(dòng)PHP容器。
docker-compose up php
此時(shí),就重新啟動(dòng)了一個(gè)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
測(cè)試效果
此時(shí),我們啟動(dòng)PHP容器對(duì)應(yīng)的9501端口服務(wù)。訪問(wèn),結(jié)果如下:
這說(shuō)明我們的端口映射成功了。接下來(lái),我們進(jìn)入NGINX容器配置一個(gè)反向代理,直接通過(guò)域名訪問(wèn)對(duì)應(yīng)的端口。
upstream travelApi {
	# 這里的php直接寫PHP容器的名稱即可。
	發(fā)現(xiàn)協(xié)程127.0.0.1是不行的,因?yàn)樵L問(wèn)的是容器內(nèi)部的端口,
	如果不通過(guò)容器訪問(wèn),則直接宿主機(jī)的IP,但是IP可能會(huì)變動(dòng),則寫容器名比較合適。
	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;
    }
}
將對(duì)應(yīng)的域名寫入到宿主機(jī)的host文件,進(jìn)行訪問(wèn),效果如下:
說(shuō)明我們的反向代理也配置成功了。
問(wèn)題總結(jié)
1.docker中的expose不是做端口映射,而僅僅是聲明端口。
2.容器之間監(jiān)聽端口,建議使用容器名稱,如NGINX中的反向代理配置。
總結(jié)
以上是生活随笔為你收集整理的玩转dnmp之端口配置篇的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: 「常识」人是灵长类动物吗
- 下一篇: 护眼色的RGB值和颜色代码
