mac環境下使用docker安裝nginx


前言

距離上一篇文章已經很長時間,近期實在事情太多了,也沒來得及繼續更新一些新的內容。現在開發使用的工作實在太多了,小編實在忍受不了windows那樣卡機的狀態,於是最近換了一個mac電腦,雖然做開發已經很長時間了,之前一直沒有用過mac,不過使用過后才發現mac實在是windows無法媲美的,當然了mac的價格也是相當的昂貴啊....

好了廢話不多說了,現在讓我們開始正題,首先讓我們現在mac下如何安裝docker

docker安裝

Docker 官網:http://www.docker.com

Github Docker 源碼:https://github.com/docker/docker

docker相關介紹,這里就不多說了啊,沒學習過的同學可以看下上面的2個網址學習下。

安裝命令

brew cask install docker

怎么樣是不是很方便,在mac環境下只需要執行上面一句話就可以搞定docker的安裝了,當然了這里的前提是你已經安裝了Homebrew(macOS 缺失的軟件包的管理器),不要問我Homebrew 是什么了,這里我把教程附上,有興趣的同學自己看下把,mac下使用brew命令還是相當的方便的

https://brew.sh/index_zh-cn   中文官方網站

按上述步驟安裝完成后,執行biew -v 如果出現下面結果及說明安裝成功

Homebrew 1.8.6
Homebrew/homebrew-core (git revision b22b69a; last commit 2019-01-05)
Homebrew/homebrew-cask (git revision 382e0; last commit 2019-04-03)

這里順便附下其他系統的docker安裝把

Ubuntu Docker 安裝
CentOS Docker 安裝 (親試)
Windows Docker 安裝  (個人建議進來不要使用windows,裝個虛擬機都可以)
MacOS Docker 安裝 (親試)

nginx安裝

讓我們先來拉取下nginx的鏡像吧,這里我采用網易雲的鏡像,官方的鏡像國內打開是在太慢了

docker pull hub.c.163.com/library/nginx:latest

拉取成功后讓我們先看下本地的鏡像

docker images

  

通過上門的命令就可以看到nginx的鏡像已經被我們拉取過來了

然后我們就可以先啟動一下這個nginx了,在這里我們使用docker run命令來運行,不熟悉的同學可以通過docker run --help 來查看幫助文檔

-d :分離模式: 在后台運行

docker run -d hub.c.163.com/library/nginx

讓我們來檢查下nginx進程

jack-4:~ jack$ docker run -d hub.c.163.com/library/nginx
2d839f976fa88513854f4540d9c8f49ff1110640570bd2bd8c51471491f8a85d
jack-4:~ jack$ docker ps
CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS              PORTS               NAMES
2d839f976fa8        hub.c.163.com/library/nginx   "nginx -g 'daemon of…"   3 seconds ago       Up 2 seconds        80/tcp              affectionate_elion
jack-4:~ jack$ 

這里我們就能看到我們的nginx已經起來了,但是由於docker是虛擬了一個容器出來,所以我們現在還不能訪問nginx,接下來我們通過把本地端口映射到虛擬容器的nginx端口上就可以訪問nginx了

映射本地端口8080到容器的80的端口上

docker run -d -p 8080:80 hub.c.163.com/library/nginx

運行改命令后,命令行會輸出當前容器的id   

34453d528a8c9adbb4d67959053d5fb2ae38221b81c7519744f184f7fd0d5330

下面我們會用到他,這里稍微標記下

接下來我們通過訪問:http://127.0.0.1:8080/   就可以看到我們熟悉的nginx歡迎界面了。

好了到此為止,一個nginx就通過docker的方式在我們本機器啟動起來了,而且也可以正常訪問了,使用過nginx的同學都知道這肯定不滿足我們的要求啊,我還要修改nginx.conf呢,怎么辦呢, 怎么進入docker容器重啟nginx呢... 等等一系列的問題還沒解決呢,下面讓我們繼續來好好地搞一搞吧。

Nginx實戰

上面我們通過將本地8080端口映射到docker容器的80端口上實現了nginx的訪問,當然我們也可以通過隨機端口的映射方式

docker run -d -P hub.c.163.com/library/nginx
-P 方式會在容器內開放所有端口映射到隨機端口上
此時注意下返回值:
.0.0.0:32768->80/tcp     32768就是隨機分配的端口了,訪問 http://127.0.0.1:32768/就可以了

部署nginx 項目並修改配置文件

 一般情況下docker啟動時進行配置,只要把配置文件的目錄掛載出來就可以,但是nginx卻是先加載一個主配置文件nginx.conf,在nginx.conf里再加載conf.d目錄下的子配置文件(一般最少一個default.conf文件)。 

docker拉取下來的nginx配置文件路徑

日志文件位置:/var/log/nginx
配置文件位置: /etc/nginx
資源存放的位置: /usr/share/nginx/html

接下來我們現在本地創建對應的目錄,並將目錄掛在到docker容器的nginx上(可以看后面的采坑實力如何拷貝nginx.conf和conf.d中的文件)

 

  /Users/jack/Documents/docker/nginx/log

 

  /Users/jack/Documents/docker/nginx/html

 

  /Users/jack/Documents/docker/nginx/conf/nginx.conf  注意:這是文件

 

  /Users/jack/Documents/docker/nginx/conf/conf.d      注意:這是文件夾

 

本地掛載目錄創建完畢后讓我們來重新看下我們的nginx啟動命令,這次增加了很多東西

 

# 1. 第一個“-v”,是nginx日志位置,把ngixn日志放到掛載到的目錄下
# 2. 第二個“-v”,是項目位置,把項目放到掛載到的目錄下即可 
# 3. 第三個“-v”,是掛載的主配置文件"nginx.conf",注意"nginx.conf"文件內有一行 
#    "include /etc/nginx/conf.d/*.conf;" ,
#    這個include指向了子配置文件的路徑,此處注意include后所跟的路徑一定不能出錯
# 4. 第四個“-v”,把docker內子配置文件的路徑也掛載了出來,注意要與 “2.” 中include指向路徑一致
# 5. nginx.conf是掛載了一個文件(docker是不推薦這樣用的),conf.d掛載的是一個目錄

 

  

 

 

docker run \
  --name myNginx \
  -d -p 8080:80 \
  -v /Users/jack/Documents/docker/nginx/log/:/var/log/nginx \
  -v /Users/jack/Documents/docker/nginx/html:/usr/share/nginx/html \
  -v /Users/jack/Documents/docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro \
  -v /Users/jack/Documents/docker/nginx/conf/conf.d:/etc/nginx/conf.d \
  hub.c.163.com/library/nginx

這次命令我增加了一個--name屬性,給我們的docker容器新增加了一個名字,后面可以通過myNginx來重啟或者關閉容器

啟動成功后我們再通過命令來看下docker啟動情況和掛載情況

jack-4:~ jack$ docker ps
CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS              PORTS                  NAMES
48b10d0f0fdb        hub.c.163.com/library/nginx   "nginx -g 'daemon of…"   30 seconds ago      Up 29 seconds       0.0.0.0:8080->80/tcp   myNginx

 這里可以看到8080端口已經映射成功了,繼續執行命令查看掛載情況

docker inspect myNginx | grep Mounts -A 200

  

        "Mounts": [
            {
                "Type": "bind",
                "Source": "/Users/jack/Documents/docker/nginx/conf/conf.d",
                "Destination": "/etc/nginx/conf.d",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/Users/jack/Documents/docker/nginx/log",
                "Destination": "/var/log/nginx",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/Users/jack/Documents/docker/nginx/html",
                "Destination": "/usr/share/nginx/html",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/Users/jack/Documents/docker/nginx/conf/nginx.conf",
                "Destination": "/etc/nginx/nginx.conf",
                "Mode": "ro",
                "RW": false,
                "Propagation": "rprivate"
            }
        ],
        "Config": {
            "Hostname": "48b10d0f0fdb",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "80/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "NGINX_VERSION=1.13.0-1~stretch",
                "NJS_VERSION=1.13.0.0.1.10-1~stretch"
            ],
            "Cmd": [
                "nginx",
                "-g",
                "daemon off;"
            ],
            "ArgsEscaped": true,
            "Image": "hub.c.163.com/library/nginx",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {},
            "StopSignal": "SIGQUIT"
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "d0f15aa6836d41199d6c6ab2a13a77df69c9fe336e7721127b24ea626edc2ea5",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "80/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "8080"
                    }
                ]
            },
            "SandboxKey": "/var/run/docker/netns/d0f15aa6836d",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "6d937b1e1b72da739281adf9c6727ee618beb203660e168fbffd0fc6e1b6b8f6",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:02",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "b9eff4ad3b8cdd9dc1e6d16eaecedabfbeb4ae9f89be23c79a23569089e5a99b",
                    "EndpointID": "6d937b1e1b72da739281adf9c6727ee618beb203660e168fbffd0fc6e1b6b8f6",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02",
                    "DriverOpts": null
                }
            }
        }
    }
]

