Skip to content

Conversation

@skinny
Copy link

@skinny skinny commented Apr 1, 2024

My use case also uses the timezone information (available on ipinfo.io) but was not yet available in this self hosted soltution. This PR downloads the City geo database and uses that to return a "best guess" timezone for the users IP.

Summary by CodeRabbit

  • New Features

    • Timezone data is now returned in default API responses alongside IP address, country, and AS information
    • Introduced a dedicated /timezone endpoint for retrieving timezone information independently
  • Documentation

    • Updated API documentation to reflect new timezone endpoints and response fields

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Apr 1, 2024

Warning

Rate limit exceeded

@nb-rubenoost has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 1 minutes and 33 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 72a67bc and 56b5625.

📒 Files selected for processing (1)
  • .github/workflows/build.yml
📝 Walkthrough

Walkthrough

The changes introduce timezone detection capabilities to the IP information service. GeoLite2-City database support is added to the Docker build process, nginx is configured to map IP addresses to timezones using geoip2, a new /timezone endpoint is exposed with timezone data included in JSON responses, and Kubernetes deployment manifests with Docker build automation are introduced.

Changes

Cohort / File(s) Summary
Core Feature - Timezone Detection
nginx/conf.d/geoip2.conf, nginx/conf.d/ipinfo.conf, Dockerfile
Adds GeoLite2-City database download/verification in Docker build; configures nginx geoip2 block with time_zone mapping for remote addresses; introduces new /timezone endpoint and includes timezone field in /json response payload
Infrastructure - Kubernetes Manifests
k8s/deployment.yaml, k8s/ingress.yaml, k8s/service.yaml
Adds eva-whoami Kubernetes Deployment (2 replicas, port 8080), Ingress with TLS/cert-manager for whoami.on-eva.io, and LoadBalancer Service with Azure annotations
Documentation & CI/CD
README.md, .github/workflows/build.yml
Updates README with timezone examples and new endpoint documentation; introduces GitHub Actions build workflow with Docker Buildx multi-platform (linux/amd64, linux/arm64) image building and registry authentication

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant nginx as nginx + geoip2
    participant GeoLite2 as GeoLite2-City DB
    participant Response

    Client->>nginx: GET /json (from IP: 192.0.2.1)
    nginx->>GeoLite2: Lookup IP address
    GeoLite2-->>nginx: Return location data (city, timezone)
    nginx->>nginx: Map to timezone ($ip_time_zone)
    nginx-->>Response: JSON {ip, country, as, timezone}
    Response-->>Client: Response with timezone field
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Added timezone information to the available fields' accurately reflects the primary changes in the pull request: adding timezone data support throughout the stack (GeoLite2-City database, nginx configuration, API endpoints, Kubernetes infrastructure, and CI/CD). The title correctly identifies the main feature being implemented.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@skinny skinny changed the title feat: add timezone information to the available fields Added timezone information to the available fields Apr 1, 2024
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Review Status

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between f6845af and ec894c4.
Files selected for processing (3)
  • Dockerfile (1 hunks)
  • nginx/conf.d/geoip2.conf (1 hunks)
  • nginx/conf.d/ipinfo.conf (2 hunks)
Additional Context Used
Additional comments not posted (3)
nginx/conf.d/geoip2.conf (1)

15-18: The addition of the GeoLite2-City.mmdb database configuration for retrieving timezone information is correctly implemented and aligns with the PR's objectives. However, for maintainability, consider externalizing configurable values such as the database path and auto-reload interval into a separate configuration file or environment variables. This approach can simplify future updates or changes to these settings.

nginx/conf.d/ipinfo.conf (2)

53-55: The addition of the /timezone endpoint is correctly implemented and serves the PR's objective of making timezone information accessible. Well done!


64-64: The modification to the /json endpoint to include the timezone field is correctly implemented and aligns with the PR's objectives. This enhances the endpoint's utility by providing additional valuable information.

Comment on lines +22 to +26
RUN wget "${MAXMIND_BASE_URL}edition_id=GeoLite2-City&suffix=tar.gz" -O GeoLite2-City.tar.gz
RUN wget "${MAXMIND_BASE_URL}edition_id=GeoLite2-City&suffix=tar.gz.sha256" -O GeoLite2-City.tar.gz.sha256
RUN sed 's/GeoLite2-City_[0-9]*.tar.gz/GeoLite2-City.tar.gz/g' -i GeoLite2-City.tar.gz.sha256
RUN sha256sum -c GeoLite2-City.tar.gz.sha256
RUN tar xvf GeoLite2-City.tar.gz --strip 1
Copy link

Choose a reason for hiding this comment

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

The steps for handling the GeoLite2-City database are correctly implemented, ensuring secure download, verification, and extraction. To optimize the Dockerfile and reduce the number of layers, consider combining these RUN commands into a single RUN command using && to chain the commands together. This can improve the build performance and reduce the image size.

-RUN wget "${MAXMIND_BASE_URL}edition_id=GeoLite2-City&suffix=tar.gz" -O GeoLite2-City.tar.gz
-RUN wget "${MAXMIND_BASE_URL}edition_id=GeoLite2-City&suffix=tar.gz.sha256" -O GeoLite2-City.tar.gz.sha256
-RUN sed 's/GeoLite2-City_[0-9]*.tar.gz/GeoLite2-City.tar.gz/g' -i GeoLite2-City.tar.gz.sha256
-RUN sha256sum -c GeoLite2-City.tar.gz.sha256
-RUN tar xvf GeoLite2-City.tar.gz --strip 1
+RUN wget "${MAXMIND_BASE_URL}edition_id=GeoLite2-City&suffix=tar.gz" -O GeoLite2-City.tar.gz && \
+    wget "${MAXMIND_BASE_URL}edition_id=GeoLite2-City&suffix=tar.gz.sha256" -O GeoLite2-City.tar.gz.sha256 && \
+    sed 's/GeoLite2-City_[0-9]*.tar.gz/GeoLite2-City.tar.gz/g' -i GeoLite2-City.tar.gz.sha256 && \
+    sha256sum -c GeoLite2-City.tar.gz.sha256 && \
+    tar xvf GeoLite2-City.tar.gz --strip 1

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.

Suggested change
RUN wget "${MAXMIND_BASE_URL}edition_id=GeoLite2-City&suffix=tar.gz" -O GeoLite2-City.tar.gz
RUN wget "${MAXMIND_BASE_URL}edition_id=GeoLite2-City&suffix=tar.gz.sha256" -O GeoLite2-City.tar.gz.sha256
RUN sed 's/GeoLite2-City_[0-9]*.tar.gz/GeoLite2-City.tar.gz/g' -i GeoLite2-City.tar.gz.sha256
RUN sha256sum -c GeoLite2-City.tar.gz.sha256
RUN tar xvf GeoLite2-City.tar.gz --strip 1
RUN wget "${MAXMIND_BASE_URL}edition_id=GeoLite2-City&suffix=tar.gz" -O GeoLite2-City.tar.gz && \
wget "${MAXMIND_BASE_URL}edition_id=GeoLite2-City&suffix=tar.gz.sha256" -O GeoLite2-City.tar.gz.sha256 && \
sed 's/GeoLite2-City_[0-9]*.tar.gz/GeoLite2-City.tar.gz/g' -i GeoLite2-City.tar.gz.sha256 && \
sha256sum -c GeoLite2-City.tar.gz.sha256 && \
tar xvf GeoLite2-City.tar.gz --strip 1

Copy link
Owner

@PeterDaveHello PeterDaveHello left a comment

Choose a reason for hiding this comment

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

Cool, thanks for your contribution, @skinny. Please allow me to do some tests, and then we can merge it!

}

geoip2 /usr/share/GeoIP/GeoLite2-City.mmdb {
auto_reload 1d; # Automatically reload the database daily
Copy link
Owner

Choose a reason for hiding this comment

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

We don't need those additional comments just for the city database, so let's maintain consistency here.

auto_reload 1d; # Automatically reload the database daily
$ip_time_zone source=$remote_addr location time_zone; # Retrieve the time zone
}

Copy link
Owner

Choose a reason for hiding this comment

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

This additional newline should also been removed.

Copy link
Owner

@PeterDaveHello PeterDaveHello left a comment

Choose a reason for hiding this comment

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

We should add some documentation about the timezone feature in the README file, allowing users to understand how to utilize this new functionality.

e.g.

$ curl https://ipinfo.tw/timezone
Asia/Taipei

