這個(gè)問(wèn)題的tag帶了docker和容器,正好最近我把我自己的日記網(wǎng)站進(jìn)行了容器化的部署改造,這里就從零開(kāi)始說(shuō)一下如何部署一個(gè)Nodejs的容器化" />

国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

所在位置: 首頁(yè) > 營(yíng)銷(xiāo)資訊 > 網(wǎng)站運(yùn)營(yíng) > 部署一個(gè)屬于自己的網(wǎng)站需要什么步驟?

部署一個(gè)屬于自己的網(wǎng)站需要什么步驟?

時(shí)間:2023-10-23 09:12:01 | 來(lái)源:網(wǎng)站運(yùn)營(yíng)

時(shí)間:2023-10-23 09:12:01 來(lái)源:網(wǎng)站運(yùn)營(yíng)

部署一個(gè)屬于自己的網(wǎng)站需要什么步驟?:一直想回答一下這個(gè)問(wèn)題,帶大家走進(jìn)科學(xué)。

這個(gè)問(wèn)題的tag帶了docker和容器,正好最近我把我自己的日記網(wǎng)站進(jìn)行了容器化的部署改造,這里就從零開(kāi)始說(shuō)一下如何部署一個(gè)Nodejs的容器化網(wǎng)站。

準(zhǔn)備工作:

首先,我們這篇文章不談網(wǎng)站的開(kāi)發(fā),只聊網(wǎng)站的部署,不涉及域名注冊(cè)和vps購(gòu)買(mǎi),其次本篇文章需要的前置資源我也列一下:

硬件資源:

1,一臺(tái)vps服務(wù)+一個(gè)服務(wù)域名,一個(gè)dropbox賬戶(hù)(需要爬山)。

2,我本機(jī)環(huán)境是macos,如果你也是m1芯片的mac,應(yīng)該也會(huì)遇到和我一樣的很多m1芯片不兼容x86的問(wèn)題。

軟件概念:

Docker和Docker-compose的基礎(chǔ)知識(shí),一些linux基礎(chǔ)知識(shí),一些Nodejs基礎(chǔ)知識(shí),別擔(dān)心你不會(huì),因?yàn)槲以诟脑烨耙餐牟畈欢嗔?,所以這里給大家科普的同時(shí),也是一篇給我自己做記錄整理的文章。

網(wǎng)站項(xiàng)目介紹:

我要部署的網(wǎng)站是我10年開(kāi)發(fā)的一個(gè)日記網(wǎng)站,目前已經(jīng)在部署完成了,在日本的linode vps上運(yùn)行,域名注冊(cè)在godaddy上,地址是:http://www.tuer.me

網(wǎng)站的nodejs版本很古老了,是v0.10.33,其安裝的node_modules已經(jīng)無(wú)法正常安裝了,我物理備份了一套可運(yùn)行的。

下邊給大家看一下整個(gè)項(xiàng)目的一個(gè)目錄結(jié)構(gòu):

├── crontab│ └── help.sh├── docker-compose.yml├── dropbox.py├── mongo│ ├── backup│ ├── data│ ├── Dockerfile│ ├── mongo.conf│ └── setup.sh├── nginx│ ├── conf│ ├── Dockerfile│ ├── http-concat│ └── logs├── node│ ├── Dockerfile│ ├── node_modules│ ├── public│ └── tuer2.0└── readme.md這里簡(jiǎn)單做一下解釋?zhuān)琧rontab放置的是每天備份數(shù)據(jù)的腳本,docker-compose.yml是對(duì)我的服務(wù)的編排操作的配置文件,dropbox.py是dropbox的linux版本的命令行工具,mongo目錄放置的是mongodb相關(guān)的鏡像配置和卷目錄,nginx,node也是,一共會(huì)構(gòu)建三個(gè)鏡像提供整個(gè)web服務(wù)。

這里再簡(jiǎn)單的介紹一下node目錄,其中的public是放置靜態(tài)資源和用戶(hù)上傳的圖片文件的,node_modules是作為卷掛載進(jìn)容器的,tuer2.0是nodejs的源碼目錄。

Nodejs服務(wù)鏡像準(zhǔn)備

那么我先從node鏡像的Dockerfile說(shuō)起:

