一、概述
vue項目可以打一個dist靜態資源包,直接使用Nginx發布即可。
現在由於要上docker,需要將vue項目和nginx打成一個鏡像才行。
項目結構如下:
./
├── build
│ └── build.js
├── config
│ └── index.js
├── dist
│ ├── index.html
│ └── static
├── index.html
├── package.json
├── README.md
├── src
│ └── App.vue
└── static
二、封裝docker鏡像
這里使用鏡像nginx:1.17.8
登錄服務器
創建目錄
mkdir -p /data/nginx
nginx.conf
這個文件是從nginx:1.17.8拷貝出來的,並做了一定的優化,完整內容如下:

user nginx; worker_processes auto; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; worker_rlimit_nofile 65535; events { use epoll; worker_connections 1024; } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 120; types_hash_max_size 2048; server_names_hash_bucket_size 128; client_header_buffer_size 32k; client_max_body_size 2048m; client_body_buffer_size 128k; proxy_connect_timeout 10; default_type application/octet-stream; gzip on; gzip_min_length 1k; gzip_http_version 1.1; gzip_buffers 4 16k; gzip_comp_level 2; gzip_types text/plain application/x-javascript text/css application/xml application/javascript; gzip_vary on; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Scheme $scheme; proxy_set_header X-Forwarded-Proto $scheme; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; server_tokens off; include /etc/nginx/mime.types; include /etc/nginx/conf.d/*.conf; }
default.conf
這個文件是從nginx:1.17.8拷貝出來的,為了適應vue,做了一定的改動,完整內容如下:

server { listen 80; server_name localhost; charset utf-8; access_log /var/log/nginx/host.access.log main; location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri $uri/ /index.html; } }
dockerfile
主要工作就是覆蓋配置文件,拷貝dist包,並設置權限。

FROM nginx:1.17.8 ADD nginx.conf /etc/nginx/nginx.conf ADD default.conf /etc/nginx/conf.d/default.conf ADD dist /usr/share/nginx/html RUN chown nginx:nginx -R /usr/share/nginx/html EXPOSE 80 ENTRYPOINT [ "nginx", "-g", "daemon off;"]
/data/nginx完整目錄結構如下:
./
├── default.conf
├── dockerfile
└── nginx.conf
將這3個文件拷貝到vue項目,使用docker build命令,就可以打包了。
創建代碼目錄
mkdir -p /data/code
安裝組件,用於jenkins發布
yum install -y rsync lsof
三、jenkins發布
由於有多個vue項目,每個vue項目的dockerfile都是一樣的。因此,不需要將dockerfile提交到github中,放到服務器的固定位置即可。
發布時,將dockerfile拷貝到目錄即可。
環境介紹
gitlab版本:GitLab 社區版 10.5.1
jenkins版本:2.219
服務器:centos 7.6
由於jenkins服務器的操作系統為:centos 6.9,它不能安裝docker,因此docker打包動作需要在服務器上面執行。
ansible分組
vi /etc/ansible/hosts
內容如下:
[test_vue] 192.168.28.34
ansible playbook
vi /opt/ansible/test/docker_vue.yml
內容如下:

--- # 需要傳入變量HOSTS,ENV,PROJECT_NAME,PORT # 分別表示: 主機,環境,項目名,端口 - hosts: "{{ HOSTS }}" remote_user: root become: yes become_method: sudo # 聲明變量 vars: # 遠程項目基礎目錄 BASE_DIR: "/data/code" # 遠程項目目錄名 PROJECT_DIR: "{{ ENV }}_{{ PROJECT_NAME }}_{{ PORT }}" # 完整的jenkins 項目跟路徑 JENKINS_DIR: "/data/jenkins_data/workspace/{{ JOB_NAME }}" tasks: #刪除原來的包 - name: delete directory file: path: "{{ BASE_DIR }}/{{ PROJECT_DIR }}/dist" state: absent #同步web靜態文件到目標服務器 - name: synchronous web static file synchronize: src: "{{ JENKINS_DIR }}/dist" dest: "{{ BASE_DIR }}/{{ PROJECT_DIR }}/" #復制nginx default.conf和dockerfile - name: copy nginx conf and dockerfile shell: \cp /data/nginx/* {{ BASE_DIR }}/{{ PROJECT_DIR }}/ # 打包鏡像 - name: docker build shell: cd {{ BASE_DIR }}/{{ PROJECT_DIR }} && docker build -t {{ PROJECT_NAME }}:{{ BUILD_NUMBER }} . #刪除之前的docker - name: docker rm image shell: docker rm -f {{ PROJECT_NAME }} ignore_errors: yes #啟動docker - name: docker run image # 提前創建bridge網絡:docker network create testnet shell: docker run -it -d --restart=always --name {{ PROJECT_NAME }} --network testnet --network-alias {{ PROJECT_NAME }} -p {{ PORT }}:80 {{ PROJECT_NAME }}:{{ BUILD_NUMBER }} - name: view port,Wait for 1 seconds shell: sleep 1;lsof -i:{{ PORT }}
由於1台服務器有多個vue項目,因此需要使用非80端口來映射。
新建job
新建一個job,名字為:test_vue,使用自由風格
源碼管理
執行shell腳本
完整命令如下:
ansible-playbook -v /opt/ansible/test/docker_vue.yml -e "HOSTS=test_vue JOB_NAME=${JOB_NAME} BUILD_NUMBER=${BUILD_NUMBER} ENV=test PROJECT_NAME=web_vue PORT=7000"
點擊最下面的保存,最后點擊構建即可
由於服務器運行的vue項目,映射的是非80端口,域名解析到這台服務器,是無法訪問的。
因此需要使用Nginx轉發一下即可。
server { listen 80; server_name vue.baidu.com; access_log /var/log/nginx/ vue.baidu.com.access.log main; error_log /var/log/nginx/ vue.baidu.com.error.log; location / { proxy_pass http://127.0.0.1:7000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 300s; proxy_send_timeout 300s; proxy_read_timeout 300s; # websocket support proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }