variant: flatcar version: 1.0.0 systemd: units: - name: gitea-mcp.service enabled: true contents: | [Unit] Description=Gitea MCP Server After=docker.service Requires=docker.service [Service] TimeoutStartSec=0 ExecStartPre=-/usr/bin/docker rm --force gitea-mcp # The image ships a broken HEALTHCHECK: it is CMD-SHELL form but the # image is distroless, so every probe fails on a missing /bin/sh and # the container is reported unhealthy while serving fine. Exec-form # health tests cannot be set from docker run, so the check is dropped; # "/app/gitea-mcp -healthcheck" still works via docker exec. ExecStart=/usr/bin/docker run --name gitea-mcp --no-healthcheck \ -e GITEA_HOST=https://git.atlashorizon.net \ -p 8080:8080 \ docker.gitea.com/gitea-mcp-server \ /app/gitea-mcp -t http --port 8080 ExecStop=/usr/bin/docker stop gitea-mcp Restart=always RestartSec=5s [Install] WantedBy=multi-user.target - name: litellm.service enabled: true contents: | [Unit] Description=LiteLLM proxy After=docker.service Requires=docker.service [Service] TimeoutStartSec=0 ExecStartPre=-/usr/bin/docker rm --force litellm ExecStart=/usr/bin/docker run --name litellm \ -e DATABASE_URL=${litellm_database_url} \ -e STORE_MODEL_IN_DB=True \ -e LITELLM_MASTER_KEY=${litellm_master_key} \ -e LITELLM_SALT_KEY=${litellm_salt_key} \ -e LITELLM_LOG=ERROR \ -e JSON_LOGS=True \ -p 4000:4000 \ docker.litellm.ai/berriai/litellm:main-stable ExecStop=/usr/bin/docker stop litellm Restart=always RestartSec=5s [Install] WantedBy=multi-user.target # ── Open WebUI (disabled) ────────────────────────────────────────────── # Commented out until it is ready to launch. To re-enable: # 1. strip the leading "# " from every line of the block below (this # restores the original indentation exactly) # 2. un-double the dollar signs in each interpolation: $$ back to $ # 3. re-add the seven OPENWEBUI_* keys to secrets.tmpl (listed below; # they are removed while this is off so the generated JSON, which # data.external parses, stays valid) # # OPENWEBUI_DATABASE_URL -> openwebui_database_url # OPENWEBUI_SECRET_KEY -> openwebui_secret_key # OPENWEBUI_S3_ACCESS_KEY -> openwebui_s3_access_key # OPENWEBUI_S3_SECRET_KEY -> openwebui_s3_secret_key # OPENWEBUI_OAUTH_CLIENT_ID -> openwebui_oauth_client_id # OPENWEBUI_OAUTH_CLIENT_SECRET -> openwebui_oauth_client_secret # OPENWEBUI_OIDC_PROVIDER_URL -> openwebui_oidc_provider_url # # The doubling in step 2 is not cosmetic: templatefile() substitutes on # raw text before anything parses it as YAML, so an interpolation left # intact here would still be resolved -- and would still fail the plan on # a missing key -- even though it sits inside a comment. # # Open WebUI. # # # # Prerequisites, all of which must exist before the VM is rebuilt: # # - Postgres database, with "CREATE EXTENSION vector;" run inside it # # - openwebui bucket in Garage, plus a key with r/w on it # # - an embedding model in LiteLLM matching RAG_EMBEDDING_MODEL below # # - an OIDC client at the provider, with the callback URI registered as # # https://llm.atlashorizon.net/oauth/oidc/callback # # - llm.atlashorizon.net terminating TLS and proxying to this host's # # :3000 (not managed here -- see WEBUI_URL below) # # - the OPENWEBUI_* secrets in Infisical (see secrets.tmpl) # - name: open-webui.service # enabled: true # contents: | # [Unit] # Description=Open WebUI # After=docker.service litellm.service # Requires=docker.service # [Service] # TimeoutStartSec=0 # # Large image, so it is pulled up front: a slow first pull is then not # # mistaken for a hung unit. # ExecStartPre=/usr/bin/docker pull ghcr.io/open-webui/open-webui:v0.11.4 # ExecStartPre=-/usr/bin/docker rm --force open-webui # # No volume is mounted. Every piece of durable state lives off-box -- # # Postgres for app data, pgvector for embeddings, Garage for uploads -- # # so /app/backend/data holds nothing worth keeping and the container # # (and the whole VM) can be rebuilt at will. What stays local is cache # # only, re-fetched on the next start. # # # # gitea-mcp already owns host :8080, so the UI is published on :3000. # ExecStart=/usr/bin/docker run --name open-webui \ # -e DATABASE_URL=$${openwebui_database_url} \ # -e VECTOR_DB=pgvector \ # -e PGVECTOR_DB_URL=$${openwebui_database_url} \ # -e STORAGE_PROVIDER=s3 \ # -e S3_ENDPOINT_URL=http://s3.lan.oswaldtheotter.net:30188 \ # -e S3_REGION_NAME=garage \ # -e S3_BUCKET_NAME=openwebui \ # -e S3_ACCESS_KEY_ID=$${openwebui_s3_access_key} \ # -e S3_SECRET_ACCESS_KEY=$${openwebui_s3_secret_key} \ # -e WEBUI_SECRET_KEY=$${openwebui_secret_key} \ # -e ENABLE_OLLAMA_API=false \ # -e OPENAI_API_BASE_URL=http://192.168.7.61:4000/v1 \ # -e OPENAI_API_KEY=$${litellm_master_key} \ # -e RAG_EMBEDDING_ENGINE=openai \ # -e RAG_OPENAI_API_BASE_URL=http://192.168.7.61:4000/v1 \ # -e RAG_OPENAI_API_KEY=$${litellm_master_key} \ # -e RAG_EMBEDDING_MODEL=text-embedding-3-small \ # -e OAUTH_CLIENT_ID=$${openwebui_oauth_client_id} \ # -e OAUTH_CLIENT_SECRET=$${openwebui_oauth_client_secret} \ # -e OPENID_PROVIDER_URL=$${openwebui_oidc_provider_url} \ # -e OAUTH_PROVIDER_NAME=SSO \ # -e ENABLE_OAUTH_SIGNUP=true \ # -e WEBUI_URL=https://llm.atlashorizon.net \ # -p 3000:8080 \ # ghcr.io/open-webui/open-webui:v0.11.4 # ExecStop=/usr/bin/docker stop open-webui # Restart=always # RestartSec=5s # [Install] # WantedBy=multi-user.target - name: dozzle-agent.service enabled: true contents: | [Unit] Description=Dozzle Agent After=docker.service Requires=docker.service [Service] TimeoutStartSec=0 ExecStartPre=-/usr/bin/docker rm --force dozzle-agent ExecStart=/usr/bin/docker run --name dozzle-agent \ -v /var/run/docker.sock:/var/run/docker.sock \ -p 7007:7007 \ amir20/dozzle:v11.1.1 agent ExecStop=/usr/bin/docker stop dozzle-agent Restart=always RestartSec=5s [Install] WantedBy=multi-user.target