diff --git a/.github/workflows/build-docker-image.yml b/.github/workflows/build-docker-image.yml new file mode 100644 index 0000000..07e39fd --- /dev/null +++ b/.github/workflows/build-docker-image.yml @@ -0,0 +1,31 @@ +name: Build Docker Image + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + - uses: s4u/maven-settings-action@64e42c454dbd42ef6370ac8539685755aedd205b + with: + servers: | + [{ + "id": "github-playground-micronaut", + "username": "epsilonlabs", + "password": "${{ secrets.GH_TOKEN_READ_MICRONAUT }}" + }] + - name: Download the backend JAR + run: mvn -B dependency:copy-dependencies -DexcludeTransitive=true + - name: Build the Docker image + run: docker build --tag playground-docker:micronaut . diff --git a/.github/workflows/push-docker-image.yml b/.github/workflows/push-docker-image.yml new file mode 100644 index 0000000..587e23e --- /dev/null +++ b/.github/workflows/push-docker-image.yml @@ -0,0 +1,61 @@ +name: Push Docker Image + +on: + push: + branches: [ "main", "micronaut" ] + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build: + runs-on: ubuntu-24.04 + permissions: + contents: read + packages: write + attestations: write + id-token: write + steps: + - uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + - uses: s4u/maven-settings-action@64e42c454dbd42ef6370ac8539685755aedd205b + with: + servers: | + [{ + "id": "github-playground-micronaut", + "username": "epsilonlabs", + "password": "${{ secrets.GH_TOKEN_READ_MICRONAUT }}" + }] + - name: Download the backend JAR + run: mvn -B dependency:copy-dependencies -DexcludeTransitive=true + - name: Log in to the Container registry + uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + - name: Build and push Docker image + id: push + uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + - name: Generate artifact attestation + uses: actions/attest-build-provenance@v1 + with: + subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}} + subject-digest: ${{ steps.push.outputs.digest }} + push-to-registry: true diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d392f0e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.jar diff --git a/Dockerfile b/Dockerfile index 26571c0..8ddbda8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,14 @@ FROM bitnami/git AS git_clones -# Clone the Epsilon Playground repo that contains the back-end -RUN git clone --depth=1 https://github.com/epsilonlabs/playground - # Clone the Epsilon website repo that contains the front-end RUN git clone --depth=1 https://github.com/eclipse/epsilon-website epsilon FROM nginx:latest AS webapp +LABEL maintainer "epsilon.devs@gmail.com" +LABEL org.opencontainers.image.authors="epsilon.devs@gmail.com" +LABEL org.opencontainers.image.licenses="EPL-2.0" + # Needed to avoid prompts blocking the build process ENV DEBIAN_FRONTEND=noninteractive @@ -16,21 +17,21 @@ ENV PORT=80 # Install Python RUN apt-get update \ - && apt-get install -y python3-minimal maven tini netcat-traditional \ + && apt-get install -y python3-minimal openjdk-17-jre-headless tini netcat-traditional \ && rm -rf /var/lib/apt/lists/* # Copy playground sources -COPY --from=git_clones /playground/ /playground/ COPY --from=git_clones /epsilon/mkdocs/docs/playground/ /etc/nginx/html/ -# Redirect /services/ URLs to the backend services running on ports 8001-8003 +# Create directory for playground all-in-one JAR +RUN mkdir -p /opt/playground +COPY ./target/dependency/http-server-*-all.jar /opt/playground/backend.jar + +# Redirect /services/ URLs to the backend services running on port 8080 ADD ./nginx.conf.template /etc/nginx.conf.template WORKDIR /playground -# Build fat jar with all services and dependencies -RUN mvn package - # Copy start script and make it executable ADD start.sh / RUN chmod +x /start.sh diff --git a/README.md b/README.md index 989f767..74b9543 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,58 @@ # Dockerized Epsilon Playground -This is a dockerized version of the [Epsilon Playground](https://eclipse.org/epsilon/playground). +This is a Dockerized version of the [Epsilon Playground](https://eclipse.org/epsilon/playground). -## Fetch and Run the Docker Hub Image +## Fetch and Run the Image -Use this command to fetch the latest version of the Epsilon Playground image from Docker Hub and run it in a container: +Use this command to fetch the latest version of the Epsilon Playground image from Github Packages and run it in a container: ```shell -docker run -p 8000:80 eclipseepsilon/playground:latest +docker run --rm -p 8000:80 ghcr.io/epsilonlabs/playground-docker:micronaut ``` ## Build and Run the Docker Image -If you prefer to build the image from source instead of fetching it from Docker Hub, clone the repository and use this command to build the image: +### Setting up token-based access to the playground-micronaut packages + +If you prefer to build the image from source instead of fetching it, first ensure that your `$HOME/.m2/settings.xml` has a [personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) that can read public repositories associated to the `github-playground-micronaut` server. + +The `settings.xml` file could look like this: + +```xml + + + + github-playground-micronaut + YOUR_GITHUB_USERNAME + YOUR_GITHUB_TOKEN + + + +``` + +### Building the image + +You can now clone the repository and use this command to build the image: ```shell -docker image build -t playground:latest . +./docker-build.sh ``` -and this command to run the image in a container: +### Running the image + +Use this command to run the image in a container: ```shell -docker run -p 8000:80 playground:latest +docker run -p 8000:80 playground-docker:micronaut ``` Should you need to customise the port that `nginx` runs on, you can do so through the `PORT` environment variable (as required by Google Cloud Build): ```shell -docker run --env PORT=8020 -p 8000:8020 playground:latest +docker run --env PORT=8020 -p 8000:8020 playground-docker:micronaut ``` ## Access the Epsilon Playground @@ -39,7 +64,7 @@ Once the container is up, go to http://localhost:8000 in your browser to access The dockerized version of the playground comes with the same set of examples as the [online version](https://eclipse.org/epsilon/playground). To start an instance with your own examples on the left hand side, use the following command, replacing `` with the **absolute** path of your `examples` folder. ```shell -docker run -p 8000:80 -v :/etc/nginx/html/examples playground:latest +docker run -p 8000:80 -v :/etc/nginx/html/examples playground-docker:micronaut ``` Your `examples` folder should contain an `examples.json` file with at least one example. A sample `examples` folder with a single example is provided [in this repository](examples) and more examples are available in the `examples` folder of [Epsilon's website repository](https://github.com/eclipse-epsilon/epsilon-website/tree/main/mkdocs/docs/playground/examples). @@ -49,23 +74,8 @@ Your `examples` folder should contain an `examples.json` file with at least one If you would like to use only the backend services and replace the front-end altogether, you can start an instance using the following command, replacing `` with the **absolute** path of your custom front-end folder. ```shell -docker run -p 8000:80 -v :/etc/nginx/html playground:latest +docker run -p 8000:80 -v :/etc/nginx/html playground-docker:micronaut ``` Your front-end folder should contain an `index.html` file. A minimal alternative front-end that you can use as a starting point for developing your custom front-end is available in the `miniground` folder of [this repository](miniground). -## Publish to Docker Hub - -Run the following command to build a `linux/amd64` image (replace `x.y.z` with the actual version you wish to release) - -``` -docker buildx build --no-cache --platform linux/amd64 -t eclipseepsilon/playground:x.y.z . -docker tag eclipseepsilon/playground:x.y.z eclipseepsilon/playground:latest -``` - -And then push it to Docker Hub - -``` -docker push eclipseepsilon/playground:x.y.z -docker push eclipseepsilon/playground:latest -``` - +Alternatively, you may want to use the [Docker image for the Micronaut-based backend](https://github.com/epsilonlabs/playground-micronaut/pkgs/container/playground-micronaut) directly, without using this image. diff --git a/docker-build.sh b/docker-build.sh new file mode 100755 index 0000000..ca10ece --- /dev/null +++ b/docker-build.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +mvn dependency:copy-dependencies -DexcludeTransitive=true +docker build -t playground-docker:micronaut . \ No newline at end of file diff --git a/nginx.conf.template b/nginx.conf.template index 980753d..06662f6 100644 --- a/nginx.conf.template +++ b/nginx.conf.template @@ -2,14 +2,14 @@ server { listen ${PORT}; location /services/RunEpsilonFunction { - proxy_pass http://127.0.0.1:8001/; + proxy_pass http://127.0.0.1:8080/epsilon; } location /services/FlexmiToPlantUMLFunction { - proxy_pass http://127.0.0.1:8002/; + proxy_pass http://127.0.0.1:8080/flexmi2plantuml; } location /services/EmfaticToPlantUMLFunction { - proxy_pass http://127.0.0.1:8003/; + proxy_pass http://127.0.0.1:8080/emfatic2plantuml; } } diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..9049f3a --- /dev/null +++ b/pom.xml @@ -0,0 +1,36 @@ + + 4.0.0 + + org.eclipse.epsilon.labs.playground + playground-docker + 1.0-SNAPSHOT + pom + + + + github-playground-micronaut + GitHub Epsilon Labs Playground Micronaut Apache Maven Packages + https://maven.pkg.github.com/epsilonlabs/playground-micronaut + + true + + + + + + UTF-8 + 17 + + + + + org.eclipse.epsilon.labs.playground.micronaut + http-server + 0.1-SNAPSHOT + all + + + + \ No newline at end of file diff --git a/start.sh b/start.sh index 0c8ea26..271124a 100644 --- a/start.sh +++ b/start.sh @@ -27,14 +27,8 @@ wait_for_service() { } # Functions for running Epsilon -java -cp target/org.eclipse.epsilon.playground.jar com.google.cloud.functions.invoker.runner.Invoker --target org.eclipse.epsilon.playground.RunEpsilonFunction --port 8001 & -wait_for_service Epsilon 127.0.0.1 8001 - -java -cp target/org.eclipse.epsilon.playground.jar com.google.cloud.functions.invoker.runner.Invoker --target org.eclipse.epsilon.playground.FlexmiToPlantUMLFunction --port 8002 & -wait_for_service Flexmi 127.0.0.1 8002 - -java -cp target/org.eclipse.epsilon.playground.jar com.google.cloud.functions.invoker.runner.Invoker --target org.eclipse.epsilon.playground.EmfaticToPlantUMLFunction --port 8003 & -wait_for_service Emfatic 127.0.0.1 8003 +java -jar /opt/playground/backend.jar & +wait_for_service Epsilon 127.0.0.1 8080 # nginx as frontend + reverse proxy envsubst < /etc/nginx.conf.template > /etc/nginx/conf.d/default.conf