version: "3.8" x-deploy-default: &deploy_default replicas: 1 restart_policy: condition: any delay: 5s max_attempts: 3 window: 30s placement: constraints: # IMPORTANT: because these are bind-backed volumes, keep services on the node that has the data paths. - node.hostname == little services: elasticsearch: image: elasticsearch:8.15.0 environment: - discovery.type=single-node - bootstrap.memory_lock=true - "ES_JAVA_OPTS=-Xms2g -Xmx2g" - "xpack.security.enabled=false" ulimits: memlock: soft: -1 hard: -1 volumes: - seafile_elasticsearch_data:/usr/share/elasticsearch/data networks: - net healthcheck: test: ["CMD-SHELL", "curl -f http://localhost:9200/_cluster/health || exit 1"] interval: 30s timeout: 10s retries: 5 start_period: 60s deploy: <<: *deploy_default resources: limits: memory: 4G db: image: mariadb:10.11 command: - --wait_timeout=28800 - --interactive_timeout=28800 - --max_connections=500 - --net_read_timeout=60 - --net_write_timeout=60 - --max_allowed_packet=64M environment: - MARIADB_ROOT_PASSWORD=squirtle123456 - MYSQL_LOG_CONSOLE=true - MARIADB_AUTO_UPGRADE=1 volumes: - seafile_mysql_data:/var/lib/mysql networks: - net healthcheck: test: [ "CMD", "/usr/local/bin/healthcheck.sh", "--connect", "--mariadbupgrade", "--innodb_initialized", ] interval: 20s start_period: 30s timeout: 5s retries: 10 deploy: <<: *deploy_default redis: image: redis command: - /bin/sh - -c - | if [ -n "$$REDIS_PASSWORD" ]; then redis-server --requirepass "$$REDIS_PASSWORD" else redis-server fi environment: - REDIS_PASSWORD= networks: - net healthcheck: test: ["CMD-SHELL", "redis-cli ping || exit 1"] interval: 10s timeout: 3s retries: 3 start_period: 10s deploy: <<: *deploy_default seafile: image: seafileltd/seafile-pro-mc:13.0-latest volumes: - seafile_shared:/shared environment: - INIT_SEAFILE_MYSQL_ROOT_PASSWORD=squirtle123456 - SEAFILE_MYSQL_DB_HOST=db - SEAFILE_MYSQL_DB_PORT=3306 - SEAFILE_MYSQL_DB_USER=seafile - SEAFILE_MYSQL_DB_PASSWORD=squirtle123456 - SEAFILE_MYSQL_DB_CCNET_DB_NAME=ccnet_db - SEAFILE_MYSQL_DB_SEAFILE_DB_NAME=seafile_db - SEAFILE_MYSQL_DB_SEAHUB_DB_NAME=seahub_db - TIME_ZONE=Etc/UTC - INIT_SEAFILE_ADMIN_EMAIL=travis.vas@gmail.com - INIT_SEAFILE_ADMIN_PASSWORD=squirtle123 - SEAFILE_SERVER_HOSTNAME=sf.lab - SEAFILE_SERVER_PROTOCOL=http - SITE_ROOT=/ - NON_ROOT=false - JWT_PRIVATE_KEY=51a482da346fa9a7ea050600c30348b367f7a7144b814273e152c2c8f95965cc - SEAFILE_LOG_TO_STDOUT=false - ENABLE_SEADOC=true - SEADOC_SERVER_URL=http://sf.lab/sdoc-server - CACHE_PROVIDER=redis - REDIS_HOST=redis - REDIS_PORT=6379 - REDIS_PASSWORD= - MEMCACHED_HOST=memcached - MEMCACHED_PORT=11211 - SEAF_SERVER_STORAGE_TYPE=disk - S3_COMMIT_BUCKET= - S3_FS_BUCKET= - S3_BLOCK_BUCKET= - S3_KEY_ID= - S3_SECRET_KEY= - S3_USE_V4_SIGNATURE=true - S3_AWS_REGION=us-east-1 - S3_HOST= - S3_USE_HTTPS=true - S3_PATH_STYLE_REQUEST=false - S3_SSE_C_KEY= - ENABLE_NOTIFICATION_SERVER=false - INNER_NOTIFICATION_SERVER_URL=http://notification-server:8083 - NOTIFICATION_SERVER_URL=http://sf.lab/notification - ENABLE_SEAFILE_AI=true - SEAFILE_AI_SERVER_URL=http://seafile-ai:8888 - SEAFILE_AI_SECRET_KEY=51a482da346fa9a7ea050600c30348b367f7a7144b814273e152c2c8f95965cc - SEAFILE_AI_LLM_TYPE=openai - SEAFILE_AI_LLM_URL=http://llm.lab - SEAFILE_AI_LLM_KEY=sk-1234 - SEAFILE_AI_LLM_MODEL=deepseek-v3p2 - MD_FILE_COUNT_LIMIT=100000 networks: - net - public - badge-net expose: - "80" healthcheck: test: ["CMD-SHELL", "curl -f http://localhost:80 || exit 1"] interval: 30s timeout: 10s retries: 3 start_period: 10s deploy: <<: *deploy_default labels: - "traefik.enable=true" - "traefik.swarm.network=public" - "traefik.http.routers.seafile.rule=Host(`sf.lab`)" - "traefik.http.routers.seafile.entrypoints=web" - "traefik.http.services.seafile.loadbalancer.server.port=80" # Ensure Seadoc path routers win - "traefik.http.routers.seafile.priority=10" seadoc: image: seafileltd/sdoc-server:2.0-latest volumes: - seadoc_shared:/shared environment: - DB_HOST=db - DB_PORT=3306 - DB_USER=seafile - DB_PASSWORD=squirtle123456 - DB_NAME=seahub_db - TIME_ZONE=Etc/UTC - JWT_PRIVATE_KEY=51a482da346fa9a7ea050600c30348b367f7a7144b814273e152c2c8f95965cc - NON_ROOT=false - SEAHUB_SERVICE_URL=http://seafile networks: - net - public - badge-net expose: - "80" deploy: <<: *deploy_default labels: - "traefik.enable=true" - "traefik.swarm.network=public" # Route Seadoc endpoints on the same host: - "traefik.http.routers.seadoc.rule=Host(`sf.lab`) && (PathPrefix(`/socket.io`) || PathPrefix(`/sdoc-server`))" - "traefik.http.routers.seadoc.entrypoints=web" - "traefik.http.routers.seadoc.priority=100" - "traefik.http.services.seadoc.loadbalancer.server.port=80" seafile-ai: image: seafileltd/seafile-ai:13.0-latest volumes: - seafile_shared:/shared environment: - SEAFILE_AI_LLM_TYPE=openai - SEAFILE_AI_LLM_URL=http://llm.lab - SEAFILE_AI_LLM_KEY=sk-1234 - SEAFILE_AI_LLM_MODEL=deepseek-v3p2 - FACE_EMBEDDING_SERVICE_URL=http://face-embedding:8886 - FACE_EMBEDDING_SERVICE_KEY=51a482da346fa9a7ea050600c30348b367f7a7144b814273e152c2c8f95965cc - SEAFILE_SERVER_URL=http://seafile - JWT_PRIVATE_KEY=51a482da346fa9a7ea050600c30348b367f7a7144b814273e152c2c8f95965cc - SEAFILE_AI_LOG_LEVEL=info - CACHE_PROVIDER=redis - REDIS_HOST=redis - REDIS_PORT=6379 - REDIS_PASSWORD= networks: - net expose: - "8888" healthcheck: test: ["CMD-SHELL", "curl -f http://localhost:8888/health || exit 1"] interval: 30s timeout: 10s retries: 3 start_period: 30s deploy: <<: *deploy_default volumes: seafile_elasticsearch_data: name: seafile_elasticsearch_data driver: local driver_opts: type: none o: bind device: /home/trav/seafile/seafile-elasticsearch/data seafile_mysql_data: name: seafile_mysql_data driver: local driver_opts: type: none o: bind device: /home/trav/seafile/seafile-mysql/db seafile_shared: name: seafile_shared driver: local driver_opts: type: none o: bind device: /home/trav/seafile/seafile-data seadoc_shared: name: seadoc_shared driver: local driver_opts: type: none o: bind device: /home/trav/seafile/seadoc-data networks: net: driver: overlay attachable: true public: external: true name: public badge-net: external: true name: badge-net