FROM node:0.10.33RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtimeVOLUME ["/www/tuer2.0/public","/www/tuer2.0","/www/tuer2.0/node_modules"]WORKDIR /www/tuer2.0CMD ["node","/www/tuer2.0/index.js"]EXPOSE 3000 3030從node的0.10.33鏡像開(kāi)始構(gòu)建,設(shè)置一下系統(tǒng)內(nèi)時(shí)區(qū),然后使用VOLUME掛載了3個(gè)目錄,這里對(duì)不熟悉docker的小伙伴稍微介紹下,VOLUME的作用是定義3個(gè)容器內(nèi)部的目錄,可以在Docker啟動(dòng)的時(shí)候宿主機(jī)的目錄進(jìn)行關(guān)聯(lián),這樣這幾個(gè)目錄內(nèi)文件的讀寫(xiě)就都會(huì)保存在宿主機(jī)對(duì)應(yīng)掛載的目錄下了。這里我定義了靜態(tài)資源目錄,網(wǎng)站源碼目錄,還有node_modules目錄,這樣的好處是可以避免構(gòu)建鏡像的時(shí)候總是要npm install了。

然后使用node啟動(dòng)web服務(wù),對(duì)外暴露2個(gè)端口分別是3000和3030,都是nodejs的服務(wù)端口。

然后我們?cè)倏匆幌耫ocker-compose里的node鏡像是如何設(shè)置的參數(shù),這里對(duì)不熟悉docker-compose的小伙伴也稍微介紹下,docker本身是可以用run命令來(lái)啟動(dòng)容器的,但是當(dāng)你有多個(gè)容器互相依賴(lài)而且參數(shù)繁多的情況下,使用docker-compose可以簡(jiǎn)化并且易于維護(hù)。

nodejs: build: context: ./node # 構(gòu)建 node 目錄 他會(huì)去 node 下面尋找 Dockerfile environment: - DOCKER_DEFAULT_PLATFORM=linux/amd64 ports: - 3030:3030 # 映射 - 3000:3000 # 映射 volumes: - ./node/tuer2.0:/www/tuer2.0 # 項(xiàng)目文件映射 - ./node/public:/www/tuer2.0/public # 項(xiàng)目文件映射 - ./node/node_modules:/www/tuer2.0/node_modules # 項(xiàng)目文件映射 restart: always depends_on: - mongo networks: - my-network我們先是定義了一個(gè)nodejs的鏡像,他使用當(dāng)前目錄的 ./node 目錄中的dockerfile進(jìn)行構(gòu)建,然后我們?cè)O(shè)置了一個(gè)env環(huán)境變量,指定是amd64的系統(tǒng),因?yàn)閙ac m1芯片構(gòu)建的node是不能運(yùn)行的,底層不兼容,必須指定平臺(tái)。

然后映射本地的ports,掛載本地的源碼目錄,靜態(tài)目錄,node_modules目錄到容器中,設(shè)置restart always,這樣就不需要pm2了,然后該nodejs服務(wù)依賴(lài)另外一個(gè)mongo容器,使用my-netwokr來(lái)進(jìn)行網(wǎng)絡(luò)映射。

這樣設(shè)置的好處不多說(shuō)了,構(gòu)建鏡像很快,修改源碼后可以直接restart容器生效看效果,不需要頻繁的build了。

Mongodb的鏡像準(zhǔn)備

FROM mongo:3.4VOLUME ["/backup"]COPY ./setup.sh /docker-entrypoint-initdb.dRUN chmod a+x /docker-entrypoint-initdb.d/setup.shmongo目錄下的dockerfile比較簡(jiǎn)單,我們?cè)O(shè)置了一個(gè)容器內(nèi)的 /backup 目錄來(lái)做備份文件的導(dǎo)出,然后編寫(xiě)了一個(gè)setup.sh的腳本,復(fù)制到`docker-entrypoint-initdb.d`目錄下來(lái)做數(shù)據(jù)庫(kù)的初始化操作。

我們這里看一下setup.sh的內(nèi)容:

#!/bin/bashmongorestore -h 127.0.0.1 --port 27017 -d node-mongo-tuer /backup/node-mongo-tuer這個(gè)shell腳本的作用是使用mongorestore來(lái)對(duì)數(shù)據(jù)庫(kù)做數(shù)據(jù)恢復(fù),我們只需要在啟動(dòng)的時(shí)候在backup目錄下放置好之前備份的數(shù)據(jù)庫(kù)目錄就行了,當(dāng)容器啟動(dòng)時(shí)就會(huì)自動(dòng)恢復(fù)之前的內(nèi)容。

我們?cè)倏匆幌耫ocker-compose的部分:

