前端独立部署,最小docker化实践

前端容器化, 为了能够独立进行部署, 配备 nginx

Dockerfile

这里利用 docker 的 MultiStage 特性,区分打包和生产镜像的 build.
注意顺序,为了利用潜在的 cache 提高打包速度
只把生成的 dist 内容放到 nginx 里面, 并且放入自己的 nginx 配置, 毕竟默认配置不能满足 SPA 项目

FROM node:9.11.1-alpine as build-stage
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package*.json /usr/src/app/
RUN npm install
COPY . .
RUN npm run build
# production stage
FROM nginx:1.13.12-alpine as production-stage
COPY --from=build-stage /usr/src/app/dist /usr/share/nginx/html
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
COPY ./nginx/sites-enabled /etc/nginx/sites-enabled
COPY ./nginx/general.conf /etc/nginx/general.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

nginx 相关配置目录

在项目根目录下放置 nginx 目录
是一些常规配置.
特意开放了 gzip_static, 以备后续前端优化使用.

-nginx
|——sites_enabled
|——–example.com.conf
|–general.conf
|–nginx.conf

nginx.conf

#user www-data;
pid /run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 65535;

events {
multi_accept on;
worker_connections 65535;
}

http {
charset utf-8;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
server_tokens off;
log_not_found off;
types_hash_max_size 2048;
client_max_body_size 16M;

# MIME
include mime.types;
default_type application/octet-stream;

# logging
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;

# load configs
# include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}

general.conf

# security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;

# . files
location ~ /\. {
deny all;
}

# assets, media
location ~* \.(?:css(\.map)?|js(\.map)?|jpe?g|png|gif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
expires 30d;
access_log off;
}

# svg, fonts
location ~* \.(?:svgz?|ttf|ttc|otf|eot|woff2?)$ {
add_header Access-Control-Allow-Origin "*";
expires 30d;
access_log off;
}

# gzip
gzip on;
gzip_vary on;
gzip_static on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss application/atom+xml image/svg+xml;

example.com.conf

server {
listen 80;
root /usr/share/nginx/html;
index index.html index.htm;

location / {
try_files $uri $uri/ /index.html;
}
include /etc/nginx/general.conf;
}

以防不需要的,或者隐秘的文件被打入镜像. 需要 .dockerignore

node_modules
npm-debug.log
Dockerfile*
docker-compose*
.dockerignore
.git
.gitignore
.env
*/bin
*/obj
README.md
LICENSE
.vscode

打包

如果你的项目用了 sass, 注意你打包的网络, 因为我们都是使用的最小基础 alpine 镜像,没有 py 环境.如果不能下载 sass 包会打包失败.

docker build -t vue-docker:v1 .

启动镜像

docker run -p 8080:80 -d vue-docker:v1