Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build multi-platform Docker images (arm64/amd64) #544

Merged
merged 1 commit into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
32 changes: 21 additions & 11 deletions .github/workflows/build-and-push.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,25 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- name: Install Cosign
uses: sigstore/[email protected]

- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

# Add support for more platforms with QEMU
# https://github.com/docker/setup-qemu-action
- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# https://github.com/docker/setup-buildx-action
with:
platforms: linux/amd64,linux/arm64
# Sets up docker build command as an alias to docker buildx
install: true

- name: Checkout
uses: actions/checkout@v4
with:
Expand All @@ -43,23 +53,23 @@ jobs:
java-version: '21'
cache: 'maven'

- name: Build without tests
- name: Build application packages
run: |
make install
make package

- name: Build images
- name: Build and push images
run: |
make build-image

- name: Push images
run: |
make push-image
REPACKAGE=false make build-image-multiplatform

- name: Remove project jars from cached repository
run: |
rm -rf ~/.m2/repository/org/geoserver
find ~/.m2/repository -name "*SNAPSHOT*" -type d | xargs rm -rf {}

- name: Install Cosign
if: ${{ startsWith(github.ref, 'refs/tags/') }}
uses: sigstore/[email protected]

- name: Sign images
if: ${{ startsWith(github.ref, 'refs/tags/') }}
env:
Expand Down
79 changes: 57 additions & 22 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
all: install test build-image

TAG=$(shell mvn help:evaluate -Dexpression=project.version -q -DforceStdout)

COSIGN_PASSWORD := $(COSIGN_PASSWORD)
COMPOSE_PGCONFIG_OPTIONS ?= -f compose.yml -f catalog-pgconfig.yml
COMPOSE_DATADIR_OPTIONS ?= -f compose.yml -f catalog-datadir.yml
Expand All @@ -10,6 +11,8 @@ COMPOSE_ACCEPTANCE_DATADIR_OPTIONS ?= --project-name gscloud-acceptance-datadir
UID=$(shell id -u)
GID=$(shell id -g)

REPACKAGE ?= true

.PHONY: clean
clean:
./mvnw clean
Expand All @@ -26,44 +29,76 @@ format:
install:
./mvnw clean install -DskipTests -ntp -T4 -U

.PHONY: package
package:
./mvnw clean package -DskipTests -ntp -T4 -U

.PHONY: test
test:
./mvnw verify -ntp -T4

.PHONY: build-image
build-image: build-base-images build-image-infrastructure build-image-geoserver

.PHONY: build-base-images
build-base-images:
./mvnw clean package -f src/apps/base-images -DskipTests -T4 && \
COMPOSE_DOCKER_CLI_BUILD=1 \
DOCKER_BUILDKIT=1 \
TAG=$(TAG) \
docker compose -f docker-build/base-images.yml build
build-base-images: package-base-images
TAG=$(TAG) docker compose -f docker-build/base-images.yml build

.PHONY: build-image-infrastructure
build-image-infrastructure:
./mvnw clean package -f src/apps/infrastructure -DskipTests -T4 && \
build-image-infrastructure: package-infrastructure-images
TAG=$(TAG) docker compose -f docker-build/infrastructure.yml build

.PHONY: build-image-geoserver
build-image-geoserver: package-geoserver-images
TAG=$(TAG) docker compose -f docker-build/geoserver.yml build

.PHONY: build-image-multiplatform
build-image-multiplatform: build-base-images-multiplatform build-image-infrastructure-multiplatform build-image-geoserver-multiplatform

.PHONY: build-base-images-multiplatform
build-base-images-multiplatform: package-base-images
COMPOSE_DOCKER_CLI_BUILD=1 \
DOCKER_BUILDKIT=1 \
TAG=$(TAG) \
docker compose -f docker-build/infrastructure.yml build
docker compose -f docker-build/base-images-multiplatform.yml build --push

