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

Fails to run on docker image #1358

Closed
mebibou opened this issue Jun 4, 2019 · 15 comments
Closed

Fails to run on docker image #1358

mebibou opened this issue Jun 4, 2019 · 15 comments

Comments

@mebibou
Copy link

mebibou commented Jun 4, 2019

I am trying to install and run it on the docker image as follows:

FROM docker:latest

RUN apk update && apk upgrade && apk add make py-pip
RUN apk add --virtual=build gcc libffi-dev musl-dev openssl-dev python2-dev
RUN pip install azure-cli && apk del --purge build
RUN apk add --update nodejs nodejs-npm
RUN npm i -g azure-functions-core-tools@latest --unsafe-perm true

RUN func -v

But when building the image, it fails at func -v:

Step 7/17 : RUN func -v
 ---> Running in 9d2c97a80c7f
events.js:167
      throw er; // Unhandled 'error' event
      ^

Error: spawn /usr/lib/node_modules/azure-functions-core-tools/bin/func ENOENT
    at Process.ChildProcess._handle.onexit (internal/child_process.js:232:19)
    at onErrorNT (internal/child_process.js:407:16)
    at process._tickCallback (internal/process/next_tick.js:63:19)
    at Function.Module.runMain (internal/modules/cjs/loader.js:745:11)
    at startup (internal/bootstrap/node.js:282:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:743:3)
Emitted 'error' event at:
    at Process.ChildProcess._handle.onexit (internal/child_process.js:238:12)
    at onErrorNT (internal/child_process.js:407:16)
    [... lines matching original stack trace ...]
    at bootstrapNodeJSCore (internal/bootstrap/node.js:743:3)
The command '/bin/sh -c func -v' returned a non-zero code: 1

I saw 2 other issues that mention a similar error, but they seem either resolve magically or not on the same os/machine: #1136 and #167

@ghost ghost added the Needs: Triage 🔍 label Jun 4, 2019
@mebibou
Copy link
Author

mebibou commented Jun 4, 2019

Note: I tried running chmod 755 /usr/lib/node_modules/azure-functions-core-tools/bin/func before func -v but still have the same issue

@ankitkumarr
Copy link
Contributor

Looks like docker:latest is an alpine image. We currently do not support or publish an alpine compatible package.

You should be able to install dotnet core runtime, maybe from a dotnet docker image. And then, run dotnet /usr/lib/node_modules/azure-functions-core-tools/bin/func.dll to run all your commands.

@mebibou
Copy link
Author

mebibou commented Jun 6, 2019

Just tried (took the code form this Dockerfile):

FROM docker:latest

RUN apk update && apk upgrade && apk add make py-pip
RUN apk add --virtual=build gcc libffi-dev musl-dev openssl-dev python2-dev
RUN pip install azure-cli && apk del --purge build

ENV DOTNET_VERSION 2.1.11
RUN apk add gcompat libc6-compat\
    && apk add --no-cache --virtual .build-deps openssl \
    && wget -O dotnet.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Runtime/$DOTNET_VERSION/dotnet-runtime-$DOTNET_VERSION-linux-musl-x64.tar.gz \
    && dotnet_sha512='1eec1ca48827bdd2548ade5e8fad2cfabd806d59a44dc6505b7bbab8dde27ecbdf46238a6245300809eb2a560e6777691fa21e85b38874c8235e4face9580441' \
    && echo "$dotnet_sha512  dotnet.tar.gz" | sha512sum -c - \
    && mkdir -p /usr/share/dotnet \
    && tar -C /usr/share/dotnet -xzf dotnet.tar.gz \
    && ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet \
    && rm dotnet.tar.gz \
    && apk del .build-deps

RUN apk add --update nodejs nodejs-npm
RUN npm i -g azure-functions-core-tools@latest --unsafe-perm true

RUN dotnet /usr/lib/node_modules/azure-functions-core-tools/bin/func.dll -v

which gives me the error:

Failed to load 8-��U, error: Error relocating /usr/lib/node_modules/azure-functions-core-tools/bin/libcoreclr.so: gCurrentThreadInfo: symbol not found
Failed to bind to CoreCLR at '/usr/lib/node_modules/azure-functions-core-tools/bin/libcoreclr.so'
The command '/bin/sh -c dotnet /usr/lib/node_modules/azure-functions-core-tools/bin/func.dll -v' returned a non-zero code: 136

@ahmelsayed
Copy link
Contributor

Try this

+ FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS core-tools-build-env

+ RUN wget https://github.com/Azure/azure-functions-core-tools/archive/master.tar.gz && \
+     tar -xzvf master.tar.gz && \
+     cd azure-functions-core-tools-* && \
+     dotnet publish src/Azure.Functions.Cli/Azure.Functions.Cli.csproj --runtime linux-musl-x64 --output /output

FROM docker:latest
RUN apk update && apk upgrade && apk add make py-pip
RUN apk add --virtual=build gcc libffi-dev musl-dev openssl-dev python2-dev
RUN pip install azure-cli && apk del --purge build
RUN apk add --update nodejs nodejs-npm
- RUN npm i -g azure-functions-core-tools@latest --unsafe-perm true
+ # .NET Core dependencies
+ RUN apk add --no-cache ca-certificates krb5-libs libgcc libintl libssl1.1 libstdc++ lttng-ust tzdata userspace-rcu zlib
+ ENV DOTNET_RUNNING_IN_CONTAINER=true \
+    DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=true
+ COPY --from=core-tools-build-env [ "/output", "/azure-functions-core-tools" ]
+ RUN ln -s /azure-functions-core-tools/func /bin/func

RUN func -v

see this for dotnet core alpine dependencies https://github.com/dotnet/dotnet-docker/blob/master/2.1/runtime-deps/alpine3.9/amd64/Dockerfile

@ahmelsayed
Copy link
Contributor

and since the change above is building master, you won't get the right version injected. Master branch is always the latest released cli, but the build number is injected during build. You can pass the build number to dotnet publish if you want it set.

@mebibou
Copy link
Author

mebibou commented Jun 7, 2019

@ahmelsayed thanks that worked
I then tried to use func azure functionapp publish ... but it was saying the dotnet framework was not installed so I installed it and published a docker image: https://hub.docker.com/r/mebibou/dind-azure-functions

I'm actually trying to publish Python function apps using Gitlab, who has a Docker in Docker service. I am currently deploying on Travis-CI, which works fine but wanted to move the deployment to a private gitlab server. Using the above image on Gitlab, the deployment uploads 74.88 MB instead of 85.44 MB on Travis-CI, and when running the function apps it returns an error Function host is not running.. After checking on the Azure portal, the functions disappeared. Doesn't look so good

@ahmelsayed
Copy link
Contributor

Sorry I'm trying to understand your scenario.
You want to run a CI/CD on gitlab and be able to publish python functions to azure, right?

I'd recommend not using an alpine base if that were the case. The problem with alpine and python is that it doesn't use standard glibc and uses musl-libc instead. a lot of python packages (numpy, tensorflow, etc) would require a compile step for their C/C++ dependencies, and building those on alpine would not produce valid native binaries to run on our Azure host which is Debian based (uses glibc)

The core-tools spins up an instance of mcr.microsoft.com/azure-functions/python:2.0.12493-python3.6-buildenv (Dockerfile), copies your requirements.txt inside then runs

# https://github.com/Azure/azure-functions-core-tools/blob/dev/src/Azure.Functions.Cli/StaticResources/python_docker_build.sh
pip install --target=".python_packages/lib/python3.6/site-packages" -r requirements.txt

That's all to say if you want things to just work in a gitlab environment you can achieve that by this Dockerfile instead

FROM mcr.microsoft.com/azure-functions/python:2.0.12493-python3.6-buildenv

# Install azure-cli
RUN apt-get update && apt-get install apt-transport-https lsb-release software-properties-common dirmngr -y && \
    AZ_REPO=$(lsb_release -cs) && \
    echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ $AZ_REPO main" | \
        tee /etc/apt/sources.list.d/azure-cli.list && \
    apt-key --keyring /etc/apt/trusted.gpg.d/Microsoft.gpg adv \
        --keyserver packages.microsoft.com \
        --recv-keys BC528686B50D79E339D3721CEB3E94ADBE1229CF && \
    apt-get update && \
    apt-get install -y azure-cli

# Install azure-functions-core-tools
RUN apt-get update && \
    apt-get install -y azure-functions-core-tools

Then your build/publish script that runs in that above container can just be

# cd to WORKING DIR
# Build your python functions
pip install --target=".python_packages/lib/python3.6/site-packages" -r requirements.txt 

# Login into azure 
az login --service-principal -u "$AZURE_SP_ID" -p "$AZURE_SP_KEY" --tenant "$AZURE_SP_TENANT"

# set your default sub (optional)
az account set --subscription $AZURE_SUBSCRIPTION

# publish your functions
func azure functionapp publish {app-name} --no-build

@mebibou
Copy link
Author

mebibou commented Jun 10, 2019

@ahmelsayed yes that worked perfectly! I added func settings add FUNCTIONS_WORKER_RUNTIME python for good measure (not sure if it is required) and I can now publish on gitlab. This could be added to the official documentation? only an example for Travis is added, which is quite different from this.

@mebibou mebibou closed this as completed Jun 10, 2019
@mebibou
Copy link
Author

mebibou commented Jun 18, 2019

@ahmelsayed continuing on this, I have a package that needs a program in /user/bin to execute: https://pypi.org/project/GDAL/
I managed to install it correctly with pip install --target=".python_packages/lib/python3.6/site-packages" GDAL==2.1.3 --global-option=build_ext --global-option="-I/usr/include/gdal", which does produce a /user/bin/ogr2ogr file, but when running the function app I have the following error:

[Errno 2] No such file or directory: '/usr/bin/ogr2ogr'

I am guessing that running func azure functionapp publish {app-name} --no-build does not include bin files into the published image? is there a way to fix this?

@ahmelsayed
Copy link
Contributor

@mebibou sorry for the delay. No, in general we only assume that what you're publishing is a layer on top of /home/site/wwwroot of the base container we're running. There is no way to modify files elsewhere on the filesystem on startup.

I was looking at enabling custom docker containers for that scenario, though the startup time is very high today and we want to drive it down to something reasonable before enabling custom containers deployment.

I don't know if pip has a way to put these files somewhere that's not /usr/bin. I'm assuming if you're running this on a non-root machine you'd need to sudo the pip install command?

@mebibou
Copy link
Author

mebibou commented Jul 4, 2019

I'm actually running this completely on Docker directly for now, and I install it using RUN apt-get update && apt-get install -y gdal-bin

@mlazowik
Copy link

mlazowik commented Oct 7, 2019

@mebibou I guess you could move whatever binaries you need to /home/site/wwwroot/{bin, lib} and add those paths to PATH and/or LD_LIBRARY_PATH

@mebibou
Copy link
Author

mebibou commented Oct 24, 2019

@mlazowik how would I be able to add them to the PATH? @ahmelsayed is there a way to do this on the published docker image?

@ahmelsayed
Copy link
Contributor

I think if you set LD_LIBRARY_PATH as an App Setting it should work, though I'll have to test it to verify.

Setting PATH in App Settings though might mess up things, unless you set the full one, i.e: /usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin.

I think adding a way to prepend PATH and/or LD_LIBRARY_PATH would be useful for a lot of scenarios. I opened #1620 to track that.

@lock
Copy link

lock bot commented Dec 18, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Dec 18, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants