跳到主要内容

从0到1搭建个人博客(运维篇)

阅读需 8 分钟

构建与部署 deploy 篇

一、flag​

  • nginx 只需配置 nginx.conf
  • 前端 dist 文件夹
  • 后台管理 dist 文件夹
  • 解决 mongo 生成错误
  • 配置 mongo docker
  • 配置后台服务 docker
  • github提交代码后,服务器自动下载源码,进行更新部署

二、构建​

1. nginx​

书写 docker-compose.yml 文件

关于 nginx 的配置:

① 因基本不需要更改内部:直接指定 image,不需要书写 Dockerfile;

② 可直接指定容器名词:”evgo-nginx";

③ 挂载:如果是文件夹,指定好文件夹会自动创建,但如果是文件就需要提前准备好内容文件。

④ 配置文件,log 日志文件的原始位置。

// docker-compose.yml
version: '3.7'
services:
evgo-nginx:
image: "nginx:1.15.2-alpine"
container_name: evgo-nginx
## build:
## context: ./docker/nginx/
## dockerfile: Dockerfile
ports:
- "80:80"
volumes:
- ./docker/nginx/logs:/var/log/nginx ## logs
- ./docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf ## nginx.conf 配置文件
- ./front/dist:/var/www/website/front ## 前端页面

// nginx.conf
location / {
root /var/www/website/front; ## html 文件夹位置,此部分是前端页面
index index.html index.htm;
}

统一部署

docker-compose up

docker-compose down

  • github desktop bug:when create

2. mongdb​

问题:测试的过程中一直有错误,code 14。只要一挂载数据:-v ./docker/mongo/db:/data/db 就要出错。

version: '3.7'
services:
evgo-mongo:
image: mongo:4.0.9
container_name: evgo-mongo
restart: always
environment:
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=root
ports:
- 27017:27017
volumes:
- ./docker/mongo/db:/data/db

相关错误信息:--sslDisabledProtocols 'none' ,Operation not permitted ,aborting after fassert() failure ,exited with code 14 。

docker-mongo-notPermitted

尝试方法:用管理员身份运行命令,甚至用 -v C:/docker/db:/data/db 来挂载,手动输入密码确认身份,都不可以,一样的错误,隐隐觉得是 windows 的锅。用服务器运行配置,啥问题。

解决方案:用数据卷。推荐文章

version: '3.7'
services:
evgo-mongo:
...
volumes:
- mongo-db:/data/db
volumes:
mongo-db:

真滴坑啊。

3. server​

主要难度在于路径。构建时,Dockerfile 的位置并不是核心,而上下文(context)才是。

如果是将 Dockerfile 处于单独的 docker 文件夹内,则需要在 build 内的 context 内配置上下文,因为有 COPY 和 ADD ,这样构建的时候会花费很长时间(较慢,一开始我还以为是哪里出问题了):

evgo-server:
container_name: evgo-server
build: ## 相当于 docker build -f ./docker/server/Dockerfile
context: ./
dockerfile: docker/server/Dockerfile
ports:
- 3000:3000

对应 Dockerfile :

