feat: Raspberry Pi deployment — Dockerfile, CI/CD workflows, actuator
Some checks failed
CI / Build & test backend (push) Failing after 13m38s

Backend:
- backend/Dockerfile: multi-stage build (local + ci-image targets)
  - eclipse-temurin:21-jre-alpine runtime, non-root user caloriecounter
  - DOCKER_BUILDKIT=0 + native JAR build pattern for ARM64 Pi runner
- pom.xml: add spring-boot-starter-actuator
- application.yml: expose /actuator/health (liveness probe for Docker healthcheck)

CI/CD:
- .gitea/workflows/ci.yml: Maven test on pi-runner (push + PR)
- .gitea/workflows/docker.yml: build + push calorie-counter-api:latest/:sha
  - Triggers after CI passes (workflow_run) to avoid OOM on single-capacity Pi
  - Docker login before Maven build (avoids daemon timeout after heavy CPU)
  - Deploys immediately via docker.sock to /home/andris/homelab/calorie-counter/

Mobile:
- api.ts: update baseURL default to https://calories.amlab.dev
  (LAN fallback: http://10.18.1.135:8085 via WireGuard)

Homelab changes pushed directly via Gitea MCP:
- homelab/calorie-counter/docker-compose.yml (port 8085, 120s start_period)
- homelab/calorie-counter/.env.example
- homelab/.gitea/workflows/deploy-calorie-counter.yml (cron every 10 min)
- homelab/backup/backup.sh (added calorie-counter pg_dump)
This commit is contained in:
2026-05-18 23:58:44 +03:00
parent 8a031b30b6
commit 904f1c43b3
6 changed files with 283 additions and 1 deletions

51
backend/Dockerfile Normal file
View File

@@ -0,0 +1,51 @@
# Generated by GitHub Copilot
#
# Build stage — Java 21 LTS + Maven (used only for local dev via --target local).
# The CI workflow builds the JAR natively on the Pi runner before calling docker build
# to avoid QEMU's unreliable TLS stack causing Maven Central downloads to time out.
FROM eclipse-temurin:21-jdk-alpine AS build
WORKDIR /workspace
# Download Maven via curl — avoids apk's OpenJDK pulling in a conflicting JDK version.
ENV MAVEN_VERSION=3.9.9
RUN apk add --no-cache curl && \
curl -fsSL https://archive.apache.org/dist/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz \
| tar -xz -C /opt && \
ln -s /opt/apache-maven-${MAVEN_VERSION} /opt/maven
ENV PATH="/opt/maven/bin:${PATH}"
COPY pom.xml .
# Pre-fetch deps as a cached layer; rebuilds on source-only changes skip this step.
RUN mvn -q -ntp dependency:go-offline || true
COPY src src
RUN mvn -q -ntp clean package -DskipTests
# ── Runtime base — shared between local and ci-image targets ──────────────────
FROM eclipse-temurin:21-jre-alpine AS runtime-base
WORKDIR /app
# Non-root user — principle of least privilege (REQ-SEC-001)
RUN addgroup -S caloriecounter && adduser -S caloriecounter -G caloriecounter
USER caloriecounter
EXPOSE 8080
# Container-aware heap sizing: use 75% of cgroup memory limit
ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75"
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
# ── local target ──────────────────────────────────────────────────────────────
# Copies JAR from the Maven build stage above.
# Usage: docker build --target local -t calorie-counter-api .
FROM runtime-base AS local
COPY --from=build /workspace/target/*.jar app.jar
# ── ci-image target (DEFAULT) ─────────────────────────────────────────────────
# Copies a pre-built JAR from the Docker build context.
# The CI workflow builds the JAR natively (outside QEMU) before docker build,
# avoiding 20-min Maven downloads through QEMU's unreliable TLS stack.
# Usage: docker build --build-arg JAR_FILE=target/calorie-counter-backend-1.0.0-SNAPSHOT.jar .
FROM runtime-base AS ci-image
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar

View File

@@ -86,6 +86,12 @@
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!-- Actuator — liveness/readiness probes for Docker healthcheck -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>

View File

@@ -36,6 +36,18 @@ openai:
openfoodfacts:
base-url: https://world.openfoodfacts.org
management:
endpoints:
web:
exposure:
include: health
endpoint:
health:
probes:
# Enable liveness + readiness probes — used by Docker HEALTHCHECK
enabled: true
show-details: never
logging:
level:
root: WARN