Docker

Deploy to Azure VM

Copy page

Deploy to Azure VM with Docker Compose

Create a VM Instance

  • Go to Compute infrastructure | Virtual machines in your Azure Portal.
  • Create a virtual machine
  • Select a subscription and resource group
  • Assign a name for the virtual machine
  • Assign a region (e.g. (US) East US 2)
  • For Availability options, select No infrastructure redundancy required
  • Use image: Ubuntu Server 24.04 LTS - x64 Gen2
  • Recommended size is at least Standard_D2s_v3 (2 vcpus, 8 GiB memory).
  • Configure SSH (you will need to SSH into the VM)
  • In the "Disks" tab, confirm the OS disk size is at least 30 GiB.
  • In the "Networking" tab, assign public IP address
  • Click on "Review + create"
  • After the VM is running, go to the "Network Settings" page under "Networking"
  • Add inbound security rule for TCP ports: 3000,3002,3050,3051,3080

Install Docker Compose

  1. SSH into the VM

  2. Set up Docker's apt repository

# Add Docker's official GPG key:
sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF

sudo apt update
  1. Install the Docker packages
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
  1. Grant permissions
sudo usermod -aG docker $USER
newgrp docker

Deploy SigNoz and Nango

Clone this repo, which includes Docker files with SigNoz and Nango:

git clone https://github.com/inkeep/agents-optional-local-dev inkeep-external-services
cd inkeep-external-services

Run this command to autogenerate a .env file:

cp .env.docker.example .env && \
  nango_encryption_key=$(openssl rand -base64 32) && \
  nango_dashboard_password=$(openssl rand -base64 8) && \
  tmp_file=$(mktemp) && \
  sed \
    -e "s|<REPLACE_WITH_NANGO_ENCRYPTION_KEY>|$nango_encryption_key|" \
    -e "s|<REPLACE_WITH_NANGO_DASHBOARD_PASSWORD>|$nango_dashboard_password|" \
    .env > "$tmp_file" && \
  mv "$tmp_file" .env && \
  echo "Docker environment file created with auto-generated NANGO_ENCRYPTION_KEY and NANGO_DASHBOARD_PASSWORD"

Nango requires a NANGO_ENCRYPTION_KEY. Once you create this, it cannot be edited.

Here's an overview of the important environment variables when deploying to production. Make sure to review all of these in your .env file.

NANGO_ENCRYPTION_KEY=<nango_encryption_key>

# Replace these with your <vm_external_ip> in production!
NANGO_SERVER_URL=http://<vm_external_ip>:3050
NANGO_PUBLIC_CONNECT_URL=http://<vm_external_ip>:3051

# Modify these in production environments!
NANGO_DASHBOARD_USERNAME=admin@example.com
NANGO_DASHBOARD_PASSWORD=adminADMIN!@12

Build and deploy SigNoz, Nango, OTEL Collector, and Jaeger:

docker compose up -d

This may take up to 5 minutes to start.

Retrieve your SigNoz and Nango API Keys

To get your SigNoz API key SIGNOZ_API_KEY:

  • Open SigNoz in a browser at http://<vm_external_ip>:3080
  • On first login, you will be prompted to create an admin account.
  • Navigate to Settings → Account Settings → API Keys → New Key
  • Choose a role, Viewer is sufficient for observability
  • Set the expiration field to "No Expiry" to prevent the key from expiring

To get your Nango secret key NANGO_SECRET_KEY:

  • Open Nango in a browser at http://<vm_external_ip>:3050
  • Nango auto-creates two environments, Prod and Dev. Select the one you will use.
  • Navigate to Environment Settings to find the secret key

Deploy the Inkeep Agent Framework

From the root directory, create a new project directory for the Docker Compose setup for the Inkeep Agent Framework

mkdir inkeep && cd inkeep
wget https://raw.githubusercontent.com/inkeep/agents/refs/heads/main/docker-compose.yml
wget https://raw.githubusercontent.com/inkeep/agents/refs/heads/main/.env.docker.example

Generate a .env file from the example:

