自建Nextcloud私有云盘

安装

从Nextcloud官方网站下载server的安装包,复制到/var/www目录解压。

详细安装过程参考官方文档

1、按照官方文档安装完善php模块

必须要安装的模块

  • PHP (see System requirements for a list of supported versions)

  • PHP module ctype

  • PHP module curl

  • PHP module dom

  • PHP module fileinfo (included with PHP)

  • PHP module filter (only on Mageia and FreeBSD)

  • PHP module GD

  • PHP module hash (only on FreeBSD)

  • PHP module JSON (included with PHP >= 8.0)

  • PHP module libxml (Linux package libxml2 must be >=2.7.0)

  • PHP module mbstring

  • PHP module openssl (included with PHP >= 8.0)

  • PHP module posix

  • PHP module session

  • PHP module SimpleXML

  • PHP module XMLReader

  • PHP module XMLWriter

  • PHP module zip

  • PHP module zlib

选择合适的数据库模块:

  • PHP module pdo_sqlite (>= 3, usually not recommended for performance reasons)

  • PHP module pdo_mysql (MySQL/MariaDB)

  • PHP module pdo_pgsql (PostgreSQL)

推荐安装的模块:

  • PHP module bz2 (recommended, required for extraction of apps)

  • PHP module intl (increases language translation performance and fixes sorting of non-ASCII characters)

2、Apache配置文件

新增配置文件vim /etc/apache2/sites-available/nextcloud.conf,复制以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<VirtualHost *:80>
DocumentRoot /var/www/nextcloud/
ServerName your.server.com

<Directory /var/www/nextcloud/>
Require all granted
AllowOverride All
Options FollowSymLinks MultiViews

<IfModule mod_dav.c>
Dav off
</IfModule>
</Directory>
</VirtualHost>

保存,然后运行:

1
a2ensite nextcloud.conf

启用必要的Apache模块:

1
2
3
4
5
6
a2enmod rewrite

a2enmod headers
a2enmod env
a2enmod dir
a2enmod mime

If you’re running mod_fcgi instead of the standard mod_php also enable:

1
a2enmod setenvif

最后重启Apache:

1
service apache2 restart

现在就可以访问http://your.server.com安装Nextcloud。

Redis缓存配置

修改配置文件nextcloud/config/config.php

Small/Private home server

Only use APCu:

1
'memcache.local' => '\OC\Memcache\APCu',

Organizations with single-server

Use Redis for everything except local memcache:

1
2
3
4
5
6
7
'memcache.local' => '\OC\Memcache\APCu',
'memcache.distributed' => '\OC\Memcache\Redis',
'memcache.locking' => '\OC\Memcache\Redis',
'redis' => [
'host' => 'localhost',
'port' => 6379,
],

Organizations with clustered setups

Use APCu for local cache and either Redis cluster …:

1
2
3
4
5
6
7
8
9
'memcache.local' => '\OC\Memcache\APCu',
'memcache.distributed' => '\OC\Memcache\Redis',
'memcache.locking' => '\OC\Memcache\Redis',
'redis.cluster' => [
'seeds' => [ // provide some/all of the cluster servers to bootstrap discovery, port required
'cache-cluster:7000',
'cache-cluster:7001',
],
]

APCu is disabled by default on CLI which could cause issues with nextcloud’s cron jobs. Please make sure you set the apc.enable_cli to 1 on your php.ini config file or append --define apc.enable_cli=1 to the cron job call.

1
vim /etc/php/8.1/cli/php.ini

在末尾添加apc.enable_cli=1,否则当你运行occ命令的时候也会提示你APCu不可用。

OCC命令的使用

直接运行occ命令,不带任何选项,就会列出occ命令的所有可用的选项和用法:

1
sudo -u www-data php8.1 /var/www/nextcloud/occ

返回信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
Nextcloud 24.0.12

Usage:
command [options] [arguments]

