feat(deploy): optional Docker + ttyd recipe to serve the TUI dashboard in a browser#685
feat(deploy): optional Docker + ttyd recipe to serve the TUI dashboard in a browser#685danimoya wants to merge 1 commit into
Conversation
Wraps the upstream `dashboard/` TUI with ttyd so the pipeline viewer can
be served over HTTPS from a browser, behind HTTP Basic Auth. The whole
project directory is bind-mounted at /workspace so the host's AI CLI and
the container share state (cv.md, config/, data/, reports/, output/…).
Files:
- Dockerfile multi-stage: golang:1.24 builds the dashboard,
debian-slim runtime ships ttyd 1.7.7 + tini
- docker/entrypoint.sh ttyd wrapper, reads creds from env, no -O
(origin check off — required behind a proxy)
- stack-compose.yml compose stack, .env for creds, parameterised
bind path and network for reuse
- .dockerignore keep user data + local overrides out of build
- .gitignore ignore *.override.yml for deployment-specific
overrides (network, env_file paths, etc.)
Use:
docker compose -f stack-compose.yml build
echo 'CAREEROPS_WEB_USER=you' > .env
echo 'CAREEROPS_WEB_PASS=<strong>' >> .env
docker compose -f stack-compose.yml up -d
# then front it with your reverse proxy on port 7681 (WS upgrade on)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThis PR introduces an optional, opt-in Docker deployment recipe that wraps the existing Go TUI dashboard with ttyd, enabling browser-based read-only access over HTTP with HTTP Basic Auth. The recipe includes a multi-stage Dockerfile, entrypoint script, Docker Compose configuration, and updated ignore patterns—with no changes to agent code, data model, or CLI runtime for users who do not adopt it. ChangesDocker TTyd Recipe
Sequence DiagramsequenceDiagram
participant Builder as golang:1.24
participant Runtime as debian:bookworm-slim
participant Entrypoint as entrypoint.sh
participant ttyd as ttyd HTTP Server
participant Browser as Browser Client
Builder->>Builder: Copy go.mod, go.sum
Builder->>Builder: Run go mod download
Builder->>Builder: Build career-dashboard (trimmed)
Builder->>Runtime: Copy /out/career-dashboard binary
Runtime->>Runtime: Install apt deps (curl, etc)
Runtime->>Runtime: Download pinned ttyd 1.7.7
Runtime->>Runtime: Generate en_US.UTF-8 locale
Runtime->>Runtime: Create app user (APP_UID/GID)
note over Runtime: ENTRYPOINT: tini docker/entrypoint.sh
Entrypoint->>Entrypoint: Validate CAREEROPS_WEB_USER/PASS
Entrypoint->>Entrypoint: Check CAREEROPS_WORKSPACE exists
Entrypoint->>ttyd: exec ttyd with career-dashboard --path
ttyd->>ttyd: Bind 0.0.0.0:7681 with Basic Auth
Browser->>ttyd: HTTP request with Basic Auth
ttyd->>Browser: Serve xterm.js UI + WebSocket
Browser->>Browser: Render TUI dashboard in browser
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.dockerignore:
- Around line 1-10: The .dockerignore currently allows personal files like cv.md
into the build context; update .dockerignore to explicitly exclude root-level
personal/profile artifacts (for example add patterns such as /cv.md, /resume*,
/profile*, /*.md or more targeted globs) and common personal file patterns
(*.resume, *.profile, *.pdf) using leading slashes for root-only matches so you
don’t accidentally block project docs in subfolders; modify the .dockerignore
file (referencing the existing .dockerignore entries shown) to add these exclude
patterns while keeping necessary exceptions like !data/.gitkeep.
In `@Dockerfile`:
- Around line 49-51: Add a Docker HEALTHCHECK to the Dockerfile to verify the
ttyd service is alive on the exposed port (EXPOSE 7681) so orchestration can
detect failures; implement a HEALTHCHECK that periodically runs a lightweight
HTTP probe against localhost:7681 (for example using curl --fail/--max-time or
wget --spider) and returns non-zero on failure, and place it near the
EXPOSE/ENTRYPOINT block so the container runtime will use it to mark unhealthy
containers started via the existing ENTRYPOINT ["/usr/bin/tini", "--",
"/usr/local/bin/entrypoint.sh"].
- Around line 25-27: The Dockerfile currently downloads a hardcoded x86_64
binary for ttyd; change the curl step that uses TTYD_VERSION and writes to
/usr/local/bin/ttyd to detect the container architecture (e.g., via uname -m)
and map it to the release filename (x86_64 for amd64, aarch64 for arm64) so the
URL uses the correct binary for the platform before running chmod +x on
/usr/local/bin/ttyd; update the download URL construction to reference the
chosen arch variable derived from uname -m and TTYD_VERSION.
- Around line 25-27: The Dockerfile currently installs ttyd directly from GitHub
using TTYD_VERSION into /usr/local/bin/ttyd without any checksum validation;
change the install sequence to download the corresponding SHA256SUMS file from
the same release, download the ttyd artifact to a temporary path (e.g.,
/usr/local/bin/ttyd.tmp), extract the expected checksum entry for the ttyd
artifact from the SHA256SUMS, verify the downloaded file using sha256sum (or
sha256sum -c with a crafted entry), and only then move the validated file to
/usr/local/bin/ttyd and chmod +x; use the existing TTYD_VERSION variable and
temporary filename (/usr/local/bin/ttyd.tmp) so the verification uses the
matching release checksum before replacing the final /usr/local/bin/ttyd.
In `@stack-compose.yml`:
- Around line 31-34: The compose build currently doesn't pass host UID/GID into
the image (build: context/Dockerfile and image: careerops:latest), which causes
permission mismatches for the host bind-mount; update the compose "build" block
to add build args for UID/GID (e.g., args: LOCAL_UID: ${LOCAL_UID:-1001},
LOCAL_GID: ${LOCAL_GID:-1001}) so the host values are forwarded into the Docker
build, and update the Dockerfile referenced by dockerfile: Dockerfile to accept
ARG LOCAL_UID/LOCAL_GID, create/set a matching user or chown the application
directories to those IDs during image build; ensure the host bind-mounted volume
keeps correct ownership by using these build args.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: fdb49000-ddbb-4827-ad2c-4f3578726150
📒 Files selected for processing (5)
.dockerignore.gitignoreDockerfiledocker/entrypoint.shstack-compose.yml
| .git | ||
| node_modules | ||
| output | ||
| reports | ||
| data/*.md | ||
| !data/.gitkeep | ||
| jds | ||
| *.log | ||
| .env | ||
| stack-compose.override.yml |
There was a problem hiding this comment.
Exclude root/user personal files from Docker build context.
cv.md (and other personal profile files) are still eligible for inclusion in build context, which is unnecessary and increases PII exposure risk.
Proposed fix
.git
node_modules
+cv.md
+writing-samples
+config/profile.yml
+portals.yml
+modes/_profile.md
output
reports
data/*.md
!data/.gitkeep📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| .git | |
| node_modules | |
| output | |
| reports | |
| data/*.md | |
| !data/.gitkeep | |
| jds | |
| *.log | |
| .env | |
| stack-compose.override.yml | |
| .git | |
| node_modules | |
| cv.md | |
| writing-samples | |
| config/profile.yml | |
| portals.yml | |
| modes/_profile.md | |
| output | |
| reports | |
| data/*.md | |
| !data/.gitkeep | |
| jds | |
| *.log | |
| .env | |
| stack-compose.override.yml |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.dockerignore around lines 1 - 10, The .dockerignore currently allows
personal files like cv.md into the build context; update .dockerignore to
explicitly exclude root-level personal/profile artifacts (for example add
patterns such as /cv.md, /resume*, /profile*, /*.md or more targeted globs) and
common personal file patterns (*.resume, *.profile, *.pdf) using leading slashes
for root-only matches so you don’t accidentally block project docs in
subfolders; modify the .dockerignore file (referencing the existing
.dockerignore entries shown) to add these exclude patterns while keeping
necessary exceptions like !data/.gitkeep.
| && curl -fsSL -o /usr/local/bin/ttyd \ | ||
| "https://github.com/tsl0922/ttyd/releases/download/${TTYD_VERSION}/ttyd.x86_64" \ | ||
| && chmod +x /usr/local/bin/ttyd \ |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -name "Dockerfile*" -type f | head -20Repository: santifer/career-ops
Length of output: 76
🏁 Script executed:
head -40 ./DockerfileRepository: santifer/career-ops
Length of output: 1476
🌐 Web query:
ttyd v1.7.7 release github tsl0922 artifacts
💡 Result:
The ttyd version 1.7.7 was released on March 30, 2024, by the tsl0922/ttyd repository [1]. This release included fixes for version detection when not building from a git repository and restored the static version in CMake [1]. The release artifacts provided on the GitHub Releases page include binaries for various architectures (aarch64, arm, armhf, i686, mips, mips64, mips64el, mipsel, s390x, x86_64) and a Windows executable (ttyd.win32.exe), along with a SHA256SUMS file for verification [1]. Users have reported issues with the pre-built 1.7.7 binaries, specifically regarding accessibility on certain systems like WSL2, where building from source was identified as a successful workaround [2]. As of May 2026, the repository remains active, with the last push occurring in April 2026 [3].
Citations:
- 1: https://github.com/tsl0922/ttyd/releases/tag/1.7.7
- 2: 1.7.7 Release needs to be updated tsl0922/ttyd#1456
- 3: https://github.com/tsl0922/ttyd
🌐 Web query:
Docker TARGETARCH buildx variable multi-arch builds
💡 Result:
When performing multi-platform builds with Docker Buildx, TARGETARCH is one of several automatic platform build arguments provided by BuildKit [1][2]. These arguments allow your Dockerfile to adapt its behavior based on the target architecture being built [1]. Key Concepts and Usage: Automatic Availability: TARGETARCH (along with TARGETOS, TARGETVARIANT, and TARGETPLATFORM) is automatically available within your Dockerfile [1][3]. To use it, you must declare it as an ARG in the stage where you need it [1][2]. Example Usage: ARG TARGETARCH RUN echo "Building for architecture: $TARGETARCH" Cross-Compilation: The primary use case for TARGETARCH is cross-compilation [1]. For example, when building Go applications, you can pass the value of TARGETARCH to the GOARCH environment variable to ensure the compiler produces a binary for the target platform rather than the host platform [1]. FROM --platform=$BUILDPLATFORM golang:alpine AS build ARG TARGETARCH ARG TARGETOS RUN GOOS=$TARGETOS GOARCH=$TARGETARCH go build -o /app/server. Important Considerations: Declaration Requirement: Even though these arguments are provided automatically by BuildKit, you must explicitly include an ARG instruction in your Dockerfile to make them accessible within that stage [1][2]. FROM Scope: You can use these arguments in FROM instructions to dynamically select base images, but they must be declared before the FROM line if you intend to use them there [4]. Platform Mapping: Note that TARGETARCH values (e.g., amd64, arm64) may not always match the naming conventions required by external tools or package managers [5]. In such cases, you may need to use a shell case statement or similar logic to map the TARGETARCH value to the format expected by your specific dependency [5]. For complex multi-platform projects, consider using Docker Buildx Bake, which allows for more declarative and manageable multi-platform builds using HCL configuration files [6][7].
Citations:
- 1: https://docs.docker.com/build/building/multi-platform/
- 2: https://stackoverflow.com/questions/71608637/use-dockerfile-arg-to-determine-from-platform
- 3: Pass in different build args depending on platform/architecture or pass platform as build-arg? docker/build-push-action#309
- 4: Using TARGETARCH before the FROM line does not work docker/buildx#574
- 5: https://github.com/bretfisher/multi-platform-docker-build
- 6: https://medium.com/womenintechnology/multi-architecture-builds-are-possible-with-docker-compose-kind-of-2a4e8d166c56
- 7: https://docs.docker.com/guides/bake
Support multi-arch builds for ttyd download.
Line 26 hardcodes ttyd.x86_64, which breaks arm64 builds/runs with an exec-format error. The ttyd v1.7.7 release provides binaries for multiple architectures (x86_64 for amd64, aarch64 for arm64), but the Dockerfile only downloads the x86_64 variant.
Proposed fix
ARG TTYD_VERSION=1.7.7
+ARG TARGETARCH
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates curl tini bash less locales \
+ && case "${TARGETARCH}" in \
+ amd64) TTYD_ASSET="ttyd.x86_64" ;; \
+ arm64) TTYD_ASSET="ttyd.aarch64" ;; \
+ *) echo "Unsupported TARGETARCH=${TARGETARCH}" >&2; exit 1 ;; \
+ esac \
&& curl -fsSL -o /usr/local/bin/ttyd \
- "https://github.com/tsl0922/ttyd/releases/download/${TTYD_VERSION}/ttyd.x86_64" \
+ "https://github.com/tsl0922/ttyd/releases/download/${TTYD_VERSION}/${TTYD_ASSET}" \
&& chmod +x /usr/local/bin/ttyd \📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| && curl -fsSL -o /usr/local/bin/ttyd \ | |
| "https://github.com/tsl0922/ttyd/releases/download/${TTYD_VERSION}/ttyd.x86_64" \ | |
| && chmod +x /usr/local/bin/ttyd \ | |
| ARG TTYD_VERSION=1.7.7 | |
| ARG TARGETARCH | |
| RUN apt-get update \ | |
| && apt-get install -y --no-install-recommends \ | |
| ca-certificates curl tini bash less locales \ | |
| && case "${TARGETARCH}" in \ | |
| amd64) TTYD_ASSET="ttyd.x86_64" ;; \ | |
| arm64) TTYD_ASSET="ttyd.aarch64" ;; \ | |
| *) echo "Unsupported TARGETARCH=${TARGETARCH}" >&2; exit 1 ;; \ | |
| esac \ | |
| && curl -fsSL -o /usr/local/bin/ttyd \ | |
| "https://github.com/tsl0922/ttyd/releases/download/${TTYD_VERSION}/${TTYD_ASSET}" \ | |
| && chmod +x /usr/local/bin/ttyd \ |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@Dockerfile` around lines 25 - 27, The Dockerfile currently downloads a
hardcoded x86_64 binary for ttyd; change the curl step that uses TTYD_VERSION
and writes to /usr/local/bin/ttyd to detect the container architecture (e.g.,
via uname -m) and map it to the release filename (x86_64 for amd64, aarch64 for
arm64) so the URL uses the correct binary for the platform before running chmod
+x on /usr/local/bin/ttyd; update the download URL construction to reference the
chosen arch variable derived from uname -m and TTYD_VERSION.
🧩 Analysis chain
🏁 Script executed:
fd -type f -name "Dockerfile" | head -20Repository: santifer/career-ops
Length of output: 234
🏁 Script executed:
fd --type f "Dockerfile"Repository: santifer/career-ops
Length of output: 74
🏁 Script executed:
cat -n DockerfileRepository: santifer/career-ops
Length of output: 2209
🌐 Web query:
ttyd github releases checksum verification download
💡 Result:
To verify the integrity of ttyd release binaries, you can use the SHA256SUMS file provided in the project's GitHub releases [1]. Steps to verify: 1. Download the desired binary (e.g., ttyd.x86_64) and the SHA256SUMS file from the official ttyd GitHub releases page [2][1]. 2. Ensure both files are in the same directory. 3. Run the following command in your terminal to verify the checksum [3]: sha256sum --check SHA256SUMS --ignore-missing The --ignore-missing flag is useful if the SHA256SUMS file contains hashes for multiple files, as it tells the tool to only verify the files present in your current directory [3]. If the file is authentic, the command will output the filename followed by ": OK" [3]. Note that not all ttyd releases include a SHA256SUMS file [4][5]. If a release lacks this file, you cannot perform this specific verification method for that version [1]. Always ensure you are downloading from the official repository (tsl0922/ttyd) to maintain security [6].
Citations:
- 1: https://github.com/tsl0922/ttyd/releases/tag/1.7.5
- 2: https://github.com/tsl0922/ttyd/releases
- 3: https://kb.hosting.com/docs/working-with-file-checksums
- 4: https://github.com/tsl0922/ttyd/releases/tag/1.7.4
- 5: https://github.com/tsl0922/ttyd/releases/tag/1.7.0
- 6: https://github.com/tsl0922/ttyd
🌐 Web query:
ttyd 1.7.7 release github SHA256SUMS
💡 Result:
The ttyd 1.7.7 release is available on the official GitHub repository [1]. The release includes a SHA256SUMS file among its assets, which can be accessed directly via the GitHub release page [1]. You can view or download the SHA256SUMS file for ttyd 1.7.7 at the following URL: https://github.com/tsl0922/ttyd/releases/download/1.7.7/SHA256SUMS [1] This file contains the SHA-256 checksums for the various binary assets provided in the 1.7.7 release, such as ttyd.x86_64, ttyd.aarch64, and ttyd.win32.exe [1].
Citations:
🌐 Web query:
ttyd 1.7.7 x86_64 SHA256 checksum
💡 Result:
The SHA256 checksum for the ttyd 1.7.7 x86_64 binary is 8a217c968aba172e0dbf3f34447218dc015bc4d5e59bf51db2f2cd12b7be4f55 [1]. This value is documented in the ops2deb.lock.yml file within the wakemeops repository, which tracks the official release assets from the tsl0922/ttyd GitHub repository [1].
Citations:
Verify ttyd binary integrity before install.
The image executes a remote binary without checksum verification. ttyd 1.7.7 provides a SHA256SUMS file in its official GitHub releases; add verification to mitigate supply-chain risk.
Proposed fix
ARG TTYD_VERSION=1.7.7
+ARG TTYD_SHA256=8a217c968aba172e0dbf3f34447218dc015bc4d5e59bf51db2f2cd12b7be4f55
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates curl tini bash less locales \
- && curl -fsSL -o /usr/local/bin/ttyd \
- "https://github.com/tsl0922/ttyd/releases/download/${TTYD_VERSION}/ttyd.x86_64" \
- && chmod +x /usr/local/bin/ttyd \
+ && curl -fsSL -o /tmp/ttyd \
+ "https://github.com/tsl0922/ttyd/releases/download/${TTYD_VERSION}/ttyd.x86_64" \
+ && echo "${TTYD_SHA256} /tmp/ttyd" | sha256sum -c - \
+ && install -m 0755 /tmp/ttyd /usr/local/bin/ttyd \
+ && rm -f /tmp/ttyd \📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| && curl -fsSL -o /usr/local/bin/ttyd \ | |
| "https://github.com/tsl0922/ttyd/releases/download/${TTYD_VERSION}/ttyd.x86_64" \ | |
| && chmod +x /usr/local/bin/ttyd \ | |
| ARG TTYD_VERSION=1.7.7 | |
| ARG TTYD_SHA256=8a217c968aba172e0dbf3f34447218dc015bc4d5e59bf51db2f2cd12b7be4f55 | |
| RUN apt-get update \ | |
| && apt-get install -y --no-install-recommends \ | |
| ca-certificates curl tini bash less locales \ | |
| && curl -fsSL -o /tmp/ttyd \ | |
| "https://github.com/tsl0922/ttyd/releases/download/${TTYD_VERSION}/ttyd.x86_64" \ | |
| && echo "${TTYD_SHA256} /tmp/ttyd" | sha256sum -c - \ | |
| && install -m 0755 /tmp/ttyd /usr/local/bin/ttyd \ | |
| && rm -f /tmp/ttyd \ |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@Dockerfile` around lines 25 - 27, The Dockerfile currently installs ttyd
directly from GitHub using TTYD_VERSION into /usr/local/bin/ttyd without any
checksum validation; change the install sequence to download the corresponding
SHA256SUMS file from the same release, download the ttyd artifact to a temporary
path (e.g., /usr/local/bin/ttyd.tmp), extract the expected checksum entry for
the ttyd artifact from the SHA256SUMS, verify the downloaded file using
sha256sum (or sha256sum -c with a crafted entry), and only then move the
validated file to /usr/local/bin/ttyd and chmod +x; use the existing
TTYD_VERSION variable and temporary filename (/usr/local/bin/ttyd.tmp) so the
verification uses the matching release checksum before replacing the final
/usr/local/bin/ttyd.
| EXPOSE 7681 | ||
|
|
||
| ENTRYPOINT ["/usr/bin/tini", "--", "/usr/local/bin/entrypoint.sh"] |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | ⚡ Quick win
Add a HEALTHCHECK for service liveness.
A healthcheck improves orchestration and failure detection for the ttyd endpoint.
Proposed fix
WORKDIR /workspace
EXPOSE 7681
+HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
+ CMD bash -ec 'exec 3<>/dev/tcp/127.0.0.1/7681'
ENTRYPOINT ["/usr/bin/tini", "--", "/usr/local/bin/entrypoint.sh"]📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| EXPOSE 7681 | |
| ENTRYPOINT ["/usr/bin/tini", "--", "/usr/local/bin/entrypoint.sh"] | |
| WORKDIR /workspace | |
| EXPOSE 7681 | |
| HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \ | |
| CMD bash -ec 'exec 3<>/dev/tcp/127.0.0.1/7681' | |
| ENTRYPOINT ["/usr/bin/tini", "--", "/usr/local/bin/entrypoint.sh"] |
🧰 Tools
🪛 Checkov (3.2.528)
[low] 1-51: Ensure that HEALTHCHECK instructions have been added to container images
(CKV_DOCKER_2)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@Dockerfile` around lines 49 - 51, Add a Docker HEALTHCHECK to the Dockerfile
to verify the ttyd service is alive on the exposed port (EXPOSE 7681) so
orchestration can detect failures; implement a HEALTHCHECK that periodically
runs a lightweight HTTP probe against localhost:7681 (for example using curl
--fail/--max-time or wget --spider) and returns non-zero on failure, and place
it near the EXPOSE/ENTRYPOINT block so the container runtime will use it to mark
unhealthy containers started via the existing ENTRYPOINT ["/usr/bin/tini", "--",
"/usr/local/bin/entrypoint.sh"].
| build: | ||
| context: . | ||
| dockerfile: Dockerfile | ||
| image: careerops:latest |
There was a problem hiding this comment.
Propagate UID/GID into the image build to prevent bind-mount permission issues.
With a fixed image UID/GID (1001) and a host bind mount (Line 43), many Linux setups will hit write/ownership mismatches.
Proposed fix
careerops:
build:
context: .
dockerfile: Dockerfile
+ args:
+ APP_UID: ${APP_UID:-1001}
+ APP_GID: ${APP_GID:-1001}Also applies to: 43-43
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@stack-compose.yml` around lines 31 - 34, The compose build currently doesn't
pass host UID/GID into the image (build: context/Dockerfile and image:
careerops:latest), which causes permission mismatches for the host bind-mount;
update the compose "build" block to add build args for UID/GID (e.g., args:
LOCAL_UID: ${LOCAL_UID:-1001}, LOCAL_GID: ${LOCAL_GID:-1001}) so the host values
are forwarded into the Docker build, and update the Dockerfile referenced by
dockerfile: Dockerfile to accept ARG LOCAL_UID/LOCAL_GID, create/set a matching
user or chown the application directories to those IDs during image build;
ensure the host bind-mounted volume keeps correct ownership by using these build
args.
What does this PR do?
Adds an opt-in Docker recipe that wraps the existing Go TUI dashboard with ttyd so it can be served over HTTPS from a browser, behind HTTP Basic Auth. No existing files change behaviour. Users who don't touch the new files see nothing different.
Related issue
Closes #684
Type of change
What's in the diff (5 files, +152 / −1)
Dockerfilegolang:1.24-alpinebuildsdashboard/,debian-slimruntime ships ttyd 1.7.7 + tini. Final image is small (~70 MB) and runs as a non-root uid/gid (1001, overridable via build args).docker/entrypoint.shCAREEROPS_WEB_USER/CAREEROPS_WEB_PASSfrom env, launchescareer-dashboard --path /workspace. No-Oflag — that one is counterintuitive (it enables strict origin checking, which silently kills the WS upgrade when fronted by a reverse proxy).stack-compose.ymlCAREEROPS_PROJECT_DIR(defaults to the directory holding the file) andCAREEROPS_NETWORK(defaults to a freshcareerops-net; flipexternal: trueto attach to an existing reverse-proxy network)..dockerignorecv.md,reports/*,output/*, …) out of the build context..gitignore*.override.ymlso deployment-specific compose overrides (network swaps, env_file paths) stay out of the repo.How it composes with the data contract
The bind mount maps the project root to
/workspace, so:claudeCLI does — no second source of truth, no sync logic..gitignorerules cover.env,cv.md,config/profile.yml,data/*.md,reports/*,output/*, etc.What this is and isn't
Is: a way to glance at your pipeline from a phone or a second machine, behind a single-user login, while keeping all data, the agent, and the API key on your trusted host.
Is not: a way to put the agent itself on a public URL. Evaluations, scans, batch, PDF generation — all still happen via
claude(or other supported CLIs) on the host. Putting the agent behind a public URL would be a remote-code-execution surface and would conflict with the local-first vision in discussion #156.Verification
End-to-end tested on a real deployment fronted by nginx-proxy-manager:
HTTP 401without creds,HTTP 200with creds.HTTP → HTTPS 301redirect, HSTS header present.101 Switching Protocolsthrough the proxy — the load-bearing piece for the TUI streaming.data/applications.md(just the header row) is enough to render the dashboard cleanly; existing trackers display unchanged.Checklist
git diff main...web-guiis grep-clean for personal identifiers; the only "personal" data referenced anywhere is in user-layer files which remain gitignorednode test-all.mjsand all tests pass — skipped intentionally: this diff is Dockerfile + shell + compose + dotignores, none of which the test suite exercises (it checks.mjssyntax, script execution, dashboard build, data contract, and personal-data leaks against the maintainer's identifiers). Running it would requirenpm install+ Playwright/Chromium (~500 MB) for no real signal. Happy to run it on request if you'd prefer the green checkbox.If you'd rather have this as a separate companion repo, or under a
deploy/subdirectory, happy to refactor either way.Summary by CodeRabbit
Chores