docker-compose 容器挂载权限问题

       项目中遇到docker-compose启动springboot的应用,挂载的日志目录没有权限写入的问题;后来查了很多资料,终于有点眉目了,做个记录,希望遇到的朋友少踩点坑~;

1.问题描述

        项目框架是使用jhipster生成的,现在需要把生成的日志挂载出去,以便查看日志记录;首先修改下logback-spring.xml的配置,将系统生成的日志文件都存放在项目的logs目录下面;代码如下

     然后把这个目录挂载到linux中的/temp/logs/bbb/目录中;下面是app.yml代码

version: '2'
services:
    aiops-app:
        image: aiops
        volumes:
            - /temp/logs/bbb/:/home/jhipster/logs/
        environment:
            # - _JAVA_OPTIONS=-Xmx512m -Xms256m
            - SPRING_PROFILES_ACTIVE=prod,swagger
            - SPRING_DATASOURCE_URL=jdbc:mysql://test-mysql:3306/aiops?useUnicode=true&characterEncoding=utf8&useSSL=false
            - JHIPSTER_SLEEP=10 # gives time for the database to boot before the application
        ports:
            - 9999:8080

这里把logs目录挂载出去到/temp/logs/bbb/这个目录下面;再看下dockerFile文件,这个文件用来把java 应用打包成docker镜像的;如下

FROM openjdk:8-jre-alpine

ENV SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \
    JHIPSTER_SLEEP=0 \
    JAVA_OPTS=""

# Add a jhipster user to run our application so that it doesn't need to run as root
RUN adduser -D -s /bin/sh jhipster
WORKDIR /home/jhipster

ADD entrypoint.sh entrypoint.sh
RUN chmod 755 entrypoint.sh && chown jhipster:jhipster entrypoint.sh
USER jhipster

ADD *.war app.war

ENTRYPOINT ["./entrypoint.sh"]

EXPOSE 8080

这里创建了一个用户jhipster ,设置了工作目录/home/jhipster;然后 把启动命令entrypoint.sh复制到镜像中;并赋权entrypoint.sh为jhipster用户所有,然后使用jhipster用户来启动应用;下面是entrypoint.sh shell脚本的具体内容

#!/bin/sh

echo "The application will start in ${JHIPSTER_SLEEP}s..." && sleep ${JHIPSTER_SLEEP}
exec java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar "${HOME}/app.war" "$@"

这里的通过java  -jar 来启动app,这里的${HOME}目录指的是linux的用户目录,/home/{用户名},因为当前的用户是jhipster,所以这里的app目录其实是/home/jhipster/app.war;这里的${JHIPSTER_SLEEP}是上面的环境变量JHIPSTER_SLEEP=0;通过docker-compose -f app.yml up -d 命令来启动之后,就报错了,具体如图所示,在linux中会报错,docker在window上只能挂载到用户目录c:\\users\\test\\,不知为啥测试下来不会报错的;

2.报错原因及解决方案

错误的原因是,docker-compose启动的时候会分别在容器和宿主机上创建目录,在宿主机上是使用docker进程来创建目录的,默认使用的角色是root,目录挂载的时候会把这个用户同步到容器里面的目录,所以容器里面logs目录权限也是root,但是容器里面的应用是使用jhipster用户来运行的,当然没有往logs目录里面写的权限,所以就报错了;因为这两个角色是会同步的,所以解决的办法就是修改宿主机的日志权限为docker里面用户的权限;可以使用如下命令修改宿主机日志目录的权限

chown -R 1000:1000 "/temp/logs/bbb/"

修改前后对比,如图所示

可以看到修改之后默认的bbb目录权限从root变成jhipster,这里的1000就是docker中用户的id,默认docker用户的id是1000;修改之后docker容器中的目录logs角色也变成jhipster,这样权限就统一了,应用运行使用jhipster,日志文件目录权限也是jhipster,自然可以把日志写到这个目录中了;

这种方式的好处是修改起来简单,缺点是需要额外手工去操作,如果涉及到多个目录的话就很麻烦了,这里介绍另外一种方法

3.使用root权限进入命令行,然后修改权限,再使用jhipster用户启动应用;

基本思路是,使用root用户将容器中的logs目录赋权限为jhipster,然后再使用jhipster用户来启动应用即可;这里需要有个gosu命令,具体的地址是https://github.com/tianon/gosu,这个命令用来替换sudo,它是"su"和"sudo"命令的轻量级替代品,并解决了它们在tty和信号传递中的一些问题。首先需要修改下dockerFile文件,添加sudo命令支持,如下所示

FROM openjdk:8-jre-alpine

ENV SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \
    JHIPSTER_SLEEP=0 \
    JAVA_OPTS=""

# Add a jhipster user to run our application so that it doesn't need to run as root
RUN adduser -D -s /bin/sh jhipster
WORKDIR /home/jhipster
ADD *.war app.war
ADD entrypoint.sh entrypoint.sh
RUN chmod 755 entrypoint.sh && chown jhipster:jhipster entrypoint.sh

#使用root用户,下载sogu工具
USER root
ENV GOSU_VERSION 1.11
RUN set -eux; \
	\
	apk add --no-cache --virtual .gosu-deps \
		dpkg \
		gnupg \
	; \
	\
	dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \
	wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \
	wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \
	\
