{"id":44457959,"url":"https://github.com/laincloud/dockerfiles","last_synced_at":"2026-02-12T18:08:39.690Z","repository":{"id":57526621,"uuid":"98511056","full_name":"laincloud/dockerfiles","owner":"laincloud","description":"Dockerfiles with S6 overlay.","archived":false,"fork":false,"pushed_at":"2018-11-23T03:52:23.000Z","size":392,"stargazers_count":13,"open_issues_count":2,"forks_count":8,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-06-20T14:23:47.586Z","etag":null,"topics":["image"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/laincloud.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-07-27T08:13:54.000Z","updated_at":"2022-12-28T08:00:43.000Z","dependencies_parsed_at":"2022-09-07T05:30:23.189Z","dependency_job_id":null,"html_url":"https://github.com/laincloud/dockerfiles","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/laincloud/dockerfiles","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/laincloud%2Fdockerfiles","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/laincloud%2Fdockerfiles/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/laincloud%2Fdockerfiles/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/laincloud%2Fdockerfiles/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/laincloud","download_url":"https://codeload.github.com/laincloud/dockerfiles/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/laincloud%2Fdockerfiles/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29375740,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-12T08:51:36.827Z","status":"ssl_error","status_checked_at":"2026-02-12T08:51:26.849Z","response_time":55,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["image"],"created_at":"2026-02-12T18:08:38.688Z","updated_at":"2026-02-12T18:08:39.684Z","avatar_url":"https://github.com/laincloud.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dockerfiles\n\n安装了 `s6` 的 Dockerfiles.\n\n## s6 是什么？\n\n[s6](https://skarnet.org/software/s6/index.html) 是为 Unix 设计的进程管理工具，\n并且提供了 [s6-log](https://skarnet.org/software/s6/s6-log.html) 等日志收集\n工具。\n\n## 为什么要使用 `s6`？\n\n在 Linux 系统里，PID 为 1 的进程是特殊的：\n\n- PID 为 1 的进程需要在子进程退出后收割子进程\n- PID 为 1 的进程收到 `SIGTERM` 或 `SIGINT` 的信号时不会被杀掉\n\n假如容器里 PID 为 1 的进程没有正确收割子进程，会造成僵尸进程；假如 PID 为 1\n的进程没有正确处理信号，会造成无法停止容器。而应用开发者一般不会，也不需要关心\n这两件事。因此，我们需要为镜像设置一个默认的 PID 为 1 的进程来管理子进程和信号。\n这样，当应用开发者不关心自己的进程 PID 为几时，由此 PID 为 1 的进程来管理\n开发者的进程、传递信号，并在应用不响应信号时做适当的操作；当应用开发者\n希望使用自己的 PID 为 1 的进程时，可以覆盖此默认设置。\n\n另一方面，在使用 docker 的过程中，我们发现 docker 的日志收集有性能瓶颈：假如容器\n将日志打到了标准输出，根据 `log-driver` 的设置，docker 会将容器的标准输出收集到\n`syslog` 或 `json-file` 等；而这个过程是中心化的，所有容器的标准输出都会先经过\ndocker daemon，docker daemon 会成为收集过程的瓶颈。我们测试后得到以下结果：\n\nlog-driver | 日志收集速度\n--- | ---\n`syslog` | 14.9 MB/s\n`json-file` | 37.9 MB/s\n\n假如不是将日志打到标准输出，而是直接写入文件，速度则为 220 MB/s。可见 docker daemon\n收集标准输出里的日志时性能较差。尤其严重的是，假如日志过多，会造成 docker daemon\n卡死，从而影响宿主机上所有的容器。\n\n`s6` 能同时解决上述 3 个问题。`s6-svscan` 和 `s6-supervise` 负责管理子进程，可以在\n子进程退出后收割子进程，并正确的处理信号；`s6-log` 可以收集 stdout/stderr 并自动 rotate，\n并且能达到 200 MB/s 的速度。所以我们使用 `s6`。\n\n\u003e `s6-log` 的性能测试参见 [centos/7.3.1611/README.md#性能测试](centos/7/README.md#性能测试)。\n\n## `s6-overlay` 与 `s6` 的关系\n\n[s6-overlay](https://github.com/just-containers/s6-overlay) 提供了一系列初始化脚本和工具，\n方便了 `s6` 在 docker 镜像中的使用。\n\n## 我们对 `s6-overlay` 的定制\n\n我们定义了默认的 [s6 service](https://skarnet.org/software/s6/servicedir.html)，启动容器时：\n\n- [app-init](centos/7.3.1611/rootfs/app-init) 将 Dockerfile 或命令行里传进来的 CMD 写进\n  `/etc/services.log/app/run`，然后 `s6-supervise` 会自动启动 `/etc/services.log/app/run`\n- `s6-supervise` 自动启动 [/etc/services.log/app/log/run](centos/7.3.1611/rootfs/etc/services.d/app/log/run)，\n  收集 CMD 的 stdout/stderr，并写入 `/lain/logs/default/current`\n- `s6-log` 在 `/lain/logs/default/current` 达到 268435455 Byte 时，会自动 rotate，并保留 3 份\n  历史日志\n\nCMD 退出时，`s6-supervise` 会自动执行 [/etc/services.log/app/finish](centos/7.3.1611/rootfs/etc/services.d/app/finish)，\n然后容器也跟着退出。\n\n另外，我们还将 `s6-overlay` 里的 `s6-log` 升级到了 `2.6.0.0`，原因请参见\n[centos/7.3.1611/README.md#为什么有-rootfsusrbins6-log-文件](centos/7/README.md#为什么有-rootfsusrbins6-log-文件)\n\n## 使用示例\n\n```\n# 使用 s6 管理 docker CMD 并收集 CMD 的 stdout/stderr\ndocker run -d -v /lain/logs/default:/lain/logs/default laincloud/centos:7.3.1611 ${CMD}\n# 这时可以在宿主机上通过 tail -f /lain/logs/default/current 查看 ${CMD} 的标准输出\n\n# 不使用 s6 管理 docker CMD\ndocker run -d --entrypoint ${CMD} laincloud/centos:7.3.1611\n# 这时可以在宿主机上通过 docker logs -f ${CONTAINER_ID} 查看 ${CMD} 的标准输出\n```\n\n## dockerfiles 的构建\n\n因为 Dockerfile 较多，如果每次更改都要触发全部构建的话速度将会很慢，所以我们编写\n了 `dockerfiles` 命令行工具，只重新构建发生了变化的镜像以及依赖于变更镜像的镜\n像。\n\n### 编译\n\n```\ngo get -u github.com/golang/dep/cmd/dep\ndep ensure\ngo test ./...\ngo install\n```\n\n### 运行\n\n```\ndockerfiles build  # 构建受到 (origin/master, HEAD] 影响的镜像\ndockerfiles pull  # 下载受到 (orgin/master, HEAD] 影响的镜像\ndockerfiles push  # 推送受到 (origin/master, HEAD] 影响的镜像\ndockerfiles retag --old-registry-host ${oldRegistryHost} --old-organization ${oldOrganization} --new-registry-host ${newRegistryHost} --new-organization ${newOrganization} # 为受到 (origin/master, HEAD] 影响的镜像重新打标签\n```\n\n\u003e - dockerfiles 的运行依赖于：\n\u003e     - docker\n\u003e     - git\n\u003e     - make\n\u003e - dockerfiles 构建 ${a}/${b} 目录下的 Dockerfile 时：\n\u003e     - 如果 Dockerfile 首行有 `# TAGS ${tag1} ${tag2} ... ${tagN}`，则将其打标签为 `laincloud/${a}:${tag1}, laincloud/${a}:${tag2}，...，laincloud/${a}:${tagN}`\n\u003e     - 如果没有，则将其打标签为 `laincloud/${a}:${b}`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flaincloud%2Fdockerfiles","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flaincloud%2Fdockerfiles","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flaincloud%2Fdockerfiles/lists"}