15158846557 在线咨询 在线咨询
15158846557 在线咨询
所在位置: 首页 > 营销资讯 > 网站运营 > 部署一个属于自己的网站需要什么步骤?

部署一个属于自己的网站需要什么步骤?

时间:2023-10-23 09:12:01 | 来源:网站运营

时间:2023-10-23 09:12:01 来源:网站运营

部署一个属于自己的网站需要什么步骤?:一直想回答一下这个问题,带大家走进科学。

这个问题的tag带了docker和容器,正好最近我把我自己的日记网站进行了容器化的部署改造,这里就从零开始说一下如何部署一个Nodejs的容器化网站。

准备工作:

首先,我们这篇文章不谈网站的开发,只聊网站的部署,不涉及域名注册和vps购买,其次本篇文章需要的前置资源我也列一下:

硬件资源:

1,一台vps服务+一个服务域名,一个dropbox账户(需要爬山)。

2,我本机环境是macos,如果你也是m1芯片的mac,应该也会遇到和我一样的很多m1芯片不兼容x86的问题。

软件概念:

Docker和Docker-compose的基础知识,一些linux基础知识,一些Nodejs基础知识,别担心你不会,因为我在改造前也忘的差不多了,所以这里给大家科普的同时,也是一篇给我自己做记录整理的文章。

网站项目介绍:

我要部署的网站是我10年开发的一个日记网站,目前已经在部署完成了,在日本的linode vps上运行,域名注册在godaddy上,地址是:http://www.tuer.me

网站的nodejs版本很古老了,是v0.10.33,其安装的node_modules已经无法正常安装了,我物理备份了一套可运行的。

下边给大家看一下整个项目的一个目录结构:

├── 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这里简单做一下解释,crontab放置的是每天备份数据的脚本,docker-compose.yml是对我的服务的编排操作的配置文件,dropbox.py是dropbox的linux版本的命令行工具,mongo目录放置的是mongodb相关的镜像配置和卷目录,nginx,node也是,一共会构建三个镜像提供整个web服务。

这里再简单的介绍一下node目录,其中的public是放置静态资源和用户上传的图片文件的,node_modules是作为卷挂载进容器的,tuer2.0是nodejs的源码目录。

Nodejs服务镜像准备

那么我先从node镜像的Dockerfile说起:

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镜像开始构建,设置一下系统内时区,然后使用VOLUME挂载了3个目录,这里对不熟悉docker的小伙伴稍微介绍下,VOLUME的作用是定义3个容器内部的目录,可以在Docker启动的时候宿主机的目录进行关联,这样这几个目录内文件的读写就都会保存在宿主机对应挂载的目录下了。这里我定义了静态资源目录,网站源码目录,还有node_modules目录,这样的好处是可以避免构建镜像的时候总是要npm install了。

然后使用node启动web服务,对外暴露2个端口分别是3000和3030,都是nodejs的服务端口。

然后我们再看一下docker-compose里的node镜像是如何设置的参数,这里对不熟悉docker-compose的小伙伴也稍微介绍下,docker本身是可以用run命令来启动容器的,但是当你有多个容器互相依赖而且参数繁多的情况下,使用docker-compose可以简化并且易于维护。

nodejs: build: context: ./node # 构建 node 目录 他会去 node 下面寻找 Dockerfile environment: - DOCKER_DEFAULT_PLATFORM=linux/amd64 ports: - 3030:3030 # 映射 - 3000:3000 # 映射 volumes: - ./node/tuer2.0:/www/tuer2.0 # 项目文件映射 - ./node/public:/www/tuer2.0/public # 项目文件映射 - ./node/node_modules:/www/tuer2.0/node_modules # 项目文件映射 restart: always depends_on: - mongo networks: - my-network我们先是定义了一个nodejs的镜像,他使用当前目录的 ./node 目录中的dockerfile进行构建,然后我们设置了一个env环境变量,指定是amd64的系统,因为mac m1芯片构建的node是不能运行的,底层不兼容,必须指定平台。

然后映射本地的ports,挂载本地的源码目录,静态目录,node_modules目录到容器中,设置restart always,这样就不需要pm2了,然后该nodejs服务依赖另外一个mongo容器,使用my-netwokr来进行网络映射。

这样设置的好处不多说了,构建镜像很快,修改源码后可以直接restart容器生效看效果,不需要频繁的build了。

Mongodb的镜像准备

FROM mongo:3.4VOLUME ["/backup"]COPY ./setup.sh /docker-entrypoint-initdb.dRUN chmod a+x /docker-entrypoint-initdb.d/setup.shmongo目录下的dockerfile比较简单,我们设置了一个容器内的 /backup 目录来做备份文件的导出,然后编写了一个setup.sh的脚本,复制到`docker-entrypoint-initdb.d`目录下来做数据库的初始化操作。

我们这里看一下setup.sh的内容:

#!/bin/bashmongorestore -h 127.0.0.1 --port 27017 -d node-mongo-tuer /backup/node-mongo-tuer这个shell脚本的作用是使用mongorestore来对数据库做数据恢复,我们只需要在启动的时候在backup目录下放置好之前备份的数据库目录就行了,当容器启动时就会自动恢复之前的内容。

我们再看一下docker-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的启动目录,mongo.conf 可以设置一些mongo的配置,比如登录验证等,但是我没有配置,我在后边会介绍,直接用Linux的防火墙软件关闭外网访问mongo端口的方法。

