Skip to content

Add Container build#13

Merged
kdvalin merged 5 commits intomainfrom
container
Mar 27, 2026
Merged

Add Container build#13
kdvalin merged 5 commits intomainfrom
container

Conversation

@kdvalin
Copy link
Copy Markdown
Member

@kdvalin kdvalin commented Mar 26, 2026

Adds a container build process, with a github workflow to do it automatically, and documentation outlining how to use the container.

@kdvalin kdvalin requested a review from grdumas March 26, 2026 15:17
@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

Add container build and deployment automation

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Adds containerized deployment with Containerfile for easy distribution
• Implements GitHub Actions workflow for automated container builds and pushes
• Publishes images to quay.io with multi-platform support (amd64, arm64)
• Documents container usage with configuration and runtime examples
Diagram
flowchart LR
  A["Source Code"] -- "Containerfile" --> B["Container Image"]
  B -- "GitHub Actions" --> C["quay.io Registry"]
  D["README"] -- "Usage Docs" --> E["Users"]
  C -- "Pull Image" --> E
Loading

Grey Divider

File Changes

1. Containerfile ⚙️ Configuration changes +11/-0

Container image definition for chronicler

• Creates container image based on Fedora Python 3.13 minimal image
• Sets CHRONICLER_CONFIG environment variable to /config/config.yaml
• Installs chronicler package via pip during build
• Defines entrypoint to run chronicler.run_postprocessing module

Containerfile


2. .github/workflows/containerize.yaml ⚙️ Configuration changes +39/-0

GitHub Actions workflow for container builds

• Triggers on push to main and pull requests
• Authenticates with Quay.io registry using secrets
• Builds and pushes container images with latest and SHA tags
• Supports multi-platform builds for linux/amd64 and linux/arm64
• Uses GitHub Actions cache for faster builds

.github/workflows/containerize.yaml


3. README.md 📝 Documentation +61/-0

Container usage documentation and examples

• Adds new "Running with a Container" section with setup instructions
• Provides examples for both Podman and Docker with volume mounts
• Documents config file preparation and placement
• Shows examples for OpenSearch export and JSON output modes
• Explains SELinux :z flag usage and environment variable override

README.md


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review Bot commented Mar 26, 2026

Code Review by Qodo

🐞 Bugs (4) 📘 Rule violations (0) 📎 Requirement gaps (0) 📐 Spec deviations (0)

Grey Divider


Action required

1. Broken ENTRYPOINT exec form🐞 Bug ✓ Correctness
Description
Containerfile sets ENTRYPOINT using a bracketed exec-form array but with single quotes, which is not
valid JSON for Dockerfile exec-form and can cause the container build to fail during Dockerfile
parsing. This prevents the published image from being runnable at all.
Code

Containerfile[11]

+ENTRYPOINT ['python3', '-m', 'chronicler.run_postprocessing']
Evidence
The Containerfile uses the bracketed (JSON) exec-form for ENTRYPOINT, but the elements are
single-quoted rather than JSON strings, making the instruction invalid for Dockerfile/BuildKit JSON
parsing.

Containerfile[1-11]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`ENTRYPOINT ['python3', '-m', 'chronicler.run_postprocessing']` uses a JSON/exec-form-looking array but with single quotes, which is not valid JSON and may fail Dockerfile parsing/build.

### Issue Context
This image is intended to run `python3 -m chronicler.run_postprocessing` and accept CLI args appended from `docker/podman run`.

### Fix Focus Areas
- Containerfile[9-11]

### Suggested change
Replace with a proper JSON exec-form:
```dockerfile
ENTRYPOINT ["python3", "-m", "chronicler.run_postprocessing"]
```
(Optionally add a `CMD []` if you want an explicit default.)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Multi-arch build reliability risk 🐞 Bug ⛯ Reliability
Description
The workflow builds for both linux/amd64 and linux/arm64, but does not explicitly set up binfmt/QEMU
emulation, so the arm64 build can fail when executing RUN python3 -m pip install . during the
image build. This can break CI on PRs and block publishing on pushes to main.
Code

.github/workflows/containerize.yaml[R26-39]

+      - name: Setup Buildx
+        uses: docker/setup-buildx-action@v3
+
+      - name: Build Container
+        uses: docker/build-push-action@v6
+        with:
+          push: ${{ github.event_name == 'push' }}
+          tags: | 
+            quay.io/zathras/chronicler:latest
+            quay.io/zathras/chronicler:${{ github.sha }}
+          cache-from: type=gha
+          cache-to: type=gha,mode=max
+          platforms: linux/amd64,linux/arm64
+          file: Containerfile
Evidence
The workflow requests multi-platform builds (amd64+arm64). The Containerfile includes a RUN step
that must execute in the target architecture image, which commonly requires binfmt/QEMU support on
the runner to succeed for non-native architectures.

