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

Add support for Node 20 #912

Merged
merged 13 commits into from
Jul 14, 2023
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ Linux amd64 Tags
| `4-node18-appservice` | Debian 11 |
| `4-node18-core-tools` | Debian 11 |
| `4-node18-appservice-quickstart` | Debian 11 |
| `4-node20` | Debian 11 |
| `4-node20-slim` | Debian 11 |
| `4-node20-appservice` | Debian 11 |
| `4-node20-core-tools` | Debian 11 |

#### Powershell

Expand Down
43 changes: 43 additions & 0 deletions host/4/bullseye/amd64/node/node20/node20-composite.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
FROM mcr.microsoft.com/dotnet/runtime-deps:6.0
ARG HOST_VERSION

COPY --from=runtime-image [ "/FuncExtensionBundles", "/FuncExtensionBundles" ]
COPY sshd_config /etc/ssh/
COPY start.sh /azure-functions-host/
COPY --from=runtime-image [ "/azure-functions-host", "/azure-functions-host" ]
COPY --from=runtime-image [ "/workers/node", "/azure-functions-host/workers/node" ]

# Chrome Headless Dependencies (01/2023)
# https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#chrome-headless-doesnt-launch-on-unix
RUN apt-get update && \
apt-get install -y ca-certificates fonts-liberation libasound2 libatk-bridge2.0-0 libatk1.0-0 libc6 \
libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libglib2.0-0 libgtk-3-0 libnspr4 \
libnss3 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 \
libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 lsb-release wget xdg-utils

RUN apt-get update && \
apt-get install -y curl gnupg && \
curl -sL https://deb.nodesource.com/setup_20.x | bash - && \
apt-get update && \
apt-get install -y nodejs

ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
HOME=/home \
FUNCTIONS_WORKER_RUNTIME=node \
DOTNET_USE_POLLING_FILE_WATCHER=true \
HOST_VERSION=${HOST_VERSION} \
ASPNETCORE_CONTENTROOT=/azure-functions-host

# Fix from https://github.com/GoogleCloudPlatform/google-cloud-dotnet-powerpack/issues/22#issuecomment-729895157
RUN apt-get update && \
apt-get install -y libc-dev

EXPOSE 2222 80

RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends openssh-server dialog && \
echo "root:Docker!" | chpasswd

RUN chmod +x /azure-functions-host/start.sh

ENTRYPOINT ["/azure-functions-host/start.sh"]
46 changes: 46 additions & 0 deletions host/4/bullseye/amd64/node/node20/node20-core-tools.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------

FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:20-bullseye

# Avoid warnings by switching to noninteractive
ENV DEBIAN_FRONTEND=noninteractive

# The javascript-node image includes a non-root user with sudo access. Use the "remoteUser"
# property in devcontainer.json to use it. On Linux, the container user's GID/UIDs
# will be updated to match your local UID/GID (when using the dockerFile property).
# See https://aka.ms/vscode-remote/containers/non-root-user for details.
ARG USERNAME=node
ARG USER_UID=1000
ARG USER_GID=$USER_UID

# Configure apt and install packages
RUN apt-get update \
#
# Install Azure Functions, .NET Core, and Azure CLI
&& echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ $(lsb_release -cs) main" > /etc/apt/sources.list.d/azure-cli.list \
&& echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-debian-$(lsb_release -cs)-prod $(lsb_release -cs) main" > /etc/apt/sources.list.d/dotnetdev.list \
&& curl -sL https://packages.microsoft.com/keys/microsoft.asc | (OUT=$(apt-key add - 2>&1) || echo $OUT) \
&& apt-get update \
&& apt-get install -y azure-cli dotnet-sdk-6.0 azure-functions-core-tools-4 \
#
# [Optional] Update a non-root user to UID/GID if needed.
&& if [ "$USER_GID" != "1000" ] || [ "$USER_UID" != "1000" ]; then \
groupmod --gid $USER_GID $USERNAME \
&& usermod --uid $USER_UID --gid $USER_GID $USERNAME; \
fi \
&& mkdir -p /home/$USERNAME/.local/share \
&& chown -R $USER_UID:$USER_GID /home/$USERNAME \
#
# Clean up
&& apt-get autoremove -y \
&& apt-get clean -y \
&& rm -rf /var/lib/apt/lists/*

# Azure Functions Core Tools needs a place to save data
ENV XDG_DATA_HOME=/home/$USERNAME/.local/share

# Switch back to dialog for any ad-hoc use of apt-get
ENV DEBIAN_FRONTEND=dialog
62 changes: 62 additions & 0 deletions host/4/bullseye/amd64/node/node20/node20-slim.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Build the runtime from source
ARG HOST_VERSION=4.23.0
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS runtime-image
ARG HOST_VERSION

ENV PublishWithAspNetCoreTargetManifest=false

RUN BUILD_NUMBER=$(echo ${HOST_VERSION} | cut -d'.' -f 3) && \
git clone --branch v${HOST_VERSION} https://github.com/Azure/azure-functions-host /src/azure-functions-host && \
cd /src/azure-functions-host && \
HOST_COMMIT=$(git rev-list -1 HEAD) && \
dotnet publish -v q /p:BuildNumber=$BUILD_NUMBER /p:CommitHash=$HOST_COMMIT src/WebJobs.Script.WebHost/WebJobs.Script.WebHost.csproj -c Release --output /azure-functions-host --runtime linux-x64 && \
mv /azure-functions-host/workers /workers && mkdir /azure-functions-host/workers && \
rm -rf /root/.local /root/.nuget /src

RUN apt-get update && \
apt-get install -y gnupg wget unzip && \
EXTENSION_BUNDLE_VERSION_V2=2.26.0 && \
EXTENSION_BUNDLE_FILENAME_V2=Microsoft.Azure.Functions.ExtensionBundle.${EXTENSION_BUNDLE_VERSION_V2}_linux-x64.zip && \
wget https://functionscdn.azureedge.net/public/ExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle/$EXTENSION_BUNDLE_VERSION_V2/$EXTENSION_BUNDLE_FILENAME_V2 && \
mkdir -p /FuncExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle/$EXTENSION_BUNDLE_VERSION_V2 && \
unzip /$EXTENSION_BUNDLE_FILENAME_V2 -d /FuncExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle/$EXTENSION_BUNDLE_VERSION_V2 && \
rm -f /$EXTENSION_BUNDLE_FILENAME_V2 &&\
EXTENSION_BUNDLE_VERSION_V3=3.24.0 && \
EXTENSION_BUNDLE_FILENAME_V3=Microsoft.Azure.Functions.ExtensionBundle.${EXTENSION_BUNDLE_VERSION_V3}_linux-x64.zip && \
wget https://functionscdn.azureedge.net/public/ExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle/$EXTENSION_BUNDLE_VERSION_V3/$EXTENSION_BUNDLE_FILENAME_V3 && \
mkdir -p /FuncExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle/$EXTENSION_BUNDLE_VERSION_V3 && \
unzip /$EXTENSION_BUNDLE_FILENAME_V3 -d /FuncExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle/$EXTENSION_BUNDLE_VERSION_V3 && \
rm -f /$EXTENSION_BUNDLE_FILENAME_V3 &&\
EXTENSION_BUNDLE_VERSION_V4=4.7.0 && \
EXTENSION_BUNDLE_FILENAME_V4=Microsoft.Azure.Functions.ExtensionBundle.${EXTENSION_BUNDLE_VERSION_V4}_linux-x64.zip && \
wget https://functionscdn.azureedge.net/public/ExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle/$EXTENSION_BUNDLE_VERSION_V4/$EXTENSION_BUNDLE_FILENAME_V4 && \
mkdir -p /FuncExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle/$EXTENSION_BUNDLE_VERSION_V4 && \
unzip /$EXTENSION_BUNDLE_FILENAME_V4 -d /FuncExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle/$EXTENSION_BUNDLE_VERSION_V4 && \
rm -f /$EXTENSION_BUNDLE_FILENAME_V4 &&\
find /FuncExtensionBundles/ -type f -exec chmod 644 {} \;

FROM mcr.microsoft.com/dotnet/runtime-deps:6.0
ARG HOST_VERSION

RUN apt-get update && \
apt-get install -y curl gnupg && \
curl -sL https://deb.nodesource.com/setup_20.x | bash - && \
apt-get update && \
apt-get install -y nodejs

ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
HOME=/home \
FUNCTIONS_WORKER_RUNTIME=node \
DOTNET_USE_POLLING_FILE_WATCHER=true \
HOST_VERSION=${HOST_VERSION} \
ASPNETCORE_CONTENTROOT=/azure-functions-host

# Fix from https://github.com/GoogleCloudPlatform/google-cloud-dotnet-powerpack/issues/22#issuecomment-729895157
RUN apt-get update && \
apt-get install -y libc-dev

COPY --from=runtime-image [ "/azure-functions-host", "/azure-functions-host" ]
COPY --from=runtime-image [ "/workers/node", "/azure-functions-host/workers/node" ]
COPY --from=runtime-image [ "/FuncExtensionBundles", "/FuncExtensionBundles" ]

CMD [ "/azure-functions-host/Microsoft.Azure.WebJobs.Script.WebHost" ]
69 changes: 69 additions & 0 deletions host/4/bullseye/amd64/node/node20/node20.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Build the runtime from source
ARG HOST_VERSION=4.23.0
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS runtime-image
ARG HOST_VERSION

ENV PublishWithAspNetCoreTargetManifest=false

RUN BUILD_NUMBER=$(echo ${HOST_VERSION} | cut -d'.' -f 3) && \
git clone --branch v${HOST_VERSION} https://github.com/Azure/azure-functions-host /src/azure-functions-host && \
cd /src/azure-functions-host && \
HOST_COMMIT=$(git rev-list -1 HEAD) && \
dotnet publish -v q /p:BuildNumber=$BUILD_NUMBER /p:CommitHash=$HOST_COMMIT src/WebJobs.Script.WebHost/WebJobs.Script.WebHost.csproj -c Release --output /azure-functions-host --runtime linux-x64 && \
mv /azure-functions-host/workers /workers && mkdir /azure-functions-host/workers && \
rm -rf /root/.local /root/.nuget /src

RUN apt-get update && \
apt-get install -y gnupg wget unzip && \
EXTENSION_BUNDLE_VERSION_V2=2.26.0 && \
EXTENSION_BUNDLE_FILENAME_V2=Microsoft.Azure.Functions.ExtensionBundle.${EXTENSION_BUNDLE_VERSION_V2}_linux-x64.zip && \
wget https://functionscdn.azureedge.net/public/ExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle/$EXTENSION_BUNDLE_VERSION_V2/$EXTENSION_BUNDLE_FILENAME_V2 && \
mkdir -p /FuncExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle/$EXTENSION_BUNDLE_VERSION_V2 && \
unzip /$EXTENSION_BUNDLE_FILENAME_V2 -d /FuncExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle/$EXTENSION_BUNDLE_VERSION_V2 && \
rm -f /$EXTENSION_BUNDLE_FILENAME_V2 &&\
EXTENSION_BUNDLE_VERSION_V3=3.24.0 && \
EXTENSION_BUNDLE_FILENAME_V3=Microsoft.Azure.Functions.ExtensionBundle.${EXTENSION_BUNDLE_VERSION_V3}_linux-x64.zip && \
wget https://functionscdn.azureedge.net/public/ExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle/$EXTENSION_BUNDLE_VERSION_V3/$EXTENSION_BUNDLE_FILENAME_V3 && \
mkdir -p /FuncExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle/$EXTENSION_BUNDLE_VERSION_V3 && \
unzip /$EXTENSION_BUNDLE_FILENAME_V3 -d /FuncExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle/$EXTENSION_BUNDLE_VERSION_V3 && \
rm -f /$EXTENSION_BUNDLE_FILENAME_V3 &&\
EXTENSION_BUNDLE_VERSION_V4=4.7.0 && \
EXTENSION_BUNDLE_FILENAME_V4=Microsoft.Azure.Functions.ExtensionBundle.${EXTENSION_BUNDLE_VERSION_V4}_linux-x64.zip && \
wget https://functionscdn.azureedge.net/public/ExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle/$EXTENSION_BUNDLE_VERSION_V4/$EXTENSION_BUNDLE_FILENAME_V4 && \
mkdir -p /FuncExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle/$EXTENSION_BUNDLE_VERSION_V4 && \
unzip /$EXTENSION_BUNDLE_FILENAME_V4 -d /FuncExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle/$EXTENSION_BUNDLE_VERSION_V4 && \
rm -f /$EXTENSION_BUNDLE_FILENAME_V4 &&\
find /FuncExtensionBundles/ -type f -exec chmod 644 {} \;

FROM mcr.microsoft.com/dotnet/runtime-deps:6.0
ARG HOST_VERSION

RUN apt-get update && \
apt-get install -y curl gnupg && \
curl -sL https://deb.nodesource.com/setup_20.x | bash - && \
apt-get update && \
apt-get install -y nodejs

ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
HOME=/home \
FUNCTIONS_WORKER_RUNTIME=node \
DOTNET_USE_POLLING_FILE_WATCHER=true \
HOST_VERSION=${HOST_VERSION} \
ASPNETCORE_CONTENTROOT=/azure-functions-host

# Fix from https://github.com/GoogleCloudPlatform/google-cloud-dotnet-powerpack/issues/22#issuecomment-729895157
RUN apt-get update && \
apt-get install -y libc-dev

# Chrome Headless Dependencies (01/2023)
# https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#chrome-headless-doesnt-launch-on-unix
RUN apt-get install -y ca-certificates fonts-liberation libasound2 libatk-bridge2.0-0 libatk1.0-0 libc6 \
libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libglib2.0-0 libgtk-3-0 libnspr4 \
libnss3 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 \
libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 lsb-release wget xdg-utils

COPY --from=runtime-image [ "/azure-functions-host", "/azure-functions-host" ]
COPY --from=runtime-image [ "/workers/node", "/azure-functions-host/workers/node" ]
COPY --from=runtime-image [ "/FuncExtensionBundles", "/FuncExtensionBundles" ]

CMD [ "/azure-functions-host/Microsoft.Azure.WebJobs.Script.WebHost" ]
15 changes: 15 additions & 0 deletions host/4/bullseye/amd64/node/node20/sshd_config
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# This is ssh server systemwide configuration file.
#
# /etc/sshd_config

Port SSH_PORT
ListenAddress 0.0.0.0
LoginGraceTime 180
X11Forwarding yes
Ciphers aes128-cbc,3des-cbc,aes256-cbc
MACs hmac-sha1,hmac-sha1-96
StrictModes yes
SyslogFacility DAEMON
PasswordAuthentication yes
PermitEmptyPasswords no
PermitRootLogin yes
28 changes: 28 additions & 0 deletions host/4/bullseye/amd64/node/node20/start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env bash

export DOTNET_USE_POLLING_FILE_WATCHER=true

if [ -z $PORT ]; then
export ASPNETCORE_URLS=http://*:80
else
export ASPNETCORE_URLS=http://*:$PORT
fi

if [ -z $SSH_PORT ]; then
export SSH_PORT=2222
fi

if [ "$APPSVC_REMOTE_DEBUGGING" == "TRUE" ]; then
export languageWorkers__node__arguments="--inspect=0.0.0.0:$APPSVC_TUNNEL_PORT"
export languageWorkers__python__arguments="-m ptvsd --host localhost --port $APPSVC_TUNNEL_PORT"
fi

sed -i "s/SSH_PORT/$SSH_PORT/g" /etc/ssh/sshd_config

service ssh start

if [ -f /azure-functions-host/Microsoft.Azure.WebJobs.Script.WebHost ]; then
/azure-functions-host/Microsoft.Azure.WebJobs.Script.WebHost
else
dotnet /azure-functions-host/Microsoft.Azure.WebJobs.Script.WebHost.dll
fi
56 changes: 56 additions & 0 deletions host/4/core-tools-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,19 @@ stages:
continueOnError: false
env:
DOCKER_BUILDKIT: 1
- bash: |
set -e
IMAGE_NAME=azurefunctions.azurecr.io/azure-functions/4/node:$(PrivateVersion)-node20-core-tools

docker build -t $IMAGE_NAME \
-f host/4/bullseye/amd64/node/node20/node20-core-tools.Dockerfile \
host/4/bullseye/amd64/node/node20/
npm run test $IMAGE_NAME --prefix test/
docker push $IMAGE_NAME
displayName: node20-core-tools
continueOnError: false
env:
DOCKER_BUILDKIT: 1

- job: python
displayName: python
Expand Down Expand Up @@ -745,6 +758,49 @@ stages:
displayName: push node18 images
continueOnError: false
condition: ne(variables['SkipProduction'], 'true')

- bash: |
set -e
docker pull $SOURCE_REGISTRY/node:$(PrivateVersion)-node20-core-tools

docker tag $SOURCE_REGISTRY/node:$(PrivateVersion)-node20-core-tools $TARGET_REGISTRY/node:$(TargetVersion)-core-tools
docker tag $SOURCE_REGISTRY/node:$(PrivateVersion)-node20-core-tools $TARGET_REGISTRY/node:$(TargetVersion)-node20-core-tools

docker tag $SOURCE_REGISTRY/node:$(PrivateVersion)-node20-core-tools $TARGET_REGISTRY/node:$(MajorVersion)-core-tools
docker tag $SOURCE_REGISTRY/node:$(PrivateVersion)-node20-core-tools $TARGET_REGISTRY/node:$(MajorVersion)-node20-core-tools
displayName: tag node20 images
continueOnError: false

- bash: |
set -e
PrivateImageId=`docker image inspect $SOURCE_REGISTRY/node:$(PrivateVersion)-node20-core-tools --format='{{.Id}}'`
MajorImageId=`docker image inspect $TARGET_REGISTRY/node:$(MajorVersion)-node20-core-tools --format='{{.Id}}'`
if [[ "$PrivateImageId" != "$MajorImageId" ]]; then
echo "unmatch the Target image id and Major image id ${PrivateImageId} and ${MajorImageId}";
exit 1;
fi

ActualVersion=`docker run $TARGET_REGISTRY/node:$(MajorVersion)-node20-core-tools func --version`
if [[ "$ActualVersion" != "$(TargetVersion)" ]]; then
echo "unmatch the ActualVersion and TargetVersion ${ActualVersion} and $(TargetVersion)";
exit 1;
fi
docker run $TARGET_REGISTRY/node:$(MajorVersion)-node20-core-tools az --version
displayName: test node20 images
continueOnError: false

- bash: |
set -e
docker push $TARGET_REGISTRY/node:$(TargetVersion)-core-tools
docker push $TARGET_REGISTRY/node:$(TargetVersion)-node20-core-tools

docker push $TARGET_REGISTRY/node:$(MajorVersion)-core-tools
docker push $TARGET_REGISTRY/node:$(MajorVersion)-node20-core-tools

docker system prune -a -f
displayName: push node20 images
continueOnError: false
condition: ne(variables['SkipProduction'], 'true')

- bash: docker system prune -a -f
displayName: clearn up docker images
Expand Down
Loading