Nginx的镜像准备

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有点复杂,但是其实只需要关注上面的VOLUME ["/www/tuer2.0/public" ]这一句就行了,其他的都是Nginx的官网配置,为什么不直接使用Nginx的镜像来做容器呢,因为我的网站使用了Nginx的额外插件,所以需要源码编译的方式。

插件我用了阿里的http-concat,在nginx目录下放置一个插件目录,然后插件目录里放一个source文件即可。

├── nginx│ ├── conf│ ├── Dockerfile│ ├── http-concat│ ├── source │ └── logssource的文件内容就是插件的下载地址:

https://github.com/alibaba/nginx-http-concat/archive/1.2.2.tar.gz我们再看一下nginx的配置部分:

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; } }}这里只写了一部分,比如插件的加载需要在nginx配置的头部就使用load_module进行加载,其中网站的vhosts部分,使用了proxy_pass的反向代理,但是这里注意不能用127.0.0.1这种或者localhost,需要使用容器网络中的name,比如nodejs容器的name在我这里就是tuer30_nodejs_1,需要使用docker network inspect my-network来进行查看确认,这里被坑了很久,容器内一直访问不了其他容器。

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

nginx: # nginx 容器 这里的名字可以当做变量使用 environment: - DOCKER_DEFAULT_PLATFORM=linux/amd64 build: # 定义需要构建的内容 context: ./nginx # 选取 nginx 文件夹 args: ENABLED_MODULES: http-concat ports: # 映射端口 - 80:80 - 443:443 volumes: # 挂载文件夹,配置我们可以写在宿主机,然后挂载进去 - ./node/public:/www/tuer2.0/public - ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf - ./nginx/logs:/var/log/nginx restart: always # 服务挂了的时候始终自动重启 networks: # 使用我们上面定义的网络 - my-network因为增加了http-concat插件,所以在build的时候增加args参数,来设置ENABLE_MODULES,多个插件空格隔开。

使用Dropbox来同步数据和备份

上面基本介绍了如何编写镜像,下边说一下数据如何同步到vps上,我们为了备份和同步数据方便直接把网站项目做到了dropbox网盘中,在本地mac上做实时备份,在vps上安装linux版本的dropbox即可。

cd ~ && wget -O - "https://www.dropbox.com/download?plat=lnx.x86_64" | tar xzf -~/.dropbox-dist/dropboxd直接下载后启动就行,在centos7中可能会遇到依赖问题,提示缺少glibc,如果遇到了需要手工下载,切记需要2.19以上版本才能运行。

安装方法:

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安装好后,启动Dropbox,同步所有网站文件和数据到vps就行了,设置dropbox开机启动可以参考这篇文章:https://www.ltsplus.com/linux/centos-7-install-dropbox

在vps上安装docker和docker-compose

我是在centos7上操作的,遇到不少问题,这里也记录一下:

首先需要安装python3,可以参考这篇文章:Linux Centos7安装python3.7和安装pykmip

然后需要安装docker,docker-compose,可以参考这篇文章:Redhat OS安装docker-ce及docker-compose步骤

然后还要安装pip3,可以参考这篇文章:docker-compose安装---pip3_TaotaoPlus的博客-CSDN博客

在vps上启动docker服务

docker-compose up --force-recreate --build -d直接构建加启动,不出意外就是下边这个样子:

在vps上设置防火墙

启动好服务后虽然可以直接访问了,但是我们还是需要设置一下防火墙规则,这里我使用自带的firewalld来设置,这里需要注意很重要的一点,一开始我怎么设置都不生效后来发现原来是docker启动时捣的鬼,可以参考这篇文章进行恢复:Linux系统安装docker后,firewall规则无效不起作用 - 高效码农

设置好防火墙生效后我们设置关闭外部访问mongodb既27017端口,再对外打开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 设置完成后记得reload操作,还有对firewall进行开机启动设置。

使用crontab对mongodb数据库定时备份

在命令行输入crontab -e,可以进入crontab设置:

0 0 * * * /bin/bash /root/Dropbox/tuer3.0/crontab/help.sh每天0点进行一次备份操作,我们看一下help脚本怎么写的:

#!/bin/shcd '/root/Dropbox/tuer3.0/mongo/backup'cur_dir=$(pwd)#重启服务cd $cur_dir#备份数据库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我们在挂载的backup目录下,对容器tuer30_mongo_1调用容器内的mongodump命令进行备份,备份后删除前一天的备份压缩包,然后tar压缩当天的备份,删除导出的备份目录即可。

以上所有部署代码的源码参考

之前一直使用的git同步代码,pm2重启方式来进行的网站部署,经过这一顿折腾,感觉比原来清爽多了。

本身我是有一个私有的git仓库来维护这个项目的,但是因为里面涉及到了网站的源代码,所以就不对外了,如果有感兴趣的同学想接盘这个网站的可以联系我,我可以开放权限给你。或者对文章的配置有疑问的,可以在评论里留言我把更详细的代码可以局部发给你。

关键词:步骤,部署

74
73
25
news

版权所有© 亿企邦 1997-2025 保留一切法律许可权利。

为了最佳展示效果,本站不支持IE9及以下版本的浏览器,建议您使用谷歌Chrome浏览器。 点击下载Chrome浏览器
关闭