diff --git a/.github/workflows/example-http-node25-stable.yaml b/.github/workflows/example-http-node25-stable.yaml new file mode 100644 index 00000000..e31292fe --- /dev/null +++ b/.github/workflows/example-http-node25-stable.yaml @@ -0,0 +1,77 @@ +name: examples/http-node25 (stable) + +on: + workflow_dispatch: + + push: + branches: [main] + paths: + - '.github/workflows/example-http-node25-stable.yaml' + - 'http-node25/**' + - '!http-node25/README.md' + + pull_request: + types: [opened, synchronize, reopened] + branches: [main] + paths: + - '.github/workflows/example-http-node25-stable.yaml' + - 'http-node25/**' + - '!http-node25/README.md' + + schedule: + - cron: '15 15 * * 1-5' + +# Automatically cancel in-progress actions on the same branch +concurrency: + group: ${{ github.workflow }}-${{ github.event_name == 'pull_request_target' && github.head_ref || github.ref }} + cancel-in-progress: true + +env: + UKC_METRO: "https://api.${{ vars.UKC_METRO_STABLE }}.unikraft.cloud/v1" + UKC_TOKEN: ${{ secrets.UKC_TOKEN }} + KRAFTKIT_NO_CHECK_UPDATES: true + KRAFTKIT_LOG_LEVEL: debug + +jobs: + integration: + timeout-minutes: 60 + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Test + id: test + uses: unikraft/kraftkit@staging + with: + run: | + set -xe; + + cd http-node25; + + kraft cloud deploy \ + --no-start \ + --name http-node25-stable-${GITHUB_RUN_ID} \ + --runtime index.unikraft.io/official-testing/base-compat:latest \ + --subdomain http-node25-stable-${GITHUB_RUN_ID} \ + -p 443:8080 \ + -M 512 \ + .; + + # wait for the instance to start + kraft cloud vm start -w 5s http-node25-stable-${GITHUB_RUN_ID}; + sleep 5; + + curl -Lv --fail-with-body --max-time 10 https://http-node25-stable-${GITHUB_RUN_ID}.${{ vars.UKC_METRO_STABLE }}.unikraft.app + + - name: Cleanup + uses: unikraft/kraftkit@staging + if: always() + with: + run: | + set -xe; + + kraft cloud vm stop http-node25-stable-${GITHUB_RUN_ID} || true; + kraft cloud vm logs http-node25-stable-${GITHUB_RUN_ID} || true; + kraft cloud vm rm http-node25-stable-${GITHUB_RUN_ID} || true; + kraft cloud img rm index.unikraft.io/test/http-node25-stable-${GITHUB_RUN_ID} || true; diff --git a/.github/workflows/example-http-node25-staging.yaml b/.github/workflows/example-http-node25-staging.yaml new file mode 100644 index 00000000..d20a430a --- /dev/null +++ b/.github/workflows/example-http-node25-staging.yaml @@ -0,0 +1,77 @@ +name: examples/http-node25 (staging) + +on: + workflow_dispatch: + + push: + branches: [main] + paths: + - '.github/workflows/example-http-node25-staging.yaml' + - 'http-node25/**' + - '!http-node25/README.md' + + pull_request: + types: [opened, synchronize, reopened] + branches: [main] + paths: + - '.github/workflows/example-http-node25-staging.yaml' + - 'http-node25/**' + - '!http-node25/README.md' + + schedule: + - cron: '15 15 * * 1-5' + +# Automatically cancel in-progress actions on the same branch +concurrency: + group: ${{ github.workflow }}-${{ github.event_name == 'pull_request_target' && github.head_ref || github.ref }} + cancel-in-progress: true + +env: + UKC_METRO: "https://api.${{ vars.UKC_METRO_STAGING }}.unikraft.cloud/v1" + UKC_TOKEN: ${{ secrets.UKC_TOKEN }} + KRAFTKIT_NO_CHECK_UPDATES: true + KRAFTKIT_LOG_LEVEL: debug + +jobs: + integration: + timeout-minutes: 60 + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Test + id: test + uses: unikraft/kraftkit@staging + with: + run: | + set -xe; + + cd http-node25; + + kraft cloud deploy \ + --no-start \ + --name http-node25-staging-${GITHUB_RUN_ID} \ + --runtime index.unikraft.io/official-staging/base-compat:latest \ + --subdomain http-node25-staging-${GITHUB_RUN_ID} \ + -p 443:8080 \ + -M 512 \ + .; + + # wait for the instance to start + kraft cloud vm start -w 5s http-node25-staging-${GITHUB_RUN_ID}; + sleep 5; + + curl -Lv --fail-with-body --max-time 10 https://http-node25-staging-${GITHUB_RUN_ID}.${{ vars.UKC_METRO_STAGING }}.unikraft.app + + - name: Cleanup + uses: unikraft/kraftkit@staging + if: always() + with: + run: | + set -xe; + + kraft cloud vm stop http-node25-staging-${GITHUB_RUN_ID} || true; + kraft cloud vm logs http-node25-staging-${GITHUB_RUN_ID} || true; + kraft cloud vm rm http-node25-staging-${GITHUB_RUN_ID} || true; + kraft cloud img rm index.unikraft.io/test/http-node25-staging-${GITHUB_RUN_ID} || true; diff --git a/http-node25/Dockerfile b/http-node25/Dockerfile new file mode 100644 index 00000000..5ff08c28 --- /dev/null +++ b/http-node25/Dockerfile @@ -0,0 +1,14 @@ +FROM node:25-alpine AS node + +FROM scratch + +# Node binary +COPY --from=node /usr/local/bin/node /usr/bin/node + +# System libraries +COPY --from=node /lib/ld-musl-x86_64.so.1 /lib/ld-musl-x86_64.so.1 +COPY --from=node /usr/lib/libgcc_s.so.1 /usr/lib/libgcc_s.so.1 +COPY --from=node /usr/lib/libstdc++.so.6 /usr/lib/libstdc++.so.6 + +# Node HTTP server +COPY ./server.js /usr/src/server.js diff --git a/http-node25/Kraftfile b/http-node25/Kraftfile new file mode 100644 index 00000000..83dc7641 --- /dev/null +++ b/http-node25/Kraftfile @@ -0,0 +1,12 @@ +spec: v0.6 + +runtime: base-compat:latest + +labels: + cloud.unikraft.v1.instances/scale_to_zero.policy: "on" + cloud.unikraft.v1.instances/scale_to_zero.stateful: "false" + cloud.unikraft.v1.instances/scale_to_zero.cooldown_time_ms: 1000 + +rootfs: ./Dockerfile + +cmd: ["/usr/bin/node", "/usr/src/server.js"] diff --git a/http-node25/README.md b/http-node25/README.md new file mode 100644 index 00000000..d3512b53 --- /dev/null +++ b/http-node25/README.md @@ -0,0 +1,20 @@ +# Node 25 + +[Node,js](https://nodejs.org) is a free, open-source, cross-platform JavaScript runtime environment. + +To run Node.js on Unikraft Cloud, first [install the `kraft` CLI tool](https://unikraft.org/docs/cli). +Then clone this examples repository and `cd` into this directory, and invoke: + +```console +kraft cloud deploy --metro fra -p 443:8080 -M 512 . +``` + +The command will deploy the `server.js` file. + +After deploying, you can query the service using the provided URL. + +## Learn more + +- [Node.js's Documentation](https://nodejs.org/docs/latest/api/) +- [Unikraft Cloud's Documentation](https://unikraft.cloud/docs/) +- [Building `Dockerfile` Images with `Buildkit`](https://unikraft.org/guides/building-dockerfile-images-with-buildkit) diff --git a/http-node25/server.js b/http-node25/server.js new file mode 100644 index 00000000..e4de2967 --- /dev/null +++ b/http-node25/server.js @@ -0,0 +1,16 @@ +const http = require('http'); // Loads the http module + +http.createServer((request, response) => { + + // 1. Tell the browser everything is OK (Status code 200), and the data is in plain text + response.writeHead(200, { + 'Content-Type': 'text/plain' + }); + + // 2. Write the announced text to the body of the page + response.write('Hello, World!\n'); + + // 3. Tell the server that all of the response headers and body have been sent + response.end(); + +}).listen(8080); // 4. Tells the server what port to be on