#写在最前,本文来源github,纯手工部署,需要一些知识储备和动手能力。目前已经使用了大半年,安全稳定。
适合用户:linux桌面版
偷个懒,让ai来做介绍:(要是懒的看,可以直接去下面部署阶段,反正我是没看)
Sync‑in 功能介绍
Sync‑in 是 AGPL‑3.0 开源、可自托管的文件存储、同步与团队协作平台,对标 Nextcloud / Dropbox,数据完全自主可控,支持 Docker 快速部署,适合个人、家庭、企业内网部署使用。
✨ 核心定位
自建私有云盘,兼顾多端文件同步、团队空间协作、在线文档编辑、权限管控;支持 MySQL/Redis 外部数据库分离部署,不绑定内置数据库,适合生产环境落地。
📂 文件存储 & 同步能力
多平台桌面客户端:Windows /macOS/ Linux,后台自动同步,支持多服务器同时连接。
三种同步模式:双向同步、仅上传、仅下载;可自定义同步周期、同步模拟测试、完整同步日志排错。
个人空间 + 团队协作空间 (Spaces)
个人空间:个人私有文件存储
团队空间:按项目 / 部门创建共享工作区,用于多人协作
WebDAV 原生支持:可直接在系统资源管理器挂载网络磁盘,手机、第三方客户端均可访问,权限完全继承平台配置。
Web 端文件管理:拖拽上传、画廊视图、文件预览、文件锁定、回收站、存储配额、压缩包解压 / 打包(ZIP/TAR/TGZ)。
👥 权限、共享与安全
细粒度权限体系:用户、用户组、角色管理;针对团队空间设置:只读、读写、管理等权限。
外部安全分享链接:支持密码保护、访问次数限制、链接过期时间,对外分享文件 / 文件夹,支持访客账号访问。
认证体系
本地账号密码登录
MFA TOTP 多因素二次验证
LDAP 企业账号对接
OIDC 单点登录
应用专用密码,用于第三方客户端访问。
完整操作日志、事件通知、文件评论功能,可追踪文件变更记录。
📝 在线文档协作
支持对接外部在线办公服务:
OnlyOffice / Collabora Online / Euro‑Office
多人实时协同编辑 Word、Excel、PPT;支持 Office 格式,权限与 Sync‑in 平台打通,无需导出下载即可在线修改文档。
🔍 搜索能力
全文内容索引搜索:不只搜文件名,可解析文档内部内容进行检索,支持常见文档格式;可开关内容索引功能,节省服务器资源。
🐳 部署与运维特性
支持 Docker Compose 一键部署、离线包部署、源码部署;支持外部 MySQL、Redis 缓存分离部署(本次部署方案使用外部数据库)。
完整日志系统,可配置日志级别、日志文件输出路径。
邮件通知:支持企业 SMTP,账号通知、分享通知、告警邮件推送。
任务队列机制:大文件上传、压缩、拷贝任务排队执行,防止服务器过载,任务可取消、查看进度。
📌 适用场景
家庭 / 个人自建私有云盘,多设备文件同步
中小企业内网文件服务器,团队文档协作
需要数据**,不想使用公有云网盘,所有数据存自己服务器
需要对接 LDAP/OIDC 企业账号体系的内部文件平台
开始部署:
配置文件:
#docker-compose.yaml
#include:
# - ./config/nginx/docker-compose.nginx.yaml
# - ./config/onlyoffice/docker-compose.onlyoffice.yaml
# - ./config/collabora/docker-compose.collabora.yaml
# - ./config/eurooffice/docker-compose.eurooffice.yaml
# - ./config/sync-in-desktop-releases/docker-compose.sync-in-desktop-releases.yaml
name: sync-in
services:
sync_in:
image: syncin/server:2.4.2
container_name: sync-in
restart: always
environment:
- INIT_ADMIN
- INIT_ADMIN_PASSWORD
- INIT_ADMIN_LOGIN
- PUID=1000
- PGID=1001
ports:
- "8080:8080"
volumes:
- ./environment.yaml:/app/environment/environment.yaml
- ./data:/app/data
- ./desktop_releases:/app/static/releases:ro
logging:
driver: json-file
options:
max-size: "25m"
max-file: "5"
networks:
- sync_in_network
mariadb:
image: mariadb:11
container_name: mariadb
restart: always
command: --innodb_ft_cache_size=16000000 --max-allowed-packet=1G
environment:
MYSQL_ROOT_PASSWORD: MySQLRootPassword
MYSQL_DATABASE: sync_in
volumes:
- ./mariadb_data:/var/lib/mysql
networks:
- sync_in_network
networks:
sync_in_network:
name: sync_in_network
driver: bridge
volumes:
data:
mariadb_data:
desktop_releases:
#environment.yaml
server:
# default host : `0.0.0.0`
host: 0.0.0.0
# default port : `8080`
port: 8080
# workers: `auto` or `0` (use all cpus) | number of CPUs to use
# default: 1
workers: 1
# trust proxy: number (trust the nth hop from the front-facing proxy server as the client) | `true` | `false` | `127.0.0.1,192.168.1.1/24`
# default: 1
trustProxy: 1
# restartOnFailure: automatically restart workers if they are killed or die
# default: `true`
restartOnFailure: true
logger:
# level: `trace` | `debug` | `info` | `warn` | `error` | `fatal`
# default: `info`
level: info
# stdout: if false logs are written to `filePath`
# default: `true`
stdout: true
# Colorize output.
# Disabled by default when stdout is set to false.
# default: `true`
colorize: true
# JSON output. When enabled, `colorize` is ignored.
# default: `false`
jsonOutput: false
# Path to the log file used when stdout is set to false
filePath:
mysql:
# required
url: 'mysql://root:MySQLRootPassword@mariadb:3306/sync_in'
# default: `false`
logQueries: false
cache:
# adapter: `mysql` | `redis`
# default: `mysql`
adapter: mysql
# TTL in seconds
# default: `60`
ttl: 60
# Redis adapter url
# default: `redis://127.0.0.1:6379`
redis: redis://127.0.0.1:6379
websocket:
# adapter: `cluster` (Node.js Workers: default) | `redis`
# default: `cluster`
adapter: cluster
# Cors origin allowed
# default: `*`
corsOrigin: '*'
# Redis adapter url
# default: `redis://127.0.0.1:6379`
redis: redis://127.0.0.1:6379
mail:
host: smtp.server.com
# default: `25`
port: 25
# default: `Sync-in<notification@sync-in.com>`
sender: 'Sync-in<notification@sync-in.com>'
# optional
auth:
user: user
pass: 'password'
# Defines if the connection should use SSL (if true) or not (if false)
# Note: setting `secure: false` does not necessarily mean messages are sent in plaintext
# If the server supports STARTTLS, the connection is usually upgraded to TLS automatically
# default: `false`
secure: false
# ignoreTLS: if true, disables the use of STARTTLS even if the server advertises it
# default: false
ignoreTLS: false
# rejectUnauthorized: reject the connection if the server's TLS certificate is invalid
# default: false
rejectUnauthorized: false
# Enable logger
# default: `false`
logger: false
# Set log level to debug
# default: `false`
debug: false
auth:
# provider : `mysql` | `ldap` | `oidc`
# default: `mysql`
provider: mysql
# Key used to encrypt user secret keys in the database
# Optional but strongly recommended
# Warning: do not change or remove the encryption key after MFA activation, or the codes will become invalid
encryptionKey: 'changeEncryptionKeyWithStrongKey'
# cookie sameSite setting: `lax` | `strict`
# default: `strict`
cookieSameSite: strict
token:
access:
# Used for token and cookie signatures
# required
secret: 'changeAccessWithStrongSecret'
# token expiration = cookie maxAge
# default: `30m`
expiration: 30m
refresh:
# Used for token and cookie signatures
# required
secret: 'changeRefreshWithStrongSecret'
# token expiration = cookie maxAge
# default: `4h`
expiration: 4h
# Multifactor authentication
mfa:
# Sync-in MFA is enforced for local password authentication.
# When OIDC is used, MFA is expected to be enforced by the identity provider.
# TOTP configuration
totp:
# Enable TOTP authentication
# default: true
enabled: true
# Name displayed in the authentication app (FreeOTP, Proton Authenticator, Aegis Authenticator etc.)
# default: Sync-in
issuer: Sync-in
# LDAP authentication
ldap:
# e.g.: [ldap://localhost:389, ldaps://localhost:636] (array required)
# Multiple servers are tried in order until a bind/search succeeds.
# required
servers: []
# tlsOptions: Node.js TLS options used for the LDAP secure connection.
# Supports standard TLS options such as `ca`, `rejectUnauthorized`, etc.
# See: https://nodejs.org/api/tls.html
# https://nodejs.org/api/tls.html#tlscreatesecurecontextoptions
# Example:
# tlsOptions:
# rejectUnauthorized: true
# ca: [/app/certs/ca.pem]
# optional
tlsOptions:
# baseDN: Distinguished name (e.g.: ou=people,dc=ldap,dc=sync-in,dc=com)
# Used as the search base for users, and for groups when adminGroup is a CN.
# required
baseDN: ou=people,dc=ldap,dc=sync-in,dc=com
# filter, e.g: (acl=admin)
# Appended as-is to the LDAP search filter (trusted config).
# optional
filter:
# upnSuffix: AD domain suffix used with `userPrincipalName` to build UPN-style logins (e.g.: user@`sync-in.com`)
# Only used when login is set to userPrincipalName.
# optional
upnSuffix:
# netbiosName: NetBIOS domain name used with `sAMAccountName` to build legacy logins (e.g.: `SYNC_IN`\user)
# Only used when login is set to sAMAccountName.
# optional
netbiosName:
# serviceBindDN: Distinguished Name for a service account used to search users/groups.
# When set, searches are performed with this account; user bind is used only to validate the password.
# e.g.: cn=syncin,ou=services,dc=ldap,dc=sync-in,dc=com
# optional
serviceBindDN:
# serviceBindPassword: Password for the service account used to search users/groups.
# optional
serviceBindPassword:
attributes:
# LDAP attribute that matches the login stored in the database.
# With a service bind, it is used to locate the user (then bind with the found DN).
# Without a service bind, it is used to construct the user's DN for binding (except AD: UPN/DOMAIN\\user).
# If you choose mail, local logins should be the user's email address.
# e.g.: uid | cn | mail | sAMAccountName | userPrincipalName
# default: uid
login: uid
# Attribute used to retrieve the user's email address
# email: `mail` or `email`
# default: `mail`
email: mail
# Attribute used to retrieve the user's storage quota in bytes.
# If the attribute is missing, the local storageQuota is not updated.
# If the attribute exists with null or 0, local storageQuota is set to null (unlimited).
# default: `storageQuota`
storageQuota: storageQuota
options:
# autoCreateUser: Automatically create a local user on first successful LDAP authentication.
# The local account is created from LDAP attributes:
# - login: from the configured LDAP login attribute (e.g.: uid, cn, sAMAccountName, userPrincipalName)
# - email: from the configured email attribute (required)
# - firstName / lastName: from givenName+sn, or displayName, or cn (fallback)
# When disabled, only existing users can authenticate via LDAP.
# default: true
autoCreateUser: true
# autoCreatePermissions: Permissions assigned to users automatically created via LDAP.
# Applied only at user creation time when autoCreateUser is enabled.
# Has no effect on existing users.
# A complete list of permissions is available in the documentation: https://sync-in.com/docs/admin-guide/permissions
# e.g.: [personal_space, spaces_access] (array required)
# default: []
autoCreatePermissions: []
# adminGroup: LDAP group that grants Sync-in administrator privileges.
# Accepts either a simple CN (e.g.: "Admins") or a full DN (e.g.: "CN=Admins,OU=Groups,DC=ldap,DC=sync-in,DC=com").
# If set, users whose LDAP `memberOf` contains this CN (or whose group DN matches) are assigned the administrator role.
# If `memberOf` is missing, Sync-in can also check membership by searching `groupOfNames` groups.
# If users cannot read `groupOfNames`, use a service bind account to perform this lookup.
# If not set, existing administrator users keep their role and it cannot be removed via LDAP.
# optional
adminGroup:
# enablePasswordAuthFallback: Allow local password authentication for regular users when the LDAP service is unavailable.
# Applies only to LDAP connection/DNS/timeout errors after all configured LDAP servers fail.
# Always allowed for administrator users (break-glass access).
# default: false
enablePasswordAuthFallback: false
oidc:
# issuerUrl: The URL of the OIDC provider's discovery endpoint
# e.g.:
# - Keycloak: https://auth.example.com/realms/my-realm
# - Authentik: https://auth.example.com/application/o/my-app/
# - Google: https://accounts.google.com
# - Microsoft: https://login.microsoftonline.com/<tenant-id>/v2.0
# The server will automatically discover the authorization, token, and userinfo endpoints.
# required
issuerUrl:
# clientId: OAuth 2.0 Client ID obtained from your OIDC provider
# required
clientId:
# clientSecret: OAuth 2.0 Client Secret obtained from your OIDC provider
# required
clientSecret: 'changeOIDCClientSecret'
# redirectUri: The callback URL where users are redirected after authentication
# This URL must be registered in your OIDC provider's allowed redirect URIs
# e.g.: (API callback): https://sync-in.domain.com/api/auth/oidc/callback
#
# To allow authentication from the desktop application, the following redirect URLs must also be registered in your OIDC provider:
# - http://127.0.0.1:49152/oidc/callback
# - http://127.0.0.1:49153/oidc/callback
# - http://127.0.0.1:49154/oidc/callback
#
# required
redirectUri: https://sync-in.domain.com/api/auth/oidc/callback
options:
# autoCreateUser: Automatically create a local user account on first successful OIDC login.
# When enabled, the user `login` is derived from OIDC claims: preferred_username, then the email local-part, with `sub` as a last-resort fallback.
# When disabled, only existing users are allowed to authenticate via OIDC.
# default: true
autoCreateUser: true
# autoCreatePermissions: Permissions assigned to users automatically created via OIDC.
# Applied only when autoCreateUser is enabled and only applied at user creation time.
# This option has no effect on existing users.
# A complete list of permissions is available in the documentation: https://sync-in.com/docs/admin-guide/permissions
# e.g.: [personal_space, spaces_access] (array required)
# default: []
autoCreatePermissions: []
# storageQuotaClaim: OIDC claim used to retrieve the user's storage quota in bytes.
# If the claim is missing, the local storageQuota is not updated.
# If the claim exists with null or 0, local storageQuota is set to null (unlimited).
# default: `storageQuota`
storageQuotaClaim: storageQuota
# adminRoleOrGroup: Name of the role or group that grants Sync-in administrator access
# Users with this value will be granted administrator privileges.
# The value is matched against `roles` or `groups` claims provided by the IdP.
# Note: depending on the provider (e.g.: Keycloak), roles/groups may be exposed only in tokens
# and require proper IdP mappers to be included in the ID token or UserInfo response.
# optional
adminRoleOrGroup:
# enablePasswordAuth: Allow local password-based authentication when using OIDC.
# When enabled, users may authenticate with their Sync-in password instead of OIDC.
# Sync-in MFA applies to this local password flow.
# OIDC logins rely on the identity provider to enforce MFA/SSO policies.
# Local password authentication is always allowed for:
# - guest users
# - administrator users (break-glass access)
# - application scopes (app passwords)
# Regular users are allowed only when this option is enabled.
# Users must already exist locally and have a password set.
# default: false
enablePasswordAuth: false
# autoSyncAvatar: Automatically download and synchronize the user avatar from the OIDC `picture` claim.
# default: false
autoSyncAvatar: false
# autoRedirect: Automatically redirect users to the OIDC login flow.
# When enabled, the login page is skipped and users are sent directly to the OIDC provider.
# default: false
autoRedirect: false
# buttonText: Label displayed on the OIDC login button.
# default: Continue with OpenID Connect
buttonText: Continue with OpenID Connect
security:
# scope: OAuth 2.0 scopes to request (space-separated string)
# Common scopes: openid (required), email, profile, groups, roles
# default: `openid email profile`
scope: openid email profile
# supportPKCE: Enable PKCE (Proof Key for Code Exchange) in the authorization code flow.
# When true, PKCE is used if supported by the OIDC provider.
# default: true
supportPKCE: true
# allowInsecureRequests: Allow OIDC discovery and token requests over insecure HTTP.
# Set to true only for local development or trusted legacy providers.
# default: false
allowInsecureRequests: false
# OAuth 2.0 / OIDC client authentication method used at the token endpoint.
# Possible values:
# - client_secret_basic (DEFAULT): HTTP Basic auth using client_id and client_secret.
# Recommended for backend (confidential) clients.
# - client_secret_post: client_id and client_secret sent in the request body.
# - none (or undefined): no client authentication (public clients: mobile / SPA with PKCE).
# default: `client_secret_basic`
tokenEndpointAuthMethod: client_secret_basic
# tokenSigningAlg: Algorithm used to verify the signature of ID tokens (JWT) returned by the OpenID Connect provider.
# Common values: RS256, RS384, RS512, ES256, ES384, ES512
# default: `RS256`
tokenSigningAlg: RS256
# userInfoSigningAlg: Algorithm used to request a signed UserInfo response from the OpenID Connect provider.
# When not set, the UserInfo endpoint returns a standard JSON response (not signed). This is the most common and recommended configuration.
# Common values: (empty), RS256, RS384, RS512, ES256, ES384, ES512
# default: empty
userInfoSigningAlg:
# skipSubjectCheck: Disable verification that the `sub` claim returned by the UserInfo endpoint
# matches the `sub` claim from the ID token.
# Set to true only for non-compliant or legacy OIDC providers.
# default: false
skipSubjectCheck: false
# requireVerifiedEmail: Require the OIDC provider to mark profile emails as verified before account linking or profile synchronization.
# Recommended when your provider exposes a reliable `email_verified` claim.
# Some providers omit this claim unless specific scopes/mappers are configured.
# default: false
requireVerifiedEmail: false
# allowPrivateIpAvatarDownload: Allow OIDC avatar downloads from private/internal IP ranges.
# Set to true only when the OIDC provider returns trusted internal avatar URLs.
# default: false
allowPrivateIpAvatarDownload: false
applications:
users:
# showUngroupedUsers: make users without a group globally visible to regular users/admins.
# Guest accounts are excluded from this global visibility (both as listed accounts and as requesters).
# default: `true`
showUngroupedUsers: true
files:
# required
dataPath: /app/data
# maxUploadSize: Maximum upload file size.
# default: 5368709120 (5 GB)
maxUploadSize: 5368709120
contentIndexing:
# Enable indexing of file contents for search (disabling this turns off full-text search)
# default: true
enabled: true
ocr:
# Enable OCR on PDF
# default: true
enabled: true
# OCR languages used by tesseract.js
# Supports ISO 639-2/T three-letter codes: 'eng', 'spa', 'fra', 'deu', etc.
# examples: `[eng,fra]`, `[fra]`
# default: [eng]
languages: [eng]
# Offline mode: do not download OCR languages, only use local language files from the built-in OCR folder
# To download languages, use this scheme: https://cdn.jsdelivr.net/npm/@tesseract.js-data/<lang>@1.0.0/4.0.0_best_int/<lang>.traineddata.gz
# default: false
offline: false
# Path to local OCR language files
# Used when offline mode is enabled or to override default location
# default: built-in OCR directory
languagesPath:
# Trash retention in days. Set each value to a number of days to enable automatic trash cleanup.
# Set to `false` or `0` to disable cleanup for that repository type.
# default: users/spaces false
trashRetention:
users: false
spaces: false
# Show files starting with a dot in the file explorer
# default: false
showHiddenFiles: false
# Optional document groups shown in the "new document" dialog.
# options: `microsoft` | `opendocument`
# use [] to only show Text and Markdown
# default: [opendocument, microsoft]
sampleDocuments: [opendocument, microsoft]
editors:
onlyoffice:
# enable onlyoffice integration
# default: false
enabled: false
# Secret used for jwt tokens, it must be the same on the onlyoffice server
# required
secret: 'onlyOfficeSecret'
# If no external server is configured, the local Nginx service from the Docker Compose setup is used.
# If an external server is configured, it will be used instead.
# Note: when using an external server (e.g.: https://onlyoffice.domain.com), make sure it is accessible from the client/browser.
# default: null
externalServer:
# If you use https, set to `true`.
# default: false
verifySSL: false
eurooffice:
# enable Euro-Office integration
# default: false
enabled: false
# Secret used for jwt tokens, it must be the same on the Euro-Office server
# required
secret: 'euroOfficeSecret'
# If an external server is configured, it will be used.
# Note: make sure it is accessible from the client/browser.
# default: null
externalServer:
# If you use https, set to `true`.
# default: false
verifySSL: false
collabora:
# enable collabora online integration
# default: false
enabled: false
# If no external server is configured, the local Nginx service from the Docker Compose setup is used.
# If an external server is configured, it will be used instead.
# Note: when using an external server (e.g.: https://collabora.domain.com), make sure it is accessible from the client/browser.
# default: null
externalServer:
# Client application repository configuration
appStore:
# repository: `public` | `local`
# default: `public`
repository: public
启动:
docker compose up -d
重置登录密码:
docker compose exec -it sync_in sh -c 'node server/infrastructure/database/scripts/create-user.js --role admin --login "admin" --password "password"'
登录地址:http://{你的内网ip}:8080/
用户名:admin
密码:password
#请自行修改用户名密码
客户端下载:
https://sync-in.com/downloads/
注意事项:
- 注意磁盘空间,不建议放系统盘
- 请自行修改配置文件中的用户名密码
- 我只是搬运工,项目地址 https://github.com/Sync-in/server ,有特殊需要的可以自行issue。
- 部署完成后记得开放访问端口
最后吐槽一下,这个编辑器真难用!!