{"ip":"3.115.123.234","country_code":"JP","country_name":"Japan","timezone":"Asia/Tokyo","asn":"16509","as_desc":"Amazon.com, Inc.","user_agent":"curl/7.58.0"}

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Review Status

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between ec894c4 and 219b674.
Files selected for processing (1)
  • nginx/conf.d/geoip2.conf (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • nginx/conf.d/geoip2.conf

@skinny
Copy link
Author

skinny commented Apr 2, 2024

@PeterDaveHello removed the comments, newlines and added a bit of documentation on the timezone field

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Review Status

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 219b674 and 6ebdb16.
Files selected for processing (1)
  • README.md (3 hunks)
Additional comments not posted (5)
README.md (5)

58-58: The server's response now includes timezone information, which is a significant enhancement. It's crucial to ensure that this new feature is well-documented and that examples are provided to guide users on how to use it effectively.


63-63: The JSON response example is clear and informative, showing the new timezone information. This addition enhances the usability of the service for clients that require timezone data.


78-78: The addition of a /timezone endpoint is a valuable feature for users specifically interested in timezone information. It's important to ensure that this endpoint is tested thoroughly to maintain the reliability of the service.


101-103: Providing an example of the /timezone endpoint usage is helpful for users. It might be beneficial to include more examples or scenarios where this endpoint could be particularly useful, enhancing the documentation's comprehensiveness.


55-66: > 📝 NOTE

This review was outside the diff hunks, and no overlapping diff hunk was found. Original lines [134-134]

When instructing users to build their own image with a docker build command, it's mentioned to use a MAXMIND_LICENSE_KEY. It would be helpful to emphasize the importance of keeping this key secure and not exposing it in publicly accessible places, such as GitHub repositories.

Comment on lines 55 to 66
- `wget -qO- https://ipinfo.tw`
- `curl https://ipinfo.tw`

Without any specified URI, the server will return IP address, country, AS, and user agent.
Without any specified URI, the server will return IP address, country, timezone, AS, and user agent.

If you prefer to receive a machine-readable result, use path `/json` (without trailing slash), e.g. `https://ipinfo.tw/json`, the result will look like:

```json
{"ip":"3.115.123.234","country_code":"JP","country_name":"Japan","asn":"16509","as_desc":"Amazon.com, Inc.","user_agent":"curl/7.58.0"}
{"ip":"3.115.123.234","country_code":"JP","country_name":"Japan","timezone":"Asia/Tokyo","asn":"16509","as_desc":"Amazon.com, Inc.","user_agent":"curl/7.58.0"}
```

#### Endpoints
Copy link

Choose a reason for hiding this comment

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

📝 NOTE
This review was outside the diff hunks, and no overlapping diff hunk was found. Original lines [29-29]

The description of the demo setup mentions "an reverse proxy" which should be corrected to "a reverse proxy" for grammatical accuracy.

- this demo is behind an reverse proxy with https enabled
+ this demo is behind a reverse proxy with https enabled

📝 NOTE
This review was outside the diff hunks, and no overlapping diff hunk was found. Original lines [29-29]

There's a minor typographical error with "http traffic" which should be capitalized as "HTTP traffic" for consistency with standard terminology.

- http traffic will be redirected to use https
+ HTTP traffic will be redirected to use https

📝 NOTE
This review was outside the diff hunks, and no overlapping diff hunk was found. Original lines [49-49]

The phrase "pass the it to the container" seems to contain an extra word. It should be corrected for clarity.

- set up an `X-Real-IP` header and pass the it to the container
+ set up an `X-Real-IP` header and pass it to the container

@PeterDaveHello PeterDaveHello self-requested a review April 2, 2024 17:19
README.md Outdated
```

If you want to put this container behind reverse proxy, set up an `X-Real-IP` header and pass the it to the container, so that it can use the header as the IP of the client.
If you want to put this container behind reverse proxy, set up an `X-Real-IP` header and pass it to the container, so that it can use the header as the IP of the client.
Copy link
Owner

Choose a reason for hiding this comment

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

This is not related to the changes in the PR, we should leave it alone.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot reviewed 1 out of 4 changed files in this pull request and generated no suggestions.

Files not reviewed (3)
  • Dockerfile: Language not supported
  • nginx/conf.d/geoip2.conf: Language not supported
  • nginx/conf.d/ipinfo.conf: Language not supported

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
nginx/conf.d/ipinfo.conf (1)

66-69: Consider adding City database build epoch for completeness.

The /build_epoch endpoint currently reports freshness for Country and ASN databases but omits the newly added City database. Adding $ip_city_build_epoch would provide users visibility into the City database freshness, maintaining consistency with the existing pattern.

📅 Proposed addition for City build epoch

First, define the variable in nginx/conf.d/geoip2.conf by adding this line to the City geoip2 block:

 geoip2 /usr/share/GeoIP/GeoLite2-City.mmdb {
     auto_reload 1d;
     $ip_time_zone source=$remote_addr location time_zone;
+    $ip_city_build_epoch metadata build_epoch;
 }

Then update the endpoint response:

     location = /build_epoch {
         default_type application/json;
-        return 200 "{\"GeoLite2-Country\":\"$ip_country_build_epoch\",\"GeoLite2-ASN\":\"$ip_as_build_epoch\"}\n";
+        return 200 "{\"GeoLite2-Country\":\"$ip_country_build_epoch\",\"GeoLite2-ASN\":\"$ip_as_build_epoch\",\"GeoLite2-City\":\"$ip_city_build_epoch\"}\n";
     }
Dockerfile (1)

22-26: City database download follows established pattern.

The implementation correctly mirrors the ASN and Country database handling with proper checksum verification. Note that the City database is significantly larger (~70MB compressed vs ~6-8MB for Country/ASN), which will increase the container image size and runtime memory footprint. This is expected for city-level geolocation data.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6ebdb16 and 4dfc6a9.

📒 Files selected for processing (4)
  • Dockerfile
  • README.md
  • nginx/conf.d/geoip2.conf
  • nginx/conf.d/ipinfo.conf
🚧 Files skipped from review as they are similar to previous changes (1)
  • README.md
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
Repo: PeterDaveHello/ipinfo.tw PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-25T10:20:08.033Z
Learning: Applies to nginx/conf.d/geoip2.conf : Load GeoLite2-Country and GeoLite2-ASN databases and define GeoIP2 variables ($ip_country_code, $ip_country_name, $ip_asn, $ip_aso), including build_epoch values, in nginx/conf.d/geoip2.conf
Learnt from: CR
Repo: PeterDaveHello/ipinfo.tw PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-25T10:20:08.033Z
Learning: Applies to nginx/conf.d/{geoip2.conf,ipinfo.conf} : When adding new endpoints: define needed variables in geoip2.conf or compose existing ones in ipinfo.conf, then add the location block with return in ipinfo.conf
Learnt from: CR
Repo: PeterDaveHello/ipinfo.tw PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-25T10:20:08.033Z
Learning: Applies to nginx/conf.d/ipinfo.conf : Define and maintain all endpoint location blocks (/, /json, /ip, and field endpoints) in nginx/conf.d/ipinfo.conf using return to emit text or JSON
📚 Learning: 2025-10-25T10:20:08.033Z
Learnt from: CR
Repo: PeterDaveHello/ipinfo.tw PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-25T10:20:08.033Z
Learning: Applies to nginx/conf.d/geoip2.conf : Load GeoLite2-Country and GeoLite2-ASN databases and define GeoIP2 variables ($ip_country_code, $ip_country_name, $ip_asn, $ip_aso), including build_epoch values, in nginx/conf.d/geoip2.conf

Applied to files:

  • Dockerfile
  • nginx/conf.d/geoip2.conf
  • nginx/conf.d/ipinfo.conf
📚 Learning: 2025-10-25T10:20:08.033Z
Learnt from: CR
Repo: PeterDaveHello/ipinfo.tw PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-25T10:20:08.033Z
Learning: Applies to nginx/conf.d/{geoip2.conf,ipinfo.conf} : When adding new endpoints: define needed variables in geoip2.conf or compose existing ones in ipinfo.conf, then add the location block with return in ipinfo.conf

Applied to files:

  • Dockerfile
  • nginx/conf.d/geoip2.conf
  • nginx/conf.d/ipinfo.conf
📚 Learning: 2025-10-25T10:20:08.033Z
Learnt from: CR
Repo: PeterDaveHello/ipinfo.tw PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-25T10:20:08.033Z
Learning: Applies to nginx/conf.d/ipinfo.conf : Define and maintain all endpoint location blocks (/, /json, /ip, and field endpoints) in nginx/conf.d/ipinfo.conf using return to emit text or JSON

Applied to files:

  • nginx/conf.d/geoip2.conf
  • nginx/conf.d/ipinfo.conf
📚 Learning: 2025-10-25T10:20:08.033Z
Learnt from: CR
Repo: PeterDaveHello/ipinfo.tw PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-25T10:20:08.033Z
Learning: Applies to nginx/nginx.conf : Place global nginx directives (worker counts, events, HTTP defaults) in nginx/nginx.conf

Applied to files:

  • nginx/conf.d/geoip2.conf
🔇 Additional comments (3)
nginx/conf.d/geoip2.conf (1)

15-18: LGTM! Consistent with existing database blocks.

The City database configuration follows the same pattern as Country and ASN blocks, maintaining consistency across the file. Based on learnings, this correctly defines the GeoIP2 variable for use in ipinfo.conf.

nginx/conf.d/ipinfo.conf (2)

64-64: JSON response correctly includes timezone field.

The timezone field is properly integrated into the JSON response. Same consideration about empty values applies here: when $ip_time_zone is empty, the response will contain "timezone":"", which is valid JSON.


53-55: Implementation is correct and consistent.

The /timezone endpoint properly uses the $ip_time_zone variable defined in geoip2.conf and follows the established pattern used by all other single-value endpoints. When timezone data is unavailable, the variable returns empty (standard geoip2 module behavior), consistent with how all other endpoints handle missing GeoIP2 data.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In @k8s/deployment.yaml:
- Line 32: The deployment currently has an empty resources block ("resources:
{}"); replace it with explicit resource requests and limits by adding a
resources section containing requests (cpu and memory) and limits (cpu and
memory) for the container (e.g., under the container spec where "resources"
appears), choosing appropriate values for your app (start with conservative
defaults like requests: cpu: "100m", memory: "128Mi" and limits: cpu: "500m",
memory: "256Mi" and adjust based on real usage); ensure the new resources block
is added to the same container spec that originally had "resources: {}".

In @k8s/ingress.yaml:
- Line 7: The manifest still uses the deprecated annotation key
"kubernetes.io/ingress.class: nginx" while also specifying the newer field
ingressClassName: nginx; remove the deprecated annotation entry so the Ingress
relies solely on the ingressClassName field. Locate the Ingress metadata
annotations block and delete the "kubernetes.io/ingress.class" annotation,
leaving ingressClassName: nginx intact to avoid duplication and deprecation
warnings.
🧹 Nitpick comments (3)
k8s/deployment.yaml (1)

25-34: Consider adding health probes.

The deployment lacks liveness and readiness probes, which are essential for Kubernetes to manage the application lifecycle properly and ensure zero-downtime deployments.

🏥 Proposed health probe configuration
       containers:
       - image: cratecache.azurecr.io/new-black/eva-whoami
         imagePullPolicy: Always
         name: whoami
         ports:
         - containerPort: 8080
           protocol: TCP
+        livenessProbe:
+          httpGet:
+            path: /
+            port: 8080
+          initialDelaySeconds: 30
+          periodSeconds: 10
+        readinessProbe:
+          httpGet:
+            path: /
+            port: 8080
+          initialDelaySeconds: 5
+          periodSeconds: 5
         resources: {}

Adjust paths and timings based on the actual application endpoints and startup time.

k8s/service.yaml (1)

15-19: Consider removing static nodePort assignment.

The static nodePort (31514) can cause port conflicts when deploying to multiple clusters or when other services request the same port. Kubernetes can allocate nodePorts automatically from its configured range.

🔄 Proposed change
   ports:
   - name: whoami
-    nodePort: 31514
     port: 8080
     protocol: TCP
     targetPort: 8080

Only specify nodePort if external systems have hard dependencies on this specific port.

k8s/ingress.yaml (1)

24-25: Consider using explicit pathType.

ImplementationSpecific delegates path matching to the ingress controller, which can behave inconsistently across implementations. Prefix is more explicit and portable for root path routing.

📝 Proposed change
         path: /
-        pathType: ImplementationSpecific
+        pathType: Prefix
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4dfc6a9 and ba579be.

📒 Files selected for processing (3)
  • k8s/deployment.yaml
  • k8s/ingress.yaml
  • k8s/service.yaml
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: PeterDaveHello/ipinfo.tw PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-25T10:20:08.033Z
Learning: Applies to nginx/conf.d/geoip2.conf : Load GeoLite2-Country and GeoLite2-ASN databases and define GeoIP2 variables ($ip_country_code, $ip_country_name, $ip_asn, $ip_aso), including build_epoch values, in nginx/conf.d/geoip2.conf
Learnt from: CR
Repo: PeterDaveHello/ipinfo.tw PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-25T10:20:08.033Z
Learning: Applies to nginx/conf.d/ipinfo.conf : Define and maintain all endpoint location blocks (/, /json, /ip, and field endpoints) in nginx/conf.d/ipinfo.conf using return to emit text or JSON
Learnt from: CR
Repo: PeterDaveHello/ipinfo.tw PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-25T10:20:08.033Z
Learning: Applies to nginx/conf.d/{geoip2.conf,ipinfo.conf} : When adding new endpoints: define needed variables in geoip2.conf or compose existing ones in ipinfo.conf, then add the location block with return in ipinfo.conf
🪛 Checkov (3.2.334)
k8s/deployment.yaml

[medium] 1-39: Containers should not run with allowPrivilegeEscalation

(CKV_K8S_20)


[medium] 1-39: Minimize the admission of root containers

(CKV_K8S_23)

Comment on lines +1 to +39
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: eva-whoami
name: eva-whoami
namespace: platform-tools
spec:
progressDeadlineSeconds: 600
replicas: 2
revisionHistoryLimit: 10
selector:
matchLabels:
app: eva-whoami
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: eva-whoami
spec:
containers:
- image: cratecache.azurecr.io/new-black/eva-whoami
imagePullPolicy: Always
name: whoami
ports:
- containerPort: 8080
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical mismatch: Files don't match PR objectives.

The PR summary states this adds "timezone information to the available fields" for the ipinfo.tw project with nginx configuration changes, but this file deploys an entirely different service (eva-whoami) in Kubernetes. This appears to be either:

  • Files from a different PR mistakenly included
  • A completely unrelated change bundled in the timezone PR

Please verify that the correct files are included in this PR.

🧰 Tools
🪛 Checkov (3.2.334)

[medium] 1-39: Containers should not run with allowPrivilegeEscalation

(CKV_K8S_20)


[medium] 1-39: Minimize the admission of root containers

(CKV_K8S_23)

Comment on lines +25 to +38
containers:
- image: cratecache.azurecr.io/new-black/eva-whoami
imagePullPolicy: Always
name: whoami
ports:
- containerPort: 8080
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add security context to prevent privilege escalation.

The deployment lacks security context constraints, leaving it vulnerable to privilege escalation and running as root. This violates Kubernetes security best practices and Pod Security Standards.

🔒 Proposed security hardening
       containers:
       - image: cratecache.azurecr.io/new-black/eva-whoami
         imagePullPolicy: Always
         name: whoami
         ports:
         - containerPort: 8080
           protocol: TCP
         resources: {}
+        securityContext:
+          allowPrivilegeEscalation: false
+          runAsNonRoot: true
+          runAsUser: 10001
+          capabilities:
+            drop:
+              - ALL
+          readOnlyRootFilesystem: true
         terminationMessagePath: /dev/termination-log
         terminationMessagePolicy: File
       dnsPolicy: ClusterFirst
       restartPolicy: Always
       schedulerName: default-scheduler
-      securityContext: {}
+      securityContext:
+        runAsNonRoot: true
+        seccompProfile:
+          type: RuntimeDefault
       terminationGracePeriodSeconds: 30

Note: If the application requires write access, mount an emptyDir volume for temporary storage instead of using a writable root filesystem.

Based on static analysis hints.

ports:
- containerPort: 8080
protocol: TCP
resources: {}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Define resource limits and requests.

The deployment has no resource constraints, which can lead to resource contention, unpredictable performance, and potential node exhaustion. Production deployments should always specify CPU and memory limits/requests.

⚙️ Proposed resource configuration
-        resources: {}
+        resources:
+          requests:
+            cpu: 100m
+            memory: 128Mi
+          limits:
+            cpu: 500m
+            memory: 256Mi

Adjust values based on actual application requirements.

📝 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.

Suggested change
resources: {}
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
🤖 Prompt for AI Agents
In @k8s/deployment.yaml at line 32, The deployment currently has an empty
resources block ("resources: {}"); replace it with explicit resource requests
and limits by adding a resources section containing requests (cpu and memory)
and limits (cpu and memory) for the container (e.g., under the container spec
where "resources" appears), choosing appropriate values for your app (start with
conservative defaults like requests: cpu: "100m", memory: "128Mi" and limits:
cpu: "500m", memory: "256Mi" and adjust based on real usage); ensure the new
resources block is added to the same container spec that originally had
"resources: {}".

annotations:
cert-manager.io/acme-challenge-type: dns01
cert-manager.io/cluster-issuer: letsencrypt-prod-dns
kubernetes.io/ingress.class: nginx
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Remove deprecated ingress class annotation.

The deprecated annotation kubernetes.io/ingress.class: nginx is redundant with the newer ingressClassName: nginx field (line 14). Modern Kubernetes versions (1.18+) should use only the ingressClassName field.

🧹 Proposed cleanup
   annotations:
     cert-manager.io/acme-challenge-type: dns01
     cert-manager.io/cluster-issuer: letsencrypt-prod-dns
-    kubernetes.io/ingress.class: nginx
   generation: 2

Also applies to: 14-14

🤖 Prompt for AI Agents
In @k8s/ingress.yaml at line 7, The manifest still uses the deprecated
annotation key "kubernetes.io/ingress.class: nginx" while also specifying the
newer field ingressClassName: nginx; remove the deprecated annotation entry so
the Ingress relies solely on the ingressClassName field. Locate the Ingress
metadata annotations block and delete the "kubernetes.io/ingress.class"
annotation, leaving ingressClassName: nginx intact to avoid duplication and
deprecation warnings.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In @.github/build.yml:
- Around line 19-24: The Docker login step using docker/login-action (step name
"Login to Docker Hub") incorrectly sets registry to include the repository path;
change the registry value from "cratecache.azurecr.io/new-black" to just
"cratecache.azurecr.io" and ensure the "new-black" namespace is applied when
tagging/pushing images (not in the registry field) so image references become
e.g. cratecache.azurecr.io/new-black:tag at push time.
- Around line 38-52: The workflow uses both the docker/build-push-action inputs
"tags" and "images" which conflict; decide whether you want to push the same
built image under multiple names or generate tags from a base image. Fix by
removing the unused "images" key (images:
cratecache.azurecr.io/new-black/henk2:${{ env.build_number }}) if you intend to
push eva-whoami tags only, or instead move all desired fully-qualified names
into the "tags" list (e.g., cratecache.azurecr.io/new-black/eva-whoami:latest,
cratecache.azurecr.io/new-black/eva-whoami:${{ env.build_number }},
cratecache.azurecr.io/new-black/henk2:${{ env.build_number }}) and delete the
"images" entry so only "tags" are used.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ba579be and cbd7cc7.

📒 Files selected for processing (1)
  • .github/build.yml
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: PeterDaveHello/ipinfo.tw PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-25T10:20:08.033Z
Learning: Applies to nginx/conf.d/geoip2.conf : Load GeoLite2-Country and GeoLite2-ASN databases and define GeoIP2 variables ($ip_country_code, $ip_country_name, $ip_asn, $ip_aso), including build_epoch values, in nginx/conf.d/geoip2.conf
Learnt from: CR
Repo: PeterDaveHello/ipinfo.tw PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-25T10:20:08.033Z
Learning: Applies to nginx/conf.d/ipinfo.conf : Define and maintain all endpoint location blocks (/, /json, /ip, and field endpoints) in nginx/conf.d/ipinfo.conf using return to emit text or JSON
Learnt from: CR
Repo: PeterDaveHello/ipinfo.tw PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-25T10:20:08.033Z
Learning: Applies to nginx/conf.d/{geoip2.conf,ipinfo.conf} : When adding new endpoints: define needed variables in geoip2.conf or compose existing ones in ipinfo.conf, then add the location block with return in ipinfo.conf
📚 Learning: 2025-10-25T10:20:08.033Z
Learnt from: CR
Repo: PeterDaveHello/ipinfo.tw PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-25T10:20:08.033Z
Learning: Applies to hooks/build : Use hooks/build as the canonical image build entrypoint (expects MAXMIND_LICENSE_KEY, DOCKERFILE_PATH, IMAGE_NAME in the environment)

Applied to files:

  • .github/build.yml
🔇 Additional comments (2)
.github/build.yml (2)

27-29: LGTM!

The Buildx setup is correctly configured with commit hash pinning for security.


38-46: No changes needed to this workflow.

The workflow correctly uses docker/build-push-action rather than hooks/build. The hooks/build script is a simple shell wrapper for local development builds, while this GitHub Actions workflow is the appropriate CI/CD approach for automated image building and pushing. The workflow properly specifies image names, tags, and the required MAXMIND_LICENSE_KEY build argument. The multi-platform support (linux/amd64,linux/arm64) and target specification (target: final) are modern enhancements not available in the shell script approach.

Likely an incorrect or invalid review comment.

Comment on lines +19 to +24
- name: Login to Docker Hub
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef #v3.6.0
with:
username: ${{ secrets.ACR_USERNAME }}
password: ${{ secrets.ACR_PASSWORD }}
registry: cratecache.azurecr.io/new-black
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix the registry configuration.

The registry field should contain only the registry hostname (e.g., cratecache.azurecr.io), not include the repository path /new-black. The namespace belongs in the image tags, not the registry URL.

🔧 Proposed fix
       - name: Login to Docker Hub
         uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef #v3.6.0
         with:
           username: ${{ secrets.ACR_USERNAME }}
           password: ${{ secrets.ACR_PASSWORD }}
-          registry: cratecache.azurecr.io/new-black
+          registry: cratecache.azurecr.io
📝 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.

Suggested change
- name: Login to Docker Hub
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef #v3.6.0
with:
username: ${{ secrets.ACR_USERNAME }}
password: ${{ secrets.ACR_PASSWORD }}
registry: cratecache.azurecr.io/new-black
- name: Login to Docker Hub
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef #v3.6.0
with:
username: ${{ secrets.ACR_USERNAME }}
password: ${{ secrets.ACR_PASSWORD }}
registry: cratecache.azurecr.io
🤖 Prompt for AI Agents
In @.github/build.yml around lines 19 - 24, The Docker login step using
docker/login-action (step name "Login to Docker Hub") incorrectly sets registry
to include the repository path; change the registry value from
"cratecache.azurecr.io/new-black" to just "cratecache.azurecr.io" and ensure the
"new-black" namespace is applied when tagging/pushing images (not in the
registry field) so image references become e.g.
cratecache.azurecr.io/new-black:tag at push time.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In @.github/workflows/build.yml:
- Around line 32-36: The workflow step uses id: commit-id but actually exports
the run/build number and writes to $GITHUB_ENV unquoted; rename the step id to
something descriptive like build-number or set-build-number (e.g., id:
build-number) and update the run command to quote the environment variable file
path (echo "build_number=$GITHUB_RUN_NUMBER" >> "$GITHUB_ENV") so the id matches
intent and the $GITHUB_ENV is safely quoted.
- Around line 19-25: The workflow step named "Login to Docker Hub" is misleading
because it logs into Azure Container Registry using docker/login-action; rename
the step (the "name" field for the step using docker/login-action@5e57cd1) to
something like "Login to ACR" or "Login to Azure Container Registry" so the step
accurately reflects the action and registry (cratecache.azurecr.io/new-black);
no other behavior changes required.
- Around line 6-11: The workflow currently triggers only on workflow_dispatch
and push to master (the on: workflow_dispatch and on: push: branches: - master
block), which means PRs won't run CI; either add a pull_request trigger (add on:
pull_request with desired branches or types) to run CI for PRs, or add a clear
inline YAML comment above the on: section documenting that push is intentionally
restricted to master and PRs must be manually dispatched—make one change (prefer
adding pull_request for automatic PR builds) and ensure the YAML remains valid.
- Around line 38-52: The workflow uses incorrect inputs for
docker/build-push-action: change the `build_args` key to `build-args` so
MAXMIND_LICENSE_KEY is actually passed, remove the invalid `images` input and
instead add cratecache.azurecr.io/new-black/henk2:${{ env.build_number }} as an
additional `tags:` entry, and (optional/recommended) pass the MaxMind key via
the action's `secrets:`/BuildKit secret mechanism rather than a build-arg so it
doesn't leak (this requires updating the Dockerfile to use secret mounts); keep
the existing action reference (docker/build-push-action@263435318d...) and other
inputs like `platforms`, `target`, `builder: ${{ steps.buildx.outputs.name }}`
unchanged.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cbd7cc7 and 72a67bc.

📒 Files selected for processing (1)
  • .github/workflows/build.yml
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: PeterDaveHello/ipinfo.tw PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-25T10:20:08.033Z
Learning: Applies to nginx/conf.d/geoip2.conf : Load GeoLite2-Country and GeoLite2-ASN databases and define GeoIP2 variables ($ip_country_code, $ip_country_name, $ip_asn, $ip_aso), including build_epoch values, in nginx/conf.d/geoip2.conf
Learnt from: CR
Repo: PeterDaveHello/ipinfo.tw PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-25T10:20:08.033Z
Learning: Applies to nginx/conf.d/{geoip2.conf,ipinfo.conf} : When adding new endpoints: define needed variables in geoip2.conf or compose existing ones in ipinfo.conf, then add the location block with return in ipinfo.conf
📚 Learning: 2025-10-25T10:20:08.033Z
Learnt from: CR
Repo: PeterDaveHello/ipinfo.tw PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-25T10:20:08.033Z
Learning: Applies to hooks/build : Use hooks/build as the canonical image build entrypoint (expects MAXMIND_LICENSE_KEY, DOCKERFILE_PATH, IMAGE_NAME in the environment)

Applied to files:

  • .github/workflows/build.yml
🔇 Additional comments (1)
.github/workflows/build.yml (1)

27-30: Verify multi-arch build actually works on ubuntu-22.04 (may need QEMU). (docs.docker.com)

Building linux/arm64 often requires adding docker/setup-qemu-action@v3; if the Dockerfile has RUN steps, arm64 builds can fail without emulation.

Proposed diff (if needed)
       - name: Set up Docker Buildx
         id: buildx
         uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f #3.12.0
+
+      - name: Set up QEMU
+        uses: docker/setup-qemu-action@v3

Also applies to: 38-43

Comment on lines +6 to +11
on:
workflow_dispatch:
push:
branches:
- master

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Consider adding a PR build (no push) trigger, or explicitly document “master-only push” behavior.

Right now this only runs on workflow_dispatch and push to master, so you won’t get CI signal on PRs unless someone manually dispatches. If that’s intentional, a short comment helps future maintainers.

🤖 Prompt for AI Agents
In @.github/workflows/build.yml around lines 6 - 11, The workflow currently
triggers only on workflow_dispatch and push to master (the on: workflow_dispatch
and on: push: branches: - master block), which means PRs won't run CI; either
add a pull_request trigger (add on: pull_request with desired branches or types)
to run CI for PRs, or add a clear inline YAML comment above the on: section
documenting that push is intentionally restricted to master and PRs must be
manually dispatched—make one change (prefer adding pull_request for automatic PR
builds) and ensure the YAML remains valid.

Comment on lines +19 to +25
- name: Login to Docker Hub
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef #v3.6.0
with:
username: ${{ secrets.ACR_USERNAME }}
password: ${{ secrets.ACR_PASSWORD }}
registry: cratecache.azurecr.io/new-black

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Step name is misleading (this logs into ACR, not Docker Hub).

Rename the step to avoid confusion during incident/debugging.

Proposed diff
-      - name: Login to Docker Hub
+      - name: Login to Azure Container Registry (ACR)
         uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef #v3.6.0
         with:
           username: ${{ secrets.ACR_USERNAME }}
           password: ${{ secrets.ACR_PASSWORD }}
           registry: cratecache.azurecr.io/new-black
🤖 Prompt for AI Agents
In @.github/workflows/build.yml around lines 19 - 25, The workflow step named
"Login to Docker Hub" is misleading because it logs into Azure Container
Registry using docker/login-action; rename the step (the "name" field for the
step using docker/login-action@5e57cd1) to something like "Login to ACR" or
"Login to Azure Container Registry" so the step accurately reflects the action
and registry (cratecache.azurecr.io/new-black); no other behavior changes
required.

Comment on lines +32 to +36
- name: Set the run number
id: commit-id
run: |
echo "build_number=$GITHUB_RUN_NUMBER" >> $GITHUB_ENV
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Minor: quote $GITHUB_ENV and align the step id with what it sets.

id: commit-id is a bit confusing since you’re exporting a run/build number.

Proposed diff
-      - name: Set the run number
-        id: commit-id
+      - name: Set the run number
+        id: build-number
         run: |
-          echo "build_number=$GITHUB_RUN_NUMBER" >> $GITHUB_ENV
+          echo "build_number=$GITHUB_RUN_NUMBER" >> "$GITHUB_ENV"
🤖 Prompt for AI Agents
In @.github/workflows/build.yml around lines 32 - 36, The workflow step uses id:
commit-id but actually exports the run/build number and writes to $GITHUB_ENV
unquoted; rename the step id to something descriptive like build-number or
set-build-number (e.g., id: build-number) and update the run command to quote
the environment variable file path (echo "build_number=$GITHUB_RUN_NUMBER" >>
"$GITHUB_ENV") so the id matches intent and the $GITHUB_ENV is safely quoted.

Comment on lines 38 to 52
- name: Build production image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 #v6.18.0
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
target: release
build_args: |
MAXMIND_LICENSE_KEY=${{ secrets.MAXMIND_LICENSE_KEY }}
tags: |
cratecache.azurecr.io/new-black/eva-whoami:latest
cratecache.azurecr.io/new-black/eva-whoami:${{ env.build_number }}
builder: ${{ steps.buildx.outputs.name }}
images: |
cratecache.azurecr.io/new-black/henk2:${{ env.build_number }}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, check the repository structure
git ls-files | head -20

Repository: PeterDaveHello/ipinfo.tw

Length of output: 382


🏁 Script executed:

# Look for hooks/build or similar build scripts
fd -t f "hooks" | head -20
fd -t f "build" | grep -v node_modules | grep -v ".git"

Repository: PeterDaveHello/ipinfo.tw

Length of output: 79


🏁 Script executed:

# Check the current build.yml workflow file
cat -n .github/workflows/build.yml | head -60

Repository: PeterDaveHello/ipinfo.tw

Length of output: 2009


🌐 Web query:

docker/build-push-action v6.18.0 input parameters build-args images

💡 Result:

Summary — docker/build-push-action v6 (including v6.18.0)

  • build-args: use the with key "build-args" as a multi-line list (List type). Provide each ARG as KEY=VALUE (or just KEY to forward during build). Example:
    with:
    build-args: |
    FOO=bar
    SECRET=${{ secrets.MY_SECRET }}
    HTTP_PROXY=http://proxy:3128
    (Each line becomes a --build-arg in docker build.) [1][2]

  • images / tags: the action accepts tags/images via "tags" (CSV or multi-line) or the older single "image" + "tags" style. Common usage (v6) — pass tags (comma or newline separated). Example:
    with:
    push: true
    tags: |
    ghcr.io/myorg/myapp:latest
    ghcr.io/myorg/myapp:${{ github.sha }}
    (You can also use context/file, platforms, and push=true to push the built images.) [1][2]

Examples (concise):

  • Single-image, build-args:

    • uses: docker/build-push-action@v6
      with:
      context: .
      file: Dockerfile
      build-args: |
      APP_ENV=production
      API_KEY=${{ secrets.API_KEY }}
      push: true
      tags: myrepo/myapp:latest
  • Multi-platform + multiple tags:

    • uses: docker/build-push-action@v6
      with:
      context: .
      platforms: linux/amd64,linux/arm64
      build-args: |
      VERSION=1.2.3
      push: true
      tags: |
      ghcr.io/myorg/myapp:1.2.3
      ghcr.io/myorg/myapp:latest

Sources:

  • docker/build-push-action README (inputs, build-args, tags). [1]
  • docker/build-push-action (GitHub repo docs / examples). [2]

If you want I can show the exact action.yml snippet from v6.18.0.


🏁 Script executed:

cat -n hooks/build

Repository: PeterDaveHello/ipinfo.tw

Length of output: 208


🏁 Script executed:

# Check if there are any other references to hooks/build in the codebase
rg "hooks/build" --type yml --type yaml
rg "hooks.build"

Repository: PeterDaveHello/ipinfo.tw

Length of output: 1408


Fix docker/build-push-action input names; build_args/images won't do what you expect.

  • Use build-args: (hyphen) so MAXMIND_LICENSE_KEY is actually passed.
  • Remove the images: input (not valid for this action); add cratecache.azurecr.io/new-black/henk2:${{ env.build_number }} as another tags: entry instead.
  • Recommended: pass the MaxMind key via BuildKit secrets: instead of build-args to reduce leak risk (requires Dockerfile using secret mounts).

Also note: hooks/build is documented in AGENTS.md as the canonical build entrypoint, but the current workflow uses docker/build-push-action directly for multi-platform builds and ACR push. Consider whether to standardize on hooks/build with appropriate environment variables, or keep the current approach if the multi-platform requirements differ from the canonical script.

Proposed diff (minimal correctness fix)
       - name: Build production image
         uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 #v6.18.0
         with:
           context: .
           platforms: linux/amd64,linux/arm64
           push: true
           target: release
-          build_args: |
+          build-args: |
             MAXMIND_LICENSE_KEY=${{ secrets.MAXMIND_LICENSE_KEY }}
           tags: |
             cratecache.azurecr.io/new-black/eva-whoami:latest
             cratecache.azurecr.io/new-black/eva-whoami:${{ env.build_number }}
+            cratecache.azurecr.io/new-black/henk2:${{ env.build_number }}
           builder: ${{ steps.buildx.outputs.name }}
-          images: |
-            cratecache.azurecr.io/new-black/henk2:${{ env.build_number }}
📝 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.

Suggested change
- name: Build production image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 #v6.18.0
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
target: release
build_args: |
MAXMIND_LICENSE_KEY=${{ secrets.MAXMIND_LICENSE_KEY }}
tags: |
cratecache.azurecr.io/new-black/eva-whoami:latest
cratecache.azurecr.io/new-black/eva-whoami:${{ env.build_number }}
builder: ${{ steps.buildx.outputs.name }}
images: |
cratecache.azurecr.io/new-black/henk2:${{ env.build_number }}
- name: Build production image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 #v6.18.0
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
target: release
build-args: |
MAXMIND_LICENSE_KEY=${{ secrets.MAXMIND_LICENSE_KEY }}
tags: |
cratecache.azurecr.io/new-black/eva-whoami:latest
cratecache.azurecr.io/new-black/eva-whoami:${{ env.build_number }}
cratecache.azurecr.io/new-black/henk2:${{ env.build_number }}
builder: ${{ steps.buildx.outputs.name }}
🤖 Prompt for AI Agents
In @.github/workflows/build.yml around lines 38 - 52, The workflow uses
incorrect inputs for docker/build-push-action: change the `build_args` key to
`build-args` so MAXMIND_LICENSE_KEY is actually passed, remove the invalid
`images` input and instead add cratecache.azurecr.io/new-black/henk2:${{
env.build_number }} as an additional `tags:` entry, and (optional/recommended)
pass the MaxMind key via the action's `secrets:`/BuildKit secret mechanism
rather than a build-arg so it doesn't leak (this requires updating the
Dockerfile to use secret mounts); keep the existing action reference
(docker/build-push-action@263435318d...) and other inputs like `platforms`,
`target`, `builder: ${{ steps.buildx.outputs.name }}` unchanged.

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.

3 participants