.PHONY: build-image-geoserver
build-image-geoserver:
./mvnw clean package -f src/apps/geoserver -DskipTests -T4 && \
.PHONY: build-image-infrastructure-multiplatform
build-image-infrastructure-multiplatform: package-infrastructure-images
COMPOSE_DOCKER_CLI_BUILD=1 \
DOCKER_BUILDKIT=1 \
TAG=$(TAG) \
docker compose -f docker-build/geoserver.yml build
docker compose -f docker-build/infrastructure-multiplatform.yml build --push

.PHONY: build-image
build-image: build-base-images build-image-infrastructure build-image-geoserver

.PHONY: push-image
push-image:
.PHONY: build-image-geoserver-multiplatform
build-image-geoserver-multiplatform: package-geoserver-images
COMPOSE_DOCKER_CLI_BUILD=1 \
DOCKER_BUILDKIT=1 \
TAG=$(TAG) \
docker compose \
-f docker-build/infrastructure.yml \
-f docker-build/geoserver.yml \
push
docker compose -f docker-build/geoserver-multiplatform.yml build --push

.PHONY: package-base-images
package-base-images:
ifeq ($(REPACKAGE), true)
./mvnw clean package -f src/apps/base-images -DskipTests -T4
else
@echo "Not re-packaging base images, assuming the target/*-bin.jar files exist"
endif

.PHONY: package-infrastructure-images
package-infrastructure-images:
ifeq ($(REPACKAGE), true)
./mvnw clean package -f src/apps/infrastructure -DskipTests -T4
else
@echo "Not re-packaging infra images, assuming the target/*-bin.jar files exist"
endif

.PHONY: package-geoserver-images
package-geoserver-images:
ifeq ($(REPACKAGE), true)
./mvnw clean package -f src/apps/geoserver -DskipTests -T4
else
@echo "Not re-packaging geoserver images, assuming the target/*-bin.jar files exist"
endif

.PHONY: sign-image
sign-image:
Expand Down
36 changes: 28 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,29 +141,49 @@ which you can also run individually during development depending on your needs.
you'd run `make build-image-geoserver` to speed up the process when made a change and want
to test the geoserver containers, without having to rebuild the base and infra images.

### Targeted builds
#### Multiplatform (amd64/arm64) images

*GeoServer Cloud*-specific modules source code is under the `src/` directory.
The "build and push" github actions job will create `linux/amd64` and `linux/arm64` multi-platform images by running

When you already have the `2.23.0-CLOUD` GeoServer artifacts, you can choose to only build these projects, either by:
```bash
make build-image-multiplatform
```

This target assumes `buildx` is set up as an alias for `docker build` and there's a build runner that supports both platforms.

Building multi-platform images requires pushing to the container registry, so the `build-image-multiplatform` target
will run `docker compose build --push` with the appropriate `*-multiplatform.yml` compose file from the `docker-build` directory.

If you want to build the multi-platform images yourself:

* Install QEmu
* Run the following command to create a `buildx` builder:

```bash
$ ./mvnw clean install -f src/
docker buildx create --name gscloud-builder --driver docker-container --bootstrap --use
```

Or
In order to push the images to your own dockerhub account, use the `RESPOSITORY` environment variable, for example:

```bash
REPOSITORY=groldan make build-image-multiplatform
```

will build and push `groldan/<image-name>:<version>` tagged images instead of the default `geoservercloud/<image-name>:<version>` ones.


Finally, to remove the multi-platform builder, run

```bash
$ cd src/
$ ../mvnw clean install
docker buildx stop gscloud-builder
docker buildx rm gscloud-builder
```

### Note on custom upstream GeoServer version

*GeoServer Cloud* depends on a custom GeoServer branch, `gscloud/gs_version/integration`, which contains patches to upstream GeoServer that have not yet been integrated into the mainstream `main` branch.

Additionally, this branch changes the artifact versions (e.g. from `2.23-SNAPSHOT` to `2.23.0-CLOUD`), to avoid confusing maven if you also work with vanilla GeoServer, and to avoid your IDE downloading the latest `2.23-SNAPSHOT` artifacts from the OsGeo maven repository, overriding your local maven repository ones, and having confusing compilation errors that would require re-building the branch we need.
Additionally, this branch changes the artifact versions (e.g. from `2.26.0` to `2.26.0.0`), to avoid confusing maven if you also work with vanilla GeoServer, and to avoid your IDE downloading the latest `2.23-SNAPSHOT` artifacts from the OsGeo maven repository, overriding your local maven repository ones, and having confusing compilation errors that would require re-building the branch we need.

