26 Commits

Author SHA1 Message Date
furyhawk 91200fe37e Refactor deployment scripts and configuration files 2024-05-30 20:21:45 +08:00
furyhawk 895f1d0aef Refactor volume source paths in deploy-librechat.yml 2024-05-30 20:05:06 +08:00
furyhawk f0a1969e73 Refactor traefik.yml to remove unused services and fix routing rules for chat and bot subdomains 2024-05-30 19:58:17 +08:00
furyhawk cd14a1ce23 Refactor container names and remove unused services in deploy-emqx.yml 2024-05-30 19:56:37 +08:00
furyhawk 3ddbbbb255 Refactor .gitignore to ignore .DS_Store files and directories 2024-05-30 19:54:44 +08:00
furyhawk d0483114dc Refactor traefik.yml to enable Traefik routing for the postgres service 2024-05-30 19:49:07 +08:00
furyhawk 722b942079 Refactor container names in deploy-librechat.yml and services.yml 2024-05-30 19:46:21 +08:00
furyhawk 86d8b19ae3 Refactor traefik.yml to fix routing rules for chat and bot subdomains 2024-05-30 19:37:06 +08:00
furyhawk 63b190ccbd Refactor traefik.yml to fix routing rules for chat and bot subdomains 2024-05-30 19:22:36 +08:00
furyhawk 0bb60245dc Refactor submodule configuration in .gitmodules file 2024-05-30 17:12:47 +08:00
furyhawk b70e7111ae Refactor compose.yml to update path for LibreChat subproject 2024-05-30 17:01:25 +08:00
furyhawk 788ec952fd Refactor submodule configuration in .gitmodules file 2024-05-30 16:20:38 +08:00
furyhawk 038bf3e8d9 Refactor compose/apps.yml to remove user and volume configuration for pgadmin service 2024-05-30 16:14:32 +08:00
furyhawk 1cc77c6609 Refactor compose.yml to update path for LibreChat subproject 2024-05-30 16:11:48 +08:00
furyhawk dfd071150f Refactor LibreChat subproject commit reference 2024-05-30 16:09:43 +08:00
furyhawk b55afab109 Refactor compose.yml to update path for LibreChat subproject 2024-05-30 15:39:52 +08:00
furyhawk cbbbe695ec Refactor compose/apps.yml to remove trailing slash from pgadmin_data volume path 2024-05-30 12:16:16 +08:00
furyhawk 6f3d3bbe49 Refactor traefik.yml to fix routing rules for resume and blog subdomains 2024-05-30 11:50:36 +08:00
furyhawk 3baf43ad74 Refactor compose/apps.yml to add dependency on postgres service 2024-05-30 11:47:03 +08:00
furyhawk e2784f41fe Refactor compose/apps.yml to add pgadmin_data volume 2024-05-30 11:36:02 +08:00
furyhawk 1ac98da285 Refactor compose/apps.yml to add pgadmin service 2024-05-30 11:33:43 +08:00
furyhawk 03463c6b88 Refactor compose/apps.yml to update port mapping for privatebin service 2024-05-30 11:14:51 +08:00
furyhawk a1112357b8 Refactor traefik.yml to add swarm endpoint for Docker swarm mode 2024-05-30 10:16:50 +08:00
furyhawk 10676c0754 Refactor docker-compose.yml to add deploy constraints for manager node 2024-05-30 09:29:56 +08:00
furyhawk 1e581d71fb Refactor traefik.yml to remove commented out swarm endpoint for Docker swarm mode 2024-05-30 09:24:31 +08:00
furyhawk a345319737 Refactor traefik.yml to add swarm endpoint for Docker swarm mode 2024-05-30 09:10:45 +08:00
14 changed files with 394 additions and 93 deletions
+1 -1
View File
@@ -171,4 +171,4 @@ privatebin-data/
# postgres-data/
minio-data/
usersfile
.DS_Store
.DS_Store
-6
View File
@@ -1,6 +0,0 @@
[submodule "LibreChat"]
path = LibreChat
url = https://github.com/furyhawk/LibreChat.git
[submodule "emqx-docker"]
path = emqx-docker
url = https://github.com/furyhawk/emqx-docker.git
Submodule LibreChat deleted from 026961f719
+13 -11
View File
@@ -20,17 +20,19 @@ This simple project uses Traefik as a reverse proxy to a Streamlit application a
- Build for ARM64 platform
## Production Deployment
1. `git clone
1. `git submodule update --init --recursive`
1. In `compose/traefik/traefik.yml`, change `example@test.com` to your email.
2. In `compose/traefik/traefik.yml`, change `example.com` to your domain.
3. `sudo apt-get install build-essential` (if not already installed) to use makefile.
4. `mdkir ~/st-sync` syncthing folder.
5. `cd ~/site` public site folder.
5. `mkdir ./compose/config` to store config.
8. `cp .env.example ./compose/.env`
9. `cp usersfile.example ./compose/usersfile`
10. `make serve`
1. `git clone https://github.com/furyhawk/cloudy.git`
2. `cd cloudy`
3. `git submodule update --init --recursive`
4. In `compose/traefik/traefik.yml`, change `example@test.com` to your email.
5. In `compose/traefik/traefik.yml`, change `example.com` to your domain.
6. `sudo apt-get install build-essential` (if not already installed) to use makefile.
7. `mkdir ~/st-sync` syncthing folder.
8. `mkdir ~/site` public site folder.
9. `mkdir ./compose/config` to store config.
10. `cp .env.example ./compose/.env && cp .env ~/config/.env`
11. `cp ./compose/config/conf.php ~/config/conf.php`
12. `cp usersfile.example ./compose/usersfile`
13. `make serve`
### Notes:
```yaml
+2 -2
View File
@@ -14,5 +14,5 @@ include:
- compose/base.yml
- compose/services.yml
- compose/apps.yml
- emqx-docker/docker-compose.yml
- LibreChat/docker-compose.yml
- compose/deploy-emqx.yml
- compose/deploy-librechat.yml
BIN
View File
Binary file not shown.
+28 -6
View File
@@ -12,6 +12,7 @@ volumes:
jellyfin_config: {}
jellyfin_cache: {}
pgadmin: {}
pgadmin_data: {}
privatebin_data: {}
thelounge_data: {}
@@ -22,20 +23,17 @@ services:
environment:
PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL}
PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD}
PGID: 1000
PUID: 1000
PATH: "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
PYTHONPATH: "/pgadmin4"
TZ: Asia/Singapore
DOMAINNAME: ${DOMAINNAME}
user: "1000:1000"
volumes:
- pgadmin:/var/lib/pgadmin
restart: unless-stopped
depends_on:
- postgres
expose:
- 80
- 8080
networks:
- net
labels:
@@ -65,7 +63,6 @@ services:
ghost-db:
image: mysql:8
container_name: ghost-db
security_opt:
- seccomp:unconfined
restart: always
@@ -81,7 +78,6 @@ services:
ghost-server:
image: ghost
container_name: ghost_server
cap_add:
- CAP_SYS_NICE
security_opt:
@@ -176,6 +172,29 @@ services:
- "traefik.http.routers.meshtastic.service=meshtastic_app"
- "traefik.http.services.meshtastic_app.loadbalancer.server.port=8080"
pgadmin:
image: dpage/pgadmin4
environment:
PGADMIN_DEFAULT_EMAIL: "${PGADMIN_DEFAULT_EMAIL}"
PGADMIN_DEFAULT_PASSWORD: "${PGADMIN_DEFAULT_PASSWORD}"
volumes:
- pgadmin_data:/var/lib/pgadmin
restart: unless-stopped
depends_on:
- postgres
expose:
- 80
networks:
- net
labels:
- "traefik.enable=true"
- "traefik.http.routers.pgadmin.entrypoints=web-secure"
- "traefik.http.routers.pgadmin.rule=Host(`pgadmin.${DOMAINNAME}`)"
- "traefik.http.routers.pgadmin.middlewares=csrf@file"
- "traefik.http.routers.pgadmin.tls.certresolver=letsencrypt"
- "traefik.http.routers.pgadmin.service=pgadmin_app"
- "traefik.http.services.pgadmin_app.loadbalancer.server.port=80"
privatebin:
image: privatebin/nginx-fpm-alpine:latest
read_only: true
@@ -199,6 +218,9 @@ services:
- "traefik.http.services.privatebin_app.loadbalancer.server.port=8080"
redlib:
# disable container temporarily
profiles:
- donotstart
image: quay.io/redlib/redlib:latest-arm
restart: unless-stopped
user: nobody
+4
View File
@@ -52,6 +52,10 @@ services:
security_opt:
- no-new-privileges:true
restart: always
deploy:
placement:
constraints:
- node.role == manager
volumes:
- logs:/logs
- production_traefik:/etc/traefik/acme:z
+144
View File
@@ -0,0 +1,144 @@
# For more information, see the Configuration Guide:
# https://docs.librechat.ai/install/configuration/custom_config.html
# Configuration version (required)
version: 1.0.6
# Cache settings: Set to true to enable caching
cache: true
# Custom nterface configuration
interface:
# Privacy policy settings
privacyPolicy:
externalUrl: 'https://librechat.ai/privacy-policy'
openNewTab: true
# Terms of service
termsOfService:
externalUrl: 'https://librechat.ai/tos'
openNewTab: true
# Example Registration Object Structure (optional)
registration:
socialLogins: ['github', 'google', 'discord', 'openid', 'facebook']
# allowedDomains:
# - "gmail.com"
# rateLimits:
# fileUploads:
# ipMax: 100
# ipWindowInMinutes: 60 # Rate limit window for file uploads per IP
# userMax: 50
# userWindowInMinutes: 60 # Rate limit window for file uploads per user
# Definition of custom endpoints
endpoints:
# assistants:
# disableBuilder: false # Disable Assistants Builder Interface by setting to `true`
# pollIntervalMs: 750 # Polling interval for checking assistant updates
# timeoutMs: 180000 # Timeout for assistant operations
# # Should only be one or the other, either `supportedIds` or `excludedIds`
# supportedIds: ["asst_supportedAssistantId1", "asst_supportedAssistantId2"]
# # excludedIds: ["asst_excludedAssistantId"]
# # (optional) Models that support retrieval, will default to latest known OpenAI models that support the feature
# retrievalModels: ["gpt-4-turbo-preview"]
# # (optional) Assistant Capabilities available to all users. Omit the ones you wish to exclude. Defaults to list below.
# capabilities: ["code_interpreter", "retrieval", "actions", "tools", "image_vision"]
custom:
# Groq Example
- name: 'groq'
apiKey: '${GROQ_API_KEY}'
baseURL: 'https://api.groq.com/openai/v1/'
models:
default: [
"llama3-70b-8192",
"llama3-8b-8192",
"llama2-70b-4096",
"mixtral-8x7b-32768",
"gemma-7b-it",
]
fetch: false
titleConvo: true
titleModel: 'llama3-70b-8192'
modelDisplayLabel: 'groq'
# # Mistral AI Example
# - name: 'Mistral' # Unique name for the endpoint
# # For `apiKey` and `baseURL`, you can use environment variables that you define.
# # recommended environment variables:
# apiKey: '${MISTRAL_API_KEY}'
# baseURL: 'https://api.mistral.ai/v1'
# # Models configuration
# models:
# # List of default models to use. At least one value is required.
# default: ['mistral-tiny', 'mistral-small', 'mistral-medium']
# # Fetch option: Set to true to fetch models from API.
# fetch: true # Defaults to false.
# # Optional configurations
# # Title Conversation setting
# titleConvo: true # Set to true to enable title conversation
# # Title Method: Choose between "completion" or "functions".
# # titleMethod: "completion" # Defaults to "completion" if omitted.
# # Title Model: Specify the model to use for titles.
# titleModel: 'mistral-tiny' # Defaults to "gpt-3.5-turbo" if omitted.
# # Summarize setting: Set to true to enable summarization.
# # summarize: false
# # Summary Model: Specify the model to use if summarization is enabled.
# # summaryModel: "mistral-tiny" # Defaults to "gpt-3.5-turbo" if omitted.
# # Force Prompt setting: If true, sends a `prompt` parameter instead of `messages`.
# # forcePrompt: false
# # The label displayed for the AI model in messages.
# modelDisplayLabel: 'Mistral' # Default is "AI" when not set.
# # Add additional parameters to the request. Default params will be overwritten.
# # addParams:
# # safe_prompt: true # This field is specific to Mistral AI: https://docs.mistral.ai/api/
# # Drop Default params parameters from the request. See default params in guide linked below.
# # NOTE: For Mistral, it is necessary to drop the following parameters or you will encounter a 422 Error:
# dropParams: ['stop', 'user', 'frequency_penalty', 'presence_penalty']
# # OpenRouter Example
# - name: 'OpenRouter'
# # For `apiKey` and `baseURL`, you can use environment variables that you define.
# # recommended environment variables:
# # Known issue: you should not use `OPENROUTER_API_KEY` as it will then override the `openAI` endpoint to use OpenRouter as well.
# apiKey: '${OPENROUTER_KEY}'
# baseURL: 'https://openrouter.ai/api/v1'
# models:
# default: ['gpt-3.5-turbo']
# fetch: true
# titleConvo: true
# titleModel: 'gpt-3.5-turbo'
# # Recommended: Drop the stop parameter from the request as Openrouter models use a variety of stop tokens.
# dropParams: ['stop']
# modelDisplayLabel: 'OpenRouter'
# fileConfig:
# endpoints:
# assistants:
# fileLimit: 5
# fileSizeLimit: 10 # Maximum size for an individual file in MB
# totalSizeLimit: 50 # Maximum total size for all files in a single request in MB
# supportedMimeTypes:
# - "image/.*"
# - "application/pdf"
# openAI:
# disabled: true # Disables file uploading to the OpenAI endpoint
# default:
# totalSizeLimit: 20
# YourCustomEndpointName:
# fileLimit: 2
# fileSizeLimit: 5
# serverFileSizeLimit: 100 # Global server file size limit in MB
# avatarSizeLimit: 2 # Limit for user avatar image size in MB
# See the Custom Configuration Guide for more information:
# https://docs.librechat.ai/install/configuration/custom_config.html
+81
View File
@@ -0,0 +1,81 @@
volumes:
vol-emqx-data1:
name: foo-emqx-data1
external: true
# vol-emqx-data2:
# name: foo-emqx-data2
# external: true
services:
emqx1:
image: emqx:latest
# environment:
# - "EMQX_NODE_NAME=emqx@node1.emqx.io"
# - "EMQX_CLUSTER__DISCOVERY_STRATEGY=static"
# - "EMQX_CLUSTER__STATIC__SEEDS=[emqx@node1.emqx.io,emqx@node2.emqx.io]"
healthcheck:
test: ["CMD", "/opt/emqx/bin/emqx", "ctl", "status"]
interval: 60s
timeout: 25s
retries: 5
networks:
net:
# emqx-bridge:
# aliases:
# - node1.emqx.io
ports:
- "1883:1883"
# - 8083:8083
# - 8084:8084
# - 8883:8883
# - 18083:18083
volumes:
- vol-emqx-data1:/opt/emqx/data
labels:
- "traefik.enable=true"
- "traefik.http.routers.emqx1.entrypoints=web-secure"
- "traefik.http.routers.emqx1.rule=Host(`mqtt.${DOMAINNAME}`)"
- "traefik.http.routers.emqx1.tls.certresolver=letsencrypt"
- "traefik.http.routers.emqx1.service=emqx-dashboard"
- "traefik.http.services.emqx-dashboard.loadbalancer.server.port=18083"
# emqx2:
# image: emqx:latest
# container_name: emqx2
# environment:
# - "EMQX_NODE_NAME=emqx@node2.emqx.io"
# - "EMQX_CLUSTER__DISCOVERY_STRATEGY=static"
# - "EMQX_CLUSTER__STATIC__SEEDS=[emqx@node1.emqx.io,emqx@node2.emqx.io]"
# healthcheck:
# test: ["CMD", "/opt/emqx/bin/emqx", "ctl", "status"]
# interval: 60s
# timeout: 25s
# retries: 5
# networks:
# net:
# emqx-bridge:
# aliases:
# - node2.emqx.io
# volumes:
# - vol-emqx-data2:/opt/emqx/data
mqttx-web:
image: emqx/mqttx-web:latest
restart: unless-stopped
networks:
- net
labels:
- "traefik.enable=true"
- "traefik.http.routers.mqttx-web.entrypoints=web-secure"
- "traefik.http.routers.mqttx-web.rule=Host(`mqttx.${DOMAINNAME}`)"
- "traefik.http.routers.mqttx-web.tls.certresolver=letsencrypt"
- "traefik.http.routers.mqttx-web.service=mqttx-web-service"
- "traefik.http.services.mqttx-web-service.loadbalancer.server.port=80"
networks:
# emqx-bridge:
# driver: bridge
net:
external: true
name: ${NETWORK:-web}
+85
View File
@@ -0,0 +1,85 @@
# Do not edit this file directly. Use a docker-compose.override.yaml file if you can.
# Refer to `docker-compose.override.yaml.example for some sample configurations.
volumes:
data-node:
pgdata2:
libre-images:
libre-logs:
meili_data:
services:
librechat_api:
ports:
- "${PORT}:${PORT}"
depends_on:
- mongodb
- rag_api
image: ghcr.io/danny-avila/librechat-dev:latest
restart: always
user: "${UID}:${GID}"
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
- HOST=0.0.0.0
- MONGO_URI=mongodb://mongodb:27017/LibreChat
- MEILI_HOST=http://meilisearch:7700
- RAG_PORT=${RAG_PORT:-8000}
- RAG_API_URL=http://rag_api:${RAG_PORT:-8000}
- DOMAINNAME=${DOMAINNAME}
volumes:
- type: bind
source: ~/config/.env
target: /app/.env
- libre-images:/app/client/public/images
- libre-logs:/app/api/logs
- type: bind
source: ./config/librechat.yaml
target: /app/librechat.yaml
labels:
- "traefik.enable=true"
- "traefik.http.routers.librechat.entrypoints=web-secure"
- "traefik.http.routers.librechat.rule=Host(`chat.${DOMAINNAME}`) || Host(`bot.${DOMAINNAME}`)"
- "traefik.http.routers.librechat.middlewares=csrf@file"
- "traefik.http.routers.librechat.tls.certresolver=letsencrypt"
- "traefik.http.routers.librechat.service=librechat_app"
- "traefik.http.services.librechat_app.loadbalancer.server.port=${PORT}"
mongodb:
image: mongo
restart: always
user: "${UID}:${GID}"
volumes:
- data-node:/data/db
command: mongod --noauth
meilisearch:
image: getmeili/meilisearch:v1.7.3
restart: always
user: "${UID}:${GID}"
environment:
- MEILI_HOST=http://meilisearch:7700
- MEILI_NO_ANALYTICS=true
volumes:
- meili_data:/meili_data
vectordb:
image: ankane/pgvector:latest
environment:
POSTGRES_DB: mydatabase
POSTGRES_USER: myuser
POSTGRES_PASSWORD: mypassword
restart: always
volumes:
- pgdata2:/var/lib/postgresql/data
rag_api:
image: ghcr.io/danny-avila/librechat-rag-api-dev:latest
environment:
POSTGRES_DB: mydatabase
POSTGRES_USER: myuser
POSTGRES_PASSWORD: mypassword
DB_HOST: vectordb
RAG_PORT: ${RAG_PORT:-8000}
restart: always
depends_on:
- vectordb
env_file:
- ~/config/.env
+6 -7
View File
@@ -35,7 +35,6 @@ services:
postgres:
image: postgres
# container_name: postgres
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
@@ -61,15 +60,15 @@ services:
- net
labels:
- "traefik.enable=true"
# - "traefik.tcp.middlewares.test-inflightconn.inflightconn.amount=10"
- "traefik.tcp.routers.postgres.entrypoints=postgres-socket"
# - "traefik.tcp.routers.postgres.rule=HostSNI(`*`)"
- "traefik.tcp.routers.postgres.rule=HostSNIRegexp(`^.+\\.furyhawk\\.lol$`)"
- "traefik.tcp.routers.postgres.tls=true"
- "traefik.tcp.routers.postgres.tls.certresolver=letsencrypt"
# - "traefik.tcp.routers.postgres.middlewares=test-inflightconn"
- "traefik.tcp.routers.postgres.rule=HostSNI(`*`)"
- "traefik.tcp.routers.postgres.service=postgres_service"
- "traefik.tcp.services.postgres_service.loadbalancer.server.port=5432"
# - "traefik.tcp.middlewares.test-inflightconn.inflightconn.amount=10"
# - "traefik.tcp.routers.postgres.rule=HostSNIRegexp(`^.+\\.furyhawk\\.lol$`)"
# - "traefik.tcp.routers.postgres.tls=true"
# - "traefik.tcp.routers.postgres.tls.certresolver=letsencrypt"
# - "traefik.tcp.routers.postgres.middlewares=test-inflightconn"
# - "traefik.http.routers.postgres.entrypoints=web-secure"
# - "traefik.http.routers.postgres.rule=Host(`db.${DOMAINNAME}`)"
# - "traefik.http.routers.postgres.middlewares=rate-limit@file, csrf@file"
+30 -58
View File
@@ -95,16 +95,6 @@ http:
routers:
chat-router:
entryPoints:
- web-secure
rule: "Host(`bot.furyhawk.lol`) || Host(`chat.furyhawk.lol`)"
middlewares:
- csrf
tls:
certResolver: letsencrypt
service: librechat_app
# forum-router:
# entryPoints:
# - web-secure
@@ -126,15 +116,15 @@ http:
# certResolver: letsencrypt
# service: kestra_app
plane-router:
entryPoints:
- web-secure
rule: "Host(`plan.furyhawk.lol`) || Host(`plane.furyhawk.lol`)"
middlewares:
- csrf
tls:
certResolver: letsencrypt
service: plane_app
# plane-router:
# entryPoints:
# - web-secure
# rule: "Host(`plan.furyhawk.lol`) || Host(`plane.furyhawk.lol`)"
# middlewares:
# - csrf
# tls:
# certResolver: letsencrypt
# service: plane_app
# graph-router:
# entryPoints:
@@ -146,15 +136,15 @@ http:
# certResolver: letsencrypt
# service: neo4j-bolt
mqtt-http-router:
entryPoints:
- web-secure
rule: "Host(`mqtt.furyhawk.lol`)"
middlewares:
- csrf
tls:
certResolver: letsencrypt
service: emqx-dashboard
# mqtt-http-router:
# entryPoints:
# - web-secure
# rule: "Host(`mqtt.furyhawk.lol`)"
# middlewares:
# - csrf
# tls:
# certResolver: letsencrypt
# service: emqx-dashboard
# mqtt-socket-router:
# rule: "Host(`mqtt.furyhawk.lol`)"
@@ -180,16 +170,6 @@ http:
- csrf
service: emqx-web-socket-secure
mqttx-router:
entryPoints:
- web-secure
rule: "Host(`mqttx.furyhawk.lol`)"
middlewares:
- csrf
tls:
certResolver: letsencrypt
service: mqttx-web
middlewares:
auth:
basicAuth:
@@ -268,22 +248,18 @@ http:
# loadBalancer:
# servers:
# - url: http://kestra:8080
librechat_app:
loadBalancer:
servers:
- url: http://LibreChat:3080
# neo4j-bolt:
# loadBalancer:
# servers:
# - url: http://neo4j_server:7687
plane_app:
loadBalancer:
servers:
- url: http://node01:80
emqx-mqtt-socket:
loadBalancer:
servers:
- url: http://emqx1:1883
# plane_app:
# loadBalancer:
# servers:
# - url: http://node01:80
# emqx-mqtt-socket:
# loadBalancer:
# servers:
# - url: http://emqx1:1883
emqx-web-socket:
loadBalancer:
servers:
@@ -294,14 +270,6 @@ http:
servers:
- url: http://emqx1:8084
# - url: http://emqx2:8084
emqx-dashboard:
loadBalancer:
servers:
- url: http://emqx1:18083
mqttx-web:
loadBalancer:
servers:
- url: http://mqttx_web:80
providers:
# https://docs.traefik.io/master/providers/file/
@@ -312,3 +280,7 @@ providers:
network: web
exposedByDefault: false
endpoint: "unix:///var/run/docker.sock"
swarm:
# network: overwatch
exposedByDefault: false
endpoint: "unix:///var/run/docker.sock"
Submodule emqx-docker deleted from 554e4b1872