Using Tailscale on Azure App Services

Azure App Services is a popular cloud-hosting platform for running applications without managing servers yourself. However, it can be difficult to use Tailscale on Azure App Services, since it doesn’t provide a /dev/net/tun device that Tailscale needs.

In Tailscale v1.12 or later, you can use Tailscale’s userspace networking mode to connect your apps to your Tailscale network.

Step 1: Generate an auth key to authenticate your Azure App Services apps

First, we’ll generate an auth key to allow Azure to authenticate our app to join our network.

Navigate to the auth keys page of the admin console. We recommend using an ephemeral key for this purpose, since it will automatically clean up devices after they shut down.

Tailscale's auth key generation page

Next, navigate to the Azure Portal and then the Configuration page for your app. From here, add a new Config Var named TAILSCALE_AUTHKEY, with the tskey-<key> value you just created.

Azure App Servicess config var interface

Step 2: Configure your Dockerfile to install Tailscale

We recommend using a multistage Dockerfile where the first stage builds your application, the second fetches and unpacks Tailscale binaries, and the final stage pulls application code and Tailscale into the final image to be uploaded to Azure.

Create a Dockerfile at the root of your app. In that Dockerfile add something like:

FROM golang:1.16.2-alpine3.13 as builder
WORKDIR /app
COPY . ./
# This is where one could build the application code as well.


FROM alpine:latest as tailscale
WORKDIR /app
COPY . ./
ENV TSFILE=tailscale_1.28.0_amd64.tgz
RUN wget https://pkgs.tailscale.com/stable/${TSFILE} && \
  tar xzf ${TSFILE} --strip-components=1
COPY . ./


FROM alpine:latest
RUN apk update && apk add ca-certificates bash sudo && rm -rf /var/cache/apk/*

# Azure allows SSH access to the container. This isn't needed for Tailscale to
# operate, but is really useful for debugging the application.
RUN apk add openssh openssh-keygen && echo "root:Docker!" | chpasswd
RUN apk add netcat-openbsd
RUN mkdir -p /etc/ssh
COPY sshd_config /etc/ssh/
EXPOSE 80 2222

# Copy binary to production image
COPY --from=builder /app/start.sh /app/start.sh
COPY --from=tailscale /app/tailscaled /app/tailscaled
COPY --from=tailscale /app/tailscale /app/tailscale
RUN mkdir -p /var/run/tailscale /var/cache/tailscale /var/lib/tailscale

# Run on container startup.
CMD ["/app/start.sh"]

The Dockerfile specifies /app/start.sh as the initial process to run. This script needs to bring Tailscale up and then start the application binary. This is where we can use the TAILSCALE_AUTHKEY variable we defined earlier.

Then, create a file named start.sh at the root of your app:

#!/bin/sh

/usr/bin/ssh-keygen -A
mkdir -p /var/run/sshd
/usr/sbin/sshd

/app/tailscaled --tun=userspace-networking --socks5-server=localhost:1055 &
/app/tailscale up --authkey=${TAILSCALE_AUTHKEY} --hostname=azure-app
echo Tailscale started
ALL_PROXY=socks5://localhost:1055/ /app/my-app

Done! The next time your Azure app deploys, it should be able to connect to your private Tailscale network.

We’d love to hear about the cool things you build. Mention @tailscale on Twitter or email us at info@tailscale.com.

Last updated

WireGuard is a registered
trademark of Jason A. Donenfeld.

© 2022 Tailscale Inc.

Privacy & Terms