diff --git a/hello-arc-windows/src/app/Dockerfile b/hello-arc-windows/src/app/Dockerfile new file mode 100644 index 00000000..b73ef84e --- /dev/null +++ b/hello-arc-windows/src/app/Dockerfile @@ -0,0 +1,32 @@ +FROM azurearcjumpstart.azurecr.io/node-windows-servercore:ltsc2019 + +ARG IMAGE_CREATE_DATE +ARG IMAGE_VERSION +ARG IMAGE_SOURCE_REVISION + +# Metadata as defined in OCI image spec annotations - https://github.com/opencontainers/image-spec/blob/master/annotations.md +LABEL org.opencontainers.image.title="Hello Arc!" \ + org.opencontainers.image.description="Provides a demo app to deploy to an Azure Arc-enabled Kubernetes cluster. It displays a message, the name of the pod and details of the node it is deployed to." \ + org.opencontainers.image.created=$IMAGE_CREATE_DATE \ + org.opencontainers.image.version=$IMAGE_VERSION \ + org.opencontainers.image.authors="Jan Egil Ring" \ + org.opencontainers.image.url="azurearcjumpstart.azurecr.io/hello-arc:windows" \ + org.opencontainers.image.documentation="https://github.com/microsoft/azure-arc-jumpstart-apps/tree/main/hello-arc-windows" \ + org.opencontainers.image.vendor="Microsoft" \ + org.opencontainers.image.licenses="MIT" \ + org.opencontainers.image.source="https://github.com/microsoft/azure-arc-jumpstart-apps.git" \ + org.opencontainers.image.revision=$IMAGE_SOURCE_REVISION + +# Create app directory +RUN mkdir -p c:\app +WORKDIR c:\\app + +# Install app dependencies +COPY package.json c:\\app +RUN npm install + +# Bundle app source +COPY . c:\\app + +#USER node +CMD [ "C:\\nodejs\\npm.cmd", "start" ] diff --git a/hello-arc-windows/src/app/package.json b/hello-arc-windows/src/app/package.json new file mode 100644 index 00000000..a133b318 --- /dev/null +++ b/hello-arc-windows/src/app/package.json @@ -0,0 +1,19 @@ +{ + "name": "hello-kubernetes", + "version": "1.8.0", + "description": "Hello Kubernetes!", + "author": "Paul Bouwer", + "license": "MIT", + "main": "server.js", + "scripts": { + "start": "node server.js" + }, + "dependencies": { + "bytes": "^3.1.0", + "express": "^4.17.1", + "express-handlebars": "^3.1.0", + "handlebars": "^4.7.6", + "minimist": ">=1.2.5", + "morgan": "^1.9.1" + } +} diff --git a/hello-arc-windows/src/app/server.js b/hello-arc-windows/src/app/server.js new file mode 100644 index 00000000..2b53abe1 --- /dev/null +++ b/hello-arc-windows/src/app/server.js @@ -0,0 +1,28 @@ +var express = require('express'); +var exphbs = require('express-handlebars'); +var app = express(); +var os = require("os"); +var morgan = require('morgan'); + +app.engine('handlebars', exphbs({defaultLayout: 'main'})); +app.set('view engine', 'handlebars'); +app.use(express.static('static')); +app.use(morgan('combined')); + +// Configuration +var port = process.env.PORT || 8080; +var message = process.env.MESSAGE || "Hello Azure Arc GitOps Demo!"; + +app.get('/', function (req, res) { + res.render('home', { + message: message, + platform: os.type(), + release: os.release(), + hostName: os.hostname() + }); +}); + +// Set up listener +app.listen(port, function () { + console.log("Listening on: http://%s:%s", os.hostname(), port); +}); \ No newline at end of file diff --git a/hello-arc-windows/src/app/static/css/main.css b/hello-arc-windows/src/app/static/css/main.css new file mode 100644 index 00000000..ca013578 --- /dev/null +++ b/hello-arc-windows/src/app/static/css/main.css @@ -0,0 +1,49 @@ +body { + margin:0; + padding:0; + background-color:white; +} + +div.main { + text-align: center; +} + +div.main img { + margin: 40px 0; +} + +div.content { + color:#f2f2f2; +} +.content #message { + margin: 10px 0 50px 0; + padding: 30px 0; + font-family: 'Ubuntu', sans-serif; + font-weight: 300; + font-size: 44pt; + background-color: #1a6ad3; + /* border-top: 2px solid #909090; + border-bottom: 2px solid #909090; */ +} + +.content #info { + margin: 0 auto; + font-family: 'Ubuntu', sans-serif; + font-weight: 300; + font-size: 16pt; + color: black; +} + +.content #info table { + margin: 10px auto; +} + +.content #info table th { + text-align: right; + padding-right: 20px; +} + +.content #info table td { + text-align: left; +} + diff --git a/hello-arc-windows/src/app/static/images/logo.png b/hello-arc-windows/src/app/static/images/logo.png new file mode 100644 index 00000000..c3948714 Binary files /dev/null and b/hello-arc-windows/src/app/static/images/logo.png differ diff --git a/hello-arc-windows/src/app/views/home.handlebars b/hello-arc-windows/src/app/views/home.handlebars new file mode 100644 index 00000000..88daf470 --- /dev/null +++ b/hello-arc-windows/src/app/views/home.handlebars @@ -0,0 +1,16 @@ +
+ {{ message }} +
+
+ + + + + + + + + +
pod:{{ hostName }}
node:{{ platform }} ({{ release }})
+ +
diff --git a/hello-arc-windows/src/app/views/layouts/main.handlebars b/hello-arc-windows/src/app/views/layouts/main.handlebars new file mode 100644 index 00000000..b9a714fc --- /dev/null +++ b/hello-arc-windows/src/app/views/layouts/main.handlebars @@ -0,0 +1,18 @@ + + + + Hello Kubernetes! + + + + + +
+ +
+ {{{body}}} +
+
+ + + diff --git a/hello-arc-windows/src/node/Dockerfile b/hello-arc-windows/src/node/Dockerfile new file mode 100644 index 00000000..e28bb38c --- /dev/null +++ b/hello-arc-windows/src/node/Dockerfile @@ -0,0 +1,48 @@ +FROM mcr.microsoft.com/windows/servercore:ltsc2019 + +SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] + +# PATH isn't actually set in the Docker image, so we have to set it from within the container +RUN $newPath = ('C:\nodejs;{0}\Yarn\bin;{1}' -f $env:LOCALAPPDATA, $env:PATH); \ + Write-Host ('Updating PATH: {0}' -f $newPath); \ + [Environment]::SetEnvironmentVariable('PATH', $newPath, [EnvironmentVariableTarget]::Machine) +# doing this first to share cache across versions more aggressively + +ENV NODE_VERSION 18.14.0 +ENV NODE_SHA256 2e8f00da72f6bd993e3b980ff844b948baf936e1e67e3694a7a3e5f6f7c9beb4 + +RUN $url = ('https://nodejs.org/dist/v{0}/node-v{0}-win-x64.zip' -f $env:NODE_VERSION); \ + Write-Host ('Downloading {0} ...' -f $url); \ + Invoke-WebRequest -Uri $url -OutFile 'node.zip'; \ + \ + Write-Host ('Verifying sha256 ({0}) ...' -f $env:NODE_SHA256); \ + if ((Get-FileHash node.zip -Algorithm sha256).Hash -ne $env:NODE_SHA256) { throw 'SHA256 mismatch' }; \ + \ + Write-Host 'Expanding ...'; \ + Expand-Archive node.zip -DestinationPath C:\; \ + \ + Write-Host 'Renaming ...'; \ + Rename-Item -Path ('C:\node-v{0}-win-x64' -f $env:NODE_VERSION) -NewName 'C:\nodejs'; \ + \ + Write-Host 'Removing ...'; \ + Remove-Item node.zip -Force; \ + \ + Write-Host 'Verifying ("node --version") ...'; \ + node --version; \ + Write-Host 'Verifying ("npm --version") ...'; \ + npm --version; \ + \ + Write-Host 'Complete.' + +ENV YARN_VERSION 1.22.17 + +# "It is recommended to install Yarn through the npm package manager" (https://classic.yarnpkg.com/en/docs/install) +RUN Write-Host 'Installing "yarn" ...'; \ + npm install --global ('yarn@{0}' -f $env:YARN_VERSION); \ + \ + Write-Host 'Verifying ("yarn --version") ...'; \ + yarn --version; \ + \ + Write-Host 'Complete.' + +CMD [ "node" ] \ No newline at end of file diff --git a/hello-arc-windows/src/test.ps1 b/hello-arc-windows/src/test.ps1 new file mode 100644 index 00000000..7d447ea8 --- /dev/null +++ b/hello-arc-windows/src/test.ps1 @@ -0,0 +1,33 @@ +cd /workspaces +git clone https://github.com/microsoft/azure-arc-jumpstart-apps.git + +cd /workspaces/azure-arc-jumpstart-apps/hello-arc-windows/src + +# Build Windows Server container image with Node installed, needed as Node does not have an official Windows image per 2023-02-08: https://github.com/nodejs/docker-node/pull/362 +docker build ./node -t azurearcjumpstart.azurecr.io/node-windows-servercore:ltsc2019 + +docker push azurearcjumpstart.azurecr.io/node-windows-servercore:ltsc2019 + +# Build node application +docker build ./app -t azurearcjumpstart.azurecr.io/hello-arc:windows + +docker push azurearcjumpstart.azurecr.io/hello-arc:windows + +# Test locally +docker run -d -p 8080:8080 azurearcjumpstart.azurecr.io/hello-arc:windows + +# AKS +az login +az aks get-credentials --resource-group aks-demo-rg --name aks-demo + +# Test Linux image on AKS Linux node +kubectl run hello-arc-linux --image liorkamrat/hello-arc --overrides='{"apiVersion": "v1", "spec": {"nodeSelector": { "kubernetes.io/os": "linux" }}}' + +# Verify app is working +kubectl port-forward hello-arc-linux 8080:8080 + +# Test Windows image on AKS Windows node +kubectl run hello-arc-windows --image azurearcjumpstart.azurecr.io/hello-arc:windows --overrides='{"apiVersion": "v1", "spec": {"nodeSelector": { "kubernetes.io/os": "windows" }}}' + +# Verify app is working +kubectl port-forward hello-arc-windows 8080:8080