Skip to content

Merge Request: Add Docker Support and German Localization#35

Open
rentasad wants to merge 5 commits into
WilliamAGH:devfrom
rentasad:dev
Open

Merge Request: Add Docker Support and German Localization#35
rentasad wants to merge 5 commits into
WilliamAGH:devfrom
rentasad:dev

Conversation

@rentasad

@rentasad rentasad commented May 13, 2026

Copy link
Copy Markdown

Summary

This Merge Request introduces full Docker support for Brief, enabling users to build and run the application in an isolated environment without requiring a local Java installation. Additionally, it provides a complete German translation of the project documentation and several improvements to the configuration guide.

Changes

1. Docker Integration

  • Created a multi-stage docker/Dockerfile using eclipse-temurin:25 (JDK for building, JRE for runtime) to ensure a small and efficient image.
  • Added docker/docker-setup.sh to automate the build process from the project root.
  • Added .dockerignore to optimize build times by excluding unnecessary files.
  • Configured the container with TERM=xterm-256color and native access for optimal TUI performance.

2. Localization (German)

  • Added README_de.md as a full translation of the main README.md.
  • Created localized Docker documentation (docker/README.md and docker/README_de.md).
  • Implemented language switchers in all documentation headers for easy navigation.

3. Documentation & UX Improvements

  • Added a detailed guide on how to use a .env file for API key management in ~/.config/brief/.env.
  • Included a section on creating a shell alias (alias brief=...) to run the Dockerized version as if it were a local binary.
  • Cleaned up redundant badges and links in the primary README.md.
  • Verification
  • Build: Verified that the multi-stage Docker build correctly compiles the Fat-JAR using Gradle and packages it into the runtime image.
  • Documentation: All Markdown links and formatting have been checked for consistency across both English and German versions.
  • Config: Verified that the suggested mount paths and environment file locations align with the application's expected configuration structure.

AI Disclosure

These changes were developed with the assistance of the Junie AI Agent.

Greptile Summary

This PR adds full Docker support via a multi-stage eclipse-temurin:25 Dockerfile and a helper docker-setup.sh script, and introduces a complete German translation of the project and Docker documentation.

  • Docker: A two-stage build compiles the fat-JAR with Gradle then packages it into a minimal JRE image; the container runs as a dedicated non-root brief user with TERM=xterm-256color and --enable-native-access=ALL-UNNAMED for JLine/TUI compatibility.
  • Localization: README_de.md, docker/README_de.md, and language-switcher links are added across all docs; content is consistent with the English originals.
  • DX: Both READMEs now document the .env file workflow and an optional shell alias so the Dockerised binary feels like a local install.

Confidence Score: 5/5

Safe to merge — changes are additive (Docker infrastructure and German docs) with no modifications to application logic.

All changes are infrastructure and documentation additions. The Dockerfile is functionally correct: non-root user, multi-stage build, explicit JAR path, and the correct JVM flags for JLine/TUI. No application code is touched.

No files require special attention.

Important Files Changed

Filename Overview
docker/Dockerfile Multi-stage Dockerfile using eclipse-temurin:25; runtime stage uses a separate RUN chown layer that can be folded into the COPY instruction
docker/docker-setup.sh Correctly resolves script and project root paths; uses set -e; output examples match the documented docker run command
.dockerignore Appropriately excludes build artifacts, IDE config, .git, .env, and the docker/ directory itself from the build context
README.md Adds language switcher and Docker quick-start section; instructions align with the Dockerfile and docker-setup.sh
README_de.md Complete German translation of README.md; content and instructions are consistent with the English original
docker/README.md Concise English Docker usage guide; commands match the Dockerfile configuration
docker/README_de.md German translation of docker/README.md; content is accurate and consistent with the English version

Sequence Diagram

sequenceDiagram
    participant User
    participant Script as docker-setup.sh
    participant Docker
    participant Builder as Stage 1: eclipse-temurin:25-jdk (builder)
    participant Runtime as Stage 2: eclipse-temurin:25-jre

    User->>Script: ./docker/docker-setup.sh
    Script->>Docker: docker build -t brief -f docker/Dockerfile .
    Docker->>Builder: COPY gradlew, gradle/, build.gradle.kts, settings, properties
    Builder->>Builder: RUN ./gradlew dependencies (cache warm-up)
    Builder->>Builder: COPY src/
    Builder->>Builder: RUN ./gradlew shadowJar
    Docker->>Runtime: "COPY --from=builder brief-*-all.jar /app/brief.jar"
    Runtime->>Runtime: useradd brief, chown, ENV TERM/HOME, USER brief
    Docker-->>Script: Image 'brief' ready
    Script-->>User: Print usage instructions

    User->>Docker: docker run -it --rm --env-file ~/.config/brief/.env -v ~/.config/brief:/home/brief/.config/brief brief
    Docker->>Runtime: "java --enable-native-access=ALL-UNNAMED -jar /app/brief.jar"
    Runtime-->>User: TUI launched in terminal
Loading
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
docker/Dockerfile:31-32
The separate `RUN chown` creates an extra image layer on top of the `COPY`. Using the built-in `--chown` flag on the `COPY` instruction achieves the same result in a single layer, keeping the final image slightly smaller.

```suggestion
COPY --chown=brief:brief --from=builder /app/build/libs/brief-*-all.jar /app/brief.jar
```

Reviews (4): Last reviewed commit: "docs: use secure editor-based API key se..." | Re-trigger Greptile

- Add `.dockerignore` for excluding unnecessary files during the Docker build.
- Introduce multi-stage `Dockerfile` for building and running Brief with JDK 25.
- Add `docker-setup.sh` script for building Docker images with Gradle.
- Add Docker-specific README files (`docker/README.md`, `docker/README_de.md`) with usage instructions.
- Update main `README.md` to include Docker usage guidelines.
@coderabbitai

coderabbitai Bot commented May 13, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a multi-stage Docker build (builder + runtime), a .dockerignore, a helper docker-setup.sh, English and German README updates, and Docker-specific docs describing image build, env-file usage, and mounting the user config directory.

Changes

Docker Support and Bilingual Documentation

Layer / File(s) Summary
Docker build, context, and helper script
docker/Dockerfile, .dockerignore, docker/docker-setup.sh
Adds a multi-stage Dockerfile that builds a fat JAR with Temurin JDK and packages it into a Temurin JRE runtime image; .dockerignore excludes build/IDE/env/archive artifacts; docker-setup.sh builds the image and prints example run commands.
English docs and README updates
README.md, docker/README.md
Adds language navigation links and a Docker section to README.md (build image, create .env with OPENAI_API_KEY, run container with mounted config); docker/README.md documents build/runtime notes, TERM setting, and expected config paths.
German localization and Docker docs
README_de.md, docker/README_de.md
Introduces a full German README with quickstart, releases, Docker usage, development prerequisites, contribution guidance, and localized Docker instructions mirroring the English docs.

Estimated Code Review Effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐳 In layered builds the tiny Brief takes flight,
A .dockerignore trims the build invite,
The helper script builds, then shows how to run,
Docs in English und Deutsch—Docker done! 🚀

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the two main additions: Docker support and German localization, matching the primary objectives of the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description thoroughly documents Docker integration, German localization, and documentation improvements—all of which directly align with the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment thread docker/Dockerfile
Comment thread docker/docker-setup.sh Outdated
Comment thread docker/Dockerfile
Comment thread README_de.md Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
docker/Dockerfile (2)

28-28: 💤 Low value

Wildcard JAR pattern may be fragile.

Using brief-*-all.jar assumes a single JAR will match. If the shadowJar task produces multiple artifacts or the naming changes, this step could fail or copy the wrong file.

Consider using the exact artifact name if it's predictable, or add a comment documenting the expected pattern. This would make the build more explicit and easier to debug.

