feat: Dockerfiles and Gitea Actions workflow for standard and bundled-postgres images
Some checks failed
Docker / build (push) Failing after 4m6s
Some checks failed
Docker / build (push) Failing after 4m6s
This commit is contained in:
76
.gitea/workflows/docker.yml
Normal file
76
.gitea/workflows/docker.yml
Normal file
@@ -0,0 +1,76 @@
|
||||
name: Docker
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master, main]
|
||||
tags: ["v*"]
|
||||
pull_request:
|
||||
branches: [master, main]
|
||||
|
||||
env:
|
||||
REGISTRY: git.govekar.net
|
||||
IMAGE: lovrog05/localmodelroutex
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Docker meta (standard)
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE }}
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=sha,prefix=sha-,format=short
|
||||
|
||||
- name: Docker meta (bundled)
|
||||
id: meta-bundled
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE }}
|
||||
tags: |
|
||||
type=ref,event=branch,suffix=-bundled
|
||||
type=semver,pattern={{version}},suffix=-bundled
|
||||
type=semver,pattern={{major}}.{{minor}},suffix=-bundled
|
||||
type=sha,prefix=sha-,format=short,suffix=-bundled
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to registry
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ secrets.REGISTRY_USER }}
|
||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
|
||||
- name: Build and push — standard
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha,scope=standard
|
||||
cache-to: type=gha,mode=max,scope=standard
|
||||
platforms: linux/amd64,linux/arm64
|
||||
|
||||
- name: Build and push — bundled (postgres included)
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile.bundled
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta-bundled.outputs.tags }}
|
||||
labels: ${{ steps.meta-bundled.outputs.labels }}
|
||||
cache-from: type=gha,scope=bundled
|
||||
cache-to: type=gha,mode=max,scope=bundled
|
||||
platforms: linux/amd64,linux/arm64
|
||||
21
Dockerfile
Normal file
21
Dockerfile
Normal file
@@ -0,0 +1,21 @@
|
||||
# ── Build stage ──────────────────────────────────────────────────────────────
|
||||
FROM node:22-alpine AS ui
|
||||
WORKDIR /src/dashboard
|
||||
COPY backend/dashboard/package*.json ./
|
||||
RUN npm ci
|
||||
COPY backend/dashboard/ ./
|
||||
RUN npm run build
|
||||
|
||||
FROM golang:1.24-alpine AS go-build
|
||||
WORKDIR /src
|
||||
COPY backend/go.mod backend/go.sum ./
|
||||
RUN go mod download
|
||||
COPY backend/ .
|
||||
COPY --from=ui /src/dashboard/../internal/web/dist ./internal/web/dist
|
||||
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /lmr ./cmd/server
|
||||
|
||||
# ── Runtime stage ─────────────────────────────────────────────────────────────
|
||||
FROM gcr.io/distroless/static-debian12:nonroot
|
||||
COPY --from=go-build /lmr /lmr
|
||||
EXPOSE 8080
|
||||
ENTRYPOINT ["/lmr"]
|
||||
36
Dockerfile.bundled
Normal file
36
Dockerfile.bundled
Normal file
@@ -0,0 +1,36 @@
|
||||
# ── Build stage ──────────────────────────────────────────────────────────────
|
||||
FROM node:22-alpine AS ui
|
||||
WORKDIR /src/dashboard
|
||||
COPY backend/dashboard/package*.json ./
|
||||
RUN npm ci
|
||||
COPY backend/dashboard/ ./
|
||||
RUN npm run build
|
||||
|
||||
FROM golang:1.24-alpine AS go-build
|
||||
WORKDIR /src
|
||||
COPY backend/go.mod backend/go.sum ./
|
||||
RUN go mod download
|
||||
COPY backend/ .
|
||||
COPY --from=ui /src/dashboard/../internal/web/dist ./internal/web/dist
|
||||
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /lmr ./cmd/server
|
||||
|
||||
# ── Runtime stage (Postgres bundled) ─────────────────────────────────────────
|
||||
FROM alpine:3.21
|
||||
|
||||
RUN apk add --no-cache postgresql16 postgresql16-client su-exec bash
|
||||
|
||||
COPY --from=go-build /lmr /usr/local/bin/lmr
|
||||
COPY deploy/entrypoint-bundled.sh /entrypoint.sh
|
||||
RUN chmod +x /entrypoint.sh
|
||||
|
||||
ENV PGDATA=/var/lib/postgresql/data
|
||||
ENV PGUSER=lmr
|
||||
ENV PGPASSWORD=lmr
|
||||
ENV PGDATABASE=lmr
|
||||
# The gateway reads GATEWAY_DB_URL; set a default that points to the local PG.
|
||||
ENV GATEWAY_DB_URL="postgres://lmr:lmr@localhost:5432/lmr?sslmode=disable"
|
||||
|
||||
VOLUME ["/var/lib/postgresql/data"]
|
||||
EXPOSE 8080
|
||||
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
44
deploy/entrypoint-bundled.sh
Normal file
44
deploy/entrypoint-bundled.sh
Normal file
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
PGDATA="${PGDATA:-/var/lib/postgresql/data}"
|
||||
PGUSER="${PGUSER:-lmr}"
|
||||
PGPASSWORD="${PGPASSWORD:-lmr}"
|
||||
PGDATABASE="${PGDATABASE:-lmr}"
|
||||
|
||||
# ── Initialise cluster if needed ─────────────────────────────────────────────
|
||||
if [ ! -f "$PGDATA/PG_VERSION" ]; then
|
||||
echo "→ initialising postgres cluster"
|
||||
install -d -m 0700 -o postgres "$PGDATA"
|
||||
su-exec postgres initdb \
|
||||
--username="$PGUSER" \
|
||||
--pwfile=<(echo "$PGPASSWORD") \
|
||||
--auth=md5 \
|
||||
-D "$PGDATA" \
|
||||
--no-instructions
|
||||
fi
|
||||
|
||||
# ── Start postgres in the background ─────────────────────────────────────────
|
||||
echo "→ starting postgres"
|
||||
su-exec postgres postgres -D "$PGDATA" \
|
||||
-c listen_addresses=localhost \
|
||||
-c log_min_messages=WARNING &
|
||||
PG_PID=$!
|
||||
|
||||
# ── Wait for postgres to accept connections ───────────────────────────────────
|
||||
echo "→ waiting for postgres"
|
||||
until su-exec postgres pg_isready -U "$PGUSER" -d "$PGDATABASE" -q 2>/dev/null; do
|
||||
sleep 0.5
|
||||
done
|
||||
|
||||
# ── Ensure the application database exists ───────────────────────────────────
|
||||
su-exec postgres psql -U "$PGUSER" -tc \
|
||||
"SELECT 1 FROM pg_database WHERE datname = '$PGDATABASE'" \
|
||||
| grep -q 1 || su-exec postgres createdb -U "$PGUSER" "$PGDATABASE"
|
||||
|
||||
# ── Start the gateway (foreground, takes over the process) ───────────────────
|
||||
echo "→ starting lmr"
|
||||
# Forward signals to both processes on exit.
|
||||
trap 'kill $PG_PID 2>/dev/null; wait $PG_PID' TERM INT
|
||||
|
||||
exec /usr/local/bin/lmr
|
||||
Reference in New Issue
Block a user