diff --git a/.dockerignore b/.dockerignore index 30442dc..ff85bf9 100644 --- a/.dockerignore +++ b/.dockerignore @@ -33,6 +33,7 @@ vendor/ tests/ # Configuration +Makefile .envrc *.yaml *.yml diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml new file mode 100644 index 0000000..dbcefed --- /dev/null +++ b/.github/workflows/docker-build.yml @@ -0,0 +1,82 @@ +name: Docker Build and Push + +on: + push: + branches: [ main ] + tags: + - 'v*' + pull_request: + branches: [ main ] + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + docker-build-push: + name: Build and Push Multi-arch Image + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout code + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Set up Go + uses: actions/setup-go@v6 + with: + go-version-file: go.mod + cache: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Get build metadata + id: build-meta + run: | + echo "version=$(make version)" >> $GITHUB_OUTPUT + echo "git_commit=$(make get-commit-hash)" >> $GITHUB_OUTPUT + echo "build_date=$(make get-build-date)" >> $GITHUB_OUTPUT + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + # Tag with 'latest' for main branch. + type=raw,value=latest,enable={{is_default_branch}} + # Tag with version string from 'make version'. + type=raw,value=${{ steps.build-meta.outputs.version }} + + - name: Build and push Docker image + id: docker_build + uses: docker/build-push-action@v6 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + build-args: | + VERSION=${{ steps.build-meta.outputs.version }} + GIT_COMMIT=${{ steps.build-meta.outputs.git_commit }} + BUILD_DATE=${{ steps.build-meta.outputs.build_date }} + cache-from: | + type=gha + type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache + cache-to: type=gha,mode=max + + - name: Image digest + run: echo "Image pushed with digest ${{ steps.docker_build.outputs.digest }}" diff --git a/Dockerfile b/Dockerfile index 984789a..c14b923 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ # Supports multi-architecture builds (amd64, arm64) # Stage 1: Build roxie binary -FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.22-alpine AS builder +FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.25-alpine AS builder # Build arguments for cross-compilation # These are automatically provided by Docker buildx @@ -176,6 +176,7 @@ USER roxie # Set environment variables ENV HOME=/ \ + KUBECONFIG=/kubeconfig \ PATH=/usr/local/bin:$PATH # Display version information on container start diff --git a/Makefile b/Makefile index e79486c..6f7330d 100644 --- a/Makefile +++ b/Makefile @@ -18,11 +18,33 @@ BUILD_DIR := . BINARY := $(BUILD_DIR)/$(BINARY_NAME) # Version information -VERSION := 0.1 -GIT_COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown") +GIT_COMMIT := $(shell git rev-parse HEAD 2>/dev/null || echo "unknown") +# Convention is that the git tags are of the form +# v..--[-dirty] +# or v.. +# +# We use sed to drop the initial 'v' in case the whole tag matches any of the above patterns. +# Hence, the resulting version string will simply be +# +# .. or ..--[-dirty] +# +# This will also become the tag of the docker images. +VERSION := $(shell git describe --tags --always --dirty | sed -E 's/^v([0-9]+\.[0-9]+\.[0-9]+-[0-9]+-[a-z0-9]+(-dirty)?$$)/\1/') BUILD_DATE := $(shell date -u '+%Y-%m-%dT%H:%M:%SZ') LDFLAGS := -X main.version=$(VERSION) -X main.gitCommit=$(GIT_COMMIT) -X main.buildDate=$(BUILD_DATE) +.PHONY: get-build-date +get-build-date: + @echo $(BUILD_DATE) + +.PHONY: get-commit-hash +get-commit-hash: + @echo $(GIT_COMMIT) + +.PHONY: version +version: + @echo $(VERSION) + # Build targets .PHONY: build build: ## Build the roxie binary @@ -145,11 +167,11 @@ validate: ## Validate go.mod and check for issues all: clean deps check test build ## Run full development workflow # Docker/Container targets -DOCKER_IMAGE := roxie -DOCKER_TAG := latest -DOCKER_VERSION_TAG := $(VERSION)-$(GIT_COMMIT) -DOCKER_FULL_IMAGE := $(DOCKER_IMAGE):$(DOCKER_TAG) -DOCKER_VERSION_IMAGE := $(DOCKER_IMAGE):$(DOCKER_VERSION_TAG) +IMAGE_DEFAULT_REGISTRY := localhost +IMAGE_REGISTRY := $(shell if [ -z "$(IMAGE_REGISTRY)" ]; then echo $(IMAGE_DEFAULT_REGISTRY); else echo $(IMAGE_REGISTRY); fi) +IMAGE_NAME := roxie +IMAGE_LATEST_TAG := $(IMAGE_REGISTRY)/$(IMAGE_NAME):latest +IMAGE_VERSION_TAG := $(IMAGE_REGISTRY)/$(IMAGE_NAME):$(VERSION) CONTAINER_RUNTIME ?= $(shell command -v podman 2>/dev/null || command -v docker 2>/dev/null) # Multi-architecture support @@ -167,67 +189,13 @@ docker-build: ## Build roxie Docker image for current platform --build-arg VERSION=$(VERSION) \ --build-arg GIT_COMMIT=$(GIT_COMMIT) \ --build-arg BUILD_DATE=$(BUILD_DATE) \ - -t $(DOCKER_FULL_IMAGE) \ - -t $(DOCKER_VERSION_IMAGE) \ + -t $(IMAGE_LATEST_TAG) \ + -t $(IMAGE_VERSION_TAG) \ -f Dockerfile . @echo "โœ… Built container images:" - @echo " - $(DOCKER_FULL_IMAGE)" - @echo " - $(DOCKER_VERSION_IMAGE)" - -.PHONY: docker-build-multiarch -docker-build-multiarch: ## Build multi-architecture images (amd64, arm64) using buildx - @echo "๐Ÿ—๏ธ Building multi-architecture roxie container images..." - @if ! command -v docker >/dev/null 2>&1; then \ - echo "โŒ Docker is required for multi-arch builds (buildx)"; \ - exit 1; \ - fi - @if ! docker buildx version >/dev/null 2>&1; then \ - echo "โŒ Docker buildx is required for multi-arch builds"; \ - echo "Install: docker buildx install"; \ - exit 1; \ - fi - @echo "Creating/using buildx builder..." - @docker buildx create --name roxie-builder --use 2>/dev/null || docker buildx use roxie-builder - @echo "Building for platforms: $(PLATFORMS)" - docker buildx build \ - --platform $(PLATFORMS) \ - --build-arg VERSION=$(VERSION) \ - --build-arg GIT_COMMIT=$(GIT_COMMIT) \ - --build-arg BUILD_DATE=$(BUILD_DATE) \ - -t $(DOCKER_FULL_IMAGE) \ - -t $(DOCKER_VERSION_IMAGE) \ - --load \ - -f Dockerfile . - @echo "โœ… Built multi-arch images:" - @echo " - $(DOCKER_FULL_IMAGE)" - @echo " - $(DOCKER_VERSION_IMAGE)" - -.PHONY: docker-build-push-multiarch -docker-build-push-multiarch: ## Build and push multi-arch images to registry (requires DOCKER_REGISTRY) - @echo "๐Ÿš€ Building and pushing multi-architecture images..." - @if [ -z "$(DOCKER_REGISTRY)" ]; then \ - echo "โŒ DOCKER_REGISTRY is required. Example: make docker-build-push-multiarch DOCKER_REGISTRY=ghcr.io/myorg"; \ - exit 1; \ - fi - @if ! docker buildx version >/dev/null 2>&1; then \ - echo "โŒ Docker buildx is required for multi-arch builds"; \ - exit 1; \ - fi - @docker buildx create --name roxie-builder --use 2>/dev/null || docker buildx use roxie-builder - docker buildx build \ - --platform $(PLATFORMS) \ - --build-arg VERSION=$(VERSION) \ - --build-arg GIT_COMMIT=$(GIT_COMMIT) \ - --build-arg BUILD_DATE=$(BUILD_DATE) \ - -t $(DOCKER_REGISTRY)/$(DOCKER_IMAGE):$(DOCKER_TAG) \ - -t $(DOCKER_REGISTRY)/$(DOCKER_IMAGE):$(DOCKER_VERSION_TAG) \ - -t $(DOCKER_REGISTRY)/$(DOCKER_IMAGE):$(VERSION) \ - --push \ - -f Dockerfile . - @echo "โœ… Pushed multi-arch images:" - @echo " - $(DOCKER_REGISTRY)/$(DOCKER_IMAGE):$(DOCKER_TAG)" - @echo " - $(DOCKER_REGISTRY)/$(DOCKER_IMAGE):$(DOCKER_VERSION_TAG)" - @echo " - $(DOCKER_REGISTRY)/$(DOCKER_IMAGE):$(VERSION)" + @echo " - $(IMAGE_LATEST_TAG)" + @echo " - $(IMAGE_VERSION_TAG)" + .PHONY: docker-build-arm64 docker-build-arm64: ## Build roxie Docker image for arm64 @@ -241,12 +209,12 @@ docker-build-arm64: ## Build roxie Docker image for arm64 --build-arg VERSION=$(VERSION) \ --build-arg GIT_COMMIT=$(GIT_COMMIT) \ --build-arg BUILD_DATE=$(BUILD_DATE) \ - -t $(DOCKER_IMAGE):$(DOCKER_TAG)-arm64 \ - -t $(DOCKER_IMAGE):$(DOCKER_VERSION_TAG)-arm64 \ + -t $(IMAGE_LATEST_TAG)-arm64 \ + -t $(IMAGE_VERSION_TAG)-arm64 \ -f Dockerfile . @echo "โœ… Built arm64 images:" - @echo " - $(DOCKER_IMAGE):$(DOCKER_TAG)-arm64" - @echo " - $(DOCKER_IMAGE):$(DOCKER_VERSION_TAG)-arm64" + @echo " - $(IMAGE_LATEST_TAG)-arm64" + @echo " - $(IMAGE_VERSION_TAG)-arm64" .PHONY: docker-build-amd64 docker-build-amd64: ## Build roxie Docker image for amd64 @@ -260,46 +228,12 @@ docker-build-amd64: ## Build roxie Docker image for amd64 --build-arg VERSION=$(VERSION) \ --build-arg GIT_COMMIT=$(GIT_COMMIT) \ --build-arg BUILD_DATE=$(BUILD_DATE) \ - -t $(DOCKER_IMAGE):$(DOCKER_TAG)-amd64 \ - -t $(DOCKER_IMAGE):$(DOCKER_VERSION_TAG)-amd64 \ + -t $(IMAGE_LATEST_TAG)-amd64 \ + -t $(IMAGE_VERSION_TAG)-amd64 \ -f Dockerfile . @echo "โœ… Built amd64 images:" - @echo " - $(DOCKER_IMAGE):$(DOCKER_TAG)-amd64" - @echo " - $(DOCKER_IMAGE):$(DOCKER_VERSION_TAG)-amd64" - -.PHONY: docker-test-podman -docker-test-podman: ## Test podman functionality inside the roxie container - @echo "๐Ÿงช Testing podman inside roxie container..." - @echo "" - @echo "1. Testing podman pull (operator bundle)..." - @$(CONTAINER_RUNTIME) run --rm \ - --entrypoint podman \ - $(DOCKER_FULL_IMAGE) \ - pull quay.io/rhacs-eng/stackrox-operator-bundle:v4.4.3 - @echo "" - @echo "2. Testing podman inspect..." - @$(CONTAINER_RUNTIME) run --rm \ - --entrypoint podman \ - $(DOCKER_FULL_IMAGE) \ - inspect quay.io/rhacs-eng/stackrox-operator-bundle:v4.4.3 > /dev/null - @echo "โœ“ Podman can pull and inspect images successfully" - @echo "" - @echo "3. Cleaning up test image..." - @$(CONTAINER_RUNTIME) run --rm \ - --entrypoint podman \ - $(DOCKER_FULL_IMAGE) \ - rmi quay.io/rhacs-eng/stackrox-operator-bundle:v4.4.3 - @echo "โœ“ Podman test complete" - -.PHONY: docker-clean -docker-clean: ## Remove roxie Docker images - @echo "๐Ÿงน Cleaning up roxie container images..." - @if [ -z "$(CONTAINER_RUNTIME)" ]; then \ - echo "โŒ No container runtime found. Please install docker or podman."; \ - exit 1; \ - fi - $(CONTAINER_RUNTIME) rmi $(DOCKER_FULL_IMAGE) 2>/dev/null || true - @echo "โœ… Cleanup complete" + @echo " - $(IMAGE_LATEST_TAG)-amd64" + @echo " - $(IMAGE_VERSION_TAG)-amd64" # Quick targets .PHONY: quick diff --git a/README.md b/README.md index 7b0b6e9..4727c86 100644 --- a/README.md +++ b/README.md @@ -22,77 +22,67 @@ roxie has been authored with significant AI contributions. ## Quick start -### Option 1: Container Image (Recommended for non-developers) +### Option 1: Deploying using Docker image (Recommended for non-developers) -**Requirements:** Only Docker/Podman and a kubeconfig! +**Requirements:** +* Working Docker setup +* kubeconfig configuration file +* quay.io registry credentials in the environment variables REGISTRY_USERNAME and REGISTRY_PASSWORD. -```bash -# Build the image (current platform) -make docker-build +Note that **Podman is currently not supported** for running +containerized roxie due to incomplete mapping of user IDs on macOS. This prevents the passing-in of the gcloud +configuration directory to be functional within the container, which is required for interacting with GKE clusters. -# This creates two tags: -# - roxie:latest -# - roxie:0.1- (e.g., roxie:0.1-4469692) - -# Build for multiple architectures (amd64 + arm64) -make docker-build-multiarch +Example for deploying Central and SecuredCluster to the current Kubernetes cluster context: +```bash +docker run --rm -it --privileged \ + -v ~/.config/gcloud:/.config/gcloud \ + -v $KUBECONFIG:/kubeconfig \ + -e REGISTRY_USERNAME=$REGISTRY_USERNAME \ + -e REGISTRY_PASSWORD=$REGISTRY_PASSWORD \ + ghcr.io/stackrox/roxie:latest deploy +``` -# Deploy ACS -make docker-deploy COMPONENT=both +A new roxie image for the current platform can be built using: -# Deploy with specific version tag (recommended for production) -make docker-deploy DOCKER_TAG=0.1-4469692 COMPONENT=both +```bash +make docker-build ``` -**Supported architectures:** linux/amd64, linux/arm64 +This creates two tags: +- `localhost/roxie:latest` +- `localhost/roxie:` -**Version Tags:** Every build automatically creates a version-tagged image (VERSION-COMMIT format) alongside `latest`. This enables: -- **Reproducible deployments** - Pin exact versions in CI/CD -- **Easy rollbacks** - Revert to any previous build -- **Version tracking** - Know exactly what code is running +Docker images can be built for the platforms `linux/amd64` and `linux/arm64`. See the `Makefile` for more +docker related targets. -### Option 2: Local Build (For development) +### Option 2: Deploying using local build Prerequisites: - `kubectl` configured to point at your target cluster -- The `roxctl` CLI installed +- `podman` is set up and available +- The `roxctl` CLI - The `roxie` branch forked and cloned to your local machine - -Get help: -```bash -./bin/roxie --help -``` - -Deploy Central (via operator): +Built using: ```bash -./bin/roxie deploy central +make build ``` -Deploy Secured Cluster (via operator): -```bash -# Ensure Central is reachable; roxie discovers and wires the endpoint -./bin/roxie deploy secured-cluster -``` - -Deploy both in one go: +Get help: ```bash -./bin/roxie deploy both +./roxie --help ``` -Use Helm instead of Operator: +Deploy using: ```bash -./bin/roxie deploy central --helm -./bin/roxie deploy secured-cluster --helm -# or -./bin/roxie deploy both --helm +./roxie deploy [ ] ``` +where `component` can be `central` or `sensor`. If not specified, both components will be deployed. -Teardown: +Similarly, the deployment(s) can be torn down using: ```bash -./bin/roxie teardown central -./bin/roxie teardown secured-cluster -./bin/roxie teardown both +./bin/roxie teardown [ ] ``` ## Development diff --git a/go.mod b/go.mod index 5481178..91f382c 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/stackrox/roxie -go 1.22 +go 1.25 require ( github.com/fatih/color v1.16.0