Options:
-h, --help Display this help message
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
-n, --no-interaction Do not ask any interactive question
--no-warnings Skip global warnings, show command output only
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Available commands:
check check dependencies of the server environment
help Display help for a command
list List commands
status show some status information
upgrade run upgrade routines after installation of a new release. The release has to be installed before.
activity
activity:send-mails Sends the activity notification mails
app
app:check-code check code to be compliant
app:disable disable an app
app:enable enable an app
app:getpath Get an absolute path to the app directory
app:install install an app
app:list List all available apps
app:remove remove an app
app:update update an app or all apps
background
background:ajax Use ajax to run background jobs
background:cron Use cron to run background jobs
background:webcron Use webcron to run background jobs
background-job
background-job:execute Execute a single background job manually
broadcast
broadcast:test test the SSE broadcaster
circles
circles:check Checking your configuration
circles:maintenance Clean stuff, keeps the app running
circles:manage:config edit config/type of a Circle
circles:manage:create create a new circle
circles:manage:destroy destroy a circle by its ID
circles:manage:details get details about a circle by its ID
circles:manage:edit edit displayName or description of a Circle
circles:manage:join emulate a user joining a Circle
circles:manage:leave simulate a user joining a Circle
circles:manage:list listing current circles
circles:manage:setting edit setting for a Circle
circles:members:add Add a member to a Circle
circles:members:details get details about a member by its ID
circles:members:level Change the level of a member from a Circle
circles:members:list listing Members from a Circle
circles:members:remove remove a member from a circle
circles:members:search Change the level of a member from a Circle
circles:memberships index and display memberships for local and federated users
circles:remote remote features
circles:shares:files listing shares files
circles:sync Sync Circles and Members
circles:test testing some features
config
config:app:delete Delete an app config value
config:app:get Get an app config value
config:app:set Set an app config value
config:import Import a list of configs
config:list List all configs
config:system:delete Delete a system config value
config:system:get Get a system config value
config:system:set Set a system config value
dav
dav:create-addressbook Create a dav addressbook
dav:create-calendar Create a dav calendar
dav:delete-calendar Delete a dav calendar
dav:list-calendars List all calendars of a user
dav:move-calendar Move a calendar from an user to another
dav:remove-invalid-shares Remove invalid dav shares
dav:retention:clean-up
dav:send-event-reminders Sends event reminders
dav:sync-birthday-calendar Synchronizes the birthday calendar
dav:sync-system-addressbook Synchronizes users to the system addressbook
db
db:add-missing-columns Add missing optional columns to the database tables
db:add-missing-indices Add missing indices to the database tables
db:add-missing-primary-keys Add missing primary keys to the database tables
db:convert-filecache-bigint Convert the ID columns of the filecache to BigInt
db:convert-mysql-charset Convert charset of MySQL/MariaDB to use utf8mb4
db:convert-type Convert the Nextcloud database to the newly configured one
encryption
encryption:change-key-storage-root Change key storage root
encryption:decrypt-all Disable server-side encryption and decrypt all files
encryption:disable Disable encryption
encryption:enable Enable encryption
encryption:encrypt-all Encrypt all files for all users
encryption:list-modules List all available encryption modules
encryption:migrate-key-storage-format Migrate the format of the keystorage to a newer format
encryption:set-default-module Set the encryption default module
encryption:show-key-storage-root Show current key storage root
encryption:status Lists the current status of encryption
federation
federation:sync-addressbooks Synchronizes addressbooks of all federated clouds
files
files:cleanup cleanup filecache
files:recommendations:recommend
files:repair-tree Try and repair malformed filesystem tree structures
files:scan rescan filesystem
files:scan-app-data rescan the AppData folder
files:transfer-ownership All files and folders are moved to another user - outgoing shares and incoming user file shares (optionally) are moved as well.
files_external
files_external:applicable Manage applicable users and groups for a mount
files_external:backends Show available authentication and storage backends
files_external:config Manage backend configuration for a mount
files_external:create Create a new mount configuration
files_external:delete Delete an external mount
files_external:export Export mount configurations
files_external:import Import mount configurations
files_external:list List configured admin or personal mounts
files_external:notify Listen for active update notifications for a configured external mount
files_external:option Manage mount options for a mount
files_external:verify Verify mount configuration
group
group:add Add a group
group:adduser add a user to a group
group:delete Remove a group
group:info Show information about a group
group:list list configured groups
group:removeuser remove a user from a group
integrity
integrity:check-app Check integrity of an app using a signature.
integrity:check-core Check integrity of core code using a signature.
integrity:sign-app Signs an app using a private key.
integrity:sign-core Sign core using a private key.
l10n
l10n:createjs Create javascript translation files for a given app
log
log:file manipulate logging backend
log:manage manage logging configuration
log:tail Tail the nextcloud logfile
log:watch Watch the nextcloud logfile
maintenance
maintenance:data-fingerprint update the systems data-fingerprint after a backup is restored
maintenance:mimetype:update-db Update database mimetypes and update filecache
maintenance:mimetype:update-js Update mimetypelist.js
maintenance:mode set maintenance mode
maintenance:repair repair this installation
maintenance:repair-share-owner repair invalid share-owner entries in the database
maintenance:theme:update Apply custom theme changes
maintenance:update:htaccess Updates the .htaccess file
notification
notification:generate Generate a notification for the given user
notification:test-push Generate a notification for the given user
preview
preview:repair distributes the existing previews into subfolders
preview:reset-rendered-texts Deletes all generated avatars and previews of text and md files
security
security:bruteforce:reset resets bruteforce attemps for given IP address
security:certificates list trusted certificates
security:certificates:import import trusted certificate in PEM format
security:certificates:remove remove trusted certificate
serverinfo
serverinfo:update-storage-statistics Triggers an update of the counts related to storages used in serverinfo
sharing
sharing:cleanup-remote-storages Cleanup shared storage entries that have no matching entry in the shares_external table
sharing:expiration-notification Notify share initiators when a share will expire the next day.
support
support:report Generate a system report
tag
tag:add Add new tag
tag:delete delete a tag
tag:edit edit tag attributes
tag:list list tags
text
text:reset Reset a text document
theming
theming:config Set theming app config values
trashbin
trashbin:cleanup Remove deleted files
trashbin:expire Expires the users trashbin
trashbin:restore Restore all deleted files
trashbin:size Configure the target trashbin size
twofactorauth
twofactorauth:cleanup Clean up the two-factor user-provider association of an uninstalled/removed provider
twofactorauth:disable Disable two-factor authentication for a user
twofactorauth:enable Enable two-factor authentication for a user
twofactorauth:enforce Enabled/disable enforced two-factor authentication
twofactorauth:state Get the two-factor authentication (2FA) state of a user
update
update:check Check for server and app updates
user
user:add adds a user
user:add-app-password Add app password for the named user
user:delete deletes the specified user
user:disable disables the specified user
user:enable enables the specified user
user:info show user info
user:lastseen shows when the user was logged in last time
user:list list configured users
user:report shows how many users have access
user:resetpassword Resets the password of the named user
user:setting Read and modify user settings
versions
versions:cleanup Delete versions
versions:expire Expires the users file versions
workflows
workflows:list Lists configured workflows

扫描所有用户文件更新:

1
sudo -u www-data php8.1 /var/www/nextcloud/occ files:scan --all

扫描特定用户文件更新:

1
sudo -u www-data php8.1 /var/www/nextcloud/occ files:scan username

扫描特定目录文件更新:

1
sudo -u www-data php8.1 /var/www/nextcloud/occ files:scan --path=/path/to/scan

后台服务优化

后台服务有三种方式:AJAX,Webcron,Cron

systemd

If systemd is installed on the system, a systemd timer could be an alternative to a cronjob.

This approach requires two files: nextcloudcron.service and nextcloudcron.timer. Create these two files in /etc/systemd/system/.

nextcloudcron.service should look like this:

1
2
3
4
5
6
7
[Unit]
Description=Nextcloud cron.php job

[Service]
User=www-data
ExecStart=/usr/bin/php -f /var/www/nextcloud/cron.php
KillMode=process

Replace the user www-data with the user of your http server and /var/www/nextcloud/cron.php with the location of cron.php in your nextcloud directory.

The KillMode=process setting is necessary for external programs that are started by the cron job to keep running after the cron job has finished.

Note that the .service unit file does not need an [Install] section. Please check your setup because we recommended it in earlier versions of this admin manual.

nextcloudcron.timer should look like this:

1
2
3
4
5
6
7
8
9
10
[Unit]
Description=Run Nextcloud cron.php every 5 minutes

[Timer]
OnBootSec=5min
OnUnitActiveSec=5min
Unit=nextcloudcron.service

[Install]
WantedBy=timers.target

The important parts in the timer-unit are OnBootSec and OnUnitActiveSec. OnBootSec will start the timer 5 minutes after boot, otherwise you would have to start it manually after every boot. OnUnitActiveSec will set a 5 minute timer after the service-unit was last activated.

Now all that is left is to start and enable the timer by running this command:

1
systemctl enable --now nextcloudcron.timer

When the option --now is used with enable, the respective unit will also be started.

客户端下载

直接从这里下载https://download.nextcloud.com/desktop/releases/

安装Jellyfin多媒体服务器

由于 Jellyfin 的 GPL 协议和 Intel 的 media-driver (iHD) Linux 驱动(部分开源)在协议上不兼容的缘故,Jellyfin 官方的 Docker 镜像:jellyfin/jellyfin 并不包含 Intel Linux 核显驱动。但是 Intel 的 QuickSync QSV 硬件加速依赖于该驱动,并且 Intel 10 代酷睿(Comet Lake)以及更新的处理器需要该驱动才能正常使用硬件加速。另外 VPP/OpenCL 色调映射也需要该驱动才能正常运作。

1 安装

开发者提供的中国特供版镜像
Docker 镜像: docker pull nyanmisaka/jellyfin:latest

Jellyfin中国特供版+Docker镜像,含驱动,免折腾开箱即用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sudo docker run -d --name=Jellyfin -p 8096:8096 \  # --name=Jellyfin 将容器名定义为 Jellyfin 
-p 8920:8920 -p 7359:7359/udp -p 1900:1900/udp #这三个端口为可选项 \
-v /var/docker/jellyfin/library:/config -v /var/docker/jellyfin/cache:/cache -v /data/media:/media \
-e TZ=Asia/Shanghai -e PUID=0 -e PGID=0 \ #将容器的时区设为上海,使用窗口在运行时使用root权限
--device=/dev/dri:/dev/dri \ #直通显卡给 Docker 容器,用于硬解
--add-host=api.themoviedb.org:13.224.161.90 \ #为容器增加 host 指向,加速海报与影视元数据的搜刮
--add-host=api.themoviedb.org:13.35.8.65 \
--add-host=api.themoviedb.org:13.35.8.93 \
--add-host=api.themoviedb.org:13.35.8.6 \
--add-host=api.themoviedb.org:13.35.8.54 \
--add-host=image.tmdb.org:138.199.37.230 \
--add-host=image.tmdb.org:108.138.246.49 \
--add-host=api.thetvdb.org:13.225.89.239 \
--add-host=api.thetvdb.org:192.241.234.54 \
--restart unless-stopped \
jellyfin/jellyfin:latest

1.如果使用 linuxserver/jellyfin 镜像,就把最后一行替换为下行

1
lscr.io/linuxserver/jellyfin:latest

2.如果使用 nyanmisaka/jellyfin 镜像,最把最后一行替换为下行

1
nyanmisaka/jellyfin:latest

–add-host是指定容器中的域名解析ip,因为每个地方、不同时间ip访问稳定性不同,所以最好不在这里指定,而是用bind解析,详见 安装Bind9用于本地域名解析。已经添加了--add-host参数想删掉的话,可以进入容器配置目录,编辑hostconfig.json文件,把ExtraHosts值清空:

1
"ExtraHosts":[],

修改容器配置需要先停掉容器,容器配置目录默认位于/var/lib/docker/containers/,里面目录是容器的全id,查询容器的全ID使用命令docker inspect 容器ID |grep Id

端口说明:

端口号 用途 可选项
8096 默认http端口号 必须
8920 默认https端口号 可选
7359 让同一局域网中的客户端设备自动发现 可选
1900 DLNA的端口 可选

2 升级

拉取最新版镜像:

1
docker pull nyanmisaka/jellyfin:latest

重命名原容器名

1
docker rename Jellyfin Jellyfin-10.8.13

用最新镜像重新启动一个容器

1
docker run -d --name=Jellyfin -p 8096:8096 -p 8920:8920 -p 7359:7359/udp -p 1900:1900/udp -v /var/docker/jellyfin/library:/config -v /var/docker/jellyfin/cache:/cache -v /data/media:/media -e TZ=Asia/Shanghai -e PUID=0 -e PGID=0 --device=/dev/dri:/dev/dri --restart unless-stopped nyanmisaka/jellyfin:latest

删除原来的容器:

1
docker rm Jellyfin-10.8.13

清理冗余镜像:

1
docker image prune

Ubuntu的SSH安全配置

查看登录日志文件:

1
sudo vim /var/log/auth.log

修改SSH的默认端口

1
iptables -A INPUT -p tcp -m tcp --dport 6022 -j ACCEPT

保存并重启iptables防火墙

1
2
service iptables save
service iptables restart

修改SSH的默认端口

1
sudo vim /etc/ssh/sshd_config

把 # Port 22 修改为 Port 6022

最好使用1024到65535之间的一个别人猜不到的端口号

重启ssh服务

1
sudo service sshd restart 

1
sudo /etc/init.d/ssh restart

可以用iptables检查端口是否开启

禁止SSH的root登录

修改 /etc/ssh/sshd_config 文件

1
PermitRootLogin no

重启ssh服务

1
sudo service sshd restart

禁用密码登陆,使用RSA私钥登录

1
2
ssh-keygen #在客户端生成密钥
ssh-copy-id myserver1 #将公钥添加至服务端

还需要配置服务端

1
2
3
sudo vim /etc/ssh/sshd_config
PasswordAuthentication no #禁止密码认证
PermitEmptyPasswords no #禁止空密码用户登录

重启ssh服务

1
sudo service sshd restart

使用 Fail2ban

Ubuntu 16.04 系统源里带有 denyhosts ,到了Ubuntu 20.04默认不再包含。DenyHosts现在几乎不再更新了,所以来使用Fail2ban

检查是否安装了特定软件包

1
2
sudo apt list --installed | grep denyhosts
sudo apt list --installed | grep fail2ban

安装fail2ban

1
sudo apt-get install fail2ban

配置fail2ban

配置文件在 /etc/fail2ban/jail.conf 。 在配置文件的[DEFAULT]区,可以在此定义所有受监控的服务的默认参数

1
2
3
4
5
6
7
8
9
10
11
12
13
[DEFAULT]
# 以空格分隔的列表,可以是 IP 地址、CIDR 前缀或者 DNS 主机名
# 用于指定哪些地址可以忽略 fail2ban 防御
ignoreip = 127.0.0.1/8 ::1

# 客户端主机被禁止的时长
bantime = 60m

# 查找失败次数的时长
findtime = 10m

# 客户端主机被禁止前允许失败的次数
maxretry = 5

根据上述配置,fail2ban会自动禁止在最近10分钟内有超过5次访问尝试失败的任意IP地址。一旦被禁,这个IP地址将会在1小时内一直被禁止访问 SSH 服务

保存配置后重启服务

1
sudo service fail2ban restart

查看fail2ban运行状态

验证fail2ban成功运行:

1
2
$ sudo fail2ban-client ping
Server replied: pong

检验fail2ban状态

