我只有一台服務器,但我想在這台服務器上運行多個項目,怎么辦?
總不能靠加端口區分吧?
百度和Google是個好東西,於是我找到了答案,使用nginx。
通過nginx,我可以給我的一台服務器配置兩個域名,然后通過不同的域名訪問我的兩個項目。
實現方式
大概流程是這么玩的,你在服務器配置好nginx,讓nginx監聽80(http端口)和443(https端口),然后在nginx配置文件寫明轉發到哪里。
比如我有一個博客系統,還有一個郵件系統。
為了區分開,我給了這兩個項目分別兩個域名:blog.tandk.com
和mail.tandk.com
。
是的,這兩個域名都是同屬一個主域名tandk.com
下的,以我上面的例子來說,你只要在域名服務商那里購買一個叫tandk.com
的域名,就可以通過配置,無需購買獲得上面兩個域名。
具體的配置過程其實也挺簡單,我只在騰訊雲配過,其他的平台應該大同小異,如果你不大了解,可以看看我的這篇文章:《騰訊雲配置多個域名前綴》
回到nginx,兩個域名有了,我要配置nginx的配置文件,要告訴nginx,當我訪問blog.tandk.com
時,轉發到內網的8080端口,當我訪問mail.tandk.com
時,轉發到內網的8181端口。
再配好ssl證書,就可以正常訪問了。
ssl證書可以讓你用https訪問你的域名,如果你覺得http可以滿足的話,那么不需要ssl也行。
具體實現
思路有了,接下來便是一步一步完成。
看到標題會點進來的,我就當你對docker有一定了解了,這里就不提怎么安裝docker了。
我們直接用docker安裝nginx:
# 安裝
docker pull nginx
# 安裝后查看docker鏡像
docker images
安裝就只需要一個命令,連安裝包都不用自己找,這就是我用docker的原因。
建目錄用於存放nginx配置文件、證書文件:
mkdir /opt/docker/nginx/conf.d -p
mkdir /opt/docker/nginx/cert -p
nginx的ssl證書長這個樣子,兩個都要,中間打碼的是你的域名:
把他們倆放到服務器的/opt/docker/nginx/cert
目錄下。
查看內網的ip,記錄下來,等下寫配置文件要用:
# linux查看內網ip
ifconfig
接下來說說配置文件的一點注意事項。
了解docker的都知道,docker容器啟動后,容器內部有自己的文件系統,配置文件也在里面。
因此我們需要把配置文件掛載到外部,就是我們的linux服務器上。
這樣我們每次需要修改nginx的配置文件的時候,只要修改掛載到外部的文件,容器內的文件也會相應改變,能省很多功夫。
強烈建議掛載文件!!!不然的話會有很多坑,自身的血淚說出這句話。
要掛載文件,首先需要啟動nginx,進去容器內部查看配置文件在哪里,並將其復制出來:
# 啟動nginx
docker run --name nginx -p 80:80 -d nginx
# 進入docker的nginx容器
docker exec -it nginx bash
確定進入容器內部后,用下面兩個命令查找nginx的配置文件在哪:
# 查找nginx配置文件default.conf
# 這個在/etc/nginx/conf.d/default.conf
find / -name "default.conf"
# 查找nginx配置文件nginx.conf
# 這個在/etc/nginx/nginx.conf
find / -name "nginx.conf"
# 注:兩者不在同一目錄下。
接下來退出容器(進入容器內部只是確認一下配置文件的位置而已):
exit
使用docker的cp命令把這兩個配置文件復制到剛剛建好的目錄下:
# 把docker內的default.conf復制到外部
docker cp nginx:/etc/nginx/conf.d/default.conf /opt/docker/nginx/conf.d/default.conf
# 把docker內的nginx.conf復制到外部
docker cp nginx:/etc/nginx/nginx.conf /opt/docker/nginx/conf.d/nginx.conf
保險起見,這個時候先不修改容器外部的配置文件,先掛載文件啟動docker,啟動成功了,確定沒問題了,再去修改配置文件。
首先停掉之前的容器並刪除:
# 停止容器
docker stop nginx
# 刪除容器
docker rm -f nginx
帶着掛載文件的命令啟動nginx:
# 掛載
docker run --name nginx -p 80:80 -p 443:443 -v /opt/docker/nginx/conf.d/nginx.conf:/etc/nginx/nginx.conf -v /opt/docker/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf -v /opt/docker/nginx/cert:/etc/nginx -d nginx
-p命令表示容器內部和外部監聽的端口,這部分不細說。
-v表示掛載的文件,-v [該文件在容器外部的位置]:[該文件在容器內部的位置]
。
使用下面的命令查看是否啟動成功:
# 查看正在運行的容器
docker ps
# 查看全部容器,包括沒有啟動的容器
# 如果上面的命令出現的列表沒有nginx,使用這個命令
docker ps -a
# 如果確定啟動失敗了,查看日志定位失敗的原因
docker logs nginx
當nginx啟動成功后,我們只需要修改配置文件,就可以實現多個域名和https訪問的需求啦。
nginx的配置文件有兩個,nginx.conf
和default.conf
。
點開看nginx.conf
的話,會發現里面引入了default.conf
的內容,也就是說這是一個文件分成兩個文件來寫。
我們只需要修改default.conf
的內容即可達到我們的目的。
這里粘一下linux編輯文本的命令:
# 打開文件
vim 文件名
# 進入默認不可編輯,需要按下i后才可以編輯
# 編輯完成后,需要按esc退出編輯狀態
# 退出並保存
:wq
# 退出不保存
:q!
修改default.conf
的內容為如下,需根據你的情況做出改變:
server {
listen 80; #偵聽80端口
listen 443 ssl; #偵聽443端口,用於SSL
server_name tandk.com www.tandk.com; # 自己的域名
# 注意證書文件名字和位置,是從/etc/nginx/下開始算起的
ssl_certificate 1_tandk.com_bundle.crt;
ssl_certificate_key 2_tandk.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
client_max_body_size 1024m;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 這里寫的是我的騰訊雲內網地址,不知道為啥,不能用127.0.0.1...
proxy_pass http://xx.xx.xx.xx:8090;
}
}
這上面便配好了一個域名的https和http訪問,假如你想多配一個域名,拿我上面的blog.tandk.com
和mail.tandk.com
來舉例,每個域名要加多一個server:
server {
listen 80; #偵聽80端口
listen 443 ssl; #偵聽443端口,用於SSL
server_name blog.tandk.com; # 自己的域名
# 注意證書文件位置,是從/etc/nginx/下開始算起的
ssl_certificate 1_blog.tandk.com_bundle.crt;
ssl_certificate_key 2_blog.tandk.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
client_max_body_size 1024m;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 這里寫的是我的騰訊雲內網地址,不知道為啥,不能用127.0.0.1...
proxy_pass http://xx.xx.xx.xx:8080;
}
}
server {
listen 80; #偵聽80端口
listen 443 ssl; #偵聽443端口,用於SSL
server_name mail.tandk.com; # 自己的域名
# 注意證書文件位置,是從/etc/nginx/下開始算起的
ssl_certificate 1_mail.tandk.com_bundle.crt;
ssl_certificate_key 2_mail.tandk.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
client_max_body_size 1024m;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 這里寫的是我的騰訊雲內網地址,不知道為啥,不能用127.0.0.1...
proxy_pass http://xx.xx.xx.xx:8181;
}
}
配置完畢后,保存、停止容器再重啟:
# 停止nginx
docker stop nginx
# 啟動容器
docker start nginx
# 查看是否啟動成功
docker ps
打開瀏覽器,分別用http和https訪問你配置的域名,來確認是否成功。
查看https是否生效,可以按下面的截圖來查看:
關於ssl證書的坑
如果你細心點,看我上面的配置文件會發現,兩個server,隨着域名的不同,ssl證書的名字也不一樣了。
對的,對於每一個不同的子域名,我都需要去申請一個ssl證書。
對於mail.tandk.com
,我需要去申請一個ssl證書,對於blog.tandk.com
,我還需要去申請一個新的ssl證書。
那么能不能申請一個通配的證書去適配一個主域名下的所有子域名呢。
有的,花錢。
別的平台我不太清楚,騰訊雲有那種證書,比如你可以申請一個*.tandk.com
的證書,那樣你所有子域名就都能用這個證書了。
但是我看了一下這種證書一年要花1600,像我這種窮逼還是算了,反正申請一個免費證書也花不了多少時間。
給你看看有錢人家和窮逼的區別:
我(窮逼),一個子域名一個證書:
有錢人家,一個通配證書配所有子域名:
騰訊雲對於免費的證書限制是這樣的:
-
免費證書不能通配。就是上面說的,雖然同屬於
tandk.com
這個主域名,但是我每多一個子域名,比如blog.tandk.com
,就需要再去申請一個專屬於blog.tandk.com
的ssl證書。 -
一個主域名只能申請20張ssl證書。
-
證書吊銷后,還會在15個月內,占用這20個證書的名額。
好家伙,這是逼着我們去買通配證書啊,不過想了想,免費證書對我這種自己玩一玩的其實夠用了。
20個項目,我是用不了那么多的,而且要真要那么多,我也多買幾個服務器和域名了,騰訊還是良心的。(騰訊快給廣告費!)
以上,參考自下面的內容:
《docker上啟動nginx,並配置修改nginx的配置文件》
感謝各位大佬的無私教程!