Dify を Azure Virtual Machine でホストしてみた

Dify を Azure Virtual Machine でホストしてみた

Clock Icon2025.02.13

こんにちは!クラウド事業本部コンサルティング部のたかくに(@takakuni_)です。

みなさん Dify 触っていますでしょうか。

言葉はよく耳にしていたものの、触ったことがなかったため絶賛勉強しています。

そこで今回は Azure 上で Dify をセルフホストして、Dify を体験してみたいと思います。

構成

今回は Azure Virtual Machines 上で Dify を立ち上げます。固定 IP アドレスをアタッチしインターネット経由でアクセスします。

Untitled(130).png

スペック

Dify ではセルフホスト用に Docker Compose 一式が用意されています。可用性は考慮されていないですが、今回は検証のためこちらの仕組みに乗っかろうと思います。

ドキュメントによると、CPU Core 数は 2 以上、メモリは 4 GiB 以上が要件のようです。

Before installing Dify, make sure your machine meets the following minimum system requirements:
CPU >= 2 Core
RAM >= 4 GiB

https://docs.dify.ai/getting-started/install-self-hosted/docker-compose

インフラ周り

今回は HashiCorp Terraform で作成しました。

provider.tf
terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "4.18.0"
    }
  }
}

provider "azurerm" {
  # Configuration options
  features {}
  subscription_id                 = var.environment.subscription_id
  resource_provider_registrations = "none"
}

locals {
  location = "Japan East"
  rg_name  = "takakuni.shinnosuke"
}

variable "environment" {
  type = object({
    subscription_id = string
  })
}

data "azurerm_resource_group" "this" {
  name = local.rg_name
}

VNet

まずは VNet です。今回は仮想マシンにパブリック IP を紐付け、APIアクセス含めインターネットを経由するような構成にしました。

そのためサブネットは必要最低限の1つのみで構成しています。

vnet.tf
################################################
# VNet
################################################
resource "azurerm_virtual_network" "this" {
  name                = "dify-vnet"
  resource_group_name = data.azurerm_resource_group.this.name
  location            = data.azurerm_resource_group.this.location
  address_space       = ["10.0.0.0/16"]
}

resource "azurerm_subnet" "this" {
  name                                          = "dify-subnet"
  resource_group_name                           = data.azurerm_resource_group.this.name
  virtual_network_name                          = azurerm_virtual_network.this.name
  address_prefixes                              = ["10.0.10.0/24"]
  private_endpoint_network_policies             = "Enabled"
  private_link_service_network_policies_enabled = true
}

Virtual Machine

続いて仮想マシンです。固定 IP を仮想マシンに振りました。OS は Ubuntu 24.04 を利用します。(Linux であれば OK です。)

ユーザー名、パスワードは、ベタ書きしていますが、本番時は隠すなりしましょう。

CPU、メモリの要件に従い、VM サイズは Standard_B2s を選択しました。

vm.tf
################################################
# Network Interface
################################################
resource "azurerm_public_ip" "this" {
  name                = "dify-public-ip"
  location            = data.azurerm_resource_group.this.location
  resource_group_name = data.azurerm_resource_group.this.name
  allocation_method   = "Static"
}

resource "azurerm_network_security_group" "vm" {
  name                = "dify-vm-nsg"
  location            = data.azurerm_resource_group.this.location
  resource_group_name = data.azurerm_resource_group.this.name

  security_rule {
    name                       = "SSH"
    priority                   = 1000
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "22"
    source_address_prefix      = "*"
    destination_address_prefix = "*"
  }
  security_rule {
    name                       = "web"
    priority                   = 1001
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "80"
    source_address_prefix      = "*"
    destination_address_prefix = "*"
  }
}

resource "azurerm_network_interface" "this" {
  name                = "dify-vm-nic"
  location            = data.azurerm_resource_group.this.location
  resource_group_name = data.azurerm_resource_group.this.name

  ip_configuration {
    name                          = "dify-vm-nic-ipconfig"
    subnet_id                     = azurerm_subnet.this.id
    private_ip_address_allocation = "Dynamic"
    public_ip_address_id          = azurerm_public_ip.this.id
  }
}

