From 70ce37129e268b45996e42040a8977ccfb54ec6d Mon Sep 17 00:00:00 2001 From: seon-yunjae <52045444+seon-yunjae@users.noreply.github.com> Date: Thu, 29 Oct 2026 18:24:59 +0000 Subject: [PATCH 1/7] feat(base): install cloudflared from Cloudflare apt repository Add install-cloudflared.sh to the root phase, using the official pkg.cloudflare.com apt repository (any suite, cloudflare-public-v2 key), and document it in CLAUDE.md, images/CLAUDE.md and README.md. Closes #10 --- CLAUDE.md | 1 + README.md | 2 ++ images/CLAUDE.md | 16 +++++++++++++++- images/base/Dockerfile | 6 ++++++ images/base/scripts/install-cloudflared.sh | 19 +++++++++++++++++++ 5 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 images/base/scripts/install-cloudflared.sh diff --git a/CLAUDE.md b/CLAUDE.md index d7ee440..ec39bb8 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -14,6 +14,7 @@ This is a Docker base image for Coder workspaces, built on top of `codercom/ente - Graphite CLI for stacked PRs - GitHub CLI extensions: `gh stack` (github/gh-stack) and `gh actions-lock` (github/gh-actions-lock) - AWS CLI, Google Cloud CLI, and Qodana CLI +- cloudflared (Cloudflare Tunnel client) from Cloudflare's apt repository - Custom Nerd Fonts for terminal display ## Repository Structure diff --git a/README.md b/README.md index f2f903d..a09d7dc 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ A comprehensive Docker base image for [Coder](https://coder.com/) workspaces, bu - **GitHub CLI extensions**: `gh stack` (native stacked PRs) and `gh actions-lock` (lock and verify GitHub Actions dependencies) - **GitHub CLI (gh)**: GitHub operations from terminal - **AWS CLI**: Amazon Web Services command line interface +- **cloudflared**: Cloudflare Tunnel client (official Cloudflare apt repository) - **Qodana CLI**: JetBrains code quality platform ## Quick Start @@ -101,6 +102,7 @@ All installation scripts are located in the `scripts/` directory: |--------|-------------|------| | `install-fonts.sh` | System fonts installation | root | | `install-root-sdk.sh` | Qodana CLI, AWS CLI | root | +| `install-cloudflared.sh` | cloudflared (Cloudflare apt repository) | root | | `install-docker.sh` | Docker Engine | root | | `install-sdk.sh` | fnm, SDKMAN, Bun, Deno, Claude Code, FVM | coder | | `install-prompt.sh` | Zimfw modules (`.zimrc`), Powerlevel10k prompt, Orca history | coder | diff --git a/images/CLAUDE.md b/images/CLAUDE.md index dc865ad..8f0b73a 100644 --- a/images/CLAUDE.md +++ b/images/CLAUDE.md @@ -15,6 +15,7 @@ images/ ├── install-fonts.sh # 시스템 폰트 설치 (Root) ├── install-root-sdk.sh # Root 레벨 도구 (Qodana, AWS CLI) ├── install-mise.sh # mise 버전 매니저 설치 (Root, apt) + ├── install-cloudflared.sh # cloudflared 설치 (Root, apt) ├── install-docker.sh # Docker Engine 설치 (Root) ├── install-sdk.sh # 사용자 개발 도구 (mise 글로벌 런타임, Claude Code) ├── install-prompt.sh # Zimfw 모듈 + Powerlevel10k 프롬프트 @@ -48,6 +49,7 @@ images/ - AWS CLI - Google Cloud CLI - GitHub CLI +- cloudflared (Cloudflare Tunnel 클라이언트) - Docker (coder 사용자가 docker 그룹에 포함) **기타:** @@ -79,7 +81,10 @@ images/ - Qodana CLI - AWS CLI -5. **Docker 설치** +5. **cloudflared 설치** (`install-cloudflared.sh`) + - Cloudflare 공식 apt repository + +6. **Docker 설치** - Docker Engine 설치 - coder 사용자를 docker 그룹에 추가 @@ -174,6 +179,13 @@ Root 레벨 개발 도구: - Qodana CLI (JetBrains 코드 분석) - AWS CLI v2 +#### install-cloudflared.sh (Root) + +cloudflared 설치: +- Cloudflare 공식 apt repository 사용 (`https://pkg.cloudflare.com/cloudflared any main`) +- 서명 키: `/usr/share/keyrings/cloudflare-public-v2.gpg` +- 바이너리만 설치하며 터널·서비스·인증 정보는 구성하지 않음 (워크스페이스별로 설정) + #### install-docker.sh (Root) Docker Engine 설치: @@ -249,6 +261,8 @@ GitHub CLI 확장 설치: **Root Phase (mise):** Docker 직전에 mise 바이너리를 apt로 시스템 설치 (`install-mise.sh`) +**Root Phase (cloudflared):** mise 다음, Docker 직전에 cloudflared를 apt로 설치 (`install-cloudflared.sh`) + **Coder User Phase:** 1. SDK (`install-sdk.sh`) - mise 글로벌 런타임(node/bun/deno/java), npm 전역 패키지, Claude Code 2. 프롬프트 (`install-prompt.sh`) - Zimfw 설치 이후 diff --git a/images/base/Dockerfile b/images/base/Dockerfile index 03cfbcd..6460435 100644 --- a/images/base/Dockerfile +++ b/images/base/Dockerfile @@ -96,6 +96,12 @@ RUN chmod +x /tmp/install-mise.sh && \ /tmp/install-mise.sh && \ rm /tmp/install-mise.sh +# cloudflared 설치 +COPY --chown=root:root scripts/install-cloudflared.sh /tmp/install-cloudflared.sh +RUN chmod +x /tmp/install-cloudflared.sh && \ + /tmp/install-cloudflared.sh && \ + rm /tmp/install-cloudflared.sh + # Docker 설치 COPY --chown=root:root scripts/install-docker.sh /tmp/install-docker.sh RUN chmod +x /tmp/install-docker.sh && \ diff --git a/images/base/scripts/install-cloudflared.sh b/images/base/scripts/install-cloudflared.sh new file mode 100644 index 0000000..ad32fb8 --- /dev/null +++ b/images/base/scripts/install-cloudflared.sh @@ -0,0 +1,19 @@ +#!/bin/bash +set -e + +echo "Installing cloudflared..." + +# Cloudflare GPG key 설치 +mkdir -p --mode=0755 /usr/share/keyrings +curl -fsSL https://pkg.cloudflare.com/cloudflare-public-v2.gpg | tee /usr/share/keyrings/cloudflare-public-v2.gpg > /dev/null + +# cloudflared apt repository 추가 +echo "deb [signed-by=/usr/share/keyrings/cloudflare-public-v2.gpg] https://pkg.cloudflare.com/cloudflared any main" | tee /etc/apt/sources.list.d/cloudflared.list + +# cloudflared 설치 +apt-get update +apt-get install -y cloudflared +apt-get clean +rm -rf /var/lib/apt/lists/* + +echo "cloudflared installed successfully: $(cloudflared --version)" From f5dd10ca278c1dd1e00e24cc990e1deab774eb3d Mon Sep 17 00:00:00 2001 From: seon-yunjae <52045444+seon-yunjae@users.noreply.github.com> Date: Thu, 29 Oct 2026 19:02:58 +0000 Subject: [PATCH 2/7] fix(base): write cloudflared GPG key with curl -o so download failures stop the build --- images/base/scripts/install-cloudflared.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/base/scripts/install-cloudflared.sh b/images/base/scripts/install-cloudflared.sh index ad32fb8..ffe98a4 100644 --- a/images/base/scripts/install-cloudflared.sh +++ b/images/base/scripts/install-cloudflared.sh @@ -5,7 +5,7 @@ echo "Installing cloudflared..." # Cloudflare GPG key 설치 mkdir -p --mode=0755 /usr/share/keyrings -curl -fsSL https://pkg.cloudflare.com/cloudflare-public-v2.gpg | tee /usr/share/keyrings/cloudflare-public-v2.gpg > /dev/null +curl -fsSL -o /usr/share/keyrings/cloudflare-public-v2.gpg https://pkg.cloudflare.com/cloudflare-public-v2.gpg # cloudflared apt repository 추가 echo "deb [signed-by=/usr/share/keyrings/cloudflare-public-v2.gpg] https://pkg.cloudflare.com/cloudflared any main" | tee /etc/apt/sources.list.d/cloudflared.list From 4e8ef50cd08e102e884cb90e65d5a5959437eb0c Mon Sep 17 00:00:00 2001 From: seon-yunjae <52045444+seon-yunjae@users.noreply.github.com> Date: Thu, 29 Oct 2026 19:03:30 +0000 Subject: [PATCH 3/7] refactor(base): write cloudflared apt source with redirect instead of tee --- images/base/scripts/install-cloudflared.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/base/scripts/install-cloudflared.sh b/images/base/scripts/install-cloudflared.sh index ffe98a4..0514f17 100644 --- a/images/base/scripts/install-cloudflared.sh +++ b/images/base/scripts/install-cloudflared.sh @@ -8,7 +8,7 @@ mkdir -p --mode=0755 /usr/share/keyrings curl -fsSL -o /usr/share/keyrings/cloudflare-public-v2.gpg https://pkg.cloudflare.com/cloudflare-public-v2.gpg # cloudflared apt repository 추가 -echo "deb [signed-by=/usr/share/keyrings/cloudflare-public-v2.gpg] https://pkg.cloudflare.com/cloudflared any main" | tee /etc/apt/sources.list.d/cloudflared.list +echo "deb [signed-by=/usr/share/keyrings/cloudflare-public-v2.gpg] https://pkg.cloudflare.com/cloudflared any main" > /etc/apt/sources.list.d/cloudflared.list # cloudflared 설치 apt-get update From 73220ea33c6607ec504fcccea87ced9c52c326c6 Mon Sep 17 00:00:00 2001 From: seon-yunjae <52045444+seon-yunjae@users.noreply.github.com> Date: Thu, 29 Oct 2026 19:04:03 +0000 Subject: [PATCH 4/7] fix(base): enable nounset and pipefail in install-cloudflared.sh --- images/base/scripts/install-cloudflared.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/base/scripts/install-cloudflared.sh b/images/base/scripts/install-cloudflared.sh index 0514f17..8f44939 100644 --- a/images/base/scripts/install-cloudflared.sh +++ b/images/base/scripts/install-cloudflared.sh @@ -1,5 +1,5 @@ #!/bin/bash -set -e +set -euo pipefail echo "Installing cloudflared..." From cad31b1d9191c27e6ade6987c70b416b507a6764 Mon Sep 17 00:00:00 2001 From: seon-yunjae <52045444+seon-yunjae@users.noreply.github.com> Date: Thu, 29 Oct 2026 19:48:05 +0000 Subject: [PATCH 5/7] fix(base): retry cloudflared GPG key download on transient failures --- images/base/scripts/install-cloudflared.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/base/scripts/install-cloudflared.sh b/images/base/scripts/install-cloudflared.sh index 8f44939..8da4970 100644 --- a/images/base/scripts/install-cloudflared.sh +++ b/images/base/scripts/install-cloudflared.sh @@ -5,7 +5,7 @@ echo "Installing cloudflared..." # Cloudflare GPG key 설치 mkdir -p --mode=0755 /usr/share/keyrings -curl -fsSL -o /usr/share/keyrings/cloudflare-public-v2.gpg https://pkg.cloudflare.com/cloudflare-public-v2.gpg +curl -fsSL --retry 5 --retry-connrefused --retry-delay 2 -o /usr/share/keyrings/cloudflare-public-v2.gpg https://pkg.cloudflare.com/cloudflare-public-v2.gpg # cloudflared apt repository 추가 echo "deb [signed-by=/usr/share/keyrings/cloudflare-public-v2.gpg] https://pkg.cloudflare.com/cloudflared any main" > /etc/apt/sources.list.d/cloudflared.list From e8441263202c5f87c506aec6e0ed797c783a30b3 Mon Sep 17 00:00:00 2001 From: seon-yunjae <52045444+seon-yunjae@users.noreply.github.com> Date: Thu, 29 Oct 2026 19:48:36 +0000 Subject: [PATCH 6/7] fix(base): install cloudflared without recommended packages --- images/base/scripts/install-cloudflared.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/base/scripts/install-cloudflared.sh b/images/base/scripts/install-cloudflared.sh index 8da4970..6756e6f 100644 --- a/images/base/scripts/install-cloudflared.sh +++ b/images/base/scripts/install-cloudflared.sh @@ -12,7 +12,7 @@ echo "deb [signed-by=/usr/share/keyrings/cloudflare-public-v2.gpg] https://pkg.c # cloudflared 설치 apt-get update -apt-get install -y cloudflared +DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends cloudflared apt-get clean rm -rf /var/lib/apt/lists/* From a7267fc758c17f799a6d1e5fa83dfff05861b7ec Mon Sep 17 00:00:00 2001 From: seon-yunjae <52045444+seon-yunjae@users.noreply.github.com> Date: Thu, 29 Oct 2026 20:32:28 +0000 Subject: [PATCH 7/7] fix(base): make cloudflared apt keyring world-readable Set the downloaded Cloudflare GPG keyring to 0644 so the unprivileged _apt user can read it regardless of the build umask. --- images/base/scripts/install-cloudflared.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/images/base/scripts/install-cloudflared.sh b/images/base/scripts/install-cloudflared.sh index 6756e6f..a5f5507 100644 --- a/images/base/scripts/install-cloudflared.sh +++ b/images/base/scripts/install-cloudflared.sh @@ -6,6 +6,7 @@ echo "Installing cloudflared..." # Cloudflare GPG key 설치 mkdir -p --mode=0755 /usr/share/keyrings curl -fsSL --retry 5 --retry-connrefused --retry-delay 2 -o /usr/share/keyrings/cloudflare-public-v2.gpg https://pkg.cloudflare.com/cloudflare-public-v2.gpg +chmod 0644 /usr/share/keyrings/cloudflare-public-v2.gpg # cloudflared apt repository 추가 echo "deb [signed-by=/usr/share/keyrings/cloudflare-public-v2.gpg] https://pkg.cloudflare.com/cloudflared any main" > /etc/apt/sources.list.d/cloudflared.list