The `gscloud/gs_version/integration` branch is checked out as a submodule on the [camptocamp/geoserver-cloud-geoserver](https://github.com/camptocamp/geoserver-cloud-geoserver) repository, which publishes the custom geoserver maven artifacts to the Github maven package registry.

Expand Down
2 changes: 2 additions & 0 deletions docker-build/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
REPOSITORY=geoservercloud

26 changes: 26 additions & 0 deletions docker-build/base-images-multiplatform.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
services:
base-image-jre:
extends:
file: templates.yml
service: multi-platform
image: ${REPOSITORY}/gs-cloud-base-jre:${TAG}
build:
context: ../src/apps/base-images/jre/

base-image-spring-boot:
extends:
file: templates.yml
service: multi-platform
image: ${REPOSITORY}/gs-cloud-base-spring-boot:${TAG}
depends_on: [base-image-jre]
build:
context: ../src/apps/base-images/spring-boot/

base-image-geoserver:
extends:
file: templates.yml
service: multi-platform
image: ${REPOSITORY}/gs-cloud-base-geoserver-image:${TAG}
depends_on: [base-image-spring-boot]
build:
context: ../src/apps/base-images/geoserver/
25 changes: 12 additions & 13 deletions docker-build/base-images.yml
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
services:
base-image-jre:
image: geoservercloud/gs-cloud-base-jre:${TAG}
extends:
file: templates.yml
service: current-platform
image: ${REPOSITORY}/gs-cloud-base-jre:${TAG}
build:
no_cache: true
pull: true
context: ../src/apps/base-images/jre/

base-image-spring-boot:
image: geoservercloud/gs-cloud-base-spring-boot:${TAG}
extends:
file: templates.yml
service: current-platform
image: ${REPOSITORY}/gs-cloud-base-spring-boot:${TAG}
depends_on: [base-image-jre]
build:
no_cache: true
pull: false
context: ../src/apps/base-images/spring-boot/
args:
TAG: ${TAG}

base-image-geoserver:
image: geoservercloud/gs-cloud-base-geoserver-image:${TAG}
extends:
file: templates.yml
service: current-platform
image: ${REPOSITORY}/gs-cloud-base-geoserver-image:${TAG}
depends_on: [base-image-spring-boot]
build:
no_cache: true
pull: false
context: ../src/apps/base-images/geoserver/
args:
TAG: ${TAG}
58 changes: 58 additions & 0 deletions docker-build/geoserver-multiplatform.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
services:
wfs:
extends:
file: templates.yml
service: multi-platform
image: ${REPOSITORY}/geoserver-cloud-wfs:${TAG}
build:
context: ../src/apps/geoserver/wfs/

wms:
extends:
file: templates.yml
service: multi-platform
image: ${REPOSITORY}/geoserver-cloud-wms:${TAG}
build:
context: ../src/apps/geoserver/wms/

wcs:
extends:
file: templates.yml
service: multi-platform
image: ${REPOSITORY}/geoserver-cloud-wcs:${TAG}
build:
context: ../src/apps/geoserver/wcs/

wps:
extends:
file: templates.yml
service: multi-platform
image: ${REPOSITORY}/geoserver-cloud-wps:${TAG}
build:
context: ../src/apps/geoserver/wps/

rest:
extends:
file: templates.yml
service: multi-platform
image: ${REPOSITORY}/geoserver-cloud-rest:${TAG}
build:
context: ../src/apps/geoserver/restconfig/

webui:
extends:
file: templates.yml
service: multi-platform
image: ${REPOSITORY}/geoserver-cloud-webui:${TAG}
build:
context: ../src/apps/geoserver/webui/

gwc:
extends:
file: templates.yml
service: multi-platform
image: ${REPOSITORY}/geoserver-cloud-gwc:${TAG}
build:
context: ../src/apps/geoserver/gwc/


Loading
Loading