resource "azurerm_network_interface_security_group_association" "this" {
  network_interface_id      = azurerm_network_interface.this.id
  network_security_group_id = azurerm_network_security_group.vm.id
}

resource "azurerm_storage_account" "this" {
  name                     = "diagdifyvmtakakuni"
  location                 = data.azurerm_resource_group.this.location
  resource_group_name      = data.azurerm_resource_group.this.name
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

################################################
# VM
################################################
data "azurerm_platform_image" "this" {
  location  = data.azurerm_resource_group.this.location
  publisher = "Canonical"
  offer     = "ubuntu-24_04-lts"
  sku       = "server"
}

resource "azurerm_virtual_machine" "this" {
  name                          = "dify-vm"
  resource_group_name           = data.azurerm_resource_group.this.name
  location                      = data.azurerm_resource_group.this.location
  vm_size                       = "Standard_B2s"
  network_interface_ids         = [azurerm_network_interface.this.id]
  delete_os_disk_on_termination = true

  storage_os_disk {
    name              = "dify-vm-osdisk"
    caching           = "ReadWrite"
    create_option     = "FromImage"
    managed_disk_type = "Standard_LRS"
  }

  storage_image_reference {
    publisher = data.azurerm_platform_image.this.publisher
    offer     = data.azurerm_platform_image.this.offer
    sku       = data.azurerm_platform_image.this.sku
    version   = data.azurerm_platform_image.this.version
  }

  os_profile {
    computer_name  = "dify-vm"
    admin_username = "difyadmin"
    admin_password = "P@ssw0rd1234!"
  }

  os_profile_linux_config {
    disable_password_authentication = false
  }
}

Azure OpenAI

最後に Azure OpenAI です。東日本リージョンでも利用可能な gpt-4 モデルを利用しました。

openai.tf
################################################
# Network Interface
################################################
resource "azurerm_cognitive_account" "this" {
  name                = "dify-openai"
  resource_group_name = data.azurerm_resource_group.this.name
  location            = data.azurerm_resource_group.this.location
  kind                = "OpenAI"
  sku_name            = "S0"

  public_network_access_enabled = true
}

resource "azurerm_cognitive_deployment" "this" {
  name                 = "dify-openai"
  cognitive_account_id = azurerm_cognitive_account.this.id

  sku {
    name = "GlobalStandard"
  }

  model {
    format  = "OpenAI"
    name    = "gpt-4"
    version = "turbo-2024-04-09"
  }
}

OS セットアップ

まずは、払い出された固定パブリック IP を利用して、SSH でログインします。

dify_on_azure % ssh difyadmin@固定
The authenticity of host '固定IPアドレスが入ります’ (割り振られた固定IPアドレスが入ります)' can't be established.
ED25519 key fingerprint is SHA256:N71UlAZM9q2ZYzBUga98AHlgmdSApGZKjYDTHoUREW8.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '割り振られた固定IPアドレス' (ED25519) to the list of known hosts.
difyadmin@割り振られた固定IPアドレス's password: 
Welcome to Ubuntu 24.04.1 LTS (GNU/Linux 6.8.0-1021-azure x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro

 System information as of Thu Feb 13 13:46:06 UTC 2025

  System load:  0.39              Processes:             125
  Usage of /:   5.4% of 28.02GB   Users logged in:       0
  Memory usage: 7%                IPv4 address for eth0: 10.0.10.4
  Swap usage:   0%

Expanded Security Maintenance for Applications is not enabled.

0 updates can be applied immediately.

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status


The list of available updates is more than a week old.
To check for new updates run: sudo apt update


The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

difyadmin@dify-vm:~$ 

デフォルトでは docker がインストールされていないため、 snap でインストールします。

インストール手順に従い docker compose up -d ができれば完了です。

difyadmin@dify-vm:~$ docker
Command 'docker' not found, but can be installed with:
sudo snap install docker         # version 27.2.0, or
sudo apt  install docker.io      # version 24.0.7-0ubuntu4.1
sudo apt  install podman-docker  # version 4.9.3+ds1-1ubuntu0.2
See 'snap info docker' for additional versions.
difyadmin@dify-vm:~$ sudo snap install docker
2025-02-13T13:47:25Z INFO Waiting for automatic snapd restart...
2025-02-13T13:48:04Z INFO task ignored
docker 27.2.0 from Canonical✓ installed
difyadmin@dify-vm:~$ git clone https://github.com/langgenius/dify.git
Cloning into 'dify'...
remote: Enumerating objects: 139195, done.
remote: Counting objects: 100% (37/37), done.
remote: Compressing objects: 100% (22/22), done.
remote: Total 139195 (delta 23), reused 17 (delta 15), pack-reused 139158 (from 3)
Receiving objects: 100% (139195/139195), 72.15 MiB | 19.11 MiB/s, done.
Resolving deltas: 100% (103245/103245), done.
difyadmin@dify-vm:~$ cd dify/docker
difyadmin@dify-vm:~/dify/docker$ cp .env.example .env
difyadmin@dify-vm:~/dify/docker$ sudo docker compose up -d
[+] Running 74/30
 ✔ web 13 layers [⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                                                                               100.2s 
 ✔ nginx 6 layers [⣿⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                                                                                      53.5s 
 ✔ weaviate 4 layers [⣿⣿⣿⣿]      0B/0B      Pulled                                                                                                                     50.6s 
 ✔ worker 11 layers [⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                                                                              168.7s 
 ✔ ssrf_proxy 3 layers [⣿⣿⣿]      0B/0B      Pulled                                                                                                                    52.1s 
 ✔ redis 8 layers [⣿⣿⣿⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                                                                                    33.3s 
 ✔ db 10 layers [⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                                                                                    70.7s 
 ✔ api Pulled                                                                                                                                                         168.8s 
 ✔ sandbox 10 layers [⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                                                                               91.6s 
[+] Running 11/11
 ✔ Network docker_default             Created                                                                                                                           0.1s 
 ✔ Network docker_ssrf_proxy_network  Created                                                                                                                           0.1s 
 ✔ Container docker-sandbox-1         Started                                                                                                                           0.4s 
 ✔ Container docker-db-1              Started                                                                                                                           0.4s 
 ✔ Container docker-web-1             Started                                                                                                                           0.4s 
 ✔ Container docker-redis-1           Started                                                                                                                           0.4s 
 ✔ Container docker-weaviate-1        Started                                                                                                                           0.4s 
 ✔ Container docker-ssrf_proxy-1      Started                                                                                                                           0.5s 
 ✔ Container docker-api-1             Started                                                                                                                           0.2s 
 ✔ Container docker-worker-1          Started                                                                                                                           0.2s 
 ✔ Container docker-nginx-1           Started                                                                                                                           0.2s

Dify にログイン

http://割り振られた/install でアクセスし初期化を行います。

2025-02-13 at 21.43.51-Dify.png

今回は次のメールアドレス、ユーザー名、パスワードを利用しました。

  • メールアドレス:hoge@fuga.piyo
  • ユーザー名:hoge
  • パスワード:h0geh0ge

初期化が完了すると再度、ログインが求められるためサインインします。

2025-02-13 at 23.00.28-Dify.png

もし管理者パスワードの設定に不備があった場合は以下のとおり、リセットができます。

https://docs.dify.ai/getting-started/install-self-hosted/faqs#id-4.-how-to-reset-the-password-of-the-admin-account

モデルの登録

Azure OpenAI のモデルを登録します。設定に進み

2025-02-13 at 23.01.07-スタジオ - Dify.png

Azure OpenAI を選択します。

2025-02-13 at 23.01.18-スタジオ - Dify.png

各種情報を Azure OpenAI から引っ張ってきて入力します。

2025-02-13 at 23.02.03-スタジオ - Dify.png

アプリの作成

アプリの作成に移ります。最初から作成する をクリックします。

2025-02-13 at 23.02.47-Dify.png

アプリ名に適当な名前をつけます。

2025-02-13 at 23.02.56-Dify.png

質問をすると、指定したモデルで返答が返ってきました。

2025-02-13 at 23.04.14-myhogeapp - Dify.png

まとめ

以上、「Dify を Azure Virtual Machine でホストしてみた。」でした。

可用性の部分やコンテナ使っている部分などをマネージドサービスに寄せられると、運用楽そうな気がしました。また機会があればチャレンジしてみます。

このブログがどなたかの参考になれば幸いです。クラウド事業本部コンサルティング部のたかくに(@takakuni_)でした!

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.