feat: Raspberry Pi deployment — Dockerfile, CI/CD workflows, actuator
Some checks failed
CI / Build & test backend (push) Failing after 13m38s
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:
51
backend/Dockerfile
Normal file
51
backend/Dockerfile
Normal 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
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user