个人练习记录,以下为springboot项目部署过程:
云服务器为:腾讯云
注意事项
写在最前,首先有个印象。
- Dockerfile 编写,文件名就叫“Dockerfile” file首字母不要大写。中了驼峰的毒,此处浪费时间半小时
- 还是Dockerfile的编写,内容的启动命令,一定要注意最后一部分,设置jar包位置。此处浪费时间2小时
- 关于项目,本地idea启动正常,放到linux上就不行,启动报错:
Cause: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1
。这个错误搜索出很多种方法,我遇到的就是mybatis的问题,xml已经没法正常解析。最后简单概括一下mybatis的集成 - 暂时想到这些,再想到在补充。
系统重装及密码重置
一、安装docker
1.1、安装yum-utils软件包
sudo yum install -y yum-utils
我这里提示已经是最新的,所以没有任何更新
[root@VM-16-16-centos ~]# sudo yum install -y yum-utils
Loaded plugins: fastestmirror, langpacks
Determining fastest mirrors
epel | 4.7 kB 00:00:00
extras | 2.9 kB 00:00:00
os | 3.6 kB 00:00:00
updates | 2.9 kB 00:00:00
Package yum-utils-1.1.31-54.el7_8.noarch already installed and latest version
Nothing to do
1.2、设置下载仓库
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
指定阿里仓库
[root@VM-16-16-centos ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
Loaded plugins: fastestmirror, langpacks
adding repo from: https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
grabbing file https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo
repo saved to /etc/yum.repos.d/docker-ce.repo
1.3、安装docker
sudo yum install docker-ce docker-ce-cli containerd.io
1.4、启动docker
sudo systemctl start docker
1.5、设置加速
设置阿里镜像加速,地址:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://*******.mirror.aliyuncs.com"]
}
EOF
依次输入以上命令
1.6、重新加载配置文件
sudo systemctl daemon-reload
1.7、重启docker
sudo systemctl restart docker
1.8、设置docker开机自启
systemctl enable docker.service
1.9、验证是否成功
systemctl list-unit-files |grep docker
参考:https://www.cnblogs.com/xssfc/p/14415947.html
1.10 docker 常用命令
docker images
:查看所有镜像docker ps
:查看所有运行中的容器docker ps -a
:查看所有容器docker stop 容器id
:关闭容器docker start 容器id
:启动容器docker restart 容器id
:重启容器docker exec -it 容器名 /bin/sh 或者 docker exec -it 容器id /bin/sh
:进入容器(比如mysql、redis)docker inspect --format='{{.Name}} - {{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)
:这个命令可以查所有容器的信息,里边会有一个172开头的就是容器的ip了
二、docker 安装mysql
安装mysql会进行两次安装:
第一次:简单安装,只是为了找到mysql配置文件的位置和数据的位置,用于进行磁盘映射
第二次:在第一步的基础上,加上磁盘映射,将配置文件和数据挂载到宿主机上,之后改配置文件可以直接在宿主机改,并将数据保留在宿主机上
2.1 下载镜像,本次使用8.0.28版本
不加版本直接下载,会默认下载当前库里边最新版本
docker pull mysql
也可以指定版本下载
docker pull mysql:8.0.28
查看所有镜像
docker images
查看镜像信息
docker inspect 镜像名字
2.2 第一次启动mysql
2.2.1 简单启动
每个人的部署mysql内,可能文件不一样。可以先建一个测试的mysql容器,然后找出文件的具体位置,记录之后,再重新创建符合需求的容器
docker run --name mysqltest -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:8.0.28
2.2.2 进入mysql容器,查找配置文件和数据位置
docker exec -it mysqltest bash
mysql --help | grep my.cnf
其中 /etc/mysql/my.cnf就是我们mysql的相关配置文件,
退出容器:exit
执行:docker inspect 容器名字
,查看容器信息,找到Mounts
节点,
其中的"Destination": "/var/lib/mysql",
即表示容器内数据存放的位置为:/var/lib/mysql
到现在为止,容器内,配置文件的位置为:/etc/mysql/my.cnf
容器内数据存放位置为:/var/lib/mysql
2.2.3 在宿主机建立需要存放配置文件和存放数据位置的文件夹
mkdir -p /docker/mysql/conf && mkdir -p /docker/mysql/datadir
建立文件夹 conf,位置:/docker/mysql/conf
建立文件夹 data,位置:/docker/mysql/datadir
2.2.4 移动 my.cnf 文件
docker cp mysqltest:/etc/mysql/my.cnf /docker/mysql/conf
注意,需要退出容器的状态下,执行命令
2.2.5 编辑 my.cnf
解决mysql8版本出现的问题: this is incompatible with sql_mode=only_full_group_by
ONLY_FULL_GROUP_BY 的意思是针对 GROUP BY 聚合操作,如果 SELECT 中的列没有在 GROUP BY 中出现,那么这个 SQL 是不合法的,因为列不在 GROUP BY 从句中
所以编辑my.cnf.在[mysqld]下边加上
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
重启mysql:docker restart mysqltest
2.3 第二次启动mysql
2.3.1 删除测试用的mysql
docker stop mysqltest
停止容器
docker rm mysqltest
删除容器
2.3.2 编写启动容器的命令
docker run --name mysql8 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root --privileged=true --restart unless-stopped -v /docker/mysql/conf/my.cnf:/etc/mysql/my.cnf -v /docker/mysql/datadir:/var/lib/mysql -v /docker/mysql/logs:/logs -v /etc/localtime:/etc/localtime -d mysql:8.0.28
命令解释
docker run;启动一个容器
--name:容器的名字是什么,这里是 mysql8
-p 3306:3306:把宿主机的3306端口映射到mysql的3306端口
-e MYSQL_ROOT_PASSWORD=root:设置root密码为:root
--restart unless-stopped:设置容器自启
-v:挂载宿主机的目录,冒号分隔,冒号前为宿主机目录,冒号后为容器目录
-d mysql:8.0.28:mysql为镜像的名字,如果镜像有版本号的话,需要写成 -d mysql:8.0.28
启动成功后会看到,datadir文件夹下边已经初始化了数据
2.3.4 利用软件进行测试
三、制作项目镜像,并启动项目
3.1 准备工作
3.1.1 在docker下建立项目的文件夹,用于存放jar包和其他数据
mkdir -p /docker/demo && mkdir -p /docker/demo/logs
3.1.2 编写Dockerfile文件
注意:Dockerfile文件的名字就是“Dockerfile” ,注意不要写错,尤其是file的首字母不要大写
以下是最简单的写法,这种写法把运行的jar包,映射到宿主机上,之后更换宿主机的jar,就可以实现重新部署,其他写法可以查询资料
内容如下
FROM java:8
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-Dspring.profiles.active=prod","-Duser.timezone-GMT+8","-jar","/data/demo/demo-0.0.1-SNAPSHOT.jar"]
FROM java 8 :指的是使用jdk8
一定要注意最后的 “/data/demo/demo-0.0.1-SNAPSHOT.jar” 后边写容器启动命令需要用到
3.1.3 jar包和Dockerfile文件上传到centos
jar需要注意的是配置文件,数据库的连接,IP地址为与服务器的外网地址。(应该填写mysql容器的ip地址也行,暂未实验)
Dockerfile 需要注意的是,文件名字别错,没有后缀,file首字母不要大写
3.2 构建镜像
切换到Dockerfile所在目录:cd /docker/demo
执行命令:docker build -t demo_prod .
(注意命令最后一个英文的标点符号 .) demo_prod 为自己起的镜像名字
首先会拉取jdk8的镜像,然后开始构建
可以执行docker images
查看刚才构建的镜像,共三个,mysql,java,项目的demo_prod
3.3 启动容器
docker run --name demo -p 80:80 -v /docker/demo/logs/:/logs/demo/ -v /docker/demo/:/data/demo/ -d demo_prod
本次demo加入了log4j2,容器内文件输出位置为:/logs/demo,将其与宿主机的 /docker/demo/logs挂载
注意:-v /docker/demo/:/data/demo/ 表示的是容器内使用的jar包位置,与宿主机的 /docker/demo 进行映射,结合3.1.2描述的理解
3.4 验证
执行:docker logs demo -f
查看容器启动日志
调用接口验证
http://云服务ip+端口/info/list
查看/docker/demo/logs下边,已经出现了log4J2的日志文件
当项目修改的时候,只需要更换jar包,然后重启容器即可
docker restart demo
四、最后
这次是最详细的记录,之前遇到过各种问题,经过各种尝试,总算弄清楚了出问题的地方。
最后概括一下mybatis的集成需要注意的地方
- 启动类 @MapperScan(“com.example.demo.mapper”)
- 配置文件 mybatis.mapper-locations=classpath:mapper/*.xml
- xml文件的存放位置,跟第二条结合起来看
- pom文件,把resources的文件全都编译一下
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.example.demo.DemoApplication</mainClass>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/java</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
</build>