本篇主要是在本地用docker部署mysql、vue项目和springboot项目,记录一下。
一、docker部署mysql
我的环境是win10,用的是docker desktop。安装很简单。照着官网的步骤安装即可。
接下来部署mysql
1.1 创建目录
首先在D盘创建目录,这里的目录是为了容器内部挂载数据,方便我们查看数据。
D:\docker\mysql
1.2 下载镜像
接下来需要从docker官方下载镜像文件以部署mysql服务。
在命令行输入指令,即可下载mysql官方镜像。也可以指定下载镜像的版本
docker pull mysql
1.3 创建并运行mysql镜像
我这里用的是mysql5.7版本。--name
指后面跟着的是生成容器的名字,-v
表示挂载位置,后面就是mysql的升值了。-p
后跟着的前者是外部端口,后者是docker内部容器端口。
docker run -d --rm --name Mysql57 -v D:\docker\mysql:/var/lib/mysql -v D:\docker\mysqlConf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=pwd -p 3306:3306 mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
注:--rm
命令会在此次容器服务结束后自动销毁创建的容器服务,不会保留。需要保留的同学请自行去掉--rm
。
1.4 进入容器Mysql57
docker exec -it Mysql57 bash
登录数据库
mysql -u root -p
输入密码即可进行操作
二、Nginx前端项目本地部署
docker有几个非常重要的概念 images、container、Dockerfile
- images
docker把应用程序和依赖打包到images文件里面,通过这个文件就可以生成一个docker 容器。 简单来说,就是把项目的源文件进行打包制作成一个镜像文件
- container
利用docker run的命令来生成该对应镜像的容器,容器很像一个小型的服务器
- Dockerfile
用来配置image的文本文件,Docker根据该文件来生成二进制的image文件
这里是借鉴哪个博客的,忘了……哈哈哈 见谅
2.1 Nginx下载
地址:http://nginx.org/en/download.html
2.2 Vue项目打包
已经本地验证过的项目,在terminal中运行npm run build
或者yarn build
即可。会在vue项目目录下生成一个dist
文件包,里面就是打包好的内容。
2.3 Vue本地部署
将打包好的dist文件夹内部的内容,copy到解压后的Nginx的html文件夹内。
如果不需要配置访问端口的同学,这时候已经可以尝试启动nginx来看自己部署好的前端项目样式了。接下来就先介绍启动Nginx。
2.3.1 启动Nginx
其实启动很简单,双击nginx.exe
,也可以在nginx.exe
所在的文件夹处按shift点右键打开powershell。
此处建议用后者打开,方便查看报错信息、重新加载或停止nginx服务。
启动服务:start nginx.exe
重新加载:.\nginx.exe -s reload
停止服务:.\nginx.exe -s stop
2.3.2 配置访问域名、端口和后端访问地址
访问域名,访问端口和后端访问地址的配置可以参看下面的vue.config.js内容。
2.4 vue.config.js
vue.config.js可以配置前端访问域名,端口号,后端映射地址和地址重写。
这里是我的配置
module.exports = {
// 打包时不生成.map文件,加快打包速度(加速生产环境构建)
productionSourceMap: false,
devServer: {
host: 'localhost', #域名
port: 8083, #端口号
proxy: { #后端地址映射
'/proxy/*': { #前端的访问带着/proxy/,访问后端时没有,需要去掉proxy
// 后端地址
target: 'http://localhost:8079',
secure: false,
changeOrigin: true,
pathRewrite: {
'^/proxy/': '/'
}
}
}
}
}
更多详细配置:https://github.com/chimurai/http-proxy-middleware#proxycontext-config
用nginx进行部署时,vue.config.js中的配置不会起效果(编译打包后,前端页面成为了单独的静态资源)。需要重新在[nginx目录]/conf/nginx.conf
中配置。
参考:https://blog.csdn.net/Jesion_T/article/details/105360625
参照vue.config.js
重新配置后,nginx.conf
形式如下
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 8083; #前端的访问端口
server_name localhost; #前端的域名
location /proxy {
proxy_pass http://localhost:8079; #后端地址
rewrite "^/proxy/(.*)$" /$1 break; #此处重写的目的是去掉访问路径中
#的proxy以便访问后端地址【下文详述】
}
location / {
root html;
index index.html index.htm;
}
}
}
【下文详述处】首先,我们映射路径是/proxy,下面一个映射路径是 / ,根据最长路径匹配原则,/proxy优先级更高。也就是说,凡是以/api/upload开头的路径,都会被第一个配置处理。
proxy_pass:反向代理,这次我们代理到8083端口,也就是upload-service服务;
【对接上文】rewrite
"^/proxy/(.*)$" /$1 break
,路径重写:(1)
^/proxy/(.*)$
:匹配路径的正则表达式,把/proxy
以后的所有部分当做1组;
(2)/$1
:重写的目标路径,这里用$1引用前面正则表达式匹配到的分组(组编号从1开始,也就是proxy),即/proxy
后面的所有。这样新的路径就是除去/proxy
以外的所有,就达到了去除proxy
前缀的目的;
- break:指令,常用的有2个,分别是:last、break;
(1)last:重写路径结束后,将得到的路径重新进行一次路径匹配;
(2)break:重写路径结束后,不再重新匹配路径。此处参考:https://blog.csdn.net/weixin_34267123/article/details/91504901
三、docker部署前端项目
该部分参照目录也可以看大概步骤。不过在执行这些步骤之前,建议先将需要用到的资源整合到一个新的文件夹下,以便理清思路。
新建一个文件夹“vue-docker”(随便取的名字,不重要),文件夹下包含如下内容:
这就是我们docker部署前端工厂需要的全部内容,其中dist
是2.2
打包好生成的文件,Dockerfile
的编写在下文3.1.1
,nginx.conf
可以先将第二章中写好的nginx.conf先copy过来(3.1.2
还会修改,原因也在下文中)。
补充一些常用的docker命令:
1.docker build -t [镜像名字] . #生成镜像
2.docker run -d --name [容器名字] -p [外部端口号]:[docker容器端口号] [镜像名字] #生成容器并运行
3.docker exec -it [容器名字] bash #交互式进入docker容器
4.docker rm -f [容器名字] #删除容器
5.docker rmi [镜像名字] #删除镜像
6.docker ps #查看当前运行的容器
7.docker images #查看当前所有镜像
3.1 准备工作
(ps:这个地方我折腾了大概6、7个小时。一直在修改-->生成镜像-->部署服务-->停止服务-->删除容器-->删除镜像-->循环
。【手动吐血】),主要是没搞懂nginx.conf
应该怎么放和放在那里,还有配置如何修改。
3.1.1 编写Dockerfile
我的Dockerfile配置如下。
#从docker官网拉取标准的nginx镜像,我们需要基于标准的nginx镜像制作自己的镜像
FROM nginx
#拷贝当前目录的文件到指定文件夹下,改文件夹为镜像中的文件夹
COPY ./dist /usr/share/nginx/html
#拷贝nginx.conf文件到镜像下,替换掉原有的nginx.conf
COPY ./nginx.conf /etc/nginx/nginx.conf
#输出完成标志
RUN echo 'build img ok!'
首先需要理解一点,第三句中的配置文件其实就是在配置即将生成的nginx镜像文件,与之前用nginx本地部署编辑nginx.conf
效果类似。
--------------------------------------------------------------解释一下------------------------------------------------------------------------
网上很多Dockerfile写法供参考,第三句有的写得配置etc/nginx/nginx.conf
,有的写得配置etc/nginx/conf.d/default.conf
,开始很迷,不知道到底该怎么写,就搜索了一下。
从技术上讲,
nginx.conf
是最重要的,如果你定义里面的所有东西它仍然可以工作,但为了保持井井有条,他们使用include
,在nginx.conf
尽头你会看到include /etc/nginx/conf.d/*
,在某些发行版你也会发现include /etc/nginx/sites-enabled/*
这是一个保持组织有序的约定,你在conf.d
或sites-enabled
文件夹中创建你的服务器块,它将被包含在这里,好像它是用nginx.conf
文件写的。引自:https://www.soinside.com/question/iW6mWueD5Yvg6jtvQiReGb
所以,我这里配置为/etc/nginx/nginx.conf
。
3.1.2 修改nginx.conf
项目部署到docker容器后,相当于一台新的虚拟机。为了更好的理解docker部署和能访问我们的后端程序(此时的后端还是本地环境的8079端口),需要修改nginx.conf
,修改后的文件内容如下。
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
#这里也稍微进行了修改,表示前端部署到容器中的端口,在docker部署时端口对应这里即可。
listen 80;
server_name localhost;
location /proxy {
root /usr/share/nginx/html/; #这一行进行了修改,表示资源地址
proxy_pass http://host.docker.internal:8079; #这一行进行了修改【下文:proxy_pass的详述】
rewrite "^/proxy/(.*)$" /$1 break;
}
location / {
root /usr/share/nginx/html/;
try_files $uri $uri/ /html/index.html last;
index index.html index.htm;
}
}
}
【proxy_pass的详述】
因为现在我的后端端口还是本机的8079,如果直接使用localhost:8079做proxy_pass,一定访问不到本机端口,因为部署之后,localhost已经不是本机地址,而是docker容器所代表的地址。
此时想要通过docker容器访问本机地址,可以用
host.docker.internal
。在容器中,host.docker.internal代表本机地址。此处我理解为如果是部署在远端,可以将这里的地址写为远端地址。所以
proxy_pass
设置为host.docker.internal:8079
,即可访问本机的8079端口了。
3.2 生成镜像
在vue-docker文件夹处(该文件夹因包含dist
、Dockerfile
、nginx.conf
)打开命令行执行下面的命令即可生成镜像文件,镜像生成后可以docker images
查看新生成的镜像文件。
#-t指定一个镜像的名字,注意最后的‘.’不能省略
docker build -t XXXXX-front .
3.3 以镜像生成容器并运行服务
这里是通过镜像生成并运行一个容器,-d
表示后端运行,--name
表示服务的名字,-p
表示映射的端口(前者是前端的访问端口。后者是3.1.2
中listen的端口,是docker容器的服务端口),最后跟创建所需镜像。
docker run -d --name [容器名字] -p 8083:80 [镜像名字]
该命令可以生成容器并运行服务。
这时候就可以在docker中查看到我们的服务运行情况了。
可能出现的问题:
- invalid number of arguments in “root” directive in /etc/nginx/nginx.conf:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JIyTH90O-1617533348081)(C:\Users\刘伟\AppData\Roaming\Typora\typora-user-images\image-20210402160031321.png)]
这里很有可能是nginx.conf的内容出现问题了。43行,缺少分号。或者用notepad++编写不是空格而是tab开头分隔的。
还有好多出过的错误,没有及时记录。留待补充吧。
至此前端服务就配置好了,小伙伴们可以参考着试试哈。
最后,建议从docker直接打开服务网页,玄学问题会很难受。
3.4子路径访问404问题
当进入子路径之后,刷新的时候我们会发现报错404页面。需要修改一下nginx.conf配置。【一步一步走的小伙伴估计骂娘的心都有了。哈哈哈】
把location / {}
部分修改一下:
location / {
try_files $uri $uri/ @router;
index /index.html;
}
location @router {
rewrite ^.*$ /index.html last;
}
参考:https://blog.csdn.net/weixin_42281031/article/details/108559827
这样就不会出现进入子路径刷新报错404的情况了
前端项目部署参考:https://zhuanlan.zhihu.com/p/60833019
这一下前端项目就真的算部署完了。
四、后端项目本地部署
首先需要在pom.xml的中加入以下构建所需的内容
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
在终端运行以下命令
mvn clean package -Dmaven.test.skip=true
clean
先去除之前生成的内容,然后打包。-Dmaven.test.skip=true
表示打包跳过测试。
生成的target文件夹中,打开命令行
java -jar [生成的jar文件]
服务即可本地启动。
更换jdk版本https://www.cnblogs.com/hkgov/p/8074085.html
五、docker部署后端项目
接下来就是在docker中部署我们的后端项目了。
最最最开始需要注意的一点:我们在编译时用的java版本要和docker拉取的镜像版本一样!!!
5.1 准备工作
有过第一次部署前端项目,这一步就很好理解了。
同样的理清思路:先创建一个后端文件夹java-backend
,其中包含两个文件:Dockerfile
、打包好的.jar
文件。
编写Dockerfile
#从docker官方拉取java8的镜像
FROM java:8
#将jar包添加到容器中并更名为app.jar
ADD todolist-1.0-SNAPSHOT.jar app.jar
#缩短 Tomcat 启动时间,添加一个系统属性指向 “/dev/./urandom” 作为 Entropy Source
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/.urandom","-jar","/app.jar"]
这里提一嘴,如果数据库也是在docker里部署的,那么需要将配置的数据库地址改为docker数据库部署的地址。
5.2 生成镜像
在java-backend
文件夹处(该文件夹因包含.jar
、Dockerfile
)打开命令行执行下面的命令。
docker build -t [镜像名字] .
5.3 生成容器并运行服务
用以下命令来创建容器并启动服务
docker run -d --name [容器名字] -p [外部映射端口]:[容器内部端口] [镜像名字]
注意:[外部映射端口]
要和前端部署项目的服务端口对应起来。
ok。至此就全部搞定了。舒服了。有哪里不对的地方还望批评指正。