mongo: environment: - DOCKER_DEFAULT_PLATFORM=linux/amd64 build: context: ./mongo ports: - 27017:27017 volumes: - ./mongo/data/db:/data/db - ./mongo/backup:/backup - ./mongo/mongo.conf:/data/configdb/mongo.conf restart: always networks: - my-network基本和nodejs的鏡像配置一樣,我們除了掛載backup目錄外還掛了mongo.conf配置文件和db的啟動(dòng)目錄,mongo.conf 可以設(shè)置一些mongo的配置,比如登錄驗(yàn)證等,但是我沒(méi)有配置,我在后邊會(huì)介紹,直接用Linux的防火墻軟件關(guān)閉外網(wǎng)訪問(wèn)mongo端口的方法。

Nginx的鏡像準(zhǔn)備

FROM nginx:mainline as builderVOLUME ["/www/tuer2.0/public" ]ARG ENABLED_MODULESRUN set -ex / && if [ "$ENABLED_MODULES" = "" ]; then / echo "No additional modules enabled, exiting"; / exit 1; / fiCOPY ./ /modules/RUN set -ex / && apt update / && apt install -y --no-install-suggests --no-install-recommends / patch make wget mercurial devscripts debhelper dpkg-dev / quilt lsb-release build-essential libxml2-utils xsltproc / equivs git g++ libparse-recdescent-perl / && XSLSCRIPT_SHA512="f7194c5198daeab9b3b0c3aebf006922c7df1d345d454bd8474489ff2eb6b4bf8e2ffe442489a45d1aab80da6ecebe0097759a1e12cc26b5f0613d05b7c09ffa *stdin" / && wget -O /tmp/xslscript.pl https://hg.nginx.org/xslscript/raw-file/01dc9ba12e1b/xslscript.pl / && if [ "$(cat /tmp/xslscript.pl | openssl sha512 -r)" = "$XSLSCRIPT_SHA512" ]; then / echo "XSLScript checksum verification succeeded!"; / chmod +x /tmp/xslscript.pl; / mv /tmp/xslscript.pl /usr/local/bin/; / else / echo "XSLScript checksum verification failed!"; / exit 1; / fi / && hg clone -r ${NGINX_VERSION}-${PKG_RELEASE%%~*} https://hg.nginx.org/pkg-oss/ / && cd pkg-oss / && mkdir /tmp/packages / && for module in $ENABLED_MODULES; do / echo "Building $module for nginx-$NGINX_VERSION"; / if [ -d /modules/$module ]; then / echo "Building $module from user-supplied sources"; / # check if module sources file is there and not empty if [ ! -s /modules/$module/source ]; then / echo "No source file for $module in modules/$module/source, exiting"; / exit 1; / fi; / # some modules require build dependencies if [ -f /modules/$module/build-deps ]; then / echo "Installing $module build dependencies"; / apt update && apt install -y --no-install-suggests --no-install-recommends $(cat /modules/$module/build-deps | xargs); / fi; / # if a module has a build dependency that is not in a distro, provide a # shell script to fetch/build/install those # note that shared libraries produced as a result of this script will # not be copied from the builder image to the main one so build static if [ -x /modules/$module/prebuild ]; then / echo "Running prebuild script for $module"; / /modules/$module/prebuild; / fi; / /pkg-oss/build_module.sh -v $NGINX_VERSION -f -y -o /tmp/packages -n $module $(cat /modules/$module/source); / BUILT_MODULES="$BUILT_MODULES $(echo $module | tr '[A-Z]' '[a-z]' | tr -d '[/_/-/./t ]')"; / elif make -C /pkg-oss/debian list | grep -P "^$module/s+/d" > /dev/null; then / echo "Building $module from pkg-oss sources"; / cd /pkg-oss/debian; / make rules-module-$module BASE_VERSION=$NGINX_VERSION NGINX_VERSION=$NGINX_VERSION; / mk-build-deps --install --tool="apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes" debuild-module-$module/nginx-$NGINX_VERSION/debian/control; / make module-$module BASE_VERSION=$NGINX_VERSION NGINX_VERSION=$NGINX_VERSION; / find ../../ -maxdepth 1 -mindepth 1 -type f -name "*.deb" -exec mv -v {} /tmp/packages/ /;; / BUILT_MODULES="$BUILT_MODULES $module"; / else / echo "Don't know how to build $module module, exiting"; / exit 1; / fi; / done / && echo "BUILT_MODULES=/"$BUILT_MODULES/"" > /tmp/packages/modules.envFROM nginx:mainlineCOPY --from=builder /tmp/packages /tmp/packagesRUN set -ex / && apt update / && . /tmp/packages/modules.env / && for module in $BUILT_MODULES; do / apt install --no-install-suggests --no-install-recommends -y /tmp/packages/nginx-module-${module}_${NGINX_VERSION}*.deb; / done / && rm -rf /tmp/packages / && rm -rf /var/lib/apt/lists/Nginx的dockerfile有點(diǎn)復(fù)雜,但是其實(shí)只需要關(guān)注上面的VOLUME ["/www/tuer2.0/public" ]這一句就行了,其他的都是Nginx的官網(wǎng)配置,為什么不直接使用Nginx的鏡像來(lái)做容器呢,因?yàn)槲业木W(wǎng)站使用了Nginx的額外插件,所以需要源碼編譯的方式。