這里可以看到nginx的掛載情況和端口映射情況,到這里為止我們就可以隨意的修改我們的nginx了,在本地的html文件夾和conf.d中任意增加代碼和配置,在docker容器中重新啟動nginx就可以了,好了,下面讓我們繼續docker的一下常用操作:

docker attach 容器名或者容器ID bash     # 進入容器的命令行(退出容器后容器會停止)
docker exec -it 容器名或者容器ID bash # 進入容器的命令行
進入容器內部

docker exec -it 34453 bash
docker exec -it myNginx bash
-i 保證我們的輸入命令有效
-t 分配一個偽終端
34453指的是運行nginx鏡像后的pid 前幾位(34453d528a8c9adbb4d67959053d5fb2ae38221b81c7519744f184f7fd0d5330)或者容器名稱 myNginx
執行完畢后發現我們直接進入了容器內部,后面就可以直接使用linux的命令了,讓我們執行下 
which nginx

直接返回了nginx在容器中的路徑,那我們修改完配置后如何重啟nginx呢,其實命令還是一樣的,直接執行

nginx -s reload

就可以重啟成功了

查看容器日志

docker logs -f 容器名稱

 

到現在為止,nginx的安裝,啟動,進入容器內部重啟就都說完了,接下來我們進入最后的一部分,如何退出、重啟docker容器呢

docker stop    容器id/名稱   # 停止容器
docker rm       容器id/名稱  # 刪除容器
docker restart 容器id/名稱   #重啟容器
exit #退出docker容器
netstat -na|grep 8080      # 本地查看8080端口映射情況

  

采坑實例

博主在一開始配置nginx的時候,並沒有拷貝nginx.conf和conf.d里面的default.conf文件到本地的掛載目錄,而是新創建了二個文件,直接拷貝nginx文件里面的代碼過來的,結果每次重啟nginx后總會包一個錯誤

 . unexpected "{" in /etc/nginx/nginx.conf:1

經過反復查看核驗文件內容均沒有發現有什么異常,這個問題困擾了1天的時間,突然想到會不會是文件編碼的問題,於是通過拷貝的方式拷貝這兩個文件到本地目錄,重啟Nginx后解決,下面附上拷貝的代碼

docker cp myNginx:/etc/nginx/nginx.conf /Users/jack/Documents/docker/nginx/conf/nginx.conf
docker cp myNginx:/etc/nginx/conf.d/default.conf /Users/jack/Documents/docker/nginx/conf/conf.d/default.conf

好了,到這里本片文章就徹底結束了,有問題的小伙伴可以給我留言評論。下面我附上我本地的兩個文件代碼

nginx.conf和default.conf

nginx.conf

user  nginx;
worker_processes  1;
worker_rlimit_nofile  65535;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    use epoll; 
    worker_connections  65535;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    charset UTF-8;
    client_max_body_size 300m;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  60;

    gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

default.conf

#upstream sisafezuul {
#        server 192.168.11.4:8080 max_fails=2 fail_timeout=30s;
#}

#server {
#        listen 80;
#        server_name sietsafe.ecej.com; 
#        client_max_body_size 10M;
#        rewrite ^(.*)$  https://$host$1 permanent;
#}

 #server {
 #       listen       443 ssl;
 #       server_name etsafeadm.guizhou001.cn;
 #
 #       ssl_certificate cert/etsafeadm.guizhou001.cn.pem;
 #       ssl_certificate_key cert/etsafeadm.guizhou001.cn.key;

 #       ssl_session_cache    shared:SSL:1m;
 #       ssl_session_timeout  5m;
 #
 #       ssl_ciphers  HIGH:!aNULL:!MD5;
 #       ssl_prefer_server_ciphers  on;
 #       location ~* /openapi {
 #            proxy_pass   http://127.0.0.1:9999;
 #       }
 #       location ~* /safety {
 #            proxy_pass   http://127.0.0.1:9999;
 #       }
 #       location / {
 #           root  website/console;
 #           index index.html;
 #       }
 #   }

server {
    listen       80;
    server_name  localhost;

    location /rewrite {
       rewrite "/" http://127.0.0.1:8888/ break;
    }

    location /mickey.html {
       root   /usr/share/nginx/html/mickey;
    }

    #location ~* \.(html|htm|gif|jpg|jpeg|bmp|png|ico|js|css|eot|svg|ttf|woff)$ {
    #   index index.htm index.html;
    #   root /data/nfsdata/website/official;
    #}

    #location / {
    #    index index.htm index.html index.jsp;
    #    proxy_pass http://sisafezuul;
    #}

    location / {
       root   /usr/share/nginx/html;
       index  index.html index.htm;
    }

}

(附加)nginx location配置詳細

 

