-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #9 from open-AIMS/dockerisation
feat: add Dockerfile and GitHub workflow to publish to ghcr
- Loading branch information
Showing
7 changed files
with
331 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
input/ | ||
output/ | ||
.git* | ||
assets/ | ||
docs/ | ||
.config.toml | ||
Dockerfile | ||
.gitignore |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
# This workflow builds and publishes the ReefGuideAPI base Docker image to GitHub Container Registry (ghcr.io) | ||
# It is triggered when a push is made to the main branch. | ||
|
||
# Additional notes: | ||
# - The workflow uses the github.repository context to name the image, ensuring it's tied to your repository | ||
# - The GITHUB_TOKEN is automatically provided by GitHub Actions, no need to set it up manually | ||
# - The Docker metadata action automatically generates appropriate tags based on the release version | ||
# - The Julia version can be easily updated by changing the JULIA_VERSION environment variable at the top of the workflow | ||
|
||
name: Build and Publish ReefGuideAPI.jl Docker Image | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
release: | ||
types: [published] | ||
|
||
env: | ||
REGISTRY: ghcr.io | ||
IMAGE_NAME: ${{ github.repository }}/reefguide-src | ||
JULIA_VERSION: 1.10.5 | ||
# Set to true to use a fixed ReefGuideAPI version for debugging, false to use the release version | ||
USE_FIXED_REEFGUIDEAPI_VERSION: true | ||
# TODO this doesn't make sense until the releasing is sorted out | ||
# The fixed ReefGuideAPI version to use when USE_FIXED_REEFGUIDEAPI_VERSION is true | ||
FIXED_REEFGUIDEAPI_VERSION: "0.1.0" | ||
|
||
jobs: | ||
build-and-push-image: | ||
runs-on: ubuntu-latest | ||
permissions: | ||
contents: read | ||
packages: write | ||
|
||
steps: | ||
# Step 1: Checkout the repository code | ||
- name: Checkout repository | ||
uses: actions/checkout@v3 | ||
|
||
# Step 2: Extract the version number from the release tag | ||
# This removes the 'v' prefix from the tag (e.g., 'v1.2.3' becomes '1.2.3') | ||
- name: Extract version from tag | ||
id: get_version | ||
run: | | ||
if ${{ env.USE_FIXED_REEFGUIDEAPI_VERSION == 'true' }}; then | ||
echo "Using fixed ReefGuideAPI version: ${{ env.FIXED_REEFGUIDEAPI_VERSION }}" | ||
echo "VERSION=${{ env.FIXED_REEFGUIDEAPI_VERSION }}" >> $GITHUB_OUTPUT | ||
elif [ "${{ github.event_name }}" = "release" ]; then | ||
RELEASE_VERSION=${GITHUB_REF#refs/tags/v} | ||
echo "Using release version: $RELEASE_VERSION" | ||
echo "VERSION=$RELEASE_VERSION" >> $GITHUB_OUTPUT | ||
else | ||
echo "No version specified and not a release event. Using default version." | ||
echo "VERSION=${{ env.FIXED_REEFGUIDEAPI_VERSION }}" >> $GITHUB_OUTPUT | ||
fi | ||
# Step 3: Log in to the GitHub Container Registry | ||
# This uses the provided GitHub token for authentication | ||
- name: Log in to the Container registry | ||
uses: docker/login-action@v2 | ||
with: | ||
registry: ${{ env.REGISTRY }} | ||
username: ${{ github.actor }} | ||
password: ${{ secrets.GITHUB_TOKEN }} | ||
|
||
# Step 4: Extract metadata for Docker | ||
# This step generates tags and labels for the Docker image | ||
- name: Extract metadata (tags, labels) for Docker | ||
id: meta | ||
uses: docker/metadata-action@v4 | ||
with: | ||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | ||
tags: | | ||
type=semver,pattern={{version}} | ||
type=semver,pattern={{major}}.{{minor}} | ||
type=semver,pattern={{major}}.{{minor}}.{{patch}} | ||
type=semver,pattern={{major}} | ||
type=ref,event=branch | ||
type=sha,format=long | ||
type=sha,format=short | ||
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }} | ||
# Step 5: Build and push the Docker image | ||
# This step builds the reefguide-src image and pushes it to the registry | ||
- name: Build and push Docker image | ||
uses: docker/build-push-action@v4 | ||
with: | ||
context: . | ||
target: reefguide-src # Specifies which stage of the Dockerfile to build | ||
push: true # Pushes the image to the registry | ||
tags: ${{ steps.meta.outputs.tags }} # Uses the tags generated in the metadata step | ||
labels: ${{ steps.meta.outputs.labels }} # Uses the labels generated in the metadata step | ||
# Passes the Julia and ReefGuideAPI versions to the Dockerfile | ||
# TODO bring back this build arg when releasing is ready | ||
# REEFGUIDE_VERSION=${{ steps.get_version.outputs.VERSION }} | ||
build-args: | | ||
JULIA_VERSION=${{ env.JULIA_VERSION }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,3 +22,5 @@ docs/site/ | |
sandbox/ | ||
|
||
/.config.toml | ||
|
||
data |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
# See https://hub.docker.com/_/julia for valid versions. | ||
ARG JULIA_VERSION="1.10.4" | ||
|
||
#------------------------------------------------------------------------------ | ||
# internal-base build target: julia with OS updates and an empty @reefguide | ||
# Julia environment prepared for use. NOT intended for standalone use. | ||
#------------------------------------------------------------------------------ | ||
FROM julia:${JULIA_VERSION}-bookworm AS internal-base | ||
|
||
# Record the actual base image used from the FROM command as label in the compiled image | ||
ARG BASE_IMAGE=$BASE_IMAGE | ||
LABEL org.opencontainers.image.base.name=${BASE_IMAGE} | ||
|
||
# Update all pre-installed OS packages (to get security updates) | ||
# and add a few extra utilities | ||
RUN --mount=target=/var/lib/apt/lists,type=cache,sharing=locked \ | ||
--mount=target=/var/cache/apt,type=cache,sharing=locked \ | ||
apt-get update \ | ||
&& apt-get -y upgrade \ | ||
&& apt-get install --no-install-recommends -y \ | ||
git \ | ||
less \ | ||
nano \ | ||
&& apt-get clean \ | ||
&& apt-get autoremove --purge \ | ||
&& rm -rf /var/lib/apt/lists/* | ||
|
||
# Tweak the JULIA_DEPOT_PATH setting so that our shared environments will end up | ||
# in a user-agnostic location, not in ~/.julia => /root/.julia which is the default. | ||
# See https://docs.julialang.org/en/v1/manual/environment-variables/#JULIA_DEPOT_PATH | ||
# This allows apps derived from this image to drop privileges and run as non-root | ||
# user accounts, but still activate environments configured by this dockerfile. | ||
ENV JULIA_DEPOT_PATH="/usr/local/share/julia" | ||
|
||
# Prepare an empty @reefguide Julia environment for derived images to use - this is created in the shared depot path | ||
RUN mkdir -p "${JULIA_DEPOT_PATH}" && \ | ||
chmod 0755 "${JULIA_DEPOT_PATH}" && \ | ||
julia -e 'using Pkg; Pkg.activate("reefguide", shared=true)' | ||
|
||
# Ensure the @reefguide environment is in the load path for Julia, so that apps derived | ||
# from this image can access any packages installed to there. | ||
# (See https://docs.julialang.org/en/v1/manual/environment-variables/#JULIA_LOAD_PATH) | ||
ENV JULIA_LOAD_PATH="@:@reefguide:@v#.#:@stdlib" | ||
|
||
# Run Julia commands by default as the container launches. | ||
# Derived applications should override the command. | ||
ENTRYPOINT ["julia", "--project=@reefguide"] | ||
|
||
|
||
#------------------------------------------------------------------------------ | ||
# reefguide-base build target: ReefGuideAPI.jl preinstalled as a non-dev package. | ||
# Use `--target=reefguide-base` on your `docker build command to build *just* this. | ||
#------------------------------------------------------------------------------ | ||
|
||
# TODO enable and update this once the package is available from registry | ||
# FROM internal-base AS reefguide-base | ||
# | ||
# # What version of ReefGuideAPI.jl from package registry to install in reefguide-base | ||
# # TODO this doesn't make sense yet | ||
# ARG REEFGUIDE_VERSION="0.1.0" | ||
# | ||
# # Which julia package registry version to install | ||
# ENV REEFGUIDE_VERSION=$REEFGUIDE_VERSION | ||
# | ||
# # Try to coerce Julia to build across multiple targets | ||
# ENV JULIA_CPU_TARGET=x86_64;haswell;skylake;skylake-avx512;tigerlake | ||
# | ||
# # Install ReefGuideAPI.jl into the @reefguide shared environment as an unregistered package. | ||
# # - Allow the package source and version to be overridden at build-time. | ||
# # - Include citation information for ReefGuideAPI.jl in the image labels. | ||
# RUN mkdir -p "${JULIA_DEPOT_PATH}" && \ | ||
# chmod 0755 "${JULIA_DEPOT_PATH}" && \ | ||
# julia --project=@reefguide -e "using Pkg; Pkg.add(name=\"ReefGuideAPI\", version=\"${REEFGUIDE_VERSION}\"); Pkg.instantiate(); Pkg.precompile(); using ReefGuideAPI;" | ||
# LABEL au.gov.aims.reefguideapi.source="https://github.com/open-AIMS/ReefGuideAPI.jl/releases/tag/v${REEFGUIDE_VERSION}" \ | ||
# au.gov.aims.reefguideapi.version="${REEFGUIDE_VERSION}" \ | ||
# au.gov.aims.reefguideapi.vendor="Australian Institute of Marine Science" \ | ||
# au.gov.aims.reefguideapi.licenses=MIT | ||
# | ||
# # Expect to include the prepped data at /data/reefguide and the config at | ||
# # /data/.config.toml | ||
# VOLUME ["/data/reefguide"] | ||
# | ||
# EXPOSE 8000 | ||
# | ||
# # Run Julia commands by default as the container launches. | ||
# # Derived applications should override the command. | ||
# ENTRYPOINT ["julia", "--project=@reefguide", "-t", "1,auto", "-e", "using ReefGuideAPI; ReefGuideAPI.start_server(\"/data/reefguide/config.toml\")"] | ||
|
||
#------------------------------------------------------------------------------ | ||
# reefguide-src build target: installs directly from source files in this repo. | ||
#------------------------------------------------------------------------------ | ||
FROM internal-base AS reefguide-src | ||
|
||
ENV REEFGUIDE_ENV_DIR="${JULIA_DEPOT_PATH}/environments/reefguide" \ | ||
REEFGUIDE_SRC_DIR="/usr/local/src/reefguide" | ||
|
||
# Try to coerce Julia to build across multiple targets | ||
ENV JULIA_CPU_TARGET=x86_64;haswell;skylake;skylake-avx512;tigerlake | ||
|
||
# Install the versioned .toml file(s) into the shared reefguide environment and use | ||
# those to set up the ReefGuideAPI source code as a development package in the | ||
# shared @reefguide environment, pre-installing and precompiling dependencies. | ||
WORKDIR "${REEFGUIDE_SRC_DIR}" | ||
COPY ./Project.toml ./Project.toml | ||
COPY ./Manifest.toml ./Manifest.toml | ||
RUN julia --project=@reefguide -e 'using Pkg; Pkg.instantiate(verbose=true)' | ||
|
||
# Install the ReefGuideAPI source code and configure it as a development | ||
# package in the @reefguide shared environment. | ||
# Should be v speedy if the .toml file is unchanged, because all the | ||
# dependencies *should* already be installed. | ||
COPY ./src src | ||
RUN julia --project=@reefguide \ | ||
-e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.precompile(); using ReefGuideAPI;' | ||
|
||
# Expect to include the prepped data at /data/reefguide and the config at | ||
# /data/.config.toml | ||
VOLUME ["/data/reefguide"] | ||
|
||
EXPOSE 8000 | ||
|
||
# Run Julia commands by default as the container launches. | ||
# Derived applications should override the command. | ||
ENTRYPOINT ["julia", "--project=@reefguide", "-t", "1,auto", "-e", "using ReefGuideAPI; ReefGuideAPI.start_server(\"/data/reefguide/config.toml\")"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
--- | ||
#------------------------------------------------- | ||
# Docker compose for ReefGuideAPI.jl docker image | ||
#-------------------------------------------------- | ||
version: "3.8" | ||
|
||
services: | ||
# TODO enable and update this once the release version is ready | ||
# reefguide-base: | ||
# build: | ||
# args: | ||
# # TODO when versioning is setup improve this | ||
# REEFGUIDE_VERSION: "v0.1.0" | ||
# JULIA_VERSION: "1.10.4" | ||
# context: . | ||
# target: reefguide-base | ||
# image: ReefGuideAPI.jl/reefguide-base:latest | ||
# volumes: | ||
# - ./data:/data/reefguide | ||
reefguide-src: | ||
build: | ||
context: . | ||
target: reefguide-src | ||
image: ReefGuideAPI.jl/reefguide-base:latest | ||
volumes: | ||
- ./data:/data/reefguide | ||
ports: | ||
- 8000:8000 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters