...
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
ansible/inventory/joe_at_home
|
||||
8
ansible/deploy-ai-at-home.yml
Normal file
8
ansible/deploy-ai-at-home.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
- name: Install Ai @ Home
|
||||
hosts: ai_at_home
|
||||
|
||||
roles:
|
||||
- ollama
|
||||
- openwebui
|
||||
- ai_at_home
|
||||
6
ansible/deploy-ollama.yml
Normal file
6
ansible/deploy-ollama.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
- name: Install Ollama
|
||||
hosts: ollama
|
||||
|
||||
roles:
|
||||
- ollama
|
||||
6
ansible/deploy-openwebui.yml
Normal file
6
ansible/deploy-openwebui.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
- name: Install Openwebui
|
||||
hosts: openwebui
|
||||
|
||||
roles:
|
||||
- openwebui
|
||||
8
ansible/inventory/example/host_vars/yourpc.yml
Normal file
8
ansible/inventory/example/host_vars/yourpc.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
ai_at_home_install_dir: /home/youruser/Projekte/ai_at_home
|
||||
openwebui_install_dir: "{{ ai_at_home_install_dir }}/openwebui"
|
||||
|
||||
common_container_labels:
|
||||
- sablier.enable=true
|
||||
ollama_container_labels: {{ common_container_labels + ["sablier.group=ai_backends"] }}
|
||||
openwebui_container_labels: {{ common_container_labels + ["sablier.group=ai_frontends"] }}
|
||||
8
ansible/inventory/example/hosts
Normal file
8
ansible/inventory/example/hosts
Normal file
@@ -0,0 +1,8 @@
|
||||
[ollama]
|
||||
yourpc
|
||||
|
||||
[openwebui]
|
||||
yourpc
|
||||
|
||||
[ai_at_home]
|
||||
yourpc
|
||||
19
ansible/roles/ai_at_home/defaults/main.yml
Normal file
19
ansible/roles/ai_at_home/defaults/main.yml
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
sablier_image: sablierapp/sablier
|
||||
sablier_image_tag: latest
|
||||
apisix_image: apache/apisix
|
||||
apisix_image_tag: latest
|
||||
|
||||
|
||||
|
||||
ai_at_home_install_dir: /opt/ai_at_home
|
||||
|
||||
ollama_install_dir: /opt/ollama
|
||||
ollama_composefile: "{{ ollama_install_dir }}/compose/composefile.yml"
|
||||
openwebui_install_dir: /opt/openwebui
|
||||
openwebui_composefile: "{{ openwebui_install_dir }}/compose/composefile.yml"
|
||||
|
||||
|
||||
# images
|
||||
# gpt-oss:20b
|
||||
# qwen3-coder-next
|
||||
17
ansible/roles/ai_at_home/files/runme.sh
Normal file
17
ansible/roles/ai_at_home/files/runme.sh
Normal file
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -a
|
||||
|
||||
CONFIG_FILE=$(dirname "$(readlink -f "$0")")/aiathome.config
|
||||
OLLAMA_COMPOSEFILE=${OLLAMA_COMPOSEFILE:-/opt/ollama/compose/composefile.yml}
|
||||
OPENWEBUI_COMPOSEFILE=${OPENWEBUI_COMPOSEFILE:-/opt/openwebui/compose/composefile.yml}
|
||||
|
||||
[[ -f ${CONFIG_FILE} ]] && source ${CONFIG_FILE}
|
||||
|
||||
docker compose -f ${OLLAMA_COMPOSEFILE} up -d
|
||||
docker compose -f ${OPENWEBUI_COMPOSEFILE} up -d
|
||||
|
||||
# TODO: Create a stack based on the config and define multiple backends...
|
||||
# Launch Backends on Demand instead of just using ollama...
|
||||
# Maybe with the traefik middleware? https://plugins.traefik.io/plugins/6715d1d37dd5a6c3095befd4/sablier
|
||||
#https://github.com/sablierapp/sablier
|
||||
3
ansible/roles/ai_at_home/files/runme_wip.sh
Normal file
3
ansible/roles/ai_at_home/files/runme_wip.sh
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
15
ansible/roles/ai_at_home/files/stopme.sh
Normal file
15
ansible/roles/ai_at_home/files/stopme.sh
Normal file
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -a
|
||||
|
||||
CONFIG_FILE=$(dirname "$(readlink -f "$0")")/aiathome.config
|
||||
OLLAMA_COMPOSEFILE=${OLLAMA_COMPOSEFILE:-/opt/ollama/compose/composefile.yml}
|
||||
OPENWEBUI_COMPOSEFILE=${OPENWEBUI_COMPOSEFILE:-/opt/openwebui/compose/composefile.yml}
|
||||
|
||||
[[ -f ${CONFIG_FILE} ]] && source ${CONFIG_FILE}
|
||||
|
||||
docker compose -f ${OLLAMA_COMPOSEFILE} stop
|
||||
docker compose -f ${OPENWEBUI_COMPOSEFILE} stop
|
||||
|
||||
docker compose -f ${OLLAMA_COMPOSEFILE} rm -f
|
||||
docker compose -f ${OPENWEBUI_COMPOSEFILE} rm -f
|
||||
21
ansible/roles/ai_at_home/tasks/deploy/apisix.yml
Normal file
21
ansible/roles/ai_at_home/tasks/deploy/apisix.yml
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
- name: Create directories
|
||||
ansible.builtin.file:
|
||||
state: directory
|
||||
path: "{{ item }}"
|
||||
loop:
|
||||
- "{{ apisix_install_dir }}"
|
||||
- "{{ apisix_install_dir }}/config"
|
||||
|
||||
|
||||
- name: Pull Apisix Image
|
||||
community.docker.docker_image:
|
||||
source: pull
|
||||
name: "{{ apisix_image }}:{{ apisix_image_tag }}"
|
||||
|
||||
- name: Copy Config file
|
||||
|
||||
docker run -d --name apache-apisix \
|
||||
-p 9080:9080 \
|
||||
-e APISIX_STAND_ALONE=true \
|
||||
apache/apisix
|
||||
45
ansible/roles/ai_at_home/tasks/deploy/main.yml
Normal file
45
ansible/roles/ai_at_home/tasks/deploy/main.yml
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
- name: Create Install Dir
|
||||
ansible.builtin.file:
|
||||
path: "{{ ai_at_home_install_dir }}"
|
||||
state: directory
|
||||
mode: "0755"
|
||||
loop:
|
||||
- "{{ ai_at_home_install_dir }}"
|
||||
- "{{ ai_at_home_install_dir }}/compose"
|
||||
- "{{ ai_at_home_install_dir }}/sablier/config"
|
||||
- "{{ ai_at_home_install_dir }}/apisix/plugins"
|
||||
- "{{ ai_at_home_install_dir }}/apisix/config"
|
||||
|
||||
|
||||
- name: Pull Images
|
||||
community.docker.docker_image:
|
||||
source: pull
|
||||
name: "{{ item }}"
|
||||
loop:
|
||||
- "{{ sablier_image }}:{{ sablier_image_tag }}"
|
||||
- "{{ apisix_image }}:{{ apisix_image_tag }}"
|
||||
|
||||
- name: Copy Templates
|
||||
ansible.builtin.template:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ item.dest }}"
|
||||
mode: "0644"
|
||||
loop:
|
||||
- src: aiathome.config
|
||||
dest: "{{ ai_at_home_install_dir }}/aiathome.config"
|
||||
- src: composefile.yml
|
||||
dest: "{{ ai_at_home_install_dir }}/compose/composefile.yml"
|
||||
- src: sablier.yml
|
||||
dest: "{{ ai_at_home_install_dir }}/sablier/sablier.yml"
|
||||
|
||||
|
||||
|
||||
- name: Copy Script
|
||||
ansible.builtin.copy:
|
||||
src: "{{ item }}"
|
||||
dest: "{{ ai_at_home_install_dir }}/{{ item }}"
|
||||
mode: "0755"
|
||||
loop:
|
||||
- runme.sh
|
||||
- stopme.sh
|
||||
5
ansible/roles/ai_at_home/tasks/main.yml
Normal file
5
ansible/roles/ai_at_home/tasks/main.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
- name: Include selected operations for Ai @ Home
|
||||
tags:
|
||||
- aiathome
|
||||
ansible.builtin.include_tasks: "{{ deployment_action|default('deploy') }}/main.yml"
|
||||
5
ansible/roles/ai_at_home/templates/aiathome.config
Normal file
5
ansible/roles/ai_at_home/templates/aiathome.config
Normal file
@@ -0,0 +1,5 @@
|
||||
OLLAMA_COMPOSEFILE={{ ollama_composefile }}
|
||||
OPENWEBUI_COMPOSEFILE={{ openwebui_composefile }}
|
||||
|
||||
# vllm/openwebui/ollama/openclawd etc..
|
||||
AI_STACK=
|
||||
11
ansible/roles/ai_at_home/templates/apisix_config.yml
Normal file
11
ansible/roles/ai_at_home/templates/apisix_config.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
deployment:
|
||||
role: data_plane
|
||||
role_data_plane:
|
||||
config_provider: yaml
|
||||
|
||||
wasm:
|
||||
plugins:
|
||||
- name: proxywasm_sablier_plugin
|
||||
priority: 7997
|
||||
file: /wasm/sablierproxywasm.wasm
|
||||
26
ansible/roles/ai_at_home/templates/composefile.yml
Normal file
26
ansible/roles/ai_at_home/templates/composefile.yml
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
services:
|
||||
apisix:
|
||||
image: {{ apisix_image }}:{{ apisix_image_tag }}
|
||||
env:
|
||||
APISIX_STAND_ALONE: "true"
|
||||
network_mode: host
|
||||
volumes:
|
||||
- {{ apisix_install_dir }}/config/apisix_config.yml:/usr/local/apisix/conf/config.yaml
|
||||
|
||||
sablier:
|
||||
image: {{ sablier_image }}:{{ sablier_image_tag }}
|
||||
command:
|
||||
- start
|
||||
- --provider.name=docker
|
||||
network_mode: host
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- {{ ai_at_home_install_dir }}/sablier/config:/etc/sablier
|
||||
|
||||
|
||||
docker run --name sablier \
|
||||
-p 10000:10000 \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
sablierapp/sablier:1.10.5 \
|
||||
start --provider.name=docker
|
||||
34
ansible/roles/ai_at_home/templates/sablier.yml
Normal file
34
ansible/roles/ai_at_home/templates/sablier.yml
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
provider:
|
||||
# Provider to use to manage containers (docker, swarm, kubernetes)
|
||||
name: docker
|
||||
server:
|
||||
# The server port to use
|
||||
port: 10000
|
||||
# The base path for the API
|
||||
base-path: /
|
||||
storage:
|
||||
# File path to save the state (default stateless)
|
||||
file:
|
||||
sessions:
|
||||
# The default session duration (default 5m)
|
||||
default-duration: 5m
|
||||
# The expiration checking interval.
|
||||
# Higher duration gives less stress on CPU.
|
||||
# If you only use sessions of 1h, setting this to 5m is a good trade-off.
|
||||
expiration-interval: 20s
|
||||
logging:
|
||||
level: debug
|
||||
strategy:
|
||||
dynamic:
|
||||
# Custom themes folder, will load all .html files recursively (default empty)
|
||||
custom-themes-path:
|
||||
# Show instances details by default in waiting UI
|
||||
show-details-by-default: false
|
||||
# Default theme used for dynamic strategy (default "hacker-terminal")
|
||||
default-theme: hacker-terminal
|
||||
# Default refresh frequency in the HTML page for dynamic strategy
|
||||
default-refresh-frequency: 5s
|
||||
blocking:
|
||||
# Default timeout used for blocking strategy (default 1m)
|
||||
default-timeout: 1m
|
||||
5
ansible/roles/ollama/defaults/main.yml
Normal file
5
ansible/roles/ollama/defaults/main.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
ollama_install_dir: /opt/ollama
|
||||
ollama_image: ollama/ollama
|
||||
ollama_image_tag: latest
|
||||
ollama_container_labels: []
|
||||
18
ansible/roles/ollama/tasks/deploy/main.yml
Normal file
18
ansible/roles/ollama/tasks/deploy/main.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
- name: Create Ollama Directories
|
||||
ansible.builtin.file:
|
||||
state: directory
|
||||
path: "{{ ollama_install_dir }}/{{ item }}"
|
||||
loop:
|
||||
- data
|
||||
- compose
|
||||
|
||||
- name: Pull Ollama Image
|
||||
community.docker.docker_image:
|
||||
source: pull
|
||||
name: "{{ ollama_image }}:{{ ollama_image_tag }}"
|
||||
|
||||
- name: Copy composefile
|
||||
ansible.builtin.template:
|
||||
src: templates/composefile.yml
|
||||
dest: "{{ ollama_install_dir }}/compose/composefile.yml"
|
||||
5
ansible/roles/ollama/tasks/main.yml
Normal file
5
ansible/roles/ollama/tasks/main.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
- name: Include selected operations for Ollama
|
||||
tags:
|
||||
- ollama
|
||||
ansible.builtin.include_tasks: "{{ deployment_action|default('deploy') }}/main.yml"
|
||||
0
ansible/roles/ollama/tasks/teardown/main.yml
Normal file
0
ansible/roles/ollama/tasks/teardown/main.yml
Normal file
20
ansible/roles/ollama/templates/composefile.yml
Normal file
20
ansible/roles/ollama/templates/composefile.yml
Normal file
@@ -0,0 +1,20 @@
|
||||
services:
|
||||
|
||||
ollama:
|
||||
image: {{ ollama_image }}:{{ ollama_image_tag }}
|
||||
deploy:
|
||||
resources:
|
||||
reservations:
|
||||
devices:
|
||||
- driver: nvidia
|
||||
count: all
|
||||
capabilities: [gpu]
|
||||
network_mode: host
|
||||
volumes:
|
||||
- {{ ollama_install_dir }}/data:/root/.ollama
|
||||
tty: true
|
||||
restart: unless-stopped
|
||||
{% if ollama_container_labels %}
|
||||
labels:
|
||||
{{ ollama_container_labels|to_nice_yaml|indent(4) }}
|
||||
{% endif %}
|
||||
5
ansible/roles/openwebui/defaults/main.yml
Normal file
5
ansible/roles/openwebui/defaults/main.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
openwebui_install_dir: /opt/openwebui
|
||||
openwebui_image: ghcr.io/open-webui/open-webui
|
||||
openwebui_image_tag: main-slim
|
||||
openwebui_container_labels: []
|
||||
19
ansible/roles/openwebui/tasks/deploy/main.yml
Normal file
19
ansible/roles/openwebui/tasks/deploy/main.yml
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
|
||||
- name: Create Directories
|
||||
ansible.builtin.file:
|
||||
state: directory
|
||||
path: "{{ openwebui_install_dir }}/{{ item }}"
|
||||
loop:
|
||||
- data
|
||||
- compose
|
||||
|
||||
- name: Pull Openwebui Image
|
||||
community.docker.docker_image:
|
||||
source: pull
|
||||
name: "{{ openwebui_image }}:{{ openwebui_image_tag }}"
|
||||
|
||||
- name: Copy composefile
|
||||
ansible.builtin.template:
|
||||
src: templates/composefile.yml
|
||||
dest: "{{ openwebui_install_dir }}/compose/composefile.yml"
|
||||
5
ansible/roles/openwebui/tasks/main.yml
Normal file
5
ansible/roles/openwebui/tasks/main.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
- name: Include selected operations for OpenWebUi
|
||||
tags:
|
||||
- openwebui
|
||||
ansible.builtin.include_tasks: "{{ deployment_action|default('deploy') }}/main.yml"
|
||||
1
ansible/roles/openwebui/tasks/teardown/main.yml
Normal file
1
ansible/roles/openwebui/tasks/teardown/main.yml
Normal file
@@ -0,0 +1 @@
|
||||
---
|
||||
17
ansible/roles/openwebui/templates/composefile.yml
Normal file
17
ansible/roles/openwebui/templates/composefile.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
services:
|
||||
open-webui:
|
||||
image: {{ openwebui_image }}:{{ openwebui_image_tag }}
|
||||
network_mode: host
|
||||
environment:
|
||||
FORWARDED_ALLOW_IPS: '*'
|
||||
OLLAMA_BASE_URL: http://localhost:11434
|
||||
OFFLINE_MODE: True
|
||||
DEFAULT_USER_ROLE: user
|
||||
volumes:
|
||||
- {{ openwebui_install_dir }}/data:/app/backend/data
|
||||
|
||||
{% if openwebui_container_labels %}
|
||||
labels:
|
||||
{{ openwebui_container_labels|to_nice_yaml|indent(4) }}
|
||||
{% endif %}
|
||||
Reference in New Issue
Block a user