为了给小学期实验做准备,这几天提前准备试验了一下使用 docker 容器部署SpringBoot+Vue前后端分离的项目。中间踩坑无数,特此记录一下,仅供学习和参考。
首先需要配置一下需要的 docker 环境,总体来讲是需要 docker engine 和 docker registry 。搭建环境网上有很多教程,这里不再赘述。
之后,需要在前后端分别添加 Dockerfile,而前端除了需要 Dockerfile 以外,还需要 Nginx 的配置文件——姑且命名为 default.conf 。
一、准备配置文件
下面列出了具体的文件。
(1)后端 Dockerfile
FROM openjdk:8 ADD /target/blog-1.0-SNAPSHOT.jar app.jar EXPOSE 11451 CMD java -jar app.jar
讯享网
执行这个 Dockerfile 的前提是需要在本地先 package 完毕,/target 目录下有对应 jar 包。
(2)前端 Dockerfile
讯享网# build stage FROM node:lts-alpine as build-stage WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build # production stage FROM nginx:stable-alpine as production-stage RUN rm /etc/nginx/conf.d/default.conf COPY --from=build-stage /app/dist /usr/share/nginx/html
COPY --from=build-stage /app/default.conf /etc/nginx/nginx.conf EXPOSE 13141 CMD ["nginx", "-g", "daemon off;"]
(3)前端 Nginx 代理配置文件
worker_processes 1 events {
worker_connections 1024; } http {
include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server {
listen 13141; server_name 10.134.136.71; root /usr/share/nginx/html; location / {
# root html; index index.html index.htm; try_files $uri $uri/ /index.html; } location /dev-api {
# rewrite ^/b/(.*)$ /$1 break; proxy_pass http://10.134.136.71:11451/api/v1; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html error_page 500 502 503 504 /50x.html; location = /50x.html {
root html; } } }
当前端的 Dockerfile 执行时,会构建一个 Vue 项目的镜像。
构建时,会先运行 npm build 指令,生成目标 dist 目录;紧接着,会清除镜像中 Nginx 原有的配置文件,并将我们本地的“/dist”目录和“default.conf”两项分别拷贝至我们刚刚创建的镜像中,同时暴露13141端口;最后,执行重启镜像 Nginx 的指令。
这便是整个构建 Docker 镜像的过程。
二、运行
Docker 相关的指令
讯享网# docker 构建指令 docker build -f {
Dockerfile 名称} -t {
镜像名称} # 查看当前仓库中的镜像 docker images # 运行镜像 docker run -d --name={
镜像名称} -p 13141:13141 {
容器名称} # 停止运行镜像 docker stop {
镜像名称/ID} # 删除镜像 docker rmi {
镜像名称/ID} # 删除容器 docker rm {
容器名称/ID} # 查看运行中的容器 docker ps # 查看所有容器(包括停止运行的) docker ps -a # 进入容器内部 docker exec -it {
容器名称/容器ID} /bin/bash docker exec -it {
容器名称/容器ID} /bin/sh # 查看 docker 容器的日志 docker logs --since 30m {
容器ID}
三、问题汇总
(1)Nginx 前后端应该完全对应,否则会出现 Nginx 400/50x 等相关错误。
首先,端口要对应。后端的 yml 文件为
因此后端 Dockerfile 开放的端口保证为 11451。前端的 default.conf 文件中代理地址则也应该保持一致。

至于为什么是“/dev-api”,这个是前端统一配置的 api 格式。通俗来讲,Nginx 会把带有“/dev-api”的请求代理到对应的接口上。如下图所示:


最后,前端的 Dockerfile 也相应地开放一个端口 13141, 用于留给 Nginx 监听,当 Nginx 监听到有请求访问这个端口时,就会进入到既定的 root 目录下的 index 界面中,并触发代理,转发到对应的后端接口地址。因此,Nginx 对应的配置如下图所示。

(2)build 后的前端制品在 Docker 镜像中的挂载目录引发的一系列问题
将前端的制品构建镜像时,我们要指定挂载目录。在前端 Dockerfile 中通过 COPY 指令操作了这一过程,如下图。

下表是一般情况下,宿主机和镜像目录的挂载对应关系。
| 宿主机 | 容器 | 用途 |
|---|---|---|
| /app/dist | /usr/share/nginx/html | 资源路径 |
| /app/default.conf | /etc/nginx/nginx.conf | nginx的默认配置文件就在此处 |
(3)Docker 运行指令中的端口映射
构建时的指令:
docker run -d --name={
镜像名称} -p 13141:13141 {
容器名称}
“-p”参数规定了宿主机和容器之间的映射关系。一般来讲,“-p port1:port2”中,port1 是宿主机的端口,port2 是容器的端口。具体可以通过“docker ps”指令进行查看。注意,在宿主机的某个指定端口上只可以绑定一个容器。
可以通过以下指令查看端口映射的信息。
讯享网# 查看容器所有映射端口 docker port {
容器名/容器ID} # 查看容器内某个端口映射到哪里 docker port {
容器名/容器ID} {
容器端口号}
(4)Docker 启动后闪退
如果出现此类问题,建议查看 docker 日志,来具体分析。查看日志的指令如下:
# 查看 docker 容器的日志 docker logs --since 30m {
容器ID}
(5)Dockerfile 中启动 Nginx 的指令
我们可以看到,在 Vue 项目的 Dockerfile 中,最后一行是:
讯享网# 指令1 CMD ["nginx", "-g", "daemon off;"]
为什么不是通用的启动指令(如下):
# 指令2 CMD service nginx start
这是因为容器只对主进程服务,当主进程退出的时候,容器也会退出。而 CMD 在使用 shell 格式的话,真实的命令会被包装为 sh -c 参数的形式执行。
结合以上两点,可以看出,启动 Nginx 的时候,主进程其实是 sh,而容器是因为 sh 这个主进程产生的,当该条命令执行完毕之后,sh 作为主进程会退出,容器自然也会退出,因此导致 Nginx 启动不了。所以需要使用指令1进行包装启动。
(6)运行Vue Docker 镜像报错:“worker_processes;指令不允许使用nginx”
造这个错误的是容器找不到“default.conf”中的指令导致的。但是为什么会找不到呢?很有可能是“default.conf”这个文件被 COPY 到错误的目录下了。
请注意:worker_processes以及 Nginx 配置文件中的所有指令,仅在配置的顶层(/etc/nginx/nginx.conf)有效,因此,请检查一下,是否将“default.conf”文件 COPY 到了“/etc/nginx/conf.d/default.conf”目录下。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/47973.html