# verify the signature
	export GNUPGHOME="$(mktemp -d)"; \
# for flaky keyservers, consider https://github.com/tianon/pgp-happy-eyeballs, ala https://github.com/docker-library/php/pull/666
	gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \
	gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \
	command -v gpgconf && gpgconf --kill all || :; \
	rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \
	\
# clean up fetch dependencies
	apk del --no-network .gosu-deps; \
	\
	chmod +x /usr/local/bin/gosu; \
# verify that the binary works
	gosu --version; \
	gosu nobody true

ENTRYPOINT ["./entrypoint.sh"]

EXPOSE 8080

相比之前的内容,添加了切换到root,并下载gosu工具的代码;具体的下载命令可以在gosu的github上也有,地址是https://github.com/tianon/gosu/blob/master/INSTALL.md,注意使用alpine的版本,因为java应用构建是基于这个的,从dockerFile第一句话可以看出;

之后再到entrypoint.sh中赋权,并使用jhipster启动应用,具体内容如下;这里为什么要切换到root用户,如果不切换的话使用chown会报错

#!/bin/sh
chown -R 1000:1000 "logs"
echo "The application will start in ${JHIPSTER_SLEEP}s..." && sleep ${JHIPSTER_SLEEP}
exec gosu jhipster java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar "app.war" "$@"

这样就解决了;这种方式的话,每次打包镜像的时候会去下载gosu,会慢一点,但是不用自己修改权限了;

总结:文章参考了https://www.cnblogs.com/jackluo/p/5783116.html,但是文章里面下载gosu的部分不能正常使用;所以做了一些修改;

 

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 答:Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。要安装 Docker Compose,请参考下面的步骤:1. 下载 Docker Compose:使用 curl 或者其他工具,从 GitHub 上下载最新的 Docker Compose 发行版:curl -L https://github.com/docker/compose/releases/download/1.25.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose2. 将可执行授权给用户:使用 chmod +x 命令,给文件赋予可执行权限:chmod +x /usr/local/bin/docker-compose3. 测试安装:在终端中运行下面的命令,查看 Docker Compose 版本号:docker-compose --version ### 回答2: Docker Compose是一个用于定义和管理多个Docker容器的工具。它可以通过一个单独的配置文件来定义和运行多个容器,简化了多容器应用程序的部署和管理过程。 以下是使用docker-compose安装的教程: 第一步:安装Docker 在使用docker-compose之前,首先需要安装Docker。Docker提供了不同操作系统的安装包,可以根据操作系统类型下载并安装适合的版本。 第二步:安装docker-compose 1. 打开终端或命令行界面,通过以下命令来下载docker-compose: ``` $ sudo curl -L "https://github.com/docker/compose/releases/download/1.27.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose ``` 2. 授予docker-compose执行权限: ``` $ sudo chmod +x /usr/local/bin/docker-compose ``` 3. 验证docker-compose安装是否成功: ``` $ docker-compose --version ``` 第三步:创建docker-compose.yml文件 1. 在项目的根目录下创建一个名为docker-compose.yml的文件。 2. 在docker-compose.yml文件中定义容器服务。例如,定义一个MySQL数据库容器和一个web应用容器的服务: ``` version: '3' services: db: image: mysql ports: - "3306:3306" environment: MYSQL_ROOT_PASSWORD: example web: image: webapp ports: - "8080:8080" depends_on: - db ``` 3.根据项目需求,可以在docker-compose.yml文件中定义更多的容器服务。 第四步:运行docker-compose 1. 在终端或命令行界面中,进入到docker-compose.yml文件所在的目录。 2. 使用以下命令来启动docker-compose: ``` $ docker-compose up -d ``` 3. docker-compose会根据配置文件创建和启动定义的容器服务。 至此,你已经成功安装和使用Docker Compose进行多容器的部署和管理。你可以通过docker-compose的命令行选项来管理容器,如停止容器服务和删除容器等操作。 ### 回答3: docker-compose 是一个工具,可以用于定义和管理多个 Docker 容器的应用程序。 要安装 docker-compose,首先需要确保已经安装了 Docker 引擎。这可以通过访问 Docker 官方网站获取并按照相应的指示进行安装。 一旦 Docker 安装完成,可以使用 Docker 制作的官方仓库来安装最新版本的 docker-compose。 步骤如下: 1. 打开终端并以 root 用户身份登录。 2. 运行以下命令来下载最新版本的 docker-compose: ``` $ curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose ``` 3. 授予可执行权限docker-compose: ``` $ chmod +x /usr/local/bin/docker-compose ``` 4. 创建一个符号链接: ``` $ ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose ``` 5. 最后,运行以下命令来验证 docker-compose 是否安装成功: ``` $ docker-compose --version ``` 如果成功安装,会显示 docker-compose 的版本号信息。 现在,可以通过编写 docker-compose.yml 文件来定义和管理容器化的应用程序。使用 docker-compose up 命令,可以轻松启动和管理多个容器。可以在 docker-compose.yml 中定义容器的服务、网络设置、卷挂载等等。 希望这个简单的教程能帮助你安装并使用 docker-compose。如果想深入了解更多关于 docker-compose 的用法和功能,建议查阅官方文档。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值