mirror of
https://github.com/Dokploy/templates.git
synced 2026-11-10 01:33:12 -06:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7683947842 |
@@ -1,256 +0,0 @@
|
||||
# Dify - open-source LLM app development platform
|
||||
# Adapted from the official docker/docker-compose.yaml (tag 1.15.0).
|
||||
# Minimal functional stack: api + worker + worker_beat + web + postgres
|
||||
# (pgvector, reused as the vector store) + redis + sandbox + ssrf_proxy
|
||||
# + plugin_daemon, fronted by a lightweight internal nginx gateway that
|
||||
# mirrors the upstream path routing (TLS terminates at Traefik).
|
||||
|
||||
x-shared-api-env: &shared-api-env
|
||||
LOG_LEVEL: INFO
|
||||
DEPLOY_ENV: PRODUCTION
|
||||
SECRET_KEY: ${SECRET_KEY}
|
||||
MIGRATION_ENABLED: "true"
|
||||
# Public URLs - a single domain, path-routed like the upstream nginx
|
||||
CONSOLE_API_URL: https://${DIFY_DOMAIN}
|
||||
CONSOLE_WEB_URL: https://${DIFY_DOMAIN}
|
||||
SERVICE_API_URL: https://${DIFY_DOMAIN}
|
||||
APP_API_URL: https://${DIFY_DOMAIN}
|
||||
APP_WEB_URL: https://${DIFY_DOMAIN}
|
||||
FILES_URL: https://${DIFY_DOMAIN}
|
||||
INTERNAL_FILES_URL: http://api:5001
|
||||
TRIGGER_URL: https://${DIFY_DOMAIN}
|
||||
ENDPOINT_URL_TEMPLATE: https://${DIFY_DOMAIN}/e/{hook_id}
|
||||
# The dedicated api_websocket collaboration service is not deployed
|
||||
ENABLE_COLLABORATION_MODE: "false"
|
||||
WEB_API_CORS_ALLOW_ORIGINS: "*"
|
||||
CONSOLE_CORS_ALLOW_ORIGINS: "*"
|
||||
# PostgreSQL
|
||||
DB_USERNAME: postgres
|
||||
DB_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
DB_HOST: db
|
||||
DB_PORT: "5432"
|
||||
DB_DATABASE: dify
|
||||
# Redis / Celery
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: "6379"
|
||||
REDIS_PASSWORD: ${REDIS_PASSWORD}
|
||||
REDIS_DB: "0"
|
||||
CELERY_BROKER_URL: redis://:${REDIS_PASSWORD}@redis:6379/1
|
||||
# File storage on a local volume
|
||||
STORAGE_TYPE: opendal
|
||||
OPENDAL_SCHEME: fs
|
||||
OPENDAL_FS_ROOT: storage
|
||||
# Vector store: pgvector, reusing the same PostgreSQL instance
|
||||
VECTOR_STORE: pgvector
|
||||
PGVECTOR_HOST: db
|
||||
PGVECTOR_PORT: "5432"
|
||||
PGVECTOR_USER: postgres
|
||||
PGVECTOR_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
PGVECTOR_DATABASE: dify
|
||||
PGVECTOR_MIN_CONNECTION: "1"
|
||||
PGVECTOR_MAX_CONNECTION: "5"
|
||||
# Code execution sandbox
|
||||
CODE_EXECUTION_ENDPOINT: http://sandbox:8194
|
||||
CODE_EXECUTION_API_KEY: ${SANDBOX_API_KEY}
|
||||
# SSRF proxy (squid) for user-triggered outbound requests
|
||||
SSRF_PROXY_HTTP_URL: http://ssrf_proxy:3128
|
||||
SSRF_PROXY_HTTPS_URL: http://ssrf_proxy:3128
|
||||
# Plugin daemon (model providers / tools are plugins since Dify 1.0)
|
||||
PLUGIN_DAEMON_URL: http://plugin_daemon:5002
|
||||
PLUGIN_DAEMON_KEY: ${PLUGIN_DAEMON_KEY}
|
||||
INNER_API_KEY_FOR_PLUGIN: ${PLUGIN_INNER_API_KEY}
|
||||
PLUGIN_MAX_PACKAGE_SIZE: "52428800"
|
||||
PLUGIN_REMOTE_INSTALL_HOST: localhost
|
||||
PLUGIN_REMOTE_INSTALL_PORT: "5003"
|
||||
MARKETPLACE_ENABLED: "true"
|
||||
MARKETPLACE_API_URL: https://marketplace.dify.ai
|
||||
|
||||
services:
|
||||
nginx:
|
||||
image: nginx:1.27-alpine
|
||||
restart: always
|
||||
volumes:
|
||||
- ../files/dify-nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
||||
depends_on:
|
||||
api:
|
||||
condition: service_healthy
|
||||
web:
|
||||
condition: service_started
|
||||
plugin_daemon:
|
||||
condition: service_started
|
||||
|
||||
# The dify-api image runs as the non-root user 1001, so the shared
|
||||
# storage volume has to be handed over to it once (same trick as the
|
||||
# upstream init_permissions container).
|
||||
init_permissions:
|
||||
image: busybox:1.36
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
FLAG_FILE="/app/api/storage/.init_permissions"
|
||||
if [ -f "$$FLAG_FILE" ]; then
|
||||
echo "Permissions already initialized."
|
||||
exit 0
|
||||
fi
|
||||
echo "Initializing permissions for /app/api/storage"
|
||||
chown -R 1001:1001 /app/api/storage && touch "$$FLAG_FILE"
|
||||
volumes:
|
||||
- dify-app-storage:/app/api/storage
|
||||
restart: "no"
|
||||
|
||||
api:
|
||||
image: langgenius/dify-api:1.15.0
|
||||
restart: always
|
||||
environment:
|
||||
<<: *shared-api-env
|
||||
MODE: api
|
||||
depends_on:
|
||||
init_permissions:
|
||||
condition: service_completed_successfully
|
||||
db:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
volumes:
|
||||
- dify-app-storage:/app/api/storage
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:5001/health"]
|
||||
interval: 15s
|
||||
timeout: 5s
|
||||
retries: 20
|
||||
start_period: 120s
|
||||
|
||||
worker:
|
||||
image: langgenius/dify-api:1.15.0
|
||||
restart: always
|
||||
environment:
|
||||
<<: *shared-api-env
|
||||
MODE: worker
|
||||
depends_on:
|
||||
init_permissions:
|
||||
condition: service_completed_successfully
|
||||
db:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
volumes:
|
||||
- dify-app-storage:/app/api/storage
|
||||
|
||||
worker_beat:
|
||||
image: langgenius/dify-api:1.15.0
|
||||
restart: always
|
||||
environment:
|
||||
<<: *shared-api-env
|
||||
MODE: beat
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
|
||||
web:
|
||||
image: langgenius/dify-web:1.15.0
|
||||
restart: always
|
||||
environment:
|
||||
CONSOLE_API_URL: https://${DIFY_DOMAIN}
|
||||
APP_API_URL: https://${DIFY_DOMAIN}
|
||||
SERVER_CONSOLE_API_URL: http://api:5001
|
||||
ENABLE_COLLABORATION_MODE: "false"
|
||||
MARKETPLACE_API_URL: https://marketplace.dify.ai
|
||||
MARKETPLACE_URL: https://marketplace.dify.ai
|
||||
NEXT_TELEMETRY_DISABLED: "1"
|
||||
|
||||
db:
|
||||
image: pgvector/pgvector:pg16
|
||||
restart: always
|
||||
environment:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
POSTGRES_DB: dify
|
||||
PGDATA: /var/lib/postgresql/data/pgdata
|
||||
volumes:
|
||||
- dify-db-data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U postgres -d dify"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 30
|
||||
|
||||
redis:
|
||||
image: redis:6-alpine
|
||||
restart: always
|
||||
environment:
|
||||
REDISCLI_AUTH: ${REDIS_PASSWORD}
|
||||
command: redis-server --requirepass ${REDIS_PASSWORD}
|
||||
volumes:
|
||||
- dify-redis-data:/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "redis-cli ping | grep -q PONG"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 30
|
||||
|
||||
sandbox:
|
||||
image: langgenius/dify-sandbox:0.2.15
|
||||
restart: always
|
||||
environment:
|
||||
API_KEY: ${SANDBOX_API_KEY}
|
||||
GIN_MODE: release
|
||||
WORKER_TIMEOUT: "15"
|
||||
ENABLE_NETWORK: "true"
|
||||
HTTP_PROXY: http://ssrf_proxy:3128
|
||||
HTTPS_PROXY: http://ssrf_proxy:3128
|
||||
SANDBOX_PORT: "8194"
|
||||
volumes:
|
||||
- dify-sandbox-deps:/dependencies
|
||||
|
||||
ssrf_proxy:
|
||||
image: ubuntu/squid:latest
|
||||
restart: always
|
||||
volumes:
|
||||
- ../files/dify-squid.conf:/etc/squid/squid.conf:ro
|
||||
|
||||
plugin_daemon:
|
||||
image: langgenius/dify-plugin-daemon:0.6.3-local
|
||||
restart: always
|
||||
environment:
|
||||
DB_HOST: db
|
||||
DB_PORT: "5432"
|
||||
DB_USERNAME: postgres
|
||||
DB_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
DB_DATABASE: dify_plugin
|
||||
DB_SSL_MODE: disable
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: "6379"
|
||||
REDIS_PASSWORD: ${REDIS_PASSWORD}
|
||||
SERVER_PORT: "5002"
|
||||
SERVER_KEY: ${PLUGIN_DAEMON_KEY}
|
||||
MAX_PLUGIN_PACKAGE_SIZE: "52428800"
|
||||
DIFY_INNER_API_URL: http://api:5001
|
||||
DIFY_INNER_API_KEY: ${PLUGIN_INNER_API_KEY}
|
||||
PLUGIN_REMOTE_INSTALLING_HOST: 0.0.0.0
|
||||
PLUGIN_REMOTE_INSTALLING_PORT: "5003"
|
||||
PLUGIN_WORKING_PATH: /app/storage/cwd
|
||||
FORCE_VERIFYING_SIGNATURE: "true"
|
||||
PYTHON_ENV_INIT_TIMEOUT: "120"
|
||||
PLUGIN_MAX_EXECUTION_TIMEOUT: "600"
|
||||
PLUGIN_STORAGE_TYPE: local
|
||||
PLUGIN_STORAGE_LOCAL_ROOT: /app/storage
|
||||
PLUGIN_INSTALLED_PATH: plugin
|
||||
PLUGIN_PACKAGE_CACHE_PATH: plugin_packages
|
||||
PLUGIN_MEDIA_CACHE_PATH: assets
|
||||
volumes:
|
||||
- dify-plugin-storage:/app/storage
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
|
||||
volumes:
|
||||
dify-app-storage:
|
||||
dify-db-data:
|
||||
dify-redis-data:
|
||||
dify-sandbox-deps:
|
||||
dify-plugin-storage:
|
||||
@@ -1,15 +0,0 @@
|
||||
## Instructions
|
||||
|
||||
### First setup
|
||||
|
||||
- The first boot runs the database migrations, so it can take **2-4 minutes** before the application responds.
|
||||
- Open your domain: you will be redirected to `/install`, where you create the admin (workspace owner) account.
|
||||
- After signing in, go to **Settings -> Model Provider** and install a model provider plugin (OpenAI, Anthropic, Ollama, etc.) from the marketplace, then configure your API keys.
|
||||
|
||||
### Notes
|
||||
|
||||
- **HTTPS is required for the console login**: Dify issues `__Host-`/`Secure` session cookies, so make sure the domain has a certificate (e.g. Let's Encrypt in the domain settings). Over plain HTTP the browser will drop the session cookies and login will not persist.
|
||||
|
||||
- The vector store is **pgvector**, running inside the bundled PostgreSQL instance (no separate Weaviate/Qdrant container needed).
|
||||
- All routing (`/console/api`, `/api`, `/v1`, `/files`, `/e/`, ...) is handled by the bundled internal nginx gateway, mirroring the upstream deployment, so the Dify service API is available at `https://<your-domain>/v1`.
|
||||
- Code execution runs in the isolated `sandbox` service, and user-triggered outbound HTTP requests go through the `ssrf_proxy` (squid) service, like in the official deployment.
|
||||
@@ -1,12 +0,0 @@
|
||||
<svg width="48" height="22" viewBox="0 0 48 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="White=False">
|
||||
<g id="if">
|
||||
<path d="M21.2002 3.73454C22.5633 3.73454 23.0666 2.89917 23.0666 1.86812C23.0666 0.837081 22.5623 0.00170898 21.2002 0.00170898C19.838 0.00170898 19.3337 0.837081 19.3337 1.86812C19.3337 2.89917 19.838 3.73454 21.2002 3.73454Z" fill="#0033FF"/>
|
||||
<path d="M27.7336 4.13435V5.33473H24.6668V8.00171H27.7336V14.6687H22.6668V5.33567H15.9998V8.00265H19.7336V14.6696H15.3337V17.3366H35.3337V14.6696H30.6668V8.00265H35.3337V5.33567H30.6668V2.66869H35.3337V0.00170898H31.8671C29.5877 0.00170898 27.7336 1.8559 27.7336 4.13529V4.13435Z" fill="#0033FF"/>
|
||||
</g>
|
||||
<g id="Dy">
|
||||
<path d="M5.66698 0.000940576H0V17.334H5.66698C12.667 17.334 14.667 13.334 14.667 8.66698C14.667 4 12.667 0 5.66698 0V0.000940576ZM5.73377 14.6679H3.20038V2.66792H5.73377C9.75823 2.66792 11.4666 4.64346 11.4666 8.66792C11.4666 12.6924 9.75823 14.6679 5.73377 14.6679Z" fill="black"/>
|
||||
<path d="M44.8335 5.3349L42.1665 14.0019L39.4995 5.3349H36.333L40.2013 16.5466C40.604 17.714 39.9229 18.6679 38.6886 18.6679H37.333V21.3349H39.3255C41.063 21.3349 42.6265 20.2361 43.2145 18.6011L48 5.3349H44.8335Z" fill="black"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"id": "dify",
|
||||
"name": "Dify",
|
||||
"version": "1.15.0",
|
||||
"description": "Dify is an open-source LLM app development platform. Build AI workflows, RAG pipelines, agents and chatbots with a visual interface and publish them as APIs or web apps.",
|
||||
"logo": "logo.svg",
|
||||
"links": {
|
||||
"github": "https://github.com/langgenius/dify",
|
||||
"website": "https://dify.ai/",
|
||||
"docs": "https://docs.dify.ai/"
|
||||
},
|
||||
"tags": [
|
||||
"ai",
|
||||
"llm",
|
||||
"rag"
|
||||
]
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
[variables]
|
||||
main_domain = "${domain}"
|
||||
secret_key = "${base64:42}"
|
||||
postgres_password = "${password:32}"
|
||||
redis_password = "${password:32}"
|
||||
sandbox_api_key = "${password:32}"
|
||||
plugin_daemon_key = "${base64:42}"
|
||||
plugin_inner_api_key = "${base64:42}"
|
||||
|
||||
[config]
|
||||
env = [
|
||||
"DIFY_DOMAIN=${main_domain}",
|
||||
"SECRET_KEY=${secret_key}",
|
||||
"POSTGRES_PASSWORD=${postgres_password}",
|
||||
"REDIS_PASSWORD=${redis_password}",
|
||||
"SANDBOX_API_KEY=${sandbox_api_key}",
|
||||
"PLUGIN_DAEMON_KEY=${plugin_daemon_key}",
|
||||
"PLUGIN_INNER_API_KEY=${plugin_inner_api_key}",
|
||||
]
|
||||
|
||||
[[config.domains]]
|
||||
serviceName = "nginx"
|
||||
port = 80
|
||||
host = "${main_domain}"
|
||||
|
||||
# Internal nginx gateway replicating the upstream Dify nginx routing
|
||||
# (TLS terminates at Traefik, which forwards everything to this nginx).
|
||||
[[config.mounts]]
|
||||
filePath = "dify-nginx.conf"
|
||||
content = '''
|
||||
map $http_x_forwarded_proto $dify_forwarded_proto {
|
||||
default $http_x_forwarded_proto;
|
||||
"" $scheme;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
client_max_body_size 100M;
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $dify_forwarded_proto;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Connection "";
|
||||
proxy_buffering off;
|
||||
proxy_read_timeout 3600s;
|
||||
proxy_send_timeout 3600s;
|
||||
|
||||
location /console/api { proxy_pass http://api:5001; }
|
||||
location /api { proxy_pass http://api:5001; }
|
||||
location /v1 { proxy_pass http://api:5001; }
|
||||
location /openapi { proxy_pass http://api:5001; }
|
||||
location /files { proxy_pass http://api:5001; }
|
||||
location /mcp { proxy_pass http://api:5001; }
|
||||
location /triggers { proxy_pass http://api:5001; }
|
||||
location /explore { proxy_pass http://web:3000; }
|
||||
|
||||
location /e/ {
|
||||
proxy_pass http://plugin_daemon:5002;
|
||||
# nginx drops inherited proxy_set_header directives as soon as a
|
||||
# location defines its own, so the shared ones are repeated here.
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $dify_forwarded_proto;
|
||||
proxy_set_header Connection "";
|
||||
proxy_set_header Dify-Hook-Url $dify_forwarded_proto://$host$request_uri;
|
||||
}
|
||||
|
||||
location / { proxy_pass http://web:3000; }
|
||||
}
|
||||
'''
|
||||
|
||||
# Squid SSRF proxy configuration, rendered from the upstream
|
||||
# docker/ssrf_proxy/squid.conf.template with its default values.
|
||||
[[config.mounts]]
|
||||
filePath = "dify-squid.conf"
|
||||
content = '''
|
||||
acl client_localnet src 0.0.0.1-0.255.255.255
|
||||
acl client_localnet src 10.0.0.0/8
|
||||
acl client_localnet src 100.64.0.0/10
|
||||
acl client_localnet src 169.254.0.0/16
|
||||
acl client_localnet src 172.16.0.0/12
|
||||
acl client_localnet src 192.168.0.0/16
|
||||
acl client_localnet src fc00::/7
|
||||
acl client_localnet src fe80::/10
|
||||
acl to_private_networks dst 0.0.0.0/8
|
||||
acl to_private_networks dst 10.0.0.0/8
|
||||
acl to_private_networks dst 100.64.0.0/10
|
||||
acl to_private_networks dst 127.0.0.0/8
|
||||
acl to_private_networks dst 169.254.0.0/16
|
||||
acl to_private_networks dst 172.16.0.0/12
|
||||
acl to_private_networks dst 192.168.0.0/16
|
||||
acl to_private_networks dst 224.0.0.0/4
|
||||
acl to_private_networks dst 240.0.0.0/4
|
||||
acl to_private_networks dst ::/128
|
||||
acl to_private_networks dst ::1/128
|
||||
acl to_private_networks dst ::ffff:0:0/96
|
||||
acl to_private_networks dst ::/96
|
||||
acl to_private_networks dst fc00::/7
|
||||
acl to_private_networks dst fe80::/10
|
||||
acl SSL_ports port 443
|
||||
acl Safe_ports port 80
|
||||
acl Safe_ports port 21
|
||||
acl Safe_ports port 443
|
||||
acl Safe_ports port 70
|
||||
acl Safe_ports port 210
|
||||
acl Safe_ports port 1025-65535
|
||||
acl Safe_ports port 280
|
||||
acl Safe_ports port 488
|
||||
acl Safe_ports port 591
|
||||
acl Safe_ports port 777
|
||||
acl CONNECT method CONNECT
|
||||
acl allowed_domains dstdomain .marketplace.dify.ai
|
||||
|
||||
http_port 3128
|
||||
|
||||
http_access deny !Safe_ports
|
||||
http_access deny CONNECT !SSL_ports
|
||||
http_access allow localhost manager
|
||||
http_access deny manager
|
||||
http_access deny to_private_networks
|
||||
http_access allow allowed_domains
|
||||
http_access allow client_localnet
|
||||
http_access allow localhost
|
||||
http_access deny all
|
||||
tcp_outgoing_address 0.0.0.0
|
||||
|
||||
coredump_dir /var/spool/squid
|
||||
refresh_pattern ^ftp: 1440 20% 10080
|
||||
refresh_pattern ^gopher: 1440 0% 1440
|
||||
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
|
||||
refresh_pattern . 0 20% 4320
|
||||
|
||||
client_request_buffer_max_size 100 MB
|
||||
max_filedescriptors 65536
|
||||
|
||||
connect_timeout 30 seconds
|
||||
request_timeout 2 minutes
|
||||
read_timeout 2 minutes
|
||||
client_lifetime 5 minutes
|
||||
shutdown_lifetime 30 seconds
|
||||
|
||||
server_persistent_connections on
|
||||
client_persistent_connections on
|
||||
persistent_request_timeout 30 seconds
|
||||
pconn_timeout 1 minute
|
||||
|
||||
client_db on
|
||||
server_idle_pconn_timeout 2 minutes
|
||||
client_idle_pconn_timeout 2 minutes
|
||||
|
||||
quick_abort_min 16 KB
|
||||
quick_abort_max 16 MB
|
||||
quick_abort_pct 95
|
||||
|
||||
memory_cache_mode disk
|
||||
cache_mem 256 MB
|
||||
maximum_object_size_in_memory 512 KB
|
||||
|
||||
dns_timeout 30 seconds
|
||||
dns_retransmit_interval 5 seconds
|
||||
|
||||
logformat dify_log %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %[un %Sh/%<a %mt
|
||||
access_log daemon:/var/log/squid/access.log dify_log
|
||||
logfile_rotate 10
|
||||
'''
|
||||
@@ -0,0 +1,66 @@
|
||||
services:
|
||||
weblate:
|
||||
image: weblate/weblate:2026.7.1.1
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
database:
|
||||
condition: service_healthy
|
||||
cache:
|
||||
condition: service_healthy
|
||||
volumes:
|
||||
- weblate-data:/app/data
|
||||
- weblate-cache:/app/cache
|
||||
tmpfs:
|
||||
- /run
|
||||
- /tmp
|
||||
environment:
|
||||
WEBLATE_SITE_DOMAIN: ${WEBLATE_SITE_DOMAIN}
|
||||
WEBLATE_SITE_TITLE: ${WEBLATE_SITE_TITLE}
|
||||
WEBLATE_ADMIN_NAME: ${WEBLATE_ADMIN_NAME}
|
||||
WEBLATE_ADMIN_EMAIL: ${WEBLATE_ADMIN_EMAIL}
|
||||
WEBLATE_ADMIN_PASSWORD: ${WEBLATE_ADMIN_PASSWORD}
|
||||
WEBLATE_SERVER_EMAIL: ${WEBLATE_SERVER_EMAIL}
|
||||
WEBLATE_DEFAULT_FROM_EMAIL: ${WEBLATE_DEFAULT_FROM_EMAIL}
|
||||
WEBLATE_ENABLE_HTTPS: ${WEBLATE_ENABLE_HTTPS}
|
||||
WEBLATE_ALLOWED_HOSTS: "*"
|
||||
WEBLATE_REGISTRATION_OPEN: ${WEBLATE_REGISTRATION_OPEN}
|
||||
POSTGRES_HOST: database
|
||||
POSTGRES_PORT: 5432
|
||||
POSTGRES_USER: ${POSTGRES_USER}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
POSTGRES_DB: ${POSTGRES_DB}
|
||||
REDIS_HOST: cache
|
||||
REDIS_PORT: 6379
|
||||
|
||||
database:
|
||||
image: postgres:18-alpine
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- weblate-postgres-data:/var/lib/postgresql
|
||||
environment:
|
||||
POSTGRES_USER: ${POSTGRES_USER}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
POSTGRES_DB: ${POSTGRES_DB}
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
cache:
|
||||
image: redis:8-alpine
|
||||
restart: unless-stopped
|
||||
command: ["redis-server", "--save", "60", "1", "--loglevel", "warning"]
|
||||
volumes:
|
||||
- weblate-redis-data:/data
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
volumes:
|
||||
weblate-data:
|
||||
weblate-cache:
|
||||
weblate-postgres-data:
|
||||
weblate-redis-data:
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"id": "weblate",
|
||||
"name": "Weblate",
|
||||
"version": "2026.7.1.1",
|
||||
"description": "Weblate is a libre web-based continuous localization platform with tight version control integration, quality checks, and support for over 50 file formats including PO, XLIFF, JSON, and Android resources.",
|
||||
"logo": "weblate.svg",
|
||||
"links": {
|
||||
"github": "https://github.com/WeblateOrg/weblate",
|
||||
"website": "https://weblate.org/",
|
||||
"docs": "https://docs.weblate.org/en/latest/admin/install/docker.html"
|
||||
},
|
||||
"tags": [
|
||||
"localization",
|
||||
"translation",
|
||||
"i18n",
|
||||
"self-hosted"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
[variables]
|
||||
main_domain = "${domain}"
|
||||
admin_password = "${password:32}"
|
||||
postgres_password = "${password:32}"
|
||||
|
||||
[config]
|
||||
env = [
|
||||
"WEBLATE_SITE_DOMAIN=${main_domain}",
|
||||
"WEBLATE_SITE_TITLE=Weblate",
|
||||
"WEBLATE_ADMIN_NAME=Weblate Admin",
|
||||
"WEBLATE_ADMIN_EMAIL=admin@${main_domain}",
|
||||
"WEBLATE_ADMIN_PASSWORD=${admin_password}",
|
||||
"WEBLATE_SERVER_EMAIL=weblate@${main_domain}",
|
||||
"WEBLATE_DEFAULT_FROM_EMAIL=weblate@${main_domain}",
|
||||
"WEBLATE_ENABLE_HTTPS=0",
|
||||
"WEBLATE_REGISTRATION_OPEN=1",
|
||||
"POSTGRES_USER=weblate",
|
||||
"POSTGRES_PASSWORD=${postgres_password}",
|
||||
"POSTGRES_DB=weblate",
|
||||
]
|
||||
mounts = []
|
||||
|
||||
[[config.domains]]
|
||||
serviceName = "weblate"
|
||||
port = 8080
|
||||
host = "${main_domain}"
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" id="svg31" width="300" height="300" version="1.1" viewBox="0 0 300 300"><metadata id="metadata37"/><linearGradient id="a" x1=".396" x2="98.808" y1="55.253" y2="55.253" gradientTransform="scale(0.98308415,1.0172069)" gradientUnits="userSpaceOnUse"><stop id="stop2" offset="0" stop-color="#00d2e6"/><stop id="stop4" offset="1" stop-color="#2eccaa"/></linearGradient><linearGradient id="b" x1="49.017" x2="99.793" y1="137.887" y2="113.962" gradientTransform="scale(1.1630616,0.85979965)" gradientUnits="userSpaceOnUse"><stop id="stop7" offset="0" stop-opacity="0"/><stop id="stop9" offset=".514"/><stop id="stop11" offset="1" stop-opacity="0"/></linearGradient><linearGradient id="c" x1="201.822" x2="103.577" y1="57.649" y2="57.649" gradientTransform="scale(0.98308415,1.0172069)" gradientUnits="userSpaceOnUse"><stop id="stop14" offset="0" stop-color="#1fa385"/><stop id="stop16" offset="1" stop-color="#2eccaa"/></linearGradient><g style="fill:none;fill-rule:evenodd" id="g27" transform="translate(50,76)"><path style="fill:url(#a);fill-rule:nonzero" id="path21" d="m 127.24725,111.60641 c -2.88836,-0.0145 -5.76656,-0.6024 -8.47973,-1.78467 -6.11167,-2.66259 -11.49342,-7.69116 -15.87156,-14.494798 1.24856,-2.219307 2.3738,-4.517338 3.37843,-6.853465 4.40506,-10.243222 6.50003,-21.459724 6.6607,-32.59332 -0.0233,-0.220825 -0.0416,-0.442436 -0.0552,-0.664833 l -0.0121,-0.571316 c -0.01,-4.365422 -0.67459,-8.789784 -2.17667,-12.908841 -1.73043,-4.745776 -4.4887,-9.495481 -8.86498,-11.347741 -0.79519,-0.335952 -1.63162,-0.477013 -2.464161,-0.457367 -5.504872,-10.288802 -5.679939,-20.1485266 0,-29.53713169 0.10115,0 0.20619,3.9293e-4 0.30734,0.001179 6.701161,0.0738703 13.340071,2.14184679 19.021181,5.75363459 15.46928,9.8349701 23.18193,29.0007861 23.35194,47.8180741 0.002,0.220826 -3.9e-4,0.441258 -0.007,0.66169 h 0.0868 c -0.0226,19.886801 -4.80489,40.053612 -14.87495,56.978905 z m -34.299625,31.21585 c -14.447871,5.94246 -31.22819,5.62359 -45.54931,-1.02501 C 30.922601,134.1497 18.333366,119.28527 10.57986,102.31827 -2.6824097,73.29666 -2.9858585,38.603143 9.5917057,9.1367387 19.037523,12.915521 27.43683,6.8970531 27.43683,6.8970531 c 0,0 -0.01945,9.2605109 8.94785,13.9049119 -9.200724,21.556385 -8.978973,47.166601 0.241203,68.172888 4.438911,10.107269 11.219825,19.519057 20.618957,24.841647 3.354732,1.8996 7.040998,3.12602 10.833017,3.58618 0.01404,0.0219 0.02808,0.0439 0.04214,0.0658 6.696522,10.44898 15.132208,19.1568 24.827633,25.35378 z"/><path style="opacity:.3;fill:url(#b)" id="path23" d="m 127.24298,111.61346 c -2.88693,-0.0151 -5.76363,-0.60296 -8.47546,-1.78465 -6.11266,-2.66302 -11.49516,-7.69279 -15.87368,-14.498094 1.24941,-2.220476 2.37535,-4.519788 3.38055,-6.857239 1.32817,-3.088408 2.44626,-6.264833 3.36439,-9.500982 2.12803,-7.497839 30.38184,2.018075 26.0717,14.370923 -2.22386,6.372982 -5.03943,12.509222 -8.4675,18.270042 z m -34.302088,31.21157 c -14.446351,5.93959 -31.223682,5.61979 -45.542576,-1.02778 -16.475715,-7.64755 0.447392,-33.30334 9.846524,-27.98075 3.353286,1.89878 7.037819,3.12496 10.828112,3.58558 0.01567,0.0245 0.03135,0.049 0.04704,0.0735 6.694972,10.44656 15.128303,19.15278 24.8209,25.34948 z"/><path style="fill:url(#c);fill-rule:nonzero" id="path25" d="m 56.762435,54.627505 c -0.0066,-0.220432 -0.0093,-0.440865 -0.007,-0.66169 C 56.925444,35.148526 64.638101,15.982711 80.107377,6.1477407 85.788484,2.5359528 92.427399,0.46797642 99.12856,0.39410609 c 0.10115,-7.8585e-4 0.20619,-0.001179 0.307339,-0.001179 V 29.930059 c -0.832539,-0.01965 -1.668968,0.121414 -2.46416,0.457367 -4.376276,1.85226 -7.134548,6.601965 -8.864984,11.347741 -1.502072,4.119057 -2.166936,8.543418 -2.176662,12.908841 l -0.01206,0.571316 c -0.01362,0.222397 -0.0319,0.444008 -0.05524,0.664833 0.160672,11.133595 2.255636,22.350098 6.660701,32.59332 4.933377,11.471906 12.775196,22.025153 23.847186,26.848723 8.35263,3.63969 17.61171,2.78114 25.18236,-1.5057 9.39914,-5.32259 16.18005,-14.734378 20.61896,-24.841647 9.22018,-21.006287 9.44193,-46.616503 0.24121,-68.172888 8.9673,-4.644401 8.94785,-13.9049119 8.94785,-13.9049119 0,0 8.3993,6.0184679 17.84512,2.2396856 12.57756,29.4664043 12.27412,64.1599213 -0.98815,93.1815313 -7.75351,16.967 -20.34275,31.83144 -36.81846,39.47898 -14.66669,6.80904 -31.9127,6.97917 -46.59106,0.58389 C 91.618199,136.63222 80.890116,126.27466 73.171624,114.23104 61.993036,96.788212 56.699411,75.552849 56.675679,54.627505 Z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 4.4 KiB |
Reference in New Issue
Block a user