Merge pull request #6 from johndoe6345789/copilot/add-docker-version-for-testing

Add Docker containerization and GHCR publishing via GitHub Actions
This commit is contained in:
2025-12-28 16:29:32 +00:00
committed by GitHub
4 changed files with 300 additions and 0 deletions

49
.dockerignore Normal file
View File

@@ -0,0 +1,49 @@
# Git
.git
.gitignore
.github
# Documentation
*.md
!README.md
ARCHITECTURE.md
CONTRIBUTING.md
LICENSE
# Build artifacts
init
*.o
*.a
*.so
*.img
*.iso
build/
# Generated rootfs contents (we build our own in Docker)
rootfs/bin/*
rootfs/sbin/init
rootfs/usr/
rootfs/lib/
rootfs/lib64/
rootfs/boot/
# Keep rootfs structure
!rootfs/etc/
!rootfs/root/
!rootfs/home/
# Temporary files
*.tmp
*.bak
/tmp/
# IDE and editor files
.vscode/
.idea/
*.swp
*.swo
*~
# OS files
.DS_Store
Thumbs.db

105
.github/workflows/docker-publish.yml vendored Normal file
View File

@@ -0,0 +1,105 @@
name: Docker Build and Publish
on:
push:
branches:
- main
- develop
tags:
- 'v*'
pull_request:
branches:
- main
- develop
workflow_dispatch:
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-test:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
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=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}
- name: Build Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: ${{ github.event_name != 'pull_request' }}
load: ${{ github.event_name == 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Test Docker image
run: |
echo "Testing SparkOS Docker image..."
# Get the first tag from the metadata output
IMAGE_TAG=$(echo "${{ steps.meta.outputs.tags }}" | head -n1)
echo "Using image: $IMAGE_TAG"
# For PRs, image is loaded locally; for branches, pull from GHCR
if [ "${{ github.event_name }}" != "pull_request" ]; then
echo "Pulling image from GHCR for testing..."
docker pull "$IMAGE_TAG"
fi
# Run the container and check output
docker run --rm "$IMAGE_TAG"
# Verify init binary exists and is executable
docker run --rm "$IMAGE_TAG" sh -c "test -x /sparkos/rootfs/sbin/init && echo 'Init binary is executable'"
echo "Docker image test completed successfully!"
- name: Output image details
if: github.event_name != 'pull_request'
run: |
echo "### Docker Image Published! 🐳" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Registry:** ${{ env.REGISTRY }}" >> $GITHUB_STEP_SUMMARY
echo "**Repository:** ${{ env.IMAGE_NAME }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Tags:**" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Pull command:**" >> $GITHUB_STEP_SUMMARY
echo '```bash' >> $GITHUB_STEP_SUMMARY
echo "docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY

93
Dockerfile Normal file
View File

@@ -0,0 +1,93 @@
# SparkOS Docker Image
# Multi-stage build for minimal final image size
# Build stage - use gcc image which has all build tools pre-installed
FROM gcc:13-bookworm AS builder
# Set working directory
WORKDIR /build
# Copy source files
COPY src/ ./src/
COPY Makefile .
COPY scripts/ ./scripts/
# Build the init system
RUN make init
# Runtime stage - use Alpine for minimal size
FROM alpine:3.19
# Note: Alpine includes busybox by default
# Create minimal rootfs structure
RUN mkdir -p /sparkos/rootfs/bin \
/sparkos/rootfs/sbin \
/sparkos/rootfs/etc \
/sparkos/rootfs/proc \
/sparkos/rootfs/sys \
/sparkos/rootfs/dev \
/sparkos/rootfs/tmp \
/sparkos/rootfs/usr/bin \
/sparkos/rootfs/usr/sbin \
/sparkos/rootfs/usr/lib \
/sparkos/rootfs/var/log \
/sparkos/rootfs/var/run \
/sparkos/rootfs/root \
/sparkos/rootfs/home/spark && \
chmod 1777 /sparkos/rootfs/tmp && \
chmod 700 /sparkos/rootfs/root && \
chmod 755 /sparkos/rootfs/home/spark
# Copy built init binary from builder
COPY --from=builder /build/init /sparkos/rootfs/sbin/init
# Set up basic configuration files
RUN echo "sparkos" > /sparkos/rootfs/etc/hostname && \
echo "127.0.0.1 localhost" > /sparkos/rootfs/etc/hosts && \
echo "127.0.1.1 sparkos" >> /sparkos/rootfs/etc/hosts && \
echo "root:x:0:0:root:/root:/bin/sh" > /sparkos/rootfs/etc/passwd && \
echo "spark:x:1000:1000:SparkOS User:/home/spark:/bin/sh" >> /sparkos/rootfs/etc/passwd && \
echo "root:x:0:" > /sparkos/rootfs/etc/group && \
echo "spark:x:1000:" >> /sparkos/rootfs/etc/group
# Create a test entrypoint
COPY <<'EOF' /sparkos/test.sh
#!/bin/sh
echo "SparkOS Docker Test Environment"
echo "================================"
echo ""
echo "SparkOS init binary: /sparkos/rootfs/sbin/init"
echo ""
echo "Verifying init binary..."
if [ -f /sparkos/rootfs/sbin/init ]; then
echo "✓ Init binary exists"
ls -lh /sparkos/rootfs/sbin/init
echo ""
echo "File type:"
file /sparkos/rootfs/sbin/init
echo ""
echo "Dependencies:"
ldd /sparkos/rootfs/sbin/init 2>&1 || echo " Static binary (no dependencies)"
else
echo "✗ Init binary not found!"
exit 1
fi
echo ""
echo "Root filesystem structure:"
ls -la /sparkos/rootfs/
echo ""
echo "SparkOS is ready for testing!"
echo ""
echo "To test the init system:"
echo " docker run --rm <image> /sparkos/rootfs/sbin/init --help"
echo ""
exec /bin/sh
EOF
RUN chmod +x /sparkos/test.sh
WORKDIR /sparkos
# Set entrypoint
ENTRYPOINT ["/sparkos/test.sh"]

View File

@@ -24,6 +24,8 @@ The current MVP provides:
- ✅ Build system (Makefile)
- ✅ Wired networking configuration with DHCP
- ✅ DNS configuration with public fallback servers
- ✅ Docker container for testing
- ✅ Automated builds and publishing to GHCR
## Prerequisites
@@ -42,6 +44,27 @@ To create bootable images (optional):
## Quick Start
### Using Docker (Recommended for Testing)
The easiest way to test SparkOS is using the pre-built Docker image from GitHub Container Registry:
```bash
# Pull and run the latest image
docker pull ghcr.io/johndoe6345789/sparkos:latest
docker run --rm ghcr.io/johndoe6345789/sparkos:latest
# Or build locally
docker build -t sparkos:local .
docker run --rm sparkos:local
```
The Docker image includes:
- Pre-built init system binary
- Minimal root filesystem structure
- Test environment for validation
Images are automatically built and published to [GitHub Container Registry](https://github.com/johndoe6345789/SparkOS/pkgs/container/sparkos) on every push to main branch.
### Building the Init System
```bash
@@ -84,6 +107,9 @@ Replace `/dev/sdX` with your actual USB device (e.g., `/dev/sdb`).
```
SparkOS/
├── .github/ # GitHub Actions workflows
│ └── workflows/
│ └── docker-publish.yml # Docker build and publish workflow
├── config/ # Build configuration files
│ └── build.conf # Build parameters
├── scripts/ # Build and setup scripts
@@ -97,6 +123,7 @@ SparkOS/
│ ├── sbin/ # System binaries
│ ├── etc/ # Configuration files
│ └── ... # Standard FHS directories
├── Dockerfile # Docker image definition
├── Makefile # Build system
└── README.md # This file
```
@@ -134,6 +161,32 @@ SparkOS provides wired networking for initial bootstrap:
## Development
### CI/CD and Docker
SparkOS uses GitHub Actions for continuous integration and delivery:
**Automated Builds:**
- Docker images are automatically built on every push to main/develop branches
- Images are also built for pull requests (testing only, not published)
- Tagged releases automatically create versioned Docker images
**Container Registry:**
- Images are published to GitHub Container Registry (GHCR)
- Pull images: `docker pull ghcr.io/johndoe6345789/sparkos:latest`
- Available tags: `latest`, `main`, `develop`, version tags (e.g., `v1.0.0`)
**Docker Development:**
```bash
# Build Docker image locally
docker build -t sparkos:dev .
# Test the image
docker run --rm sparkos:dev
# Inspect the init binary
docker run --rm sparkos:dev sh -c "ls -lh /sparkos/rootfs/sbin/init"
```
### Building Components
```bash