Sonatype Nexus Docker卷错误

8

我正在尝试使用Docker安装Sonatype Nexus,并希望与主机(Linux Ubuntu 14.04)共享Docker /opt/sonatype-work Nexus仓库中的内容到主机的/opt/nexus目录。

我的Dockerfile:

FROM centos:6

MAINTAINER Marcel Birkner <marcel.birkner@codecentric.de>

USER root
# Update the system
RUN yum -y update; \
    yum clean all

##########################################################
# Install Java JDK, SSH and other useful cmdline utilities
##########################################################
RUN yum -y install java-1.7.0-openjdk-devel \
    which \
    telnet \
    unzip \
    openssh-server \
    sudo \
    openssh-clients \
    iputils \
    iproute \
    httpd-tools \
    wget \
    tar; \
    yum clean all
ENV JAVA_HOME /usr/lib/jvm/jre

##########################################################
# Install Nexus
##########################################################
RUN mkdir -p /opt/sonatype-nexus /opt/sonatype-work
RUN wget -O /tmp/nexus-latest-bundle.tar.gz http://www.sonatype.org/downloads/nexus-latest-bundle.tar.gz
RUN tar xzvf /tmp/nexus-latest-bundle.tar.gz -C /opt/sonatype-nexus --strip-components=1
RUN useradd --user-group --system --home-dir /opt/sonatype-nexus nexus

ADD nexus.xml /opt/sonatype-work/nexus/conf/nexus.xml

RUN chown -R nexus:nexus /opt/sonatype-work /opt/sonatype-nexus

ENV NEXUS_WEBAPP_CONTEXT_PATH /nexus
RUN echo "#!/bin/bash" > /opt/start-nexus.sh
RUN echo "su -c \"/opt/sonatype-nexus/bin/nexus console\" - nexus" >> /opt/start-nexus.sh
RUN chmod +x /opt/start-nexus.sh
VOLUME /opt/sonatype-work
CMD ["/opt/start-nexus.sh"]
EXPOSE 8081

当我构建此镜像(构建成功):
docker build -t sonatype/nexus .

然后我通过这个命令运行它:

docker run -d -p 8081:8081 --name nexus -v /opt/nexus:/opt/sonatype-work sonatype/nexus

它启动并立即停止了。错误信息如下 (docker logs nexus):

nexus_1 | jvm 1    | Caused by: java.nio.file.AccessDeniedException: /opt/sonatype-work/nexus
nexus_1 | jvm 1    |    at sun.nio.fs.UnixException.translateToIOException(UnixException.java:84) ~[na:1.7.0_99]
nexus_1 | jvm 1    |    at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102) ~[na:1.7.0_99]
nexus_1 | jvm 1    |    at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107) ~[na:1.7.0_99]
nexus_1 | jvm 1    |    at sun.nio.fs.UnixFileSystemProvider.createDirectory(UnixFileSystemProvider.java:383) ~[na:1.7.0_99]
nexus_1 | jvm 1    |    at java.nio.file.Files.createDirectory(Files.java:630) ~[na:1.7.0_99]
nexus_1 | jvm 1    |    at java.nio.file.Files.createAndCheckIsDirectory(Files.java:734) ~[na:1.7.0_99]
nexus_1 | jvm 1    |    at java.nio.file.Files.createDirectories(Files.java:720) ~[na:1.7.0_99]
nexus_1 | jvm 1    |    at org.sonatype.nexus.util.file.DirSupport.mkdir(DirSupport.java:146) ~[na:na]
nexus_1 | jvm 1    |    at org.sonatype.nexus.util.file.DirSupport.mkdir(DirSupport.java:162) ~[na:na]
nexus_1 | jvm 1    |    at org.sonatype.nexus.webapp.WebappBootstrap.contextInitialized(WebappBootstrap.java:115) ~[na:na]
nexus_1 | jvm 1    |    ... 16 common frames omitted
nexus_1 | wrapper  | <-- Wrapper Stopped

如果我从Dockerfile中删除VOLUME /opt/sonatype-nexus,它就可以正常工作。

您有任何想法是什么原因导致了这个问题?如何解决?

2个回答

13
如果你在容器中绑定一个主机目录,主机目录中的文件和目录将优先于容器镜像中已存在的文件,并且会覆盖容器内部现有的文件。换句话说,它们“掩盖”了容器下面的内容。
绑定挂载会保持主机上存在的目录的权限,如果主机上不存在该目录,则Docker会创建该目录,使用root:root作为所有者。
通过查看您的Dockerfile中的useradd nexus,我怀疑start-nexus.sh使用该用户运行nexus,因此可能没有权限访问绑定挂载的目录(由root拥有)。您可以通过将目录的数字uid / gid更改为容器中nexus的uid / gid来解决此问题。
要获取该用户的uid / gid,请以交互方式启动容器;
docker run -it --rm sonatype/nexus bash

在那个外壳里请求uid/gid:

id nexus

这会给你类似于以下的东西:

uid=123(nexus) gid=456(nexus) groups=456(nexus)

现在退出容器 (exit) 并使用 uid/gid 更改主机上的目录所有权;

sudo chown -R 123:456 /opt/nexus

我注意到一些事情

看起来你正在构建自己定制版本的sonatype nexus镜像,但使用与官方镜像相同的名称 (sonatype/nexus)。我建议不要这样做,并给它一个你自己的名称(例如mycompany/nexus);这可以防止混淆,也可以防止你的镜像被官方镜像覆盖,如果有人运行 docker pull sonatype/nexus

是否有任何原因不使用官方镜像?通常推荐使用官方镜像,因为它们由软件维护者 (在本例中是Sonatype) 维护,因此应该为您提供最新的(和维护的)软件版本;https://hub.docker.com/r/sonatype/nexus/


1
确实,这是一个关于将我的主机目录/opt/nexus的所有者更改为docker用户的问题,感谢@thaJeztah。最终我切换到官方镜像sonatype/nexus,nexus uid在dockerfile中被指定为200,所以我只需要更改我的目录所有者即可,现在一切都正常工作了。 - Gimbo
1
非常好的答案。感谢分享。 - cucucool
也解决了我的问题(在运行sonatype/nexus:oss Docker定义时出现权限被拒绝、IllegalStateException的错误)。 - Alok P

0

注意SELinux

运行setenforce 0,如果有帮助,请考虑通过在/etc/sysconfig/selinux配置文件中设置 SELINUX=disabled 来永久禁用它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接