Docker composeDockerfile_volume

docker中COPY和VOLUME细节分析

2019-10-29  本文已影响0人  PENG先森_晓宇

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中可以

redis:
      container_name: laravel-redis1
      build:
        context: .
        dockerfile: docker/redis1/Dockerfile
    volumes:
       - ./redis/redis.conf:/data/redis.conf
redis:
      container_name: laravel-redis1
      build:
        context: .
        dockerfile: docker/redis1/Dockerfile
    volumes:
       - ./redis/data:/data

而不能

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

在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:容器文件路径 复制到宿主机的路径

权限问题

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

  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后,在容器内相应的文件权限也会跟着改变

FROM haproxy:lasted
COPY /haproxy /data
RUN chmod -R 777 /data

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

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

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

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

VOLUME /data

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

 docker run -v mydata:/data    

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

volumes:
      - ./docker/redis1/data:/data
上一篇下一篇

猜你喜欢

热点阅读