FROM node:10.15.3-alpine
WORKDIR /var/www/website/server
## COPY、ADD 必须处于上下文
COPY server/package*.json ./
RUN npm install --registry=https://registry.npm.taobao.org
COPY server/* ./
EXPOSE 3000
CMD ["npm", "start"]

鉴于这样的速度,我选择将 Dockerfile 和 .dockerignore 放入 server 文件夹内...文件不同如下:

build: ./server 
COPY package*.json ./
COPY . .

此外,如果在构建镜像时一直找不到 package.json 等等问题,但配置的路径确实没错,那么删除一下以前构建的镜像 =。= 此乃大坑!!

docker-compose up --build

加上 --build 就好了~ 重新构建镜像

4. client​

复制文件​

客户端的 docker 镜像,只需要导出 dist 就好。

COPY * ./ :所有文件在同一级目录。

写成 COPY . . 就可以保持原先的文件夹结构了。

DockerCOPY同一级

与 nginx 联合​

┭┮﹏┭┮ 设想:

nginx 容器直接获取 client 容器导出的 dist 数据即可。

这里研究很久,一直以为是容器启动顺序的问题,使用数据卷挂载还是错误:

ERROR  Error: EBUSY: resource busy or locked, rmdir '/var/www/website/client/dist'
evgo-client | Error: EBUSY: resource busy or locked, rmdir '/var/www/website/client/dist'

最后竟然是因为我在 client 的 Dockerfile 里面写的是 CMD:

CMD ["npx","vue-cli-service","build"]
改为:
RUN npx vue-cli-service build

直接复制 server 改的...真尴尬,大功告成。

volumes:
evgo-client-dist:
services:
evgo-client:
volumes:
- evgo-client-dist:/var/www/website/client/dist
evgo-nginx:
volumes:
- evgo-client-dist:/var/www/website/client/dist ## 前端页面

5. 启动顺序​

每部分都是单独的应用,所有需要确认启动顺序,确保在启动 nginx 之前 web dist 已有

6. Network​

"Subnet": "172.26.0.0/16",
"Gateway": "172.26.0.1"

network
external
external_links

nginx 单独配置,通过内网 IP、port 来链接。

set $internetIP '172.26.1.1';

7. volume 并不能写入​

重建 dist 后并没有更新文件!!每次必须删除后重建才可以!

为什么 docker-compose build client 后并没有更新数据

三、部署​

Docker​

根据 Docker 章节配置好 Dokerfile, Docker-compose.yml

操作​

git clone git@github.com:evgo2017/website
cd ./website/deploy
chmod init.sh index.sh
./init.sh

一键部署​

将代码提交后, Github-> hooks -> 服务器部署。

设想:新建一个 delpoy 容器来接受 Github 的 webhooks ,执行 sh。

部分镜像应该打包到云、或者私有库保存。比如数据库

其实写一个一个 js 来监听某端口,运行 sh 就可以了。

因为还有密钥,缓存等等,所以最好还是 git pull 来更新本地代码,可以配置部署密钥,只读权限。

也可以密钥等秘密配置就自己整理存在另一个地方,git clone 之后复制过去。

开始还想着几个容器处在同一个网络,接收到信息后将整个网络重置。 哈哈。

最后还是择 Jenkins ,一方面是应该单独出来,另一方面之前没接触过这个,学习学习。

Jenkins​

拉取镜像没啥说的。

docker pull jenkins/jenkins:lts-alpine

docker run -d -p 7080:8080 -p 50000:50000 --name jenkins_home -v jenkins_home:/var/jenkins_home jenkins/jenkins:lts-alpine

docker exec -it jenkins_home /bin/sh

vi /var/jenkins_home/hudson.model.UpdateCenter.xml

修改源:http://mirror.xmission.com/jenkins/updates/update-center.json

cat /var/jenkins_home/secrets/initialAdminPassword

密码记下来

docker restart jenkins_home

修改源,要不登陆后卡在默认界面。

https://blog.csdn.net/weixin_34080571/article/details/85845604

或 https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json

jenkins_install.png

配置 Github 密钥​

cd ~/.ssh && ls
ssh-keygen -t rsa -C "your_emali@example.com"
cat SSHName.pub
ssh -T git@github.com

请在测试连接时!!!输入 yes!!!而不是回车!!!!

如果连接失败或者其他,删除 ~/.ssh/known_hosts 文件再尝试

如果不是默认的名称 id_rsa,则需要增加配置 config 文件才可以正常连接

// ~/.ssh/config
Host github.com
HostName github.com
IdentityFile ~/.ssh/yourSSHName

大概文件示例:

// ~/.ssh# ls
authorized_keys config github_website github_website.pub known_hosts

git 代码

git clone git@github.com:evgo2017/website.git

如果有 authorized_keys 文件,这是 SSH 登陆你用的。

Generic Webhook Trigger

Publish over SSH

本地搭建 node 环境​

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
// wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
重开 Terminal
nvm install v10.15.3 // nvm ls-remote
npm config set registry http://registry.npm.taobao.org
// 使用 nrm 修改镜像源:https://www.cnblogs.com/susu8/p/9208826.html

配置 Webhooks​

选用 Node.js 搭建,github-webhook-handler 与 exec 库。

以 Github 的配置为例:

createHandler = require('github-webhook-handler'),
handler = createHandler({ path: '/payloadURL', secret: 'example' })
/**
* 以 Github Webhooks 为例:
* path: Payload URL(http://ip:7777/payloadURL),
* Content type: application/json
* secret: Secret(example)
*/
http.createServer(function (req, res) {}).listen(7777)

