V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
helphelp
V2EX  ›  程序员

请教一个基础的 Docker 问题,关于容器自动创建文件夹和文件,如图所示

  •  
  •   helphelp · 2023-05-28 08:35:20 +08:00 · 2864 次点击
    这是一个创建于 543 天前的主题,其中的信息可能已经有所发展或是发生改变。

    首先,在我 Linux 的 home 目录下面,一开始是没有任何的文件夹和文件的

    下面两部分代码,一个是 linuxserver 的 nginx 镜像,一个是官方版

    docker run -d \
      --name=nginx \
      -e PUID=1000 \
      -e PGID=1000 \
      -e Asia/Shanghai \
      -p 80:80 \
      -p 443:443 \
      -v /home/nginx:/config \
      --restart unless-stopped \
      lscr.io/linuxserver/nginx:latest
    
    docker run -d \
        --name nginx1 \
        --log-opt max-size=1m \
        -v /home/nginx1:/etc/nginx \
        --restart unless-stopped \
        nginx
    

    运行之后,

    linuxserver 会在 /home/nginx 里自动创建文件夹和文件(注意是文件夹和配置文件都自动创建了),

    而官方版的不会自动创建文件。

    如图: nginx

    请问:

    1.为啥官方版的 Nginx 不会自动创建文件呢?

    2.怎么让官方版的自动创建文件呢?就是 nginx.conf 这些配置文件。

    helphelp
        1
    helphelp  
    OP
       2023-05-28 08:37:09 +08:00
    以往我都是先运行一个基础容器,在`docker cp` 然后在`docker stop nginx`很是麻烦,之前一直以为是 docker 不会自动创建文件,但是当我用了 linuxserver 的镜像之后,感觉好像也不是,求解惑 谢谢各位大佬
    ghostheaven
        2
    ghostheaven  
       2023-05-28 08:52:26 +08:00
    看它的启动脚本有没有创建配置文件的部分
    hero0earth
        4
    hero0earth  
       2023-05-28 08:58:51 +08:00
    linuxserver 是用的 docker mount 吧,和 docker volume 不一样
    hero0earth
        5
    hero0earth  
       2023-05-28 09:04:06 +08:00
    唐突了,mount 也不会自动创建。。
    leonshaw
        6
    leonshaw  
       2023-05-28 09:12:58 +08:00 via Android
    写个基于 nginx 的 Dockerfile
    gitignore
        7
    gitignore  
       2023-05-28 09:30:16 +08:00 via iPhone
    本身 nginx 安装后就会在 /etc/nginx 目录生成这些文件吧,nginx docker 应该是 include 了 /config 目录,所以你要这些文件来干嘛……直接把你的配置文件丢进去不行吗


    或者是在想要,试试自己写 Dockerfile ,entrypoint 加个类似命令

    cp -R -u -p /etc/nginx /config

    启动时会复制 config 目录不存在的文件
    byron
        8
    byron  
       2023-05-28 09:41:12 +08:00
    1. 官方版的 Nginx 镜像是最小化的,只包含 Nginx 本身和一些基本配置。它默认不会创建任何额外的文件或目录。这是为了让用户有最大的灵活性,可以自己挂载配置目录和文件。

    2. 要让官方版的 Nginx 也自动创建配置文件,可以:

    - 在 Dockerfile 中复制官方的默认配置文件到 image 中:

    Dockerfile
    FROM nginx
    COPY nginx.conf /etc/nginx/nginx.conf
    - 或者在 docker run 的时候,同时挂载官方的默认配置文件目录:
    bash
    docker run -d \
    --name nginx1 \
    -v /home/nginx1:/etc/nginx \
    -v /usr/share/nginx/html:/usr/share/nginx/html:ro \
    -v /usr/share/nginx/conf.d:/etc/nginx/conf.d:ro \
    --restart unless-stopped \
    nginx

    这样,当容器启动时,就会从宿主机上拷贝默认的配置文件到容器中,实现自动创建配置文件的效果。

    结论:官方版的 Nginx 镜像更 “轻量级”,它默认不会创建额外文件,完全依赖用户的挂载。如果要自动创建配置,可以在 Dockerfile 或 docker run 中复制官方的默认配置文件到容器内。
    helphelp
        9
    helphelp  
    OP
       2023-05-28 10:01:12 +08:00
    @symbo 大佬牛逼 我说我一开始怎么没看到 dockerfile 里面有关于创建文件的部分,原来 Linuxserver 用了两个镜像编译的,先做了一个基础镜像,然后在基础镜像的基础上在编译一次,创建文件夹的代码是在 beseimage-nginx 里面。谢谢!

    不过我在 https://github.com/linuxserver/docker-baseimage-alpine-nginx/blob/master/Dockerfile 中也没看到创建 nginx.conf 的部分,只有删除默认的 default.conf 的操作,大佬可否在指点一下,它创建 Nginx.conf 的代码在哪?
    helphelp
        10
    helphelp  
    OP
       2023-05-28 10:05:27 +08:00
    @gitignore 我想要 nginx 自动创建默认的 nginx.conf ,因为有时候不需要复杂的配置文件,这样用默认的就够了
    helphelp
        11
    helphelp  
    OP
       2023-05-28 10:08:02 +08:00
    @symbo 好像看到了 谢谢大佬
    helphelp
        12
    helphelp  
    OP
       2023-05-28 10:09:40 +08:00
    @byron 谢谢大佬指点,

    -v /usr/share/nginx/html:/usr/share/nginx/html:ro \
    -v /usr/share/nginx/conf.d:/etc/nginx/conf.d:ro \

    这两行代码,首先要宿主机上要安装 Nginx 才会有吧
    helphelp
        13
    helphelp  
    OP
       2023-05-28 10:16:44 +08:00
    @symbo 又看不懂了 大佬看一下我#9 楼的回复 求指点谢谢
    helphelp
        14
    helphelp  
    OP
       2023-05-28 10:19:09 +08:00
    我问了 GPT ,GPT 说不能直接将容器的文件拷贝到宿主机上,我想知道 Linuxserver 的镜像是怎么做到自动创建文件的 大佬们

    以下是 GPT 的回答

    问:
    dockerfile 如何将容器文件拷贝到宿主机


    答:
    在 Dockerfile 中,容器文件无法直接拷贝到宿主机上。Docker 建立的容器是与宿主机隔离的,它们运行在不同的命名空间中,因此无法直接访问宿主机上的文件系统。

    如果需要将容器中的文件拷贝到宿主机上,可以使用 Docker 的 docker cp 命令。该命令允许将容器中的文件复制到宿主机上,或从宿主机上复制文件到容器中。
    helphelp
        15
    helphelp  
    OP
       2023-05-28 10:21:50 +08:00
    @leonshaw 大佬 怎么写 怎么把容器的配置文件拷贝到本地文件夹呢
    liwufan
        16
    liwufan  
       2023-05-28 10:32:23 +08:00
    @helphelp https://github.com/linuxserver/docker-baseimage-alpine-nginx/blob/5072e44869bc3de4231cfb73f66ed16e838c8a5d/Dockerfile#L51
    在这行吧,你要自己先写好再复制到 image 里。nginx 不能自己生成配置
    leonshaw
        17
    leonshaw  
       2023-05-28 10:35:07 +08:00
    @helphelp 没法直接写本地,要 mount 一个目录,然后容器写这个目录。说实话没看懂你需求到底是什么,为什么一定要写到主机目录。
    helphelp
        18
    helphelp  
    OP
       2023-05-28 10:55:21 +08:00
    @leonshaw 俺就是想要容器自己创建配置文件 我不想手动创建我懒 我希望 docker run 之后就自动创建好 我放入 html 就能用
    helphelp
        19
    helphelp  
    OP
       2023-05-28 10:58:00 +08:00
    @leonshaw 就像这张图里面的 nginx 文件夹一样: https://file.uhsea.com/2305/ca4cd2e176ce4d798b225b4d5e97db6534.png 容器啥的都给配置好了 我直接在 www 文件夹里面放入 html 就能访问了
    leonshaw
        20
    leonshaw  
       2023-05-28 11:06:54 +08:00
    @helphelp 那就 image 里直接放个默认配置,或者 entrypoint 脚本里发现没有配置就创建一个默认的
    helphelp
        21
    helphelp  
    OP
       2023-05-28 11:06:57 +08:00
    @leonshaw 就像你直接用 apt install nginx 安装它会在本地 /usr/share/nginx/conf.d 给你创建好基本的.conf 配置文件对吧,不需要你手动创建,但是 docker 版的官方 nginx 镜像它默认不创建,我想让他自动创建
    liwufan
        22
    liwufan  
       2023-05-28 11:11:40 +08:00
    nginx 没法自动创建, /usr/share/nginx/conf.d 是 apt 维护者自己写的。你去 nginx 或者 arch Linux 下载 tarball 里面都是没有这种配置文件的
    helphelp
        23
    helphelp  
    OP
       2023-05-28 11:42:55 +08:00
    @liwufan 原来是这样啊 谢谢大佬了 那 linuxserver 的 Nginx 镜像是怎么做到 docker run 的时候 自动在宿主机创建文件的
    xiaomingVTEX
        24
    xiaomingVTEX  
       2023-05-28 11:54:41 +08:00
    @helphelp #14 不是应该问 dockerfile 如何将宿主机文件拷贝到容器吗
    helphelp
        25
    helphelp  
    OP
       2023-05-28 11:59:13 +08:00
    @xiaomingVTEX 可是我本地没有文件,我想知道 linuxserver 他们是怎么做到把容器里面的文件创建到本地的
    helphelp
        26
    helphelp  
    OP
       2023-05-28 12:01:29 +08:00
    @xiaomingVTEX 怎么让官方版 nginx 像 linuxserver 版 nginx 一样自动创建文件呢?就是把 /etc/nginx/nginx.conf 这些配置文件自动拷贝或者说创建到本地。
    512357301
        27
    512357301  
       2023-05-28 12:02:03 +08:00 via Android
    你这映射的容器里的目录都不一样,没有可比性吧,而且即使映射的同一个容器内目录,不同的镜像有不同的规则,也可能出现不创建的情况,具体得以镜像的逻辑为准。
    映射的本质是让镜像读写本地的文件,默认是读,如果本地是空,有的镜像会把默认值写入,有的则不写,具体以镜像逻辑为准。
    symbo
        28
    symbo  
       2023-05-28 12:04:15 +08:00
    @helphelp nginx.conf 是不是 apk 装 nginx 装进去的啊?
    helphelp
        29
    helphelp  
    OP
       2023-05-28 12:09:34 +08:00
    ## 重新整理一下问题,刚刚可能没表达清楚

    下面两部分代码,一个是 linuxserver 的 nginx 镜像,一个是官方版

    ```
    docker run -d \
    --name=nginx \
    -v /home/nginx:/config \ # 注意看这部分
    --restart unless-stopped \
    lscr.io/linuxserver/nginx:latest
    ```

    ```
    docker run -d \
    --name nginx1 \
    --log-opt max-size=1m \
    -v /home/nginx1:/etc/nginx \ 注意看这部分
    --restart unless-stopped \
    nginx
    ```
    开始的时候我的 home 目录是空白的,什么都没有
    运行这两个容器之后,

    linuxserver 会在 /home/nginx 里自动创建文件夹和文件(注意是文件夹和配置文件都自动创建了),
    **而官方版的不会自动创建文件。**
    如图:

    nginx 文件夹下面有很多文件,都是容器自动创建的,但是 nginx1 文件夹里面什么都没有

    ![nginx]( https://file.uhsea.com/2305/ca4cd2e176ce4d798b225b4d5e97db6534.png)


    **请问:**


    **1.怎么让官方版像 linuxserver 一样自动创建文件呢?就是把容器内的 /etc/nginx/nginx.conf 这些配置文件自动拷贝或者说创建到本地。**
    javalaw2010
        30
    javalaw2010  
       2023-05-28 12:13:37 +08:00
    注意一下 https://github.com/linuxserver/docker-baseimage-alpine-nginx 这个容器的构建,/root 文件加会被添加进容器和 /合并,注意 /migrations 目录下面的文件,这个文件会被更基础的镜像 https://github.com/linuxserver/docker-baseimage-alpine-nginx 的 S6 进程管理器读取,会把 nginx 的配置文件从 apt 源安装的初始目录拷贝到 /config 文件夹下面。
    javalaw2010
        31
    javalaw2010  
       2023-05-28 12:16:29 +08:00
    @javalaw2010 #30 第二个镜像应该是 https://github.com/linuxserver/docker-baseimage-alpine ,复制错了。
    javalaw2010
        32
    javalaw2010  
       2023-05-28 12:24:07 +08:00
    想要启动容器的时候自动创建文件夹的话,一种方案就是你用跟 linuxserver 一样的进程管理器的方案,然后写一些启动脚本让它读取。还有一种更轻量级的方案就是写一个 docker-entrypoint.sh 脚本,作为容器的 entrypoint ,在这个里面做一些初始化的工作,然后用 gosu 和 exec 命令执行 command ,实际的使用示例可以看这个: https://github.com/laravel/sail/blob/1.x/runtimes/8.2/start-container
    helphelp
        33
    helphelp  
    OP
       2023-05-28 13:49:56 +08:00
    @javalaw2010 大佬牛逼 谢谢 大概明白怎么回事了 意思就是容器执行的时候顺带执行了脚本对吗
    liwufan
        34
    liwufan  
       2023-05-28 14:09:39 +08:00
    Alpine > baseimage > baseimage-nginx > linuxserver-nginx
    /config 目录是 linuxserver 自定义出来的路径,目的是在单机上让一个 compose 文件一口气拉起一大坨容器。
    https://github.com/linuxserver/docker-baseimage-alpine/blob/a0d322b3050123260b41000840c58362c688d509/Dockerfile#L90
    helphelp
        35
    helphelp  
    OP
       2023-05-28 14:29:36 +08:00
    @liwufan 谢大佬解答
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   970 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 21:01 · PVG 05:01 · LAX 13:01 · JFK 16:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.