この記事は、Elixir Advent Calendar 2025その5 の3日目です
昨日は @t-yamanashi さんで、「血圧を記録するアプリを作る その3 〜 血圧測定の結果を元にグラフを作る 〜」 でした
piacere です、ご覧いただいてありがとございます ![]()
Ollama最新版のDockerイメージは、ollama/ollama:latest にあるものの、Gemma3が梱包済みのイメージはpullできないため、自前でビルドし、Elixirからすぐ呼び出せるようにします(なお、Ollamaがバージョンアップした際は各自で再ビルドしてください)
Dockerが入っている前提で進めます
Elixirは下記を見ながらインストールしておいてください
古いOllamaの停止
既にOllamaインストール済で、ollama serve で起動済みだと、下記手順のDocker Compose内Ollamaと衝突するため、下記コマンドで古いOllamaを停止させてください
sudo systemctl stop ollama
Gemma3入りのOllamaコンテナのビルド
Gemma3入りのOllamaコンテナをビルドします
FROM ubuntu:24.04
RUN apt update && apt install -y curl ca-certificates
# Ollama install
RUN curl -fsSL https://ollama.com/install.sh | bash
RUN ollama serve & \
sleep 3 && \
ollama pull gemma3:1b && \
pkill ollama
EXPOSE 11434
CMD ["ollama", "serve"]
Dockerイメージをビルドします
docker build --no-cache -t ollama-gemma3-1b .
ここで、たとえばgpt-ossも追加したければ、上記の ollama pull gemma3:1b && \ の行を1行下にコピーし、モデル名のところを gpt-oss:20bのような感じに変更してから再度ビルドするだけで使えるようになります
Ollamaが利用できるモデルは、下記で検索できます
Ollamaコンテナを起動する
Ollamaコンテナ用のdocker-compose.yamlを適当な場所に作ります
services:
ollama:
image: ollama-with-llms
container_name: ollama_standalone
ports:
- 11434:11434
volumes:
- ollama:/root/.ollama
environment:
- OLLAMA_HOST=0.0.0.0:11434
restart: unless-stopped
volumes:
ollama:
コンテナを起動します
docker compose up -d
もしDocker起動でエラーが出た場合は …
Dockerイメージ操作中に電源が落ちたり、Dockerバージョン/ディストリビューションを変な感じで変えたり等でイメージが破損した場合、コンテナ起動時に下記のエラーが出ることがあります
Error response from daemon: pull access denied for ollama-with-llms, repository does
not exist or may require 'docker login': denied: requested access to the resource is ~
このエラーは、下記コマンドでリセットすると治ります
ただし、下記コマンドでリセットすると、docker images で出てくるイメージリストが全て消えるため、イメージをカスタムビルドしている場合は再ビルドが必要となるのでご注意ください
docker compose down --rmi all --volumes --remove-orphans
Ollamaコンテナに入ってGemma3を動かす
Ollamaコンテナ単独でGemma3が実行できるかテストします
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
+f353d7bf1b3e ollama-with-llms "ollama serve" 5 minutes ago Up 5 minutes 0.0.0.0:11434->11434/tcp, [::]:11434->11434/tcp ollama_container
docker exec -it 【Ollamaコンテナの一番左にあるID、上記例なら緑帯の f353d7bf1b3e】 bash
Gemma3起動後、>>> の後にプロンプトを打って遊んでみて、終わったら /bye で抜け、続けて exit でOllamaコンテナを抜けてください
ollama run gemma3:1b
>>> Elixirについて教えて
Elixirについてですね!Elixirは、モダンな言語で、並行処理、コンテナ、そして自動テストを重視して開発された、非常に強力なフレームワークです。
**Elixirの概要**
* **並行処理の最適化:** Elixirは、複数のプロセスを並行処理するのに最適化されています。これにより、スループットが向上し、システム全体のパフォーマンスが向上します。
* **コンテナ化:** Elixirは、コンテナ技術を活用しており、アプリケーションを簡単にデプロイ、管理、拡張できます。
* **自動テスト:** Elixirのモジュールシステムは、自動テストを簡単に実装できます。これにより、コードの品質を向上させ、バグを早期に発見できます。
* **関数型プログラミング:** Elixirは、関数型プログラミングの原則に基づいており、コードがより予測可能で、保守しやすく、再利用性が高いです。
* **イベント指向:** Elixirは、イベント指向の設計思想を採用しており、アプリケーションの応答性を高めることができます。
**Elixirの主な特徴**
* **Ecto:** Elixirのデータベースアーキテクチャとして、データの永続化と管理を容易にする機能を提供します。
* **Phoenix:** ElixirのWebフレームワークで、高速でスケーラブルなWebアプリケーションを開発できます。
* **Phoenix Futures & Events:** Webアプリケーションの非同期処理を効率的に行うための機能。
* **State:** Elixirの標準的な型システムで、状態管理を容易にします。
**Elixirのメリット**
* **高いパフォーマンス:** 並行処理とコンテナ化により、高いパフォーマンスを実現できます。
* **コードの再利用性:** 関数型プログラミングとモジュールシステムにより、コードの再利用性が向上します。
* **開発効率の向上:** 自動テストと明確なコードベースにより、開発効率が向上します。
* **安定性と信頼性:** Elixirは、信頼性が高く、安定したソフトウェアを開発するのに適しています。
**Elixirの用途**
* **Webアプリケーション:** 高いパフォーマンスとスケーラビリティが求められるWebアプリケーションを開発できます。
…(以下略)
>>> /bye
exit
ElixirからOllamaコンテナのGemma3を使う
下記でiexを起動し、Ollamaライブラリを使って上記OllamaコンテナのGemma3を使った生成AIを走らせます
iex> Mix.install([{:ollama, "~> 0.9"}])
iex> client = Ollama.init(base_url: "http://localhost:11434/api")
iex> prompt = "Elixirについて教えて"
iex> {:ok, answer} = Ollama.completion(client, model: "gemma3:1b", prompt: prompt)
iex> answer |> Map.keys
iex> answer["response"]
"Elixir についてですね! Elixir は、**関数型プログラミング** を中心とした …(以下略)
生成AIの出力をストリーミングすることも出来ます
iex> prompt = "ElixirとPythonの違いは?"
iex> {:ok, answer} = Ollama.completion(
...> client, model: "gemma3:1b", prompt: prompt, stream: true)
iex> answer |> Stream.each(&IO.inspect &1["response"]) |> Stream.run()
"El"
"ixir"
"と"
"Python"
"は"
"どちら"
"も"
"人気"
"のある"
"プロ"
"グラ"
"ミング"
"言語"
…
(以下略)
ElixirコンテナからOllamaコンテナのGemma3を使う
(そのうち書きます)
終わりに
最後に、コンテナ群を落として終了してください
docker compose down
Gemma3入りOllamaコンテナをビルドし、ElixirからGemma3を呼び出してみました
ElixirからローカルLLMを使うのが、思ったよりもハードルが低いと言うことが伝われば幸いです
明日は @mnishiguchi さんで「Elixir: charlist でのパス解析」 です