插件我用了阿里的http-concat,在nginx目錄下放置一個(gè)插件目錄,然后插件目錄里放一個(gè)source文件即可。

├── nginx│ ├── conf│ ├── Dockerfile│ ├── http-concat│ ├── source │ └── logssource的文件內(nèi)容就是插件的下載地址:

https://github.com/alibaba/nginx-http-concat/archive/1.2.2.tar.gz我們?cè)倏匆幌耼ginx的配置部分:

load_module /etc/nginx/modules/ngx_http_concat_module.so;load_module /etc/nginx/modules/ngx_http_image_filter_module.so;http { server { listen 80; server_name www.tuer.me tuer.me; if ( $host != 'www.tuer.me' ) { rewrite ^/(.*)$ http://www.tuer.me/$1 permanent; } charset utf-8; location ~* /.(eot|ttf|woff|svg|otf)$ { add_header Access-Control-Allow-Origin *; } location / { proxy_set_header Host $host:80; proxy_set_header X-Forwarded-For $remote_addr; proxy_pass http://tuer30_nodejs_1:3000; } location ~ /avatar/(.*)$ { proxy_set_header Host $host:80; proxy_set_header X-Forwarded-For $remote_addr; proxy_pass http://tuer30_nodejs_1:3000/user/avatar/$1; } location ~ /art/(.*)$ { proxy_set_header Host $host:80; proxy_set_header X-Forwarded-For $remote_addr; proxy_pass http://tuer30_nodejs_1:3000/user/art/$1; } }}這里只寫(xiě)了一部分,比如插件的加載需要在nginx配置的頭部就使用load_module進(jìn)行加載,其中網(wǎng)站的vhosts部分,使用了proxy_pass的反向代理,但是這里注意不能用127.0.0.1這種或者localhost,需要使用容器網(wǎng)絡(luò)中的name,比如nodejs容器的name在我這里就是tuer30_nodejs_1,需要使用docker network inspect my-network來(lái)進(jìn)行查看確認(rèn),這里被坑了很久,容器內(nèi)一直訪問(wèn)不了其他容器。

最后看一下docker-compose的部分:

nginx: # nginx 容器 這里的名字可以當(dāng)做變量使用 environment: - DOCKER_DEFAULT_PLATFORM=linux/amd64 build: # 定義需要構(gòu)建的內(nèi)容 context: ./nginx # 選取 nginx 文件夾 args: ENABLED_MODULES: http-concat ports: # 映射端口 - 80:80 - 443:443 volumes: # 掛載文件夾,配置我們可以寫(xiě)在宿主機(jī),然后掛載進(jìn)去 - ./node/public:/www/tuer2.0/public - ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf - ./nginx/logs:/var/log/nginx restart: always # 服務(wù)掛了的時(shí)候始終自動(dòng)重啟 networks: # 使用我們上面定義的網(wǎng)絡(luò) - my-network因?yàn)樵黾恿薶ttp-concat插件,所以在build的時(shí)候增加args參數(shù),來(lái)設(shè)置ENABLE_MODULES,多個(gè)插件空格隔開(kāi)。

使用Dropbox來(lái)同步數(shù)據(jù)和備份

上面基本介紹了如何編寫(xiě)鏡像,下邊說(shuō)一下數(shù)據(jù)如何同步到vps上,我們?yōu)榱藗浞莺屯綌?shù)據(jù)方便直接把網(wǎng)站項(xiàng)目做到了dropbox網(wǎng)盤(pán)中,在本地mac上做實(shí)時(shí)備份,在vps上安裝linux版本的dropbox即可。

cd ~ && wget -O - "https://www.dropbox.com/download?plat=lnx.x86_64" | tar xzf -~/.dropbox-dist/dropboxd直接下載后啟動(dòng)就行,在centos7中可能會(huì)遇到依賴(lài)問(wèn)題,提示缺少glibc,如果遇到了需要手工下載,切記需要2.19以上版本才能運(yùn)行。

安裝方法:

cd /usr/local/srccurl -O http://ftp.gnu.org/gnu/glibc/glibc-2.19.tar.gztar xf glibc-2.19.tar.gzcd glibc-2.19mkdir buildcd build../configure --prefix=/usrmake -j 2make install安裝好后,啟動(dòng)Dropbox,同步所有網(wǎng)站文件和數(shù)據(jù)到vps就行了,設(shè)置dropbox開(kāi)機(jī)啟動(dòng)可以參考這篇文章:https://www.ltsplus.com/linux/centos-7-install-dropbox

在vps上安裝docker和docker-compose

我是在centos7上操作的,遇到不少問(wèn)題,這里也記錄一下:

首先需要安裝python3,可以參考這篇文章:Linux Centos7安裝python3.7和安裝pykmip

然后需要安裝docker,docker-compose,可以參考這篇文章:Redhat OS安裝docker-ce及docker-compose步驟

然后還要安裝pip3,可以參考這篇文章:docker-compose安裝---pip3_TaotaoPlus的博客-CSDN博客

在vps上啟動(dòng)docker服務(wù)

docker-compose up --force-recreate --build -d直接構(gòu)建加啟動(dòng),不出意外就是下邊這個(gè)樣子:

在vps上設(shè)置防火墻

啟動(dòng)好服務(wù)后雖然可以直接訪問(wèn)了,但是我們還是需要設(shè)置一下防火墻規(guī)則,這里我使用自帶的firewalld來(lái)設(shè)置,這里需要注意很重要的一點(diǎn),一開(kāi)始我怎么設(shè)置都不生效后來(lái)發(fā)現(xiàn)原來(lái)是docker啟動(dòng)時(shí)搗的鬼,可以參考這篇文章進(jìn)行恢復(fù):Linux系統(tǒng)安裝docker后,firewall規(guī)則無(wú)效不起作用 - 高效碼農(nóng)

設(shè)置好防火墻生效后我們?cè)O(shè)置關(guān)閉外部訪問(wèn)mongodb既27017端口,再對(duì)外打開(kāi)80,443端口:

systemctl start firewalld firewall-cmd --zone=public --remove-port=27017/tcp --permanentfirewall-cmd --zone=public --add-port=80/tcp --permanent firewall-cmd --zone=public --add-port=443/tcp --permanent firewall-cmd --reload systemctl enable firewalld 設(shè)置完成后記得reload操作,還有對(duì)firewall進(jìn)行開(kāi)機(jī)啟動(dòng)設(shè)置。

使用crontab對(duì)mongodb數(shù)據(jù)庫(kù)定時(shí)備份

在命令行輸入crontab -e,可以進(jìn)入crontab設(shè)置:

0 0 * * * /bin/bash /root/Dropbox/tuer3.0/crontab/help.sh每天0點(diǎn)進(jìn)行一次備份操作,我們看一下help腳本怎么寫(xiě)的:

#!/bin/shcd '/root/Dropbox/tuer3.0/mongo/backup'cur_dir=$(pwd)#重啟服務(wù)cd $cur_dir#備份數(shù)據(jù)庫(kù)date_now=`date +%Y%m%d%H%M`backmongodbFile=tuer$date_now.tar.gzdocker exec -it tuer30_mongo_1 /bin/bash -c '/usr/bin/mongodump -h 127.0.0.1 -d node-mongo-tuer -o /backup'rm *.tar.gztar -czf $backmongodbFile node-mongo-tuer/rm node-mongo-tuer -rf我們?cè)趻燧d的backup目錄下,對(duì)容器tuer30_mongo_1調(diào)用容器內(nèi)的mongodump命令進(jìn)行備份,備份后刪除前一天的備份壓縮包,然后tar壓縮當(dāng)天的備份,刪除導(dǎo)出的備份目錄即可。

以上所有部署代碼的源碼參考

之前一直使用的git同步代碼,pm2重啟方式來(lái)進(jìn)行的網(wǎng)站部署,經(jīng)過(guò)這一頓折騰,感覺(jué)比原來(lái)清爽多了。

本身我是有一個(gè)私有的git倉(cāng)庫(kù)來(lái)維護(hù)這個(gè)項(xiàng)目的,但是因?yàn)槔锩嫔婕暗搅司W(wǎng)站的源代碼,所以就不對(duì)外了,如果有感興趣的同學(xué)想接盤(pán)這個(gè)網(wǎng)站的可以聯(lián)系我,我可以開(kāi)放權(quán)限給你?;蛘邔?duì)文章的配置有疑問(wèn)的,可以在評(píng)論里留言我把更詳細(xì)的代碼可以局部發(fā)給你。

關(guān)鍵詞:步驟,部署

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點(diǎn)擊下載Chrome瀏覽器
關(guān)閉