🤖 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 `@docker/Dockerfile` at line 28, The COPY step uses a fragile wildcard
"brief-*-all.jar" which can match multiple or unexpected artifacts; update the
Dockerfile COPY instruction to reference the exact artifact name produced by the
build (the shadow/jar task output) or explicitly document the expected filename
pattern, and if the artifact name can vary derive or set a deterministic output
name from the build (e.g., shadowJar or assemble configuration) so COPY
--from=builder /app/build/libs/<exact-artifact-name>.jar /app/brief.jar will
always select the correct JAR.

14-14: 💤 Low value

Consider clarifying or removing the || true fallback.

The || true ensures the build continues even if dependency pre-downloading fails. While this won't break the build (dependencies will be fetched again during shadowJar), it could mask configuration issues or network problems during layer caching.

If intentional, a comment explaining why failures are acceptable would help future maintainers. If not needed, removing || true would surface issues earlier.

🤖 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 `@docker/Dockerfile` at line 14, The RUN step in the Dockerfile currently
suppresses failures with "|| true" for "./gradlew dependencies --no-daemon",
which can mask real configuration or network errors; update this by either
removing "|| true" so the build fails fast and surfaces dependency-download
issues, or if the fallback is intentional (to keep cacheable layers when
offline), replace the silent suppression with an explicit explanatory comment
next to the RUN line clarifying why failures are acceptable and under what
conditions (e.g., network flakiness or reliance on later shadowJar fetch); edit
the Dockerfile RUN "./gradlew dependencies --no-daemon" line and either remove
the boolean OR fallback or add the comment to document the intent.
docker/docker-setup.sh (1)

13-19: 💤 Low value

Documentation consistency: script output differs from README instructions.

The script's success message (lines 16 and 19) shows two different ways to run the container:

  • Line 16: mounting config directory (matches README.md ✓)
  • Line 19: passing OPENAI_API_KEY via -e flag (differs from README.md's --env-file approach)

While the -e approach is valid, the README.md consistently documents using --env-file ~/.config/brief/.env. Consider updating line 19 to match the README for consistency, or keep both examples but add a note explaining the two options.

Also, the script is written in German while the primary codebase documentation is in English. Since this PR adds German localization, this might be intentional—just noting it in case you'd like to provide an English version or add comments explaining the bilingual approach.

🤖 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 `@docker/docker-setup.sh` around lines 13 - 19, Update the second example echo
that currently shows "docker run -it --rm -e OPENAI_API_KEY=\$OPENAI_API_KEY
brief" to match README's usage by replacing it with the --env-file variant
("docker run -it --rm --env-file ~/.config/brief/.env brief"), or alternatively
include both examples and a short parenthetical note explaining the difference;
also add a brief comment in the script header indicating that this file is a
German-localized message to clarify bilingual intent.
🤖 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 `@docker/Dockerfile`:
- Around line 1-34: The Dockerfile currently runs the container as root; create
a non-root user and set USER so the image runs unprivileged: add steps after
WORKDIR /app to create a dedicated user (e.g., brief), set HOME (e.g.,
/home/brief), chown /app and any config directories to that user, and switch to
that user before ENTRYPOINT; ensure the COPY --from=builder artifacts and any
runtime-created config paths are writable by that user, update ENV or
application references from /root/.config/brief to the new home-based path
(/home/brief/.config/brief), and update docs/tests accordingly so the app can
read/write config under the non-root user's home.

---

Nitpick comments:
In `@docker/docker-setup.sh`:
- Around line 13-19: Update the second example echo that currently shows "docker
run -it --rm -e OPENAI_API_KEY=\$OPENAI_API_KEY brief" to match README's usage
by replacing it with the --env-file variant ("docker run -it --rm --env-file
~/.config/brief/.env brief"), or alternatively include both examples and a short
parenthetical note explaining the difference; also add a brief comment in the
script header indicating that this file is a German-localized message to clarify
bilingual intent.

In `@docker/Dockerfile`:
- Line 28: The COPY step uses a fragile wildcard "brief-*-all.jar" which can
match multiple or unexpected artifacts; update the Dockerfile COPY instruction
to reference the exact artifact name produced by the build (the shadow/jar task
output) or explicitly document the expected filename pattern, and if the
artifact name can vary derive or set a deterministic output name from the build
(e.g., shadowJar or assemble configuration) so COPY --from=builder
/app/build/libs/<exact-artifact-name>.jar /app/brief.jar will always select the
correct JAR.
- Line 14: The RUN step in the Dockerfile currently suppresses failures with "||
true" for "./gradlew dependencies --no-daemon", which can mask real
configuration or network errors; update this by either removing "|| true" so the
build fails fast and surfaces dependency-download issues, or if the fallback is
intentional (to keep cacheable layers when offline), replace the silent
suppression with an explicit explanatory comment next to the RUN line clarifying
why failures are acceptable and under what conditions (e.g., network flakiness
or reliance on later shadowJar fetch); edit the Dockerfile RUN "./gradlew
dependencies --no-daemon" line and either remove the boolean OR fallback or add
the comment to document the intent.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2b17064e-4f69-460c-b36d-f0a825e0f207

📥 Commits

Reviewing files that changed from the base of the PR and between a7eac7f and 09e4c99.

📒 Files selected for processing (7)
  • .dockerignore
  • README.md
  • README_de.md
  • docker/Dockerfile
  • docker/README.md
  • docker/README_de.md
  • docker/docker-setup.sh

Comment thread docker/Dockerfile
rentasad and others added 3 commits May 13, 2026 21:13
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
- Updated Dockerfile to create a dedicated 'brief' user and set it as the default USER.
- Adjusted container-side configuration paths from '/root/.config/brief' to '/home/brief/.config/brief'.
- Updated README.md, README_de.md, and docker/ READMEs with the new volume mount instructions.
- Synchronized example commands in docker-setup.sh with the unprivileged user's home directory.
- Addresses Trivy DS-0002 (Least Privilege principle).

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 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 `@docker/README_de.md`:
- Line 1: Change the German README header string "# Brief Docker Setup" to a
German heading for consistency by replacing it with "# Brief Docker‑Einrichtung"
(locate the header line "# Brief Docker Setup" in docker/README_de.md and update
the text accordingly).

In `@README_de.md`:
- Around line 53-57: Die Anleitung in README_de.md schreibt derzeit vor, den
API-Key per echo in die Shell zu schreiben (die Zeile mit echo
"OPENAI_API_KEY=dein_key_hier" > ~/.config/brief/.env), was die Eingabe in der
Shell-History hinterlässt; bitte diese Zeile ersetzen durch eine sicherere
Variante: erst mkdir -p ~/.config/brief und dann die Datei mit dem Nutzereditor
öffnen (${EDITOR:-vi} ~/.config/brief/.env) und den Eintrag
OPENAI_API_KEY=dein_key_hier dort speichern; passe die Beispielanweisungen und
die erklärende Beschreibung entsprechend an, damit Nutzer wissen, die Datei im
Editor zu befüllen und zu speichern statt den Key per echo einzufügen.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b400cddb-2b80-4679-8314-53394482b75d

📥 Commits

Reviewing files that changed from the base of the PR and between 5eb59df and d7d91d5.

📒 Files selected for processing (6)
  • README.md
  • README_de.md
  • docker/Dockerfile
  • docker/README.md
  • docker/README_de.md
  • docker/docker-setup.sh
✅ Files skipped from review due to trivial changes (2)
  • docker/README.md
  • README.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • docker/Dockerfile
  • docker/docker-setup.sh

Comment thread docker/README_de.md
Comment thread README_de.md Outdated
- Replaced insecure 'echo' redirection for API keys with interactive editor usage.
- Prevents sensitive credentials from being leaked into shell history.
- Updated both README.md and README_de.md for consistency.
- Standardized directory creation with 'mkdir -p' before editing.
@rentasad

rentasad commented May 16, 2026

Copy link
Copy Markdown
Author

I tried the app in a Docker environment, but it couldn't communicate with the OpenAI API. I don't get any response to any input. I can't say for sure that the problem is related to the Docker environment—I still need to try the app with a regular installation.

UPDATE 20.05.2026

it works - I forgot to set a model in .env

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant