時(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é)。├── 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ù)。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了。 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)。FROM mongo:3.4VOLUME ["/backup"]COPY ./setup.sh /docker-entrypoint-initdb.dRUN chmod a+x /docker-entrypoint-initdb.d/setup.sh
mongo目錄下的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ù)的初始化操作。#!/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)容。 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端口的方法。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的額外插件,所以需要源碼編譯的方式。├── nginx│ ├── conf│ ├── Dockerfile│ ├── http-concat│ ├── source │ └── logs
source的文件內(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)不了其他容器。 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)。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-dropboxdocker-compose up --force-recreate --build -d
直接構(gòu)建加啟動(dòng),不出意外就是下邊這個(gè)樣子: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è)置。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)出的備份目錄即可。關(guān)鍵詞:步驟,部署
客戶(hù)&案例
營(yíng)銷(xiāo)資訊
關(guān)于我們
客戶(hù)&案例
營(yíng)銷(xiāo)資訊
關(guān)于我們
微信公眾號(hào)
版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。