1
2
3
4
$ sudo fail2ban-client status
Status
|- Number of jail: 1
`- Jail list: sshd

检验一个特定监狱的状态

1
sudo fail2ban-client status 

上面的命令会显示出被禁止IP地址列表

解锁特定的IP地址

1
sudo fail2ban-client set sshd unbanip 192.168.1.8

自建开源远程桌面工具Rustdesk中继服务器

Rustdesk支持Windows、macOS、Linux、iOS、Android、Web等几乎所有平台,客户端可以在官方网站下载,安装后自动分配id,立即可以使用。但是官方免费的服务器速度有点慢,官方还提供了服务器端程序,我们可以用docker来安装:

1
2
3
4
docker volume create rustdesk_server_data

docker run --name hbbs --net=host -v "rustdesk_server_data:/root" -d rustdesk/rustdesk-server:latest hbbs -r www.redtux.cn
docker run --name hbbr --net=host -v "rustdesk_server_data:/root" -d rustdesk/rustdesk-server:latest hbbr

这样自建的中继服务器就已经成功运行了,然后在自己的每个客户端设置中继服务器为自己的ip就可以了。

使用Acme.sh工具为Ubuntu安装免费ssl证书

安装acme.sh

1
curl https://get.acme.sh | sh -s email=my@example.com

或者

1
wget -O -  https://get.acme.sh | sh -s email=my@example.com

如果上面两个连接不成功,可以用下面国内的源:

1
2
3
git clone https://gitee.com/neilpang/acme.sh.git
cd acme.sh
./acme.sh --install -m my@example.com

acme会安装到~/acme.sh目录中,安装完成后重新加载Bash:

1
source ~/.bashrc

配置acme.sh

开启自动更新:

1
acme.sh --upgrade --auto-upgrade

选择默认 CA
目前 acme.sh 支持四个正式环境 CA,分别是 Let’s Encrypt、Buypass、ZeroSSL 和 SSL.com,默认使用 ZeroSSL,如果需要更换可以使用如下命令:

切换 Let’s Encrypt

1
acme.sh --set-default-ca --server letsencrypt

切换 Buypass

1
acme.sh --set-default-ca --server buypass

切换 ZeroSSL

1
acme.sh --set-default-ca --server zerossl

切换 SSL.com

1
acme.sh --set-default-ca --server ssl.com

切换 Google Public CA

1
acme.sh --set-default-ca --server google

使用 DNS 验证签发证书

家用网络都封了80端口,不能使用正常模式申请证书,只能使用DNS验证的模式申请,acme.sh 的 DNS API 模式申请证书:

1
acme.sh --issue --dns dns_cf -d example.com -d *.example.com

acme.sh 支持几十种 DNS 插件,常用的下面几种,:

阿里云 –dns dns_ali

1
2
export Ali_Key="1234"
export Ali_Secret="sADDsdasdgdsf"

Dnspod –dns dns_dp

1
2
export DP_Id="1234"
export DP_Key="sADDsdasdgdsf"

Godaddy –dns dns_gd

1
2
export GD_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
export GD_Secret="asdfsdfsfsdfsdfdfsdf"

AWS –dns dns_aws

1
2
export AWS_ACCESS_KEY_ID="sdfsdfsdfljlbjkljlkjsdfoiwje"
export AWS_SECRET_ACCESS_KEY="xxxxxxx"

Linode –dns dns_linode

1
export LINODE_API_KEY="xxxxxxxx"

证书申请完成后会提示证书位置:

1
2
3
4
[Sat Jul 29 11:51:54 AM UTC 2023] Your cert is in: /root/.acme.sh/redtux.cn/redtux.cn.cer
[Sat Jul 29 11:51:54 AM UTC 2023] Your cert key is in: /root/.acme.sh/redtux.cn/redtux.cn.key
[Sat Jul 29 11:51:54 AM UTC 2023] The intermediate CA cert is in: /root/.acme.sh/redtux.cn/ca.cer
[Sat Jul 29 11:51:54 AM UTC 2023] And the full chain certs is there: /root/.acme.sh/redtux.cn/fullchain.cer

安装证书

然后我们可以安装证书

Nginx

1
2
3
4
5
acme.sh --install-cert -d example.com \
--key-file /etc/nginx/ssl/example.com.key \
--fullchain-file /etc/nginx/ssl/example.com.crt \
--ca-file /etc/nginx/ssl/example.com.ca.crt \
--reloadcmd "systemctl restart nginx"

对应的 Nginx 配置指定证书文件

1
2
3
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_trusted_certificate /etc/nginx/ssl/example.com.ca.crt;

Apache

1
2
3
4
5
acme.sh --install-cert -d example.com \
--key-file /etc/apache2/ssl/example.com.key \
--fullchain-file /etc/apache2/ssl/example.com.crt \
--ca-file /etc/apache2/ssl/example.com.ca.crt \
--reloadcmd "curl https://ssl-config.mozilla.org/ffdhe2048.txt >> /etc/apache2/ssl/example.com.crt && systemctl restart apache2"

对应的 Apache 配置指定证书文件

1
2
SSLCertificateFile      /etc/apache2/ssl/example.com.crt
SSLCertificateKeyFile /etc/apache2/ssl/example.com.key

替代群晖音乐的工具:Navidrome

Linux下的安装

首先安装依赖,navidrome依赖ffmpeg:

1
2
3
sudo apt update
sudo apt upgrade
sudo apt install vim ffmpeg

然后创建navidrome工作的目录结构:

1
2
sudo install -d -o <user> -g <group> /opt/navidrome
sudo install -d -o <user> -g <group> /var/lib/navidrome

下载Navidrome

GitHub下载最新发布版本(用最新版的下载地址替换下面命令中的地址),解压到程序目录/opt/navidrome,赋予目录可执行权限。

1
2
3
wget https://github.com/navidrome/navidrome/releases/download/v0.XX.0/navidrome_0.XX.0_Linux_x86_64.tar.gz -O Navidrome.tar.gz
sudo tar -xvzf Navidrome.tar.gz -C /opt/navidrome/
sudo chown -R <user>:<group> /opt/navidrome

创建配置文件

In the working directory, /var/lib/navidrome create a new file named navidrome.toml with the following settings.

MusicFolder = “
For additional configuration options see the configuration options page.

1
2
3
4
5
6
7
8
9
10
LogLevel = 'DEBUG'
ScanSchedule = '@every 24h'
TranscodingCacheSize = '150MiB'
MusicFolder = '/mnt/music'
Port = '6019'
DefaultLanguage = 'zh-Hans'
EnableSharing = true
EnableTranscodingConfig = true
LastFM.Language = 'zh-Hans'
UIWelcomeMessage = 'Redtuxs Family Music Server'

创建系统服务配置文件

Create a new file under /etc/systemd/system/ named navidrome.service with the following data. Make sure you replace and with the user and group you want to run Navidrome under.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
[Unit]
Description=Navidrome Music Server and Streamer compatible with Subsonic/Airsonic
After=remote-fs.target network.target
AssertPathExists=/var/lib/navidrome

[Install]
WantedBy=multi-user.target

[Service]
User=<user>
Group=<group>
Type=simple
ExecStart=/opt/navidrome/navidrome --configfile "/var/lib/navidrome/navidrome.toml"
WorkingDirectory=/var/lib/navidrome
TimeoutStopSec=20
KillMode=process
Restart=on-failure

# See https://www.freedesktop.org/software/systemd/man/systemd.exec.html
DevicePolicy=closed
NoNewPrivileges=yes
PrivateTmp=yes
PrivateUsers=yes
ProtectControlGroups=yes
ProtectKernelModules=yes
ProtectKernelTunables=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
RestrictNamespaces=yes
RestrictRealtime=yes
SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @setuid @swap
ReadWritePaths=/var/lib/navidrome

# You can uncomment the following line if you're not using the jukebox This
# will prevent navidrome from accessing any real (physical) devices
#PrivateDevices=yes

# You can change the following line to `strict` instead of `full` if you don't
# want navidrome to be able to write anything on your filesystem outside of
# /var/lib/navidrome.
ProtectSystem=full

# You can uncomment the following line if you don't have any media in /home/*.
# This will prevent navidrome from ever reading/writing anything there.
#ProtectHome=true

# You can customize some Navidrome config options by setting environment variables here. Ex:
#Environment=ND_BASEURL="/navidrome"

启动Navidrome服务

Reload the service daemon, start the newly create service, and verify it has started correctly.

1
2
3
4
sudo systemctl daemon-reload
sudo systemctl start navidrome.service
sudo systemctl status navidrome.service
sudo systemctl restart navidrome.service

如果服务成功启动,你就可以访问http://localhost:4533来访问web端.

让Navidrome随系统启动

1
sudo systemctl enable navidrome.service

用Nginx配置反向代理

反向代理配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
server {
listen 619 default_server;
listen [::]:619 default_server;

# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;

#root /var/www/start;

# Add index.php to the list if you are using PHP
#index index.html index.htm index.nginx-debian.html;

server_name www.redtux.cn;

client_max_body_size 50000M;

location / {
proxy_pass http://192.168.0.6:6019;

proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_buffering off;
}
}

也可以Docker的方式安装,详见官方文档Navidrome官方网站开源音乐服务器,自建云端音乐播放器

客户端

Android手机可以从F-Droid直接安装Subtracks或者Ultrasonic,然后设置服务器地址就可以了。

PC可以使用Sonixd客户端,下载地址,下载对应系统的版本。

号外

其实还有一个自建音乐流媒体服务器koel——基于php fpm docker界面漂亮,唯一缺点就是手机客户端只能从Google play下载,国内只能用浏览器访问。

替代群晖相册的工具:immich

一直以来,我都用群晖自带的 Photos 来备份手机照片,因为除了群晖相册之外,还没用过其他好用的相册工具,自从上次群晖文件系统都变成只读之后就有了用Ubuntu替换群晖的想法。然后就在网络中发现了Immich,immich有Android手机客户端,可以直接从f-droid安装。

官方部署教程

下面简要记录部署教程:

下载安装部署必要文件

我们使用docker-compose部署,首先创建一个存储docker-compose.yml.env 文件的目录.

1
2
mkdir ./immich-app
cd ./immich-app

下载docker-compose.ymlexample.env文件

下载docker-compose.yml文件

1
wget https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml

下载.env文件

1
wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env

或者用浏览器下载这两个文件,然后放到刚刚创建的目录中。

Note: If you downloaded the files from your browser, also ensure that you rename example.env to .env.

修改.env文件中的变量值

  • Populate custom database information if necessary.
  • UPLOAD_LOCATION 设置成你的照片存储路径.
  • DB_PASSWORD 设置数据库的密码
  • TYPESENSE_API_KEY 设置成随机字符串。

可以修改docker-compose.yml文件,在Postgres数据库那里增加5432端口映射,把Postgres容器的5432端口映射到本地,这样后期本地安装应用的时候可以用到docker的数据库。

创建容器

From the directory you created in Step 1, (which should now contain your customized docker-compose.yml and .env files) run docker-compose up -d.

Start the containers using docker compose command

1
docker-compose up -d     # or `docker compose up -d` based on your docker-compose version

现在可以访问http://<machine-ip-address>:2283开始创建你的管理员账户了。

设置Nginx反向代理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
server {
listen 618 default_server;
listen [::]:618 default_server;

# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;

#root /var/www/start;

# Add index.php to the list if you are using PHP
#index index.html index.htm index.nginx-debian.html;

server_name www.redtux.cn;

client_max_body_size 50000M;

location / {
proxy_pass http://127.0.0.1:2283;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

# http://nginx.org/en/docs/http/websocket.html
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
}
}

升级

Immich的版本迭代速度相当快,如果有新版本发布,可以切换到docker-compose.yml文件存放到目录,然后执行如下命令:

1
docker-compose pull && docker-compose up -d     # Or `docker compose up -d`

备份数据库

The recommended way to backup and restore the Immich database is to use the pg_dumpall command.

备份

1
docker exec -t immich_postgres pg_dumpall -c -U postgres | gzip > "/path/to/backup/dump.sql.gz"

恢复

1
2
3
4
5
6
7
docker-compose down -v  # CAUTION! Deletes all Immich data to start from scratch.
docker-compose pull # Update to latest version of Immich (if desired)
docker-compose create # Create Docker containers for Immich apps without running them.
docker start immich_postgres # Start Postgres server
sleep 10 # Wait for Postgres server to start up
gunzip < "/path/to/backup/dump.sql.gz" | docker exec -i immich_postgres psql -U postgres -d immich # Restore Backup
docker-compose up -d # Start remainder of Immich apps

桌面系统上传工具

依赖 Node.js 16以上版本和npm

安装node.js后执行如下命令安装immich桌面端上传工具:

1
npm i -g immich

把本地目录~/toUpload中的照片上传到服务器:

1
immich upload --key sikjo7P3o5jLddv3pfiDjH3RVfj4yIuptOti8SetM --server http://192.168.0.6:2283/api --recursive ~/toUpload

把本地目录~/toUpload中的照片上传到服务器,并加入到AlbumName相册中:

1
immich upload --key sikjo7P3o5jLddv3pfiDjH3RVfj4yIuptOti8SetM --server http://192.168.0.6:2283/api --recursive --album AlbumName ~/toUpload

选项:

Parameter Description
–yes / -y Assume yes on all interactive prompts
–recursive / -r Include subfolders
–delete / -da Delete local assets after upload
–key / -k User’s API key
–server / -s Immich’s server address
–threads / -t Number of threads to use (Default 5)
–album/ -al Create albums for assets based on the parent folder or a given name
–import/ -i Import gallery (assets are not uploaded)

号外

还有一个相册工具 PhotoPrism,这是一个优秀的成熟的相册,唯一缺憾就是没有手机客户端。

安装可道云Kodexplorer

可道云Kodexplorer是一个基于web的文件管理器,这里可以查看官方文档

nginx配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
server {
listen 620 default_server;
listen [::]:620 default_server;

root /var/www/kodexplorer;
index index.php
server_name www.redtux.cn;

location / {
try_files $uri $uri/ =404;
}

location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
# fastcgi_pass 127.0.0.1:9000;
}

location ~ /\.ht {
deny all;
}
}

php库缺失 curl
php库缺失 mb_string
须开启php GD库,否则验证码、缩略图使用将不正常

配置优化

  1. 修改nginx的配置文件
1
2
3
4
5
6
7
8
client_max_body_size 500M;        
client_header_timeout 3600s;
client_body_timeout 3600s;
fastcgi_connect_timeout 3600s;
fastcgi_send_timeout 3600s;
fastcgi_read_timeout 3600s;
# 其他webserver相应修改类似限制;如apache需要修改LimitRequestBody
# 修改完成重启nginx生效: service nginx reload
  1. 修改php配置文件php.ini;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
post_max_size = 500M;
upload_max_filesize = 500M;
memory_limit = 500M;
max_execution_time = 3600;
max_input_time = 3600;

# php中设置set_time_limit无效(safe_mode=on时php代码中修改超时无效) php.ini
safe_mode = off

# php-fpm.conf 配置优化(超时时间; 4G内存推荐如下子进程配置)
request_terminate_timeout 3600
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 10
pm.max_spare_servers = 30
pm.max_requests = 500
  • 注意:
    • 如果某一类例如exe文件不能上传,其他文件可上传, 一般是服务器(杀毒软件或防火墙)做了拦截误判,取消相应软件上拦截即可;
    • 超时时间设置; 如果经常有超大文件上传,php和nginx超时时间需要设置大一些;
    • 分片上传: 一个大文件切分成多个分片上传,所有片上传完成后服务器自动合并;一个分片上传失败只需要重传该分片即可;
    • 分片大小设置: 管理员登陆后台–基础设置–上传下载; 调整上传分片大小; 必须小于php.ini和nginx的限制;
    • 修改了php或nginx配置文件后,需要重启php-fpm和nginx;
    • 上传文件限制及超时时间可以根据自己需求设置; 超时时间需大于文件上传下载的时间,否则超时会导致操作失败;
  1. 修改可道云配置

设置方法:管理员登陆可道云进入后台 系统设置—基础设置—上传/下载

  • 设置分片大小: 推荐5M

大文件上传时切分成片进行并发上传,从而实现加速和断点续传,
推荐5M; 此值必须小于下述配置;否则会引起上传异常(上传失败,进度回退)
php.ini: post_max_size, upload_max_filesize ==> 5M
nginx: client_max_body_size ==> 5M;

  • 上传并发数量; 推荐15个并发;
  1. nginx + php-fpm上传优化

在nginx.conf中添加如下代码,参考更多nginx优化

1
2
3
4
#使用共享内存做临时存贮提高上传速度,共享内存需要大一些,否则上传大文件内存不足
client_body_in_file_only clean;
client_body_temp_path /dev/shm 1 2;
fastcgi_param REQUEST_BODY_FILE $request_body_file;

安装docker及docker-compose

卸载旧版本

在你安装docker之前一定要把系统中的旧版本卸载掉,一半系统发行商在官方apt源中带有docker,但是不是最新版的,如果你是全新安装的系统,你还没有安装过docker,那就可以省掉这一步。

需要卸载掉的非官方包包括:

  • docker.io
  • docker-compose
  • docker-doc
  • podman-docker

运行如下命令卸载这些包:

1
$for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done

apt-get 可能会提示你这些包没有安装。

Images, containers, volumes, and networks 存储在 /var/lib/docker/ 目录中不会自动删除,如果你想要一个全新安装的docker,你最好手动删除他们。

安装途径

你可以根据你的需要使用如下方法安装docker:

  • 安装docker桌面版,桌面版包含了docker,这是最简单最快捷的方法;

  • 从Docker的官方apt库安装;

  • 自己手动安装;

  • 用脚本自动安装,只推荐用在测试和开发环境中。

从Docker的官方apt库安装

在新装系统第一次安装Docker之前,首先要设置Docker的官方apt库,设置apt库之后就可以使用apt命令安装了。

设置Docker的官方apt库

按照如下命令,安装一些工具和允许使用https协议:

1
2
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg

添加Docker的官方GPG key:

1
2
3
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

按照如下命令设置Docker的官方apt库:

1
2
3
4
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

注意

If you use an Ubuntu derivative distro, such as Linux Mint, you may need to use UBUNTU_CODENAME instead of VERSION_CODENAME.

更新包索引:

1
sudo apt-get update

安装 Docker Engine

运行如下命令安装最新版Docker:

1
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

如果要安装特定版本Docker,可以先用如下命令列出可用版本:

1
2
# List the available versions:
$ apt-cache madison docker-ce | awk '{ print $3 }'

返回可用的版本号:

1
2
3
5:24.0.0-1~ubuntu.22.04~jammy
5:23.0.6-1~ubuntu.22.04~jammy
<...>

选择你期望的版本进行安装:

1
2
VERSION_STRING=5:24.0.0-1~ubuntu.22.04~jammy
sudo apt-get install docker-ce=$VERSION_STRING docker-ce-cli=$VERSION_STRING containerd.io docker-buildx-plugin docker-compose-plugin

运行一下 hello-world 镜像验证Docker是否安装成功。

1
sudo docker run hello-world

这条命令会下载hello-world镜像,并在一个新建的容器中运行。

到此Docker就已经安装成功了。

安装 docker-compose

上面已经安装了docker compose插件,可以通过docker compose命令运行,就是版本会旧一些,最新版的可以去docker-compose的Github下载二进制文件,然后复制到PATH路径中。

卸载 Docker Engine

1.Uninstall the Docker Engine, CLI, containerd, and Docker Compose packages:

1
sudo apt-get purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras

2.Images, containers, volumes, or custom configuration files on your host aren’t automatically removed. To delete all images, containers, and volumes:

1
2
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd

You have to delete any edited configuration files manually.

Docker服务控制

停止Docker服务

1
systemctl stop docker

启动Docker服务

1
systemctl start docker

重新启动Docker服务

1
systemctl restart docker

Docker常用命令

  • docker start : 启动一个容器
  • docker restart : 重新启动一个容器
  • docker stop : 关闭一个容器
  • docker status : 查看docker运行状态
  • docker ps : 列出正在运行的容器
  • docker volume : 新建docker卷
  • docker run : 从一个镜像放在新建的容器中运行。

其他详细命令可以参考官方文档

其他特定命令:

获取容器ID为282c7625119d的ip

1
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 282c7625119d

启动所有容器:

1
docker start $(docker ps -aq) 

关闭所有容器:

1
docker stop $(docker ps -aq) 

创建时设置容器开机自启:

1
docker run -d --restart=always -name 容器名 使用镜像

修改已有容器开机自启:

1
2
docker update --restart=always 容器ID(或者容器名)
(容器ID或者容器名根据实际情况修改)

对已有docker容器增加新的端口映射

1、 docker ps -a #查看容器的信息

2、 docker port 容器ID/容器名称 #查看容器的端口映射情况

3、 docker inspect 容器ID |grep Id #查找要修改容器的全ID

4、 cd /var/lib/docker/containers/全ID #进到全Id相同的目录,修改 其中的hostconfig.json 和 config.v2.json文件: #注意:若该容器还在运行中,需要先停掉 docker stop 容器ID #再停掉docker服务 systemctl stop docker

5、修改hostconfig.json如下 # 格式如:”{容器内部端口}/tcp”:[{“HostIp”:””,”HostPort”:”映射的宿主机端口”}]
“PortBindings”:{“22/tcp”:[{“HostIp”:””,”HostPort”:”3316”}],”80/tcp”:[{“HostIp”:””,”HostPort”:”180”}]}

{“5432/tcp”:[{“HostIp”:””,”HostPort”:”5432”}]}

6、修改config.v2.json在ExposedPorts中加上要暴露的端口 # 格式如:”{容器内部端口}/tcp”:{} “ExposedPorts”:{“22/tcp”:{},”80/tcp”:{}}

{“5432/tcp”:{}}

修改docker镜像源

镜像源参考
中国区官方镜像:https://registry.docker-cn.com
中科大源:https://docker.mirrors.ustc.edu.cn
阿里源:https://cr.console.aliyun.com
腾讯源:https://mirror.ccs.tencentyun.com
网易源:http://hub-mirror.c.163.com

1、关闭 Docker 服务

2、修改配置文件

创建或修改/etc/docker/daemon.json文件,
默认没有daemon文件,先创建。

1
vim /etc/docker/daemon.json

增加/更新”registry-mirrors”字段

1
2
3
4
5
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn"
]
}

注:需确认”daemon.json”的位置。

3、重启 Docker 服务

删除系统自带的snap

snap list可以查看已经安装的包,默认带的组件是core、lxd、snapd。

删除一个snap包

1
sudo snap remove docker

卸载snap

1
sudo apt autoremove --purge snapd

这样就会连带snap安装的所有软件全部都卸载掉了。