語法規則: location [=|~|~*|^~] /uri/ { … }

 

  • = 開頭表示精確匹配

  • ^~ 開頭表示uri以某個常規字符串開頭,理解為匹配 url路徑即可。nginx不對url做編碼,因此請求為/static/20%/aa,可以被規則^~ /static/ /aa匹配到(注意是空格)。

  • ~ 開頭表示區分大小寫的正則匹配

  • ~* 開頭表示不區分大小寫的正則匹配

  • !~!~*分別為區分大小寫不匹配及不區分大小寫不匹配 的正則

  • / 通用匹配,任何請求都會匹配到。

 

多個location配置的情況下匹配順序為(參考資料而來,還未實際驗證,試試就知道了,不必拘泥,僅供參考):

 

首先匹配 =,其次匹配^~, 其次是按文件中順序的正則匹配,最后是交給 / 通用匹配。當有匹配成功時候,停止匹配,按當前匹配規則處理請求。

 

例子,有如下匹配規則:

 

location = / {
   #規則A
}
location = /login {
   #規則B
}
location ^~ /static/ {
   #規則C
}
location ~ \.(gif|jpg|png|js|css)$ {
   #規則D
}
location ~* \.png$ {
   #規則E
}
location !~ \.xhtml$ {
   #規則F
}
location !~* \.xhtml$ {
   #規則G
}
location / {
   #規則H
}

 

 

那么產生的效果如下:

 

訪問根目錄/, 比如http://localhost/ 將匹配規則A

 

訪問 http://localhost/login 將匹配規則B,http://localhost/register 則匹配規則H

 

訪問 http://localhost/static/a.html 將匹配規則C

 

訪問 http://localhost/a.gif, http://localhost/b.jpg 將匹配規則D和規則E,但是規則D順序優先,規則E不起作用, 而 http://localhost/static/c.png 則優先匹配到 規則C

 

訪問 http://localhost/a.PNG 則匹配規則E, 而不會匹配規則D,因為規則E不區分大小寫。

 

訪問 http://localhost/a.xhtml 不會匹配規則F和規則G,http://localhost/a.XHTML不會匹配規則G,因為不區分大小寫。規則F,規則G屬於排除法,符合匹配規則但是不會匹配到,所以想想看實際應用中哪里會用到。

 

訪問 http://localhost/category/id/1111 則最終匹配到規則H,因為以上規則都不匹配,這個時候應該是nginx轉發請求給后端應用服務器,比如FastCGI(php),tomcat(jsp),nginx作為方向代理服務器存在。

 

所以實際使用中,個人覺得至少有三個匹配規則定義,如下:

 

 
        

 

nginx的其他配置信息介紹

 

三、ReWrite語法

 

last – 基本上都用這個Flag。
break – 中止Rewirte,不在繼續匹配
redirect – 返回臨時重定向的HTTP狀態302
permanent – 返回永久重定向的HTTP狀態301

 

1、下面是可以用來判斷的表達式:

 

-f!-f用來判斷是否存在文件
-d!-d用來判斷是否存在目錄
-e!-e用來判斷是否存在文件或目錄
-x!-x用來判斷文件是否可執行

 

2、下面是可以用作判斷的全局變量

 

例:http://localhost:88/test1/test2/test.php

 

$host:localhost
$server_port:88
$request_uri:http://localhost:88/test1/test2/test.php
$document_uri:/test1/test2/test.php
$document_root:D:\nginx/html
$request_filename:D:\nginx/html/test1/test2/test.php

 

四、Redirect語法

 

server {
    listen 80;
    server_name start.igrow.cn;
    index index.html index.php;
    root html;
    if ($http_host !~ "^star\.igrow\.cn$" {
        rewrite ^(.*) http://star.igrow.cn$1 redirect;
    }
}

 

五、防盜鏈

 

location ~* \.(gif|jpg|swf)$ {
    valid_referers none blocked start.igrow.cn sta.igrow.cn;
    if ($invalid_referer) {
        rewrite ^/ http://$host/logo.png;
    }
}

 

六、根據文件類型設置過期時間

 

location ~* \.(js|css|jpg|jpeg|gif|png|swf)$ {
    if (-f $request_filename) {
        expires 1h;
        break;
    }
}

 

七、禁止訪問某個目錄

 

location ~* \.(txt|doc)${
root /data/www/wwwroot/linuxtone/test;
deny all;
}

 

附:一些可用的全局變量

 

$args
$content_length
$content_type
$document_root
$document_uri
$host
$http_user_agent
$http_cookie
$limit_rate
$request_body_file
$request_method
$remote_addr
$remote_port
$remote_user
$request_filename
$request_uri
$query

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM