Using custom startup commands with Web App for Containers
This post will cover how to use the “Startup Command” option to quickly change the startup entrypoint or command for your custom container on Web Apps for Containers.
Overview
The “Startup Command” option is available on both App Service Blessed Images and Web App for Containers - however, there are some important differences here.
“Blessed Images” are prebuilt containers which mount a volume to /home
to run your code. The Dockerfile used for these images are configured in a way that this command can easily integrate with your code, since the architecture here is designed to just deploy and run code and not focus on the nuances of configuring the image itself.
On the other hand, Web App for Containers have the expectation set that the customer would be building their own custom Docker Image - and bringing that for Azure to run as a container. With this, most people have an already set and defined container entrypoint, through the ENTRYPOINT
instruction, or the CMD command to run their application through CMD
.
If you add a “Startup Command”, this may cause issues unknowingly, as it may override your command in the same way you can do docker run -it [someimage] [somecommand]
.
Good to knows
If your custom Docker Image already has a ENTRYPOINT
or CMD
set, setting this custom startup command option may break your application, as it’s essentially trying to override your entrypoint or command execution.
Take the below example. We have a quickstart nginx:latest
image being used - which runs fine on it’s own. If we add a command of echo "Hello"
as the Startup Command, we see it execute - but ultimately the container fails because it’s overriding NGINX’s entrypoint.
Knowing this, we will go through a setup below to successfully use this option for a Web App for Container.
Custom Startup Commands
Use a command
- To be able to start a container with this method, do not have a
CMD
orENTRYPOINT
in yourDockerfile
. See the below example. We’re just copying in our application source and exposing the port. If you have aCMD
orENTRYPOINT
already set, there is a likely chance this may crash the container, as seen above, if you put a command that your application is not expecting.
FROM node:18.9.0-alpine3.15
WORKDIR /app
COPY package.json ./
RUN npm i
COPY . ./
EXPOSE 8080
- In the “Startup Command” field, add your command.
- We can now validate the container has started:
This approach can be used an alternative to the typical ENTRYPOINT
or CMD
methods with containerized applications.
Use a file
Prerequisites
Compared to the Use a command section, to reference a .sh
file directly to invoke your container entrypoint, you must have App Service persistant storage enabled. This is done through the WEBSITES_ENABLE_APP_SERVICE_STORAGE
App Setting.
On Web App for Containers, this defaults to false. Set this to true to proceed, otherwise this will not work.
Set Up
-
Assuming
WEBSITES_ENABLE_APP_SERVICE_STORAGE
is nowtrue
, we can continue. Next, using an FTP client of your choice - add your entrypoint container script to a location under/home
.In this example, we’re going to add the below
init_container.sh
to/home/site/wwwroot
(This is where FTP clients default to when connected under App Service remote storage)#!/bin/sh set -e # Get env vars in the Dockerfile to show up in the SSH session eval $(printenv | sed -n "s/^\([^=]\+\)=\(.*\)$/export \1=\2/p" | sed 's/"/\\\"/g' | sed '/=/s//="/' | sed 's/$/"/' >> /etc/profile) echo "Starting SSH ..." /usr/sbin/sshd node /app/server.js
NOTE: It’s important to understand that FTP clients only connect to the remote storage’s file system. You cannot browse the container filesystem like you would do with an SSH session.
-
Just as in the “Use a command” section - do not have an existing
ENTRYPOINT
orCMD
command in yourDockerfile
. Notice this is the case in the below file as well.As an example, we’ll be using the below Dockerfile
FROM node:18.9.0-alpine3.15 WORKDIR /app COPY package.json ./ RUN npm i COPY . ./ # Start and enable SSH RUN apk add openssh \ && echo "root:Docker!" | chpasswd \ && chmod +x /app/init_container.sh \ && cd /etc/ssh/ \ && ssh-keygen -A COPY sshd_config /etc/ssh/ EXPOSE 8080 2222
-
In the portal under Configuration -> General Settings, set the “Startup Command” to
/home/site/wwwroot/init_container.sh
You can alternatively do this in the Deployment Center:
-
Save the configuration. The container should now be using the
.sh
file being referenced for container start up.
Troubleshooting
A common issue when trying to use this option is encountering OCI runime create failed
, this would look like the following - below are 2 examples:
Error: failed to create containerd task: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "java -jar probes-0.0.1-SNAPSHOT.jar": stat java -jar probes-0.0.1-SNAPSHOT.jar: no such file or directory: unknown
Error: failed to create containerd task: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "dbt build --select stage+": executable file not found in $PATH: unknown
Validate the following if OCI runtime create failed
is being seen when using “startup command/file”:
- For files being executed - make sure the file has correct line-endings - this needs to be
LF
- if these areCLRF
then this may cause aOCI runtime create failed
issue. You can validate the line-endings of a file by going into a text editor like VSCode - see Docker run fails with standard_init_linux.go error - For files - ensure that storage is mounted - use an FTP client or through Kudu to validate the file exists somewhere under
/home
- Use a full absolute path to the file or executable being invoked
- Ensure the path specified exists and is correct
- For the first two points, you may see a message like
no such file or directory: unknown
in theOCI
error
- For the first two points, you may see a message like
- If trying to invoke a command globally, make sure it’s on
$PATH
- For executables not on
$PATH
, you may seeexecutable file not found in $PATH: unknown
- For executables not on
- Make sure the command has proper syntax and fully formed - ex.
python /some/path/python.py
- You may see
no such file or directory: unknown
for commands incorrectly set
- You may see
For further information, see the public blog - Troubleshooting OCI runtime create errors.