.github/workflows/containerize.yaml[26-39]
Containerfile[5-10]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The workflow attempts a multi-arch build (`linux/amd64,linux/arm64`) but does not explicitly configure binfmt/QEMU emulation; arm64 builds may fail when running `RUN` steps.

### Issue Context
The Containerfile runs `python3 -m pip install .` at build time, which requires executing inside the target image architecture.

### Fix Focus Areas
- .github/workflows/containerize.yaml[15-39]

### Suggested fixes (pick one)
1) Add QEMU setup step before build:
```yaml
- name: Setup QEMU
 uses: docker/setup-qemu-action@v3
```
2) If arm64 is not required yet, temporarily restrict platforms to `linux/amd64` until verified.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Runs container as root 🐞 Bug ⛨ Security
Description
The Containerfile explicitly sets USER 0 and never drops privileges, so the app runs as root and
will create root-owned files on mounted volumes (e.g., --output-json /output), causing host
permission problems and unnecessary security exposure. This is especially problematic given the
README instructs mounting host directories for results/output.
Code

Containerfile[5]

+USER 0
Evidence
The image is configured to run as UID 0. The README shows mounting host directories for results and
output, which means any files written by the container will be owned by root on the host (and
running as root increases blast radius if compromised).

Containerfile[3-11]
README.md[74-102]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The container runs as root (`USER 0`) which increases security risk and can create root-owned files on mounted volumes.

### Issue Context
README examples mount `/results` and `/output` from the host; when `--output-json` is used, the container may write files into `/output`.

### Fix Focus Areas
- Containerfile[3-11]

### Suggested change
Create an unprivileged user and run the entrypoint as that user, e.g.:
```dockerfile
RUN useradd -r -u 10001 -g 0 chronicler \
&& mkdir -p /chronicler \
&& chown -R 10001:0 /chronicler
USER 10001
```
Adjust ownership/permissions for any directories the app needs to write to (or document using `--user` at runtime).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Build context may include secrets 🐞 Bug ⛨ Security
Description
COPY . /chronicler copies the entire build context into the image; if config/export_config.yml
exists locally (gitignored but intended to contain real credentials), it can be baked into the image
layers during local builds. This increases the risk of inadvertently publishing credentials in a
custom-built image.
Code

Containerfile[7]

+COPY . /chronicler
Evidence
The repository explicitly gitignores config/export_config.yml as a credentials file, and the
config documentation states real credentials live there. Using COPY . will include any such file
present in the build context unless excluded (e.g., via .dockerignore or a narrower COPY set).

Containerfile[6-8]
.gitignore[39-41]
config/README.md[42-57]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The Containerfile uses `COPY .` which can accidentally include gitignored credential files (e.g., `config/export_config.yml`) into the image during local builds.

### Issue Context
The repo documents that `export_config.yml` contains real credentials and is gitignored.

### Fix Focus Areas
- Containerfile[6-9]

### Suggested change
1) Add a `.dockerignore` excluding at least:
- `config/export_config.yml`
- `src/chronicler/config/export_config.yml`
- results/output directories if applicable
- `.git`
2) Consider narrowing what you copy (better layer caching too), e.g. copy only `pyproject.toml`, `src/`, and required config templates before `pip install .`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Advisory comments

5. Unpinned base image tag 🐞 Bug ⛯ Reliability
Description
The Containerfile uses a floating :latest base image tag, making builds non-reproducible and
susceptible to breaking changes or unexpected CVE churn between builds. This can cause the same git
SHA to produce different container images over time.
Code

Containerfile[1]

+FROM quay.io/fedora/python-313-minimal:latest
Evidence
The base image reference explicitly uses :latest, which is a mutable tag and therefore not pinned
to a specific digest/version.

Containerfile[1-2]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
Using a mutable base image tag (`:latest`) makes container builds non-reproducible.

### Issue Context
CI will rebuild this image on future pushes; a changed base can alter behavior without code changes.

### Fix Focus Areas
- Containerfile[1-2]

### Suggested change
Pin to a specific version tag or digest, e.g.:
```dockerfile
FROM quay.io/fedora/python-313-minimal@sha256:<digest>
```
(or a non-latest version tag if digests are not desired).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment thread Containerfile Outdated
@grdumas
Copy link
Copy Markdown
Collaborator

grdumas commented Mar 26, 2026

Perhaps being paranoid here, but would adding a .dockerignore help mitigate possible risks of accidentally baking in OpenSearch credentials? Reading up on Docker/Podman it looks like it doesn't consult the .gitignore when running COPY . /chronicler. Excluding other crud in the project (.git, .venv, etc) might also help with build size/speed.

Copy link
Copy Markdown
Collaborator

@grdumas grdumas left a comment

Choose a reason for hiding this comment

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

LGTM

@grdumas grdumas added the enhancement New feature or request label Mar 26, 2026
@kdvalin kdvalin merged commit b64fa0e into main Mar 27, 2026
1 check passed
@kdvalin kdvalin deleted the container branch March 27, 2026 13:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants