Initial commit

This commit is contained in:
Dmitry Bikulov
2026-08-23 17:17:37 +03:00
commit d97525408e
16 changed files with 391 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
.env
data/*
!data/glance/
+24
View File
@@ -0,0 +1,24 @@
services:
gitea:
image: gitea/gitea
container_name: gitea
restart: unless-stopped
networks:
- proxy
ports:
- "22:22"
volumes:
- ./data/gitea:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
labels:
- "traefik.enable=true"
- "traefik.http.services.gitea.loadbalancer.server.port=3000"
- "traefik.http.routers.gitea.rule=Host(`${GITEA_HOST}`)"
- "traefik.http.routers.gitea.entrypoints=websecure"
- "traefik.http.routers.gitea.tls.certresolver=le"
networks:
proxy:
name: proxy
external: true
+1
View File
@@ -0,0 +1 @@
GITEA_HOST=
+109
View File
@@ -0,0 +1,109 @@
pages:
- name: Home
head-widgets:
- type: monitor
cache: 1m
title: Services
hide-header: true
sites:
- title: Git
url: https://git.ksar.dev
icon: sh:gitea
- title: Wiki
url: https://wiki.ksar.dev
icon: https://cdn.jsdelivr.net/gh/selfhst/icons@main/png/outline.png
- title: Notes
url: https://notes.ksar.dev
icon: https://cdn.jsdelivr.net/gh/selfhst/icons@main/png/memos.png
- title: RSS
url: https://rss.ksar.dev
icon: https://cdn.jsdelivr.net/gh/selfhst/icons@main/png/miniflux-light.png
- title: Vaultwarden
url: https://bw.ksar.dev
icon: https://cdn.jsdelivr.net/gh/selfhst/icons@main/png/vaultwarden-light.png
columns:
- size: small
widgets:
- type: weather
hide-header: true
location: Moscow, Russia
units: metric
hour-format: 24h
- type: calendar
hide-header: true
first-day-of-week: monday
- type: releases
hide-header: true
show-source-icon: true
repositories:
- docmost/docmost
- glanceapp/glance
- traefik/traefik
- usememos/memos
- miniflux/v2
- MHSanaei/3x-ui
- go-gitea/gitea
- dani-garcia/vaultwarden
- dockerhub:gitlab/gitlab-ce
- dockerhub:jetbrains/youtrack
- size: full
widgets:
- type: search
search-engine: kagi
hide-header: true
- type: group
widgets:
- type: hacker-news
limit: 30
collapse-after: 10
- type: lobsters
limit: 30
collapse-after: 10
- type: reddit
subreddit: technology
show-thumbnails: true
limit: 30
collapse-after: 10
top-period: week
sort-by: best
- type: reddit
subreddit: selfhosted
show-thumbnails: true
limit: 30
collapse-after: 10
top-period: week
sort-by: best
- type: reddit
subreddit: science
show-thumbnails: true
limit: 30
collapse-after: 10
top-period: week
sort-by: best
- size: small
widgets:
- type: videos
style: vertical-list
hide-header: true
collapse-after: 15
channels:
- UCDaIW2zPRWhzQ9Hj7a0QP1w # Руслан Усачев
- UCY6zVRa3Km52bsBmpyQnk6A # Vert Dider
- UCJQlWxJziHWs0Bq59D2Qw8A # РЫНДЫЧ
- UC2q4mHrzoR48mwSuAYtVPtQ # Александр Панчин
- UCerK03vbFNIDc8ABS87gHzw # ЛЕСНЫЕ
- UCYulscWJwKgs35FTF9FaNlw # Дмитрий Машков
- UCbS8hyArQ_VWPSBcc56FsLw # ПроВокруг
- UCQwRlx8hVI-CFv_E-v5s84Q # Адвокат Егоров
- UC2Ru64PHqW4FxoP0xhQRvJg # ТОПЛЕС
- UCY1kMZp36IQSyNx_9h4mpCg # Mark Rober
- UCt9SXdrwKnV_4WwRjUmHZsQ # Михаил Лидин
- UC6cqazSR6CnVMClY0bJI0Lg # BadComedian
- UCXUPKJO5MZQN11PqgIvyuvQ # Andrej Karpathy
- UCisCR8RgtPcHGpUXblKxrvQ # Клинический случай
+20
View File
@@ -0,0 +1,20 @@
services:
glance:
image: glanceapp/glance
container_name: glance
restart: unless-stopped
networks:
- proxy
volumes:
- ./data/glance:/app/config
labels:
- "traefik.enable=true"
- "traefik.http.services.glance.loadbalancer.server.port=8080"
- "traefik.http.routers.glance.rule=Host(`${GLANCE_HOST}`)"
- "traefik.http.routers.glance.entrypoints=websecure"
- "traefik.http.routers.glance.tls.certresolver=le"
networks:
proxy:
name: proxy
external: true
+1
View File
@@ -0,0 +1 @@
GLANCE_HOST=
+24
View File
@@ -0,0 +1,24 @@
services:
memos:
image: neosmemo/memos:stable
container_name: memos
restart: unless-stopped
networks:
- proxy
volumes:
- ./data/memos:/var/opt/memos
environment:
MEMOS_PORT: 5230
MEMOS_DRIVER: sqlite
MEMOS_INSTANCE_URL: https://${MEMOS_HOST}/
labels:
- "traefik.enable=true"
- "traefik.http.services.memos.loadbalancer.server.port=5230"
- "traefik.http.routers.memos.rule=Host(`${MEMOS_HOST}`)"
- "traefik.http.routers.memos.entrypoints=websecure"
- "traefik.http.routers.memos.tls.certresolver=le"
networks:
proxy:
name: proxy
external: true
+1
View File
@@ -0,0 +1 @@
MEMOS_HOST=
+51
View File
@@ -0,0 +1,51 @@
services:
miniflux:
image: miniflux/miniflux:latest
container_name: miniflux
restart: unless-stopped
depends_on:
miniflux-db:
condition: service_healthy
networks:
- proxy
- miniflux
environment:
- DATABASE_URL=postgres://miniflux:${MINIFLUX_POSTGRES_PASSWORD}@minifluxdb/miniflux?sslmode=disable
- RUN_MIGRATIONS=1
- OAUTH2_PROVIDER=oidc
- OAUTH2_CLIENT_ID=${MINIFLUX_OAUTH2_CLIENT_ID}
- OAUTH2_CLIENT_SECRET=${MINIFLUX_OAUTH2_CLIENT_SECRET}
- OAUTH2_REDIRECT_URL=https://${MINIFLUX_HOST}/oauth2/oidc/callback
- OAUTH2_OIDC_DISCOVERY_ENDPOINT=https://${MINIFLUX_OAUTH2_OIDC_DISCOVERY_ENDPOINT}
- OAUTH2_USER_CREATION=1
labels:
- "traefik.enable=true"
- "traefik.http.services.miniflux.loadbalancer.server.port=8080"
- "traefik.http.routers.miniflux.rule=Host(`${MINIFLUX_HOST}`)"
- "traefik.http.routers.miniflux.entrypoints=websecure"
- "traefik.http.routers.miniflux.tls.certresolver=le"
miniflux-db:
image: postgres:latest
container_name: miniflux-db
restart: unless-stopped
networks:
- miniflux
environment:
- POSTGRES_USER=miniflux
- POSTGRES_PASSWORD=${MINIFLUX_POSTGRES_PASSWORD}
- POSTGRES_DB=miniflux
volumes:
- ./data/miniflux-db:/var/lib/postgresql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U outline -d outline"]
interval: 10s
timeout: 5s
retries: 5
networks:
proxy:
name: proxy
external: true
miniflux:
name: miniflux
+5
View File
@@ -0,0 +1,5 @@
MINIFLUX_HOST=
MINIFLUX_POSTGRES_PASSWORD=
MINIFLUX_OAUTH2_CLIENT_ID=
MINIFLUX_OAUTH2_CLIENT_SECRET=
MINIFLUX_OAUTH2_OIDC_DISCOVERY_ENDPOINT=
+80
View File
@@ -0,0 +1,80 @@
services:
outline:
image: outlinewiki/outline:latest
container_name: outline
restart: unless-stopped
networks:
- proxy
- outline
environment:
- NODE_ENV=production
- URL=https://${OUTLINE_HOST}
- PORT=3000
- FILE_STORAGE_UPLOAD_MAX_SIZE=1024000000
- SECRET_KEY=${OUTLINE_SECRET_KEY}
- UTILS_SECRET=${OUTLINE_UTILS_SECRET}
- POSTGRES_PASSWORD=${OUTLINE_POSTGRES_PASSWORD}
- DATABASE_URL=postgres://outline:${OUTLINE_POSTGRES_PASSWORD}@outline-db:5432/outline
- PGSSLMODE=disable
- REDIS_URL=redis://outline-redis:6379
- FILE_STORAGE=local
- FILE_STORAGE_LOCAL_ROOT_DIR=/var/lib/outline/data
- OIDC_ISSUER_URL=https://${OUTLINE_OIDC_ISSUER_URL}
- OIDC_CLIENT_ID=${OUTLINE_OIDC_CLIENT_ID}
- OIDC_CLIENT_SECRET=${OUTLINE_OIDC_CLIENT_SECRET}
- OIDC_DISPLAY_NAME=Gitea
- OIDC_SCOPES=openid profile email
- OIDC_USERNAME_CLAIM=preferred_username
- OIDC_LOGOUT_URI=https://${OUTLINE_HOST}
volumes:
- ./data/outline:/var/lib/outline/data
depends_on:
outline-db:
condition: service_healthy
outline-redis:
condition: service_healthy
labels:
- "traefik.enable=true"
- "traefik.http.services.outline.loadbalancer.server.port=3000"
- "traefik.http.routers.outline.rule=Host(`${OUTLINE_HOST}`)"
- "traefik.http.routers.outline.entrypoints=websecure"
- "traefik.http.routers.outline.tls.certresolver=le"
outline-db:
image: postgres:latest
container_name: outline-db
restart: unless-stopped
networks:
- outline
environment:
POSTGRES_USER: outline
POSTGRES_PASSWORD: ${OUTLINE_POSTGRES_PASSWORD}
POSTGRES_DB: outline
volumes:
- ./data/outline-db:/var/lib/postgresql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U outline -d outline"]
interval: 10s
timeout: 5s
retries: 5
outline-redis:
image: redis:7-alpine
container_name: outline-redis
restart: unless-stopped
networks:
- outline
volumes:
- ./data/outline-redis:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
proxy:
name: proxy
external: true
outline:
name: outline
+7
View File
@@ -0,0 +1,7 @@
OUTLINE_HOST=
OUTLINE_SECRET_KEY= # openssl rand -hex 32
OUTLINE_UTILS_SECRET=
OUTLINE_POSTGRES_PASSWORD=
OUTLINE_OIDC_CLIENT_ID=
OUTLINE_OIDC_CLIENT_SECRET=
OUTLINE_OIDC_ISSUER_URL=
+29
View File
@@ -0,0 +1,29 @@
services:
traefik:
image: traefik:latest
container_name: traefik
restart: unless-stopped
networks:
- proxy
command:
- "--api.insecure=false"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entryPoints.web.address=:80"
- "--entryPoints.web.http.redirections.entryPoint.to=websecure"
- "--entryPoints.web.http.redirections.entryPoint.scheme=https"
- "--entryPoints.websecure.address=:443"
- "--certificatesresolvers.le.acme.tlschallenge=true"
- "--certificatesresolvers.le.acme.email=${TRAEFIK_MAIL}"
- "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"
- "--providers.docker.network=proxy"
ports:
- "80:80"
- "443:443"
volumes:
- ./data/traefik:/letsencrypt
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
proxy:
name: proxy
+1
View File
@@ -0,0 +1 @@
TRAEFIK_MAIL=
+29
View File
@@ -0,0 +1,29 @@
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: unless-stopped
networks:
- proxy
environment:
DOMAIN: "https://${VAULTWARDEN_HOST}"
SIGNUPS_ALLOWED: "false"
SSO_ENABLED: "true"
SSO_ONLY: "true"
SSO_SIGNUPS_MATCH_EMAIL: "true"
SSO_AUTHORITY: https://${VAULTWARDEN_SSO_AUTHORITY}
SSO_CLIENT_ID: ${VAULTWARDEN_SSO_CLIENT_ID}
SSO_CLIENT_SECRET: ${VAULTWARDEN_SSO_CLIENT_SECRET}
volumes:
- ./data/vaultwarden:/data/
labels:
- "traefik.enable=true"
- "traefik.http.services.vaultwarden.loadbalancer.server.port=80"
- "traefik.http.routers.vaultwarden.rule=Host(`${VAULTWARDEN_HOST}`)"
- "traefik.http.routers.vaultwarden.entrypoints=websecure"
- "traefik.http.routers.vaultwarden.tls.certresolver=le"
networks:
proxy:
name: proxy
external: true
+4
View File
@@ -0,0 +1,4 @@
VAULTWARDEN_HOST=
VAULTWARDEN_SSO_AUTHORITY=
VAULTWARDEN_SSO_CLIENT_ID=
VAULTWARDEN_SSO_CLIENT_SECRET=