Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Ignore common development files
.git
.gitignore
*.md
!README.md
.DS_Store
.vscode
.idea

# Ignore Go artifacts
*.exe
*.exe~
*.dll
*.so
*.dylib
*.test
*.out
go.sum

# Ignore node_modules if any
node_modules

# Ignore test coverage
coverage.txt
coverage.html

# Ignore local builds
dist/
build/
bin/

# Schema is optional for users, keep it
!schema.json
71 changes: 71 additions & 0 deletions .github/workflows/build-docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Build and Push Docker Image

on:
push:
branches:
- develop
tags:
- 'v*'
pull_request:
branches:
- develop
schedule:
- cron: '0 2 * * 0' # Weekly Sunday 2am UTC - refresh dependencies
workflow_dispatch:
inputs:
force-fresh:
description: 'Force fresh build without cache'
required: false
default: 'false'

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/develop' }}

- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: ${{ github.event.inputs.force-fresh == 'true' && '' || 'type=gha' }}
cache-to: ${{ github.event.inputs.force-fresh == 'true' && '' || 'type=gha,mode=max' }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ go.work.sum
# Editor/IDE
# .idea/
# .vscode/
.aider*
74 changes: 74 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Portal Builder Base Image
# Build environment for compiling LumeWeb Portal with custom plugins via docker buildx
# Use as a base image in your Dockerfile: FROM ghcr.io/lumeweb/portal-builder:latest

# Build arguments for yq version and checksum - override with --build-arg
ARG YQ_VERSION=v4.52.2
ARG YQ_SHA256=a74bd266990339e0c48a2103534aef692abf99f19390d12c2b0ce6830385c459

FROM golang:1.25-alpine
Comment thread
kody-ai[bot] marked this conversation as resolved.
Outdated

# Install build dependencies
RUN apk add --no-cache \
git \
make \
gcc \
musl-dev \
libwebp-dev \
ca-certificates \
tzdata \
python3

# Install yq (YAML parser)
# Version pinned for reproducible builds; checksum verified for security
RUN apk add --no-cache curl && \
curl -fsSL -o /usr/local/bin/yq https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_amd64 && \
echo "${YQ_SHA256} /usr/local/bin/yq" | sha256sum -c - && \
chmod +x /usr/local/bin/yq && \
rm -rf /var/cache/apk/*

# Install xportal
RUN GOPROXY=direct go install go.lumeweb.com/xportal/cmd/xportal@latest

# Pre-populate Go module cache for common dependencies
# This significantly speeds up builds in child images by avoiding re-downloads
# Set explicit Go module cache path
ENV GOMODCACHE=/go/pkg/mod

# Create a temporary workspace for downloading modules
WORKDIR /tmp/cache-warmup

# Download Portal core dependencies (develop version)
# This creates go.mod and populates the module cache
RUN go mod init cache-warmup && \
GOPROXY=direct go get go.lumeweb.com/portal@develop && \
go mod download go.lumeweb.com/portal@develop && \
# Clean up temporary files
rm -rf /tmp/cache-warmup

# Return to standard working directory
WORKDIR /workspace

# Install check-jsonschema for YAML validation using uv
# Create venv and install (only needed during build, discarded in final image)
RUN python3 -m venv /opt/venv && \
/opt/venv/bin/pip install --upgrade pip && \
/opt/venv/bin/pip install --no-cache-dir check-jsonschema && \
ln -s /opt/venv/bin/check-jsonschema /usr/local/bin/check-jsonschema

# Copy build script and schema
COPY build-portal.sh /usr/local/bin/build-portal
COPY schema.json /usr/local/share/portal-builder/schema.json
RUN chmod +x /usr/local/bin/build-portal

# Set default environment variables
ENV PLUGIN_MANIFEST=portal-plugins.yaml
ENV SCHEMA_PATH=/usr/local/share/portal-builder/schema.json
ENV OUTPUT_DIR=/dist
ENV PATH="/root/.local/bin:${PATH}"

# Set working directory
WORKDIR /workspace

# No ENTRYPOINT - this is a base image for buildx
# Users will RUN build-portal in their Dockerfiles
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2026 Lume Web
Copyright (c) 2026 Hammer Technologies LLC

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
Loading
Loading