seafile社区版12部署
部署 Seafile CE 12.0
cd /home/seafile
.env配置修改
wget -O .env https://manual.seafile.com/12.0/repo/docker/ce/env
vi .env
COMPOSE_FILE='seafile-server.yml,seadoc.yml'
COMPOSE_PATH_SEPARATOR=','
SEAFILE_IMAGE=seafileltd/seafile-mc:12.0-latest
SEAFILE_DB_IMAGE=mariadb:10.11
SEAFILE_MEMCACHED_IMAGE=memcached:1.6.29
SEAFILE_CADDY_IMAGE=lucaslorentz/caddy-docker-proxy:2.9-alpine
SEAFILE_VOLUME=/home/seafile/seafile-data
SEAFILE_MYSQL_VOLUME=/home/seafile/seafile-mysql/db
SEAFILE_CADDY_VOLUME=/home/seafile/seafile-caddy
SEAFILE_MYSQL_DB_HOST=db
INIT_SEAFILE_MYSQL_ROOT_PASSWORD=seafilePwd
SEAFILE_MYSQL_DB_USER=seafile
SEAFILE_MYSQL_DB_PASSWORD=seafilePwd
TIME_ZONE=Etc/UTC
JWT_PRIVATE_KEY=abcdefghijklmnopqrstuvwxyz
SEAFILE_SERVER_HOSTNAME=pan.xxkj.net
SEAFILE_SERVER_PROTOCOL=https
INIT_SEAFILE_ADMIN_EMAIL=admin
INIT_SEAFILE_ADMIN_PASSWORD=seafilePwd
SEADOC_IMAGE=seafileltd/sdoc-server:1.0-latest
SEADOC_VOLUME=/home/seafile/seadoc-data
ENABLE_SEADOC=true
NOTIFICATION_SERVER_IMAGE=seafileltd/notification-server:12.0-latest
NOTIFICATION_SERVER_VOLUME=/home/seafile/notification-data
wget https://manual.seafile.com/12.0/repo/docker/ce/seafile-server.yml
wget https://manual.seafile.com/12.0/repo/docker/seadoc.yml
docker compose up -d
seahub配置修改
vi /home/seafile/seafile-data/seafile/conf/seahub_settings.py
# -*- coding: utf-8 -*-
SECRET_KEY = "=f)1k*n5t(&##58q1z3+=h9+30w6k(!fr&$719v)xk$%tzcaqu"
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'seahub_db',
'USER': 'seafile',
'PASSWORD': 'seafilePwd',
'HOST': 'db',
'PORT': '3306',
'OPTIONS': {'charset': 'utf8mb4'},
}
}
CACHES = {
'default': {
'BACKEND': 'django_pylibmc.memcached.PyLibMCCache',
'LOCATION': 'memcached:11211',
},
'locmem': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
},
}
COMPRESS_CACHE_BACKEND = 'locmem'
TIME_ZONE = 'Etc/UTC'
FILE_SERVER_ROOT = 'https://pan.xxkj.net/seafhttp'
SITE_NAME = '云盘'
SITE_TITLE = '云盘'
# If you don't want to run seahub website on your site's root path, set this option to your preferred path.
# e.g. setting it to '/seahub/' would run seahub on http://example.com/seahub/.
SITE_ROOT = '/'
LOGO_PATH = 'custom/logo.png'
LOGO_WIDTH = 149
LOGO_HEIGHT = 32
BRANDING_CSS = 'custom/custom.css'
# Force user to change password when admin add/reset a user.
# Added in 5.1.1, deafults to True.
FORCE_PASSWORD_CHANGE = False
# Attempt limit before showing a captcha when login.
LOGIN_ATTEMPT_LIMIT = 999
# LEVEL based on four types of input:
# num, upper letter, lower letter, other symbols
# '3' means password must have at least 3 types of the above.
USER_PASSWORD_STRENGTH_LEVEL = 1
# 是否使用 pdf.js 来在线查看文件. 默认为 `True`
USE_PDFJS =True
#在线预览最大文件大小,默认为30M。
File_preview_max_size = 50 * 1024 * 1024
TEXT_PREVIEW_EXT = """ac, am, bat, c, cc, cmake, cpp, cs, css, diff, el, h, html,
htm, java, js, json, less, make, org, php, pl, properties, py, rb,
scala, script, sh, sql, txt, text, tex, vi, vim, xhtml, xml, log, csv,
groovy, rst, patch, go"""
ENABLE_THUMBNAIL = True
# Seafile only generates thumbnails for images smaller than the following size.
# Since version 6.3.8 pro, suport the psd online preview.
THUMBNAIL_IMAGE_SIZE_LIMIT = 200 # MB
# Enable or disable thumbnail for video. ffmpeg and moviepy should be installed first.
# For details, please refer to https://manual.seafile.com/deploy/video_thumbnails.html
# NOTE: this option is deprecated in version 7.1
ENABLE_VIDEO_THUMBNAIL = True
# Use the frame at 5 second as thumbnail
# NOTE: this option is deprecated in version 7.1
THUMBNAIL_VIDEO_FRAME_TIME = 5
# Absolute filesystem path to the directory that will hold thumbnail files.
THUMBNAIL_ROOT = '/home/seafile/seafile-data/seafile/seahub-data/thumbnail/thumb/'
# Default size for picture preview. Enlarge this size can improve the preview quality.
# NOTE: since version 6.1.1
THUMBNAIL_SIZE_FOR_ORIGINAL = 2048
# 当浏览器关闭时,用户的会话cookie是否过期。
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
# For security consideration, please set to match the host/domain of your site, e.g., ALLOWED_HOSTS = ['.example.com'].
# Please refer https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts for details.
# ALLOWED_HOSTS = ['.localhost', '127.0.0.1', '192.168.101.154', '[::1]', 'xxx.xxkj.net', 'xxx.xxkj.net','1.1.1.1']
# Whether to use a secure cookie for the CSRF cookie
# https://docs.djangoproject.com/en/3.2/ref/settings/#csrf-cookie-secure
# CSRF_COOKIE_SECURE = False
# The value of the SameSite flag on the CSRF cookie
# https://docs.djangoproject.com/en/3.2/ref/settings/#csrf-cookie-samesite
# CSRF_COOKIE_SAMESITE = 'None'
# https://docs.djangoproject.com/en/3.2/ref/settings/#csrf-trusted-origins
# CSRF_TRUSTED_ORIGINS = ['.localhost', '127.0.0.1', '192.168.101.154', '[::1]', 'xxx.xxkj.net', 'xxx.xxkj.net', '1.1.1.1']
CSRF_TRUSTED_ORIGINS = ["http://192.168.101.154:9000", "http://1.1.1.1:8000", "https://pan.xxkj.net", "http://pan.xxkj.net"]
seahub 定制化
cd /home/seafile/seafile-data/seafile/seahub-data/custom
新增了 custom.css、logo.png
套用seahub页面做自动登录
/home/seafile/seafile-data/seafile/seahub-data/custom 新增 seaFileAutoLogin.html
http://192.168.101.149:8000/media/custom/seaFileAutoLogin.html?username=user&password=111
参考文档:
seafile官方文档
https://cloud.seafile.com/wiki/publish/seafile-manual/hk5G/
Seahub 配置
https://cloud.seafile.com/published/seafile-manual-cn/config/seahub_settings_py.md
使用其他的反向代理
https://manual.seafile.com/12.0/setup/use_other_reverse_proxy/
参考文章:在CentOS下利用Docker一键安装seafile
https://www.cnblogs.com/flyflit/p/13088629.html
seahub 配置
https://manual.seafile.com/latest/config/seahub_settings_py/
seahub 定制化
https://manual.seafile.com/latest/config/seahub_customization/
接口文档:
https://seafile-api.readme.io/reference/delete_api-v2-1-repos-repo-id-file
自动注册用户java代码
xxkj:
cloud:
disk:
base-url: http://192.168.101.149:8000
adminUser: admin
adminPasswd: seafilePwd
package net.xxkj.community.controller;
import lombok.extern.slf4j.Slf4j;
import net.xxkj.cloud.upms.client.entity.system.SysUser;
import net.xxkj.common.core.controller.BaseController;
import net.xxkj.common.core.domain.AjaxResult;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 云盘接口
*/
@Slf4j
@RestController
@RequestMapping("/network-disk")
public class NetworkDiskController extends BaseController {
@Value("${xxkj.cloud.disk.base-url}")
private String baseUrl;
@Value("${xxkj.cloud.disk.adminUser}")
private String adminUser;
@Value("${xxkj.cloud.disk.adminPasswd}")
private String adminPasswd;
private static final String AUTH_URL = "/api2/auth-token/";
private static final String SEARCH_USER_URL = "/api/v2.1/admin/search-user/?query=";
private static final String ADD_USER_URL = "/api/v2.1/admin/users/";
@Autowired
private RestTemplate restTemplate;
/**
* 云盘自动登录
* @return
*/
@PostMapping("/auto-login")
public AjaxResult registerUser() {
final SysUser loginUser = getLoginUser();
return login(loginUser.getUserName(), loginUser.getNickName());
}
/**
* 云盘自动登录
* @param account
* @param name
* @return
*/
@PostMapping("/login")
public AjaxResult login(@RequestParam String account, @RequestParam String name) {
try {
String email = account + "@changda.com";
String token = getAuthToken();
// Step 2: Search for the user
ResponseEntity<Map> searchResponse = searchUser(email, token);
if (searchResponse.getBody() != null && searchResponse.getBody().get("user_list") != null) {
List<Map> userList = (List<Map>) searchResponse.getBody().get("user_list");
if (CollectionUtils.isNotEmpty(userList)) {
// User exists, return the first user
return AjaxResult.success(userList.get(0));
}
}
// Step 4: User does not exist, register new user
final ResponseEntity<?> data = addUser(email, name, token);
return AjaxResult.success(data.getBody());
} catch (Exception e) {
log.error(e.getMessage(),e);
}
return AjaxResult.error("云盘登录失败");
}
private String getAuthToken() {
Map<String, String> request = new HashMap<>();
request.put("username", adminUser);
request.put("password", adminPasswd);
ResponseEntity<Map> response = restTemplate.postForEntity(baseUrl + AUTH_URL, request, Map.class);
return (String) response.getBody().get("token");
}
private ResponseEntity<Map> searchUser(String email, String token) {
String url = baseUrl + SEARCH_USER_URL + email;
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + token);
HttpEntity<String> entity = new HttpEntity<>(headers);
return restTemplate.exchange(url, HttpMethod.GET, entity, Map.class);
}
private ResponseEntity<?> addUser(String email, String name, String token) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set("Authorization", "Bearer " + token);
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
body.add("email", email);
body.add("password", "123456");
body.add("name", name);
//分配20g空间
body.add("quota_total", "20480");
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(body, headers);
return restTemplate.postForEntity(baseUrl + ADD_USER_URL, requestEntity, Map.class);
}
}
前端集成
1: 调用网盘自动注册接口
POST http://192.168.101.154/emdev-api/network-disk/auto-login
2: 访问
https://pan.xxkj.net/media/custom/seaFileAutoLogin.html?username=abcdefg@changda.com&password=123456
nginx配置
server {
listen 8999;
server_name pan.xxkj.net;
# 静态动态压缩配置
gzip_static on;
gzip on;
gzip_proxied any;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 5;
gzip_types text/plain application/javascript application/css text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary on;
client_max_body_size 2048m; #表示最大上传350M,需要多大设置多大
location /.well-known/acme-challenge/ {
root /usr/share/nginx/html;
}
location / {
root /usr/share/nginx/html;
proxy_pass http://192.168.101.149:8000;
proxy_read_timeout 310s;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Connection "";
proxy_http_version 1.1;
client_max_body_size 0;
}
}
server {
listen 9000 ssl;
server_name pan.xxkj.net;
charset utf-8;
ssl_certificate /etc/letsencrypt/live/pan.xxkj.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/pan.xxkj.net/privkey.pem;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
client_max_body_size 2048m;
# 开启gzip
gzip on;
# 启用gzip压缩的最小文件;小于设置值的文件将不会被压缩
gzip_min_length 1k;
# gzip 压缩级别 1-10
gzip_comp_level 6;
# 进行压缩的文件类型。
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
# 是否在http header中添加Vary: Accept-Encoding,建议开启
gzip_vary on;
location / {
proxy_pass http://192.168.101.149:8000;
proxy_read_timeout 310s;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Connection "";
proxy_http_version 1.1;
client_max_body_size 0;
}
}