我会带领大家从一个网上的开源项目,一步步通过docker部署起来,因为我也不是很熟悉docker、nginx所以绕了一些坑,后面会指出来。本文主要是把一个vue项目,通过nginx docker镜像或者通过node docker镜像部署起来,会把一些关键配置以代码形式展示出来,一步一步来,肯定可以运行起来的。
docker 基础知识
docker的基础知识网上都有,就简单的理解成一个容器吧,可以把代码放进去,然后通过端口映射,访问宿主机可以访问得到容器里面的程序。下面列举一些常用操作
操作 | 代码 |
---|---|
登录仓库 | docker login docker-registry.xxxx (用户名不带mail) |
退出仓库 | docker logout |
拉取镜像 | docker pull docker-registry.xxx/docker/nginx:1.13.6 |
推送镜像 | docker push |
删除镜像 | docker rmi IMAGE ID |
查看正在运行的容器 | docker ps |
停止一个容器 | docker stop CONTAINER ID |
查看所有容器 | docker ps -a |
删除一个容器 | docker rm CONTAINER ID |
删除所有容器 | docker rm $(docker ps -a -q) |
容器挂载 | docker -v /opt/www/html:/var/www/html 宿主机绝对路径(一定要是绝对路径,不然无法挂载):docker容器 |
build容器 | docker build -t fgf/nginx:beta_v1 . (一定要有.,并且在Dockfile所在文件夹操作,也可以做其他设置,简单点就行) |
run | docker run -d -p 80:80 IMAGE ID(-d 后台运行 -p 宿主机端口:docker端口) |
进入一个正在运行的docker | docker exec -it CONTAINER ID /bin/bash |
进入一个镜像 | docker run -it IMAGE ID /bin/bash |
从容器中退出 | Ctrl + d 或者exit回车 |
镜像重命名 | docker tag IMAGE ID 新名字 |
vue项目
项目是在iview-admin一个非常棒的后台管理开源项目上开发的。最新版事基于vue-cli 3.0开发的,所以部署到docker里面遇到了一些配置问题,毕竟和vue-cli 2.0 不一样,还是有点不太习惯。大家如果想尝试的话,可以去GitHub把iview-admin代码下载下来进行docker 部署,然后用豆瓣公开的api进行nginx配置,把这个流程走一遍。
我要做的事情就是浏览器打开页面,然后页面会转发我的请求到第三方的api,比如豆瓣api什么的。然后把取回的数据进行渲染。其中有个不太一样的地方就是header里面加了一个参数:USERTOKEN。
vue 的配置
vue.config.js 只把修改的地方列举出来
const BASE_URL = process.env.NODE_ENV === 'production'
? '/'
: '/'
devServer: {
host: '0.0.0.0',
port: 80,
proxy: {
'/getXXX|/getAAA|/getBBB': {
target: 'http://abc.com/d/key',
changeOrigin: true
},
}
}
src/config/index.js 将开发环境dev、生成环境pro都设置为ip地址,因为线上环境肯定是通过ip访问的,结果本地设置为localhost可以访问,线上就会出现header参数无法代理转发等奇怪的问题,为了在本地复现这个问题,就把开发环境也设置为了ip,所以为了能顺利部署,尽量和线上环境一直,这样问题也好复现。
baseUrl: {
dev: 'http://10.5.179.17/',
pro: 'http://10.23.237.139/'
},
src/main.js 引入mock因为如果你没有对接登录的api的话,进不到后台页面,所以线上环境也mock一下吧。
require('@/mock')
src/api/xxx.js
export const findXXX = ({pid, userName, grp_name, pageNumber, pageSize}) => {
return axios.request({
baseUrl: '',
headers: {
USERTOKEN: 'abcde'
},
url: '/findxxx',
method: 'get',
params: {
pid: pid,
userName: userName,
grp_name: grp_name,
pageNumber: pageNumber,
pageSize: pageSize
}
})
}
上面的baseUrl一定要设置为空在iview-admin中,其他项目不清楚。
nginx文件配置
custom.conf
server {
listen 80;
listen [::]:80;
# 接口服务的IP地址
server_name localhost;
charset utf-8;
access_log off;
# ElecManageSystem-应用文件夹名称 app-index.html页面所在文件夹
root /var/www/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /getXXX{
proxy_pass http://abc.com/d/key/getXXX;
}
location /getAAA {
proxy_pass http://abc.com/d/key/getAAA;
}
location /getBBB{
proxy_pass http://abc.com/d/key/getBBB;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
其中
location / {try_files $uri $uri/ /index.html;}
一定要写,不然部署项目后刷新后变成404,还有就是 location /getBBB已定不要写成 location /getBBB/ 区别就是多了一个/但是效果不一样,在末尾加一个/会发现axios请求一次,但是nginx有两个请求,其中第二个还会把post请求的参数丢失
Dockerfile文件编写
node镜像(docker 里面打包)
FROM docker-registry.xxxx/docker/node:8.12.0-slim
RUN apt-get update && apt-get install -y nginx
WORKDIR /app
COPY . /app/
EXPOSE 80
RUN npm install && npm run build && cp -r dist/* /var/www/html && rm /etc/nginx/sites-enabled/default && cp custom.conf /etc/nginx/sites-enabled/ && rm -rf /app
CMD ["nginx","-g","daemon off;"]
代码解释
FROM 后面的地址大家根据自己情况,填写自己可以获得镜像的正确地址,然后是安装nginx,创建文件夹/app,然后将所有项目代码拷贝到docker镜像/app下面然后是安装依赖,打包,将打包好的文件复制到nginx目录下面,删除nginx默认目录,将自己的nginx配置文件复制到nginx对应目录。删除/app里面的文件,启动nginx。
nginx镜像(宿主机打包)
FROM docker-registry.xxx/docker/nginx:1.13.6
COPY ./dist /var/www/html
COPY ./custom.conf /etc/nginx/conf.d/
RUN rm /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx","-g","daemon off;"]
代码和上面类似就不解释了。但是方便快了很多
打包
docker build -t fgf/ngixn:beta_v1 .
运行
docker run -it -p 80:80 IMAGE ID
然后就可以通过ip访问了。
注意项
- nginx的配置一定要正确,还要记得删除原nginx的在conf.d或者sites_enabled里面的默认配置,以免出什么幺蛾子。有时候把配置build到docker镜像里面比较费时间,仅仅是为了验证nginx配置是否正确,这个时候可以通过挂载的方式验证配置,等nginx跑通了,再把nginx配置build到镜像里面。
- 一定要在本地环境跑通了,再放到线上Linux服务器里面,毕竟本地比较好调试