webhooks

tree​

显示目录属性结结构

apt-get install tree
tree
tree -L 2 // 树深度,两层
tree -p // 权限
tree -d // 只有文件夹

chmod 权限​

chmod 777 delpoy.sh

githubusercontent​

从安装 nvm 启发的写了一个 sh 来运行

blob/master​

文件夹文件,转换为上传成 Github 的 URL

示例:

https://github.com/evgo2017/website/blob/master/README.md

https://github.com/evgo2017/website/blob/master/client/Dockerfile

https://github.com/evgo2017/website/blob/master/client/src/App.vue

规则:

https://github.com/
evgo2017/website/
blob/master/
文件路径

逗号与git​

更改文件内容时,在上一行加上","会多一行修改

要怎么书写?减少这种情况

写在第一行

四、云服务器​

1. 阿里云​

选用的是阿里云的轻量应用服务器,云翼计划,一年114。

具体配置:1核 CPU | 2GB 内存 | 40GB SSD | 5Mbps 限制峰值带宽 | 1000GB 每月流量。

选用理由:以前用的是阿里的 ECS 服务器,虽说每月流量不限量,但是带宽只有 1Mbps,并且目前我一个月根本用不完 1000GB(希望以后不够用)。

建议:轻量应用服务器文档

2. 镜像 Ubuntu 16.04​

之前选用的是 Node.js 应用镜像,方便是方便,但是因为要采用 Dokcer,所以这次选择系统镜像 Ubuntu16.04,自行搭建环境。

本来想选 Centos7.3 的,适合在服务器端运行,但在 Stack Overflow 上查了查两者的问题量,还是选择 Ubuntu 吧,目前在学习阶段,较看重资料丰富程度。

采用 Docker,目前不考虑 Centos 、Ubuntu 等系统镜像性能影响。

nodejs镜像

3. 密钥连接​

连接服务器时,最好使用密钥登陆,推荐 Putty。

配置好后需要重启服务器再连接。

之前使用应用镜像时,用浏览器发起安全连接,找不到已安装的应用,但是用 ssh 就没有任何问题,不知道什么情况。

此外如有问题可以发工单,服务效率还是很高的!晚上十二点多提交工单后准备休息,结果没一会就回复了,惊呆了。

五、服务器环境​

1. 修改主机名​

因为初始的主机名太长了,改成自己的名字。

推荐文章:Ubuntu16.04修改主机名和查看主机名的方法

vi /etc/hostname //改为 evgo
vi /etc/hosts //新增 127.0.1.1 evgo

2. 安装 Docker​

获取Ubuntu的Docker && 阿里云-安装Docker && 官方镜像加速

/var/lib/docker
/etc/docker/daemon.json

3. 拉取镜像​

有 alpine 版就选 alpine 版本,899MB->71MB 可不是闹着玩的。

具体请查看【文件夹结构】文档

镜像大小挂载
node:10.15.3-alpine71MB
nginx:1.15.12-alpine16.1MBnginx.conf、logs、页面 dist
mongo:4.0.9410MBdata、log

4. 安装 Docker-compose​

  • 一键部署

相关:Install Docker Compose

5. SSL​

  • 网站 HTTPS 访问

相关:Nginx/Tengine服务器安装SSL证书

docker exec -it evgo-nginx sh //注意是sh!!
fholzer/nginx-brotli:v1.15.8 //已安装 ssl 模块
0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp //记得打开 Docker 的 443 端口
Loading Comments...