DevOps最佳实践
# 前言
从 PHP 转向 Java,从单体到微服务,似乎 “说干就干” 的冲动越来越少。在跟随老师使用 TP5、JQuery、MySQL、宝塔(Nginx)开发前后端不分离项目的那段时间,是我 “说干就干” 最多的时期,这套架构在无论是现在还是当年都不是什么拿得上台面的架构,但基于这套架构,我个人开发了交易所搬砖、云监工、成绩排名、课程表、疫苗监控等项目,也得到很多同学、网友的认可。
这些项目的开发,很多时候就是一念的想法,就马上开干,当时也不知道什么时候敏捷开发、持续集成,总之就是想到什么就去干,感觉能用了,就先部署一下,而这个部署一下,也就把 PHP 的代码上传到服务器目录。
或是因为 PHP 的弱语言类型、PHP 无需编译、模板渲染的高效,这些 buff 的叠加,让说干就干变得简单,转用 Java 后,从单体到微服务,说干就干似乎离我越来越远,想做点什么,但想到需要定义、配置好多东西才能把项目跑起来,跑起来后又要配置好多东西才能把他部署到生产环境,念头瞬间又消失了。
“开发一时爽,维护火葬场”,对于商业软件来讲,标准化和规范化的开发流程不可否认能提高产品的质量以及后续维护的成本,但一味追求标准化、规范化,也许需求评审都还没开完,当年的我可能已经上线了第一个版本。
当然,产品的事情我也不懂,我不过是一个码农,而我写这篇文章,更多是想找回当年那份 “初心”,本文站在一个开发者的角度,而非运维,尝试记录一个也许只适用于本人的 DevOps 最佳实践。
# 环境
操作系统:Ubuntu
# 云联网
# 中间件
对于生产环境,如果是商用大多数时候都是买的云服务商提供的云产品,这种有钱就行的不在本文探讨范围,本文探讨并不考虑高可用的、能用就行的自己搭建情况。
# MySQL
# Nacos
# Dockerfile
无论是前端项目还是后端项目,最终都需要使用容器镜像的方式交付(使用对象存储部署前端项目的方式不在此讨论范围内)
# Node.js(Vue)
docker/nginx.conf
:用于处理 history 模式下的 vue 项目 F5 刷新报 404 问题
worker_processes auto;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
client_max_body_size 20m;
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html; #配置Vue项目根路径
index index.html index.html; #配置首页
try_files $uri $uri/ /index.html; #防止刷新报404
}
#error_page 404 /404.html;
#location = /40x.html {
#}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
Dockerfile
:
FROM nginx:stable-alpine
COPY dist /usr/share/nginx/html
COPY docker/nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
# Node.js (后端)
FROM node:20-alpine
WORKDIR /home/node/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 9000
CMD [ "npm", "run","start" ]
问题:为什么要先 COPY package*.json ./
再 COPY . .
回答:dockerfile 中的每一个命令,都会导致创建一个新的 layer,只要 pakage.json
没有被修改,新创建的 docker image 其实是可以共享 layer 缓存的。如果直接添加本地的工作目录,那么只要我们的工作目录有文件被修改,会导致整个 docker image 重新构建。所以为了提升构建效率和速度,我们只拷贝 package.json。