docker-compose容器挂载权限问题
项⽬中遇到docker-compose启动springboot的应⽤,挂载的⽇志⽬录没有权限写⼊的问题;后来查了很多资料,终于有点眉⽬了,做个记录,希望遇到的朋友少踩点坑~;
1.问题描述
项⽬框架是使⽤jhipster⽣成的,现在需要把⽣成的⽇志挂载出去,以便查看⽇志记录;⾸先修改下l的配置,将系统⽣成的⽇志⽂件都存放在项⽬的logs⽬录下⾯;代码如下
然后把这个⽬录挂载到linux中的/temp/logs/bbb/⽬录中;下⾯是l代码
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
docker打包镜像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 ${JHIPSTER_SLEEP}
exec java ${JAVA_OPTS} -d=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 -l 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⽤户启动应⽤;
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 "github/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \
wget -O /usr/local/bin/gosu.asc "github/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \
\
# verify the signature
export GNUPGHOME="$(mktemp -d)"; \
# for flaky keyservers, consider github/tianon/pgp-happy-eyeballs, ala github/docker-library/php/pull/666
gpg --keyserver ha.pool.sks-keyservers --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
之后再到entrypoint.sh中赋权,并使⽤jhipster启动应⽤,具体内容如下;这⾥为什么要切换到root⽤户,如果不切换的话使⽤chown会报错
#!/bin/sh
chown -R 1000:1000 "logs"
echo "The application will start in ${JHIPSTER_" && sleep ${JHIPSTER_SLEEP}
exec gosu jhipster java ${JAVA_OPTS} -d=file:/dev/./urandom -jar "app.war" "$@"
这样就解决了;这种⽅式的话,每次打包镜像的时候会去下载gosu,会慢⼀点,但是不⽤⾃⼰修改权限了;

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。