美文网首页Docker composeDockerfile_volume
docker中COPY和VOLUME细节分析

docker中COPY和VOLUME细节分析

作者: PENG先森_晓宇 | 来源:发表于2019-10-29 13:31 被阅读0次

    COPY

    COPY即复制的意思,和linux中的cp类似。linux中可复制如下

    • 文件 ---》 文件夹
    cp 1.txt /test
    
    • 文件夹 ---》 文件夹
    //将test文件夹下所有文件包括以及test目录复制到/test1 目录下
    cp -r /test /test1
    
    • 文件夹下所有文件 ---》文件夹
    //将text目录下的所有文件都复制到test1目录
    cp /test/* /test1
    

    而不能

    • 文件 ---》文件
    • 文件夹 ---》文件

    docker中的COPY和linux的类似,以Dockerfile为例。目标路径如果不存在(docker内的路径),不需要事先创建, docker会在复制文件前先创建目录确实目录

    //文件复制到文件夹
    COPY master.sh /etc/keepalived/  
    //将宿主机内/conf 目录下文件都复制到容器内目录为/etc/conf下
    COPY /conf /etc/conf
    

    和linux有点区别的是docker中COPY /conf /etc/conf,是指将宿主机内/conf 目录下所有文件都复制到容器内目录为/etc/conf下,和linux的cp /conf/* /etc/conf作用一样。

    而不能如下,不然启动docker时候会报错

    COPY master.sh /etc/keepalived/master.conf
    COPY /conf /etc/conf/a.conf
    

    注意:COPY命令写在Dockerfile中,属于Dockerfile,在docker-compose中没有该命令

    VOLUME

    docker中volume可以理解为linux中软连的意思,类似windows中快捷方式的概念。

    在docker中可以

    • 文件 volume 文件
    redis:
          container_name: laravel-redis1
          build:
            context: .
            dockerfile: docker/redis1/Dockerfile
        volumes:
           - ./redis/redis.conf:/data/redis.conf
    
    • 文件夹 volume 文件夹。如下代码,代表宿主机目录为./redis/data下的所有文件与容器目录为/data的所有文件建立软连关系
    redis:
          container_name: laravel-redis1
          build:
            context: .
            dockerfile: docker/redis1/Dockerfile
        volumes:
           - ./redis/data:/data
    

    而不能

    • 文件 volume 文件夹
    • 文件夹 volume 文件

    注意:一定是文件软件文件,文件夹软连文件夹

    在docker-compose.yml中 volume中的使用如下

      redis:
          container_name: laravel-redis1
          build:
            context: .
            dockerfile: docker/redis1/Dockerfile
          ports:
          - 6380:6379
          volumes:
          - ./docker/redis1/data:/data
          networks:
          - laravel-network
    

    volume用于docker-compose.yml中,不要用于Dockerfile中,不起作用

    volume的时候通常有如下2情况

    1. 需要将宿主机的文件映射到容器内
      如果目标路径以及文件不存在(容器内),容器内不需要事先创建, volume会在容器内自动创建并形成软连关系
    1. 需要将容器内的文件映射到宿主机上
      宿主机同样不需要创建需要映射的文件以及目录。不管谁映射谁,宿主机和容器是双向的关联的
      之前的操作是使用以下命令将容器内的文件copy到宿主机后在进行软连。其实不需要的,直接volume即可。
    docker cp 容器id:容器文件路径 复制到宿主机的路径
    

    权限问题

    在实际过程中我们需要对某些文件增加权限操作,有俩种场景

    • docker-compose.yml中volume的文件,需要在docker容器加权限。比如服务的日志文件
      haproxy:
          container_name: haproxy
          build:
            context: .
            dockerfile: docker/haproxy/Dockerfile
          ports:
          - 8888:8888
          volumes:
          - ./haproxy/logs:/etc/haproxy/logs
          networks:
          - laravel-network
    

    由于日志文件必须加写权限,不然写不进去,所以我们需要给容器内的执行命令

    chmod -R 777 /etc/haproxy/logs
    

    所以在Dockerfile中执行RUN命令,如下。遗憾的是/etc/haproxy/logs目录下的文件并没有获得777权限。

    FROM haproxy:lasted
    RUN chmod -R 777 /etc/haproxy/logs
    

    所以如果是想给docker-compose.yml文件的volume文件加权限,我们可以在每次git拉取项目后,执行命令chmod -R 777 /etc/haproxy/logs,这次操作可以在自动化部署时加上该命令。
    要知道volume不仅宿主机和docker的文件一致,而且权限也是一致的,所以在本地执行chmod -R 777 /etc/haproxy/logs后,在容器内相应的文件权限也会跟着改变

    • Dockerfile中COPY的文件需要加权限
      如果是Dockerfile中COPY的文件需要加权限,我们可以直接在Dockerfile中使用RUN指定赋予权限即可。
    FROM haproxy:lasted
    COPY /haproxy /data
    RUN chmod -R 777 /data
    

    以上加权限一定要注意,volume和copy的俩种方式,如果能使用copy,不需要软连的话,尽量使用copy即可

    Dockerfile中的volume和docker-compose.yml中的volume的区别

    Dockerfile中volume 定义匿名卷
    格式如下:

    • VOLUME ["<路径1>","<路径2>“]
    • VOLUME <路径>

    之前说过,容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存到卷(volume)中,为了防止运行时用户忘记将动态文件所保存目录挂载为卷,在Dockerfile中,我们可以事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会向存储层写入大量数据。Dockerfile的VOLUME如下

    VOLUME /data
    

    这里的/data目录就会在运行时自动挂载为匿名卷,任何向/data中写入的信息都不会记录进容器存储层,从而保证了容器存储层的无状态化。当然,运行时可以覆盖这个挂载设置,比如

     docker run -v mydata:/data    
    

    和docker-compose.yml中的作用一样

    volumes:
          - ./docker/redis1/data:/data
    

    相关文章

      网友评论

        本文标题:docker中COPY和VOLUME细节分析

        本文链接:https://www.haomeiwen.com/subject/xffbvctx.html