为了能使容器内的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 # 生成日志的路径

springboot docker控制台日志乱码 docker springboot日志挂载_服务器

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.如果项目启动时报错

springboot docker控制台日志乱码 docker springboot日志挂载_java_02

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的依赖包里看到点东西

springboot docker控制台日志乱码 docker springboot日志挂载_java_03


如果你没用jhipster,可以查看我上传的文件logback.xml