为了能使容器内的SpringBoot项目的日志方便查看,我想用容器卷挂载的方式,将容器内生成的日志文件挂载到服务器上,实现同步,即使生成了新的镜像,依赖于compose file的配置,也能使日志在服务器上同意的位置生成,这样就比较方便了;
1. SpringBoot的配置文件
application.yml
logging:
level:
ROOT: INFO
tech.jhipster: DEBUG
org.hibernate.SQL: DEBUG
cn.mycompany.app: DEBUG
logback:
rollingpolicy:
max-file-size: 50MB # 一个日志文件的最大值,只配置这个,会在生成一个日志文件达到50MB的时候,对这个文件进行打包,打成.gz后缀的包,或者按日期生成,比如23:59分是一个包,第二天0:01又是一个包,因为是SpringBoot,所以约定了很多规则
file:
path: /tmp/logs # 生成日志的路径
2. compose file 文件配置
compose-file.yml
version: '2'
services:
cms服务名:
image: 192.168.1.1:8084/cms:1.1.1镜像名
container_name: 容器名
volumes:
- /test/logs:/tmp/logs #挂载配置 宿主机目录:容器目录
3. 在项目目录下运行命令:
mvn clean package -Dmaven.test.skip=true -Pprod -DskipTests jib:dockerBuild -DsendCredentialsOverHttp=true
打包成功得到一个docker镜像
[INFO] Built image to Docker daemon as 192.168.1.1:8084/cms:1.1.1镜像名
4.push到镜像仓库
docker push 192.168.1.1:8084/cms:1.1.1镜像名
5.用compose file 构建容器
因为是本地仓库,所以不需要用docker pull拉取,在存放compose-file的目录下执行命令:
docker-compose -f compose-file.yml up -d
-f, --file FILE Specify an alternate compose file (default: docker-compose.yml)
-d 以守护进程启动
如果成功了,就会构建容器并启动,如果提示有容器存在了,可以考虑把之前那个同名容器删了再构建;
6.启动后在控制台查看日志可以用指令:
查看最新的100条
docker logs -f --tail 100 容器名称
7.进入容器中 查看日志是否生成
docker exec -it -u root 容器名称 /bin/bash
进去就可以用Linux指令;
可以省略 -u root ,这样在容器中就是普通用户
进入容器中查看是否为root用户,可以输入指令
root@c8da365db18a:/tmp/logs# whoami
root
root@c8da365db18a:/tmp/logs#
8.如果项目启动时报错
2021-09-11 02:02:15.257 ERROR 1 --- [ main] o.s.boot.SpringApplication : Application run failed
java.lang.IllegalStateException: java.lang.IllegalStateException: Logback configuration error detected:
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[FILE] - openFile(/tmp/spring.log,true) call failed. java.io.FileNotFoundException: /tmp/spring.log (Permission denied)
at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:327)
at ...
是因为容器内没有权限,容器内默认是用普通用户来操作的;如果没显示(Permission denied)也很可能是因为容器内权限不够导致无法创建文件夹或者文件,亲测! 看如下文章,说容器内是最好不要用root用户的:
请注意,出于安全目的,在容器内以 root 身份运行是最糟糕的做法。Dockerfile 应始终使用 USER 指令从而避免直接使用 root 权限。
9.那么如何给容器内的文件夹加上权限呢?
由于本人对Linux和docker的粗浅认识,所以不会写docker file和compose file,只能依葫芦画瓢,看了一些别的yml,但是也没能幸运得偿所愿;
最后发现解决办法就是通过容器卷挂载,在docker compse file那里确定挂载目录,先实现挂载, 再到宿主机(服务器)上输入指令给宿主机(服务器)上的文件给权限,这样容器内的映射的文件夹也就给上权限了;
指令: chmod -R 777 /test/logs
-R 是让logs目录底下所有文件夹和文件全都有权限;友情提示谨慎使用777这条指令;
然后你就发现权限问题被解决了;挂载也实现了;这样就完成了我们的需求;
10.ps
我用的容器,默认/tmp目录就有,且有很高的权限;
SpringBoot默认生成日志就是在/tmp目录底下,所以拿这个文件为突破口;
可以参考jhipster生成项目的logback-spring.xml的日志配置文件,在SpringBoot的依赖包里看到点东西
如果你没用jhipster,可以查看我上传的文件logback.xml