cp .env.docker.example .env && \
\
  # Core secrets
  inkeep_agents_manage_ui_password=$(openssl rand -base64 8) && \
  inkeep_agents_jwt_signing_secret=$(openssl rand -base64 32) && \
  better_auth_secret=$(openssl rand -base64 32) && \
  spicedb_preshared_key=$(openssl rand -base64 32) && \
  jwt_tmp_priv=$(mktemp) && \
  jwt_tmp_pub=$(mktemp) && \
  openssl genrsa -out "$jwt_tmp_priv" 2048 2>/dev/null && \
  openssl rsa -in "$jwt_tmp_priv" -pubout -out "$jwt_tmp_pub" 2>/dev/null && \
  inkeep_agents_temp_jwt_private_key=$(base64 -i "$jwt_tmp_priv" | tr -d '\n') && \
  inkeep_agents_temp_jwt_public_key=$(base64 -i "$jwt_tmp_pub" | tr -d '\n') && \
  rm -f "$jwt_tmp_priv" "$jwt_tmp_pub" && \
  tmp_file=$(mktemp) && \
  sed \
    -e "s|<REPLACE_WITH_INKEEP_AGENTS_MANAGE_UI_PASSWORD>|$inkeep_agents_manage_ui_password|" \
    -e "s|<REPLACE_WITH_INKEEP_AGENTS_JWT_SIGNING_SECRET>|$inkeep_agents_jwt_signing_secret|" \
    -e "s|<REPLACE_WITH_BETTER_AUTH_SECRET>|$better_auth_secret|" \
    -e "s|<REPLACE_WITH_SPICEDB_PRESHARED_KEY>|$spicedb_preshared_key|" \
    -e "s|<REPLACE_WITH_INKEEP_AGENTS_TEMP_JWT_PRIVATE_KEY>|$inkeep_agents_temp_jwt_private_key|" \
    -e "s|<REPLACE_WITH_INKEEP_AGENTS_TEMP_JWT_PUBLIC_KEY>|$inkeep_agents_temp_jwt_public_key|" \
    .env > "$tmp_file" && \
  mv "$tmp_file" .env && \
  echo "✅ Docker .env created with autogenerated secrets."

Here's an overview of the important environment variables when deploying to production. Make sure to review all of these in your .env file.

ENVIRONMENT=production

# AI Provider Keys (you need at least one)
ANTHROPIC_API_KEY=
OPENAI_API_KEY=
GOOGLE_GENERATIVE_AI_API_KEY=
AZURE_API_KEY=

# From Nango dashboard at http://<vm_external_ip>:3050
NANGO_SECRET_KEY=

# From SigNoz dashboard at http://<vm_external_ip>:3080
SIGNOZ_API_KEY=

# Set these for the Manage UI at http://<vm_external_ip>:3000
PUBLIC_INKEEP_AGENTS_API_URL=http://<vm_external_ip>:3002
PUBLIC_NANGO_SERVER_URL=http://<vm_external_ip>:3050
PUBLIC_NANGO_CONNECT_BASE_URL=http://<vm_external_ip>:3051
PUBLIC_SIGNOZ_URL=http://<vm_external_ip>:3080

# Set these to access Manage UI at http://<vm_external_ip>:3000
INKEEP_AGENTS_MANAGE_UI_USERNAME=admin@example.com
INKEEP_AGENTS_MANAGE_UI_PASSWORD=

# Generated with: openssl rand -base64 32
INKEEP_AGENTS_JWT_SIGNING_SECRET=
BETTER_AUTH_SECRET=
SPICEDB_PRESHARED_KEY=

INKEEP_AGENTS_TEMP_JWT_PRIVATE_KEY=
INKEEP_AGENTS_TEMP_JWT_PUBLIC_KEY=
Tip
Tip

For long-running agents or custom deployment requirements, you can override runtime limits like execution timeouts, maximum transfers, and generation steps. See Configure Runtime Limits for examples and the complete list of overridable settings.

Run with Docker:

docker compose up -d

Then open http://<vm_external_ip>:3000 in a browser!