mac環境下使用docker安裝nginx

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 如果出現下面結果及說明安裝成功

1
2
3
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的鏡像吧,這裏我採用網易雲的鏡像,官方的鏡像國內打開是在太慢了

1
docker pull hub.c.163.com/library/nginx:latest
拉取成功後讓我們先看下本地的鏡像

1
docker images
  

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

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

-d :分離模式: 在後臺運行

1
docker run -d hub.c.163.com/library/nginx
讓我們來檢查下nginx進程

1
2
3
4
5
6
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的端口上
1
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的訪問,當然我們也可以通過隨機端口的映射方式

1
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
2
3
4
5
6
7

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掛載的是一個目錄

  

1
2
3
4
5
6
7
8
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啓動情況和掛載情況

1
2
3
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端口已經映射成功了,繼續執行命令查看掛載情況

1
docker inspect myNginx | grep Mounts -A 200
  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

    "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 # 進入容器的命令行
進入容器內部
1
docker exec -it 34453 bash
1
docker exec -it myNginx bash
-i 保證我們的輸入命令有效
-t 分配一個僞終端
34453指的是運行nginx鏡像後的pid 前幾位(34453d528a8c9adbb4d67959053d5fb2ae38221b81c7519744f184f7fd0d5330)或者容器名稱 myNginx
執行完畢後發現我們直接進入了容器內部,後面就可以直接使用linux的命令了,讓我們執行下
1
which nginx
直接返回了nginx在容器中的路徑,那我們修改完配置後如何重啓nginx呢,其實命令還是一樣的,直接執行

1
nginx -s reload
就可以重啓成功了

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

1
2
3
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後總會包一個錯誤

1
. unexpected "{" in /etc/nginx/nginx.conf:1
經過反覆查看覈驗文件內容均沒有發現有什麼異常,這個問題困擾了1天的時間,突然想到會不會是文件編碼的問題,於是通過拷貝的方式拷貝這兩個文件到本地目錄,重啓Nginx後解決,下面附上拷貝的代碼

1
2
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

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配置的情況下匹配順序爲(參考資料而來,還未實際驗證,試試就知道了,不必拘泥,僅供參考):

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

例子,有如下匹配規則:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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
原文地址https://www.cnblogs.com/blueskyli/p/10700501.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章