前言
Miniflux 是一个基于 Golang 的极简 RSS 阅读器 1,RSSHub 可以为不提供 RSS Feed 的站点提供开箱即用的 RSS 路由。
本文使用 docker compose 部署服务,RSSHub 不直接暴露任何端口(仅限容器内 Miniflux 服务使用),最后使用 Cloudflare Tunnel 访问部署好的 Miniflux 服务。
开始之前,先在服务器上 安装 最新的 Docker 和 docker compose 插件,以及用于 Cloudflare Tunnel 服务的 cloudflared
部署
SSH 登录服务器,开始执行命令
# 创建目录,用于 Miniflux 相关容器的持久化数据存储
sudo mkdir -p container/miniflux && cd container/miniflux
# 新建 docker-compose.yml 文件
touch docker-compose.yml
编辑这个文件,注意修改管理员信息及数据库相关信息
version: "3.1"
services:
miniflux:
image: miniflux/miniflux:latest
container_name: miniflux
restart: unless-stopped
ports:
- "127.0.0.1:8080:8080"
depends_on:
- db
- rsshub
environment:
- DATABASE_URL=postgres://miniflux:<数据库密码>@db/miniflux?sslmode=disable
#- POLLING_FREQUENCY=45
- RUN_MIGRATIONS=1 # 运行数据迁移
- CREATE_ADMIN=1 # 启动时创建用户
- ADMIN_USERNAME=<管理员用户名>
- ADMIN_PASSWORD=<管理员用户密码>
- POLLING_PARSING_ERROR_LIMIT=2
- BASE_URL=https://rss.youdamin.tld/ # 替换为您的自定义域名,结尾需要斜杠
#- CLEANUP_ARCHIVE_UNREAD_DAYS=60
#- CLEANUP_ARCHIVE_READ_DAYS=45
#- PROXY_IMAGES=none
- PUID=1000
- PGID=1000
db:
image: postgres:alpine
container_name: postgres
restart: unless-stopped
environment:
- POSTGRES_USER=miniflux # 数据库用户名
- POSTGRES_PASSWORD=<数据库密码>
volumes:
- ./miniflux-db:/var/lib/postgresql/data
rsshub:
image: diygod/rsshub:chromium-bundled
container_name: rsshub
restart: unless-stopped
environment:
- NODE_ENV=production
- CACHE_TYPE=redis
- REDIS_URL=redis://redis:6379/
- CACHE_EXPIRE=3600 # 缓存过期时间,单位:秒
- REQUEST_TIMEOUT=40000 # 请求超时时间,单位:毫秒
depends_on:
- redis
redis:
image: redis:alpine
container_name: redis
restart: always
volumes:
- ./rsshub-redis:/data
考虑到 Miniflux 容器不一定等到依赖服务(如 PostgreSQL 数据库)完全就绪才启动 2,第一次部署时,建议分两步启动容器
首先拉取所需的镜像 3 并启动依赖的数据库服务
sudo docker compose pull && \
sudo docker compose up -d db redis
等待大约 10 秒左右,开始第二步的容器启动
sudo docker compose up -d
查看日志没报错,服务应该已经就绪
sudo docker compose logs -f
访问
在 Cloudflare Zero Trust 控制台添加一个 Tunnel,配置自定义域名和监听地址
现在可以通过您的自定义域名访问刚才部署的 Miniflux 服务了
路由
常规的 RSS 订阅链接可以直接添加,要使用 RSSHub 支持的路由地址,先在 RSSHub 文档 上查找相应的路由路径。比如,准备订阅华尔街日报的中文新闻,可以看到路由路径是 /wsj/zh-cn/
那么在 Miniflux 添加的时候,路由域名写 http://rsshub:1200
就可以了
点击 查找源,Miniflux 应该可以正常获取订阅 4
完成
分享一个我自用的极简 CSS 样式,效果图在本文开头 🫣
:root {
--font-family: -apple-system, system-ui, "San Francisco", "Helvetica Neue",
Helvetica, Arial, "Microsoft Yahei", "WenQuanYi Micro Hei", "Noto Sans",
sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
"Noto Color Emoji";
--body-color: #333;
--body-background: #fff;
--hr-border-color: #ccc;
--title-color: #333;
--link-color: rgb(30, 30, 30);
--link-focus-color: red;
--link-hover-color: #333;
--link-visited-color: purple;
--header-list-border-color: #ddd;
--header-link-color: #444;
--header-link-focus-color: #888;
--header-link-hover-color: #888;
--header-active-link-color: #444;
--page-header-title-color: #333;
--page-header-title-border-color: #333;
--logo-color: #000;
--logo-hover-color-span: #000;
--table-border-color: #ddd;
--table-th-background: #fcfcfc;
--table-th-color: #333;
--table-tr-hover-background-color: #f9f9f9;
--table-tr-hover-color: #333;
--button-primary-border-color: #3079ed;
--button-primary-background: #4d90fe;
--button-primary-color: #fff;
--button-primary-focus-border-color: #2f5bb7;
--button-primary-focus-background: #357ae8;
--input-border: 1px solid #ccc;
--input-background: #fff;
--input-color: #333;
--input-placeholder-color: #d0d0d0;
--input-focus-color: #000;
--input-focus-border-color: rgba(82, 168, 236, 0.8);
--input-focus-box-shadow: 0 0 8px rgba(82, 168, 236, 0.6);
--alert-color: #c09853;
--alert-background-color: #fcf8e3;
--alert-border-color: #fbeed5;
--alert-success-color: #468847;
--alert-success-background-color: #dff0d8;
--alert-success-border-color: #d6e9c6;
--alert-error-color: #b94a48;
--alert-error-background-color: #f2dede;
--alert-error-border-color: #eed3d7;
--alert-info-color: #3a87ad;
--alert-info-background-color: #d9edf7;
--alert-info-border-color: #bce8f1;
--panel-background: #fcfcfc;
--panel-border-color: #ddd;
--panel-color: #333;
--modal-background: #f0f0f0;
--modal-color: #333;
--modal-box-shadow: 2px 0 5px 0 #ccc;
--pagination-link-color: #333;
--pagination-border-color: #ddd;
--category-color: #090909;
--category-background-color: #e8e8e8;
--category-border-color: #e8e8e8;
/* --category-link-color: #e8e8e8; */
/* --category-link-hover-color: #e8e8e8; */
--item-border-color: #ddd;
--item-padding: 5px;
--item-title-link-font-weight: 600;
--item-status-read-title-link-color: #777;
--item-status-read-title-focus-color: #777;
--item-meta-focus-color: #777;
--item-meta-li-color: #aaa;
--current-item-border-width: 3px;
--current-item-border-color: #bce;
--current-item-box-shadow: none;
--entry-header-border-color: #ddd;
--entry-header-title-link-color: #333;
--entry-content-color: #555;
--entry-content-code-color: #333;
--entry-content-code-background: #f0f0f0;
--entry-content-code-border-color: #ddd;
--entry-content-quote-color: #666;
--entry-content-abbr-border-color: #999;
--entry-enclosure-border-color: #333;
--parsing-error-color: #333;
--feed-parsing-error-background-color: #fcf8e3;
--feed-parsing-error-border-style: solid;
--feed-parsing-error-border-color: #f9e883;
--feed-has-unread-background-color: #dfd;
--feed-has-unread-border-style: solid;
--feed-has-unread-border-color: #bee6bc;
--category-has-unread-background-color: #dfd;
--category-has-unread-border-style: solid;
--category-has-unread-border-color: #bee6bc;
--keyboard-shortcuts-li-color: #333;
--counter-color: #666;
}
:root {
--entry-content-font-weight: 300;
--entry-content-font-family: -apple-system, system-ui, "San Francisco",
"Helvetica Neue", Helvetica, Arial, "Microsoft Yahei", "WenQuanYi Micro Hei",
"Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
"Segoe UI Symbol", "Noto Color Emoji";
--entry-content-quote-font-family: var(--entry-content-font-family);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
body {
font-family: var(--font-family);
text-rendering: optimizeLegibility;
color: var(--body-color);
background: var(--body-background);
}
hr {
border: 0;
height: 0;
border-top: 1px dotted var(--hr-border-color);
padding-bottom: 10px;
}
h1,
h2,
h3 {
color: var(--title-color);
}
main {
padding-left: 5px;
padding-right: 5px;
margin-bottom: 30px;
}
a {
color: var(--link-color);
box-shadow: 0 1px;
text-decoration: none;
}
a:focus {
outline: 0;
color: var(--link-focus-color);
text-decoration: none;
outline: 1px dotted #aaa;
}
a:hover {
color: var(--link-hover-color);
text-decoration: none;
}
.header {
margin-top: 10px;
margin-bottom: 20px;
}
.header nav ul {
display: none;
}
.header li {
cursor: pointer;
padding-left: 10px;
line-height: 2.1em;
font-size: 1.2em;
border-bottom: 1px dotted var(--header-list-border-color);
}
.header li a:hover {
color: #888;
}
.header a {
font-size: 0.9em;
color: var(--header-link-color);
text-decoration: none;
border: none;
font-weight: 400;
}
.header .active a {
color: var(--header-active-link-color);
font-weight: 600;
}
.header a:hover {
color: var(--header-link-hover-color);
}
.header a:focus {
color: var(--header-link-focus-color);
}
.page-header {
margin-bottom: 25px;
}
.page-footer {
margin-bottom: 10px;
}
.page-header h1 {
font-weight: 500;
border-bottom: 1px dotted var(--page-header-title-border-color);
}
.page-header h1 a {
text-decoration: none;
color: var(--page-header-title-color);
}
.page-header h1 a:hover,
.page-header h1 a:focus {
color: #666;
}
.page-header li,
.page-footer li {
list-style-type: none;
line-height: 1.8em;
white-space: nowrap;
}
.page-header ul a .icon {
padding-bottom: 2px;
}
.logo {
cursor: pointer;
text-align: center;
}
.logo a {
color: var(--logo-color);
letter-spacing: 1px;
}
.logo a:hover {
color: #396;
}
.logo a span {
color: #396;
}
.logo a:hover span {
color: var(--logo-hover-color-span);
}
.search {
text-align: center;
display: none;
}
.search-toggle-switch {
display: none;
}
#prompt-home-screen {
display: none;
position: fixed;
bottom: 0;
right: 0;
width: 100%;
text-align: center;
background: #000;
opacity: 85%;
}
#btn-add-to-home-screen {
text-decoration: none;
line-height: 30px;
color: #fff;
}
#btn-add-to-home-screen:hover {
color: red;
}
#toast-wrapper {
visibility: hidden;
opacity: 0;
position: fixed;
left: 0;
bottom: 10%;
color: #fff;
width: 100%;
text-align: center;
}
#toast-msg {
background-color: rgba(0, 0, 0, 0.7);
padding-bottom: 4px;
padding-left: 4px;
padding-right: 5px;
border-radius: 5px;
}
.toast-animate {
animation: toastKeyFrames 2s;
}
@keyframes toastKeyFrames {
0% {
visibility: hidden;
opacity: 0;
}
25% {
visibility: visible;
opacity: 1;
z-index: 9999;
}
50% {
visibility: visible;
opacity: 1;
z-index: 9999;
}
75% {
visibility: visible;
opacity: 1;
z-index: 9999;
}
100% {
visibility: hidden;
opacity: 0;
z-index: 0;
}
}
@media (min-width: 600px) {
body {
margin: auto;
max-width: 750px;
}
.header {
margin-bottom: 0;
}
.logo {
text-align: left;
float: left;
margin-right: 15px;
margin-left: 5px;
}
.header nav ul {
display: block;
}
.header li {
display: inline;
padding: 0;
padding-right: 15px;
line-height: normal;
border: none;
font-size: 1em;
}
.page-header li,
.page-footer li {
display: inline;
padding-right: 15px;
}
.search {
text-align: right;
display: block;
margin-top: 10px;
margin-right: 5px;
}
.search-toggle-switch {
display: block;
}
.search-form {
display: none;
}
.search-toggle-switch.has-search-query {
display: none;
}
.search-form.has-search-query {
display: block;
}
}
table {
width: 100%;
border-collapse: collapse;
}
table,
th,
td {
border: 1px solid var(--table-border-color);
}
th,
td {
padding: 5px;
text-align: left;
}
td {
vertical-align: top;
}
th {
background: var(--table-th-background);
color: var(--table-th-color);
font-weight: 400;
}
tr:hover {
color: var(--table-tr-hover-color);
background-color: var(--table-tr-hover-background-color);
}
.column-40 {
width: 40%;
}
.column-25 {
width: 25%;
}
.column-20 {
width: 20%;
}
fieldset {
border: 1px solid #ddd;
padding: 8px;
}
legend {
font-weight: 500;
padding-left: 3px;
padding-right: 3px;
}
label {
cursor: pointer;
display: block;
}
.radio-group {
line-height: 1.9em;
}
div.radio-group label {
display: inline-block;
}
select {
margin-bottom: 15px;
}
input[type="search"],
input[type="url"],
input[type="password"],
input[type="text"],
input[type="number"] {
color: var(--input-color);
background: var(--input-background);
border: var(--input-border);
padding: 3px;
line-height: 20px;
width: 250px;
font-size: 99%;
margin-bottom: 10px;
margin-top: 5px;
-webkit-appearance: none;
}
input[type="search"]:focus,
input[type="url"]:focus,
input[type="password"]:focus,
input[type="text"]:focus,
input[type="number"]:focus {
color: var(--input-focus-color);
border-color: var(--input-focus-border-color);
outline: 0;
box-shadow: var(--input-focus-box-shadow);
}
#form-entries-per-page {
max-width: 80px;
}
input[type="checkbox"] {
margin-bottom: 15px;
}
textarea {
width: 350px;
color: var(--input-color);
background: var(--input-background);
border: var(--input-border);
padding: 3px;
margin-bottom: 10px;
margin-top: 5px;
-webkit-appearance: none;
}
textarea:focus {
color: var(--input-focus-color);
border-color: var(--input-focus-border-color);
outline: 0;
box-shadow: var(--input-focus-box-shadow);
}
input::placeholder {
color: var(--input-placeholder-color);
padding-top: 2px;
}
.form-label-row {
display: flex;
}
.form-help {
font-size: 0.9em;
color: brown;
margin-bottom: 15px;
}
.form-section {
border-left: 2px dotted #ddd;
padding-left: 20px;
margin-left: 10px;
}
details > summary {
outline: none;
cursor: pointer;
}
.details-content {
margin-top: 15px;
}
a.button {
text-decoration: none;
}
.button {
display: inline-block;
-webkit-appearance: none;
-moz-appearance: none;
font-size: 1.1em;
cursor: pointer;
padding: 3px 10px;
border: 1px solid;
border-radius: unset;
}
.button-primary {
border-color: var(--button-primary-border-color);
background: var(--button-primary-background);
color: var(--button-primary-color);
}
a.button-primary:hover,
a.button-primary:focus,
.button-primary:hover,
.button-primary:focus {
border-color: var(--button-primary-focus-border-color);
background: var(--button-primary-focus-background);
color: var(--button-primary-color);
}
.button-danger {
border-color: #b0281a;
background: #d14836;
color: #fff;
}
.button-danger:hover,
.button-danger:focus {
color: #fff;
background: #c53727;
}
.button:disabled {
color: #ccc;
background: #f7f7f7;
border-color: #ccc;
}
.buttons {
margin-top: 10px;
margin-bottom: 20px;
}
.alert {
padding: 8px 35px 8px 14px;
margin-bottom: 20px;
color: var(--alert-color);
background-color: var(--alert-background-color);
border: 1px solid var(--alert-border-color);
border-radius: 4px;
overflow: auto;
}
.alert h3 {
margin-top: 0;
margin-bottom: 15px;
}
.alert-success {
color: var(--alert-success-color);
background-color: var(--alert-success-background-color);
border-color: var(--alert-success-border-color);
}
.alert-error {
color: var(--alert-error-color);
background-color: var(--alert-error-background-color);
border-color: var(--alert-error-border-color);
}
.alert-error h3,
.alert-error a {
color: var(--alert-error-color);
}
.alert-info {
color: var(--alert-info-color);
background-color: var(--alert-info-background-color);
border-color: var(--alert-info-border-color);
}
.panel {
color: var(--panel-color);
background-color: var(--panel-background);
border: 1px solid var(--panel-border-color);
border-radius: 5px;
padding: 10px;
margin-bottom: 15px;
}
.panel h3 {
font-weight: 500;
margin-top: 0;
margin-bottom: 20px;
}
.panel ul {
margin-left: 30px;
}
template {
display: none;
}
#modal-left {
position: fixed;
top: 0;
left: 0;
bottom: 0;
width: 380px;
overflow: auto;
color: var(--modal-color);
background: var(--modal-background);
box-shadow: var(--modal-box-shadow);
padding: 5px;
padding-top: 30px;
}
#modal-left h3 {
font-weight: 400;
margin: 0;
}
.btn-close-modal {
position: absolute;
top: 0;
right: 0;
font-size: 1.7em;
color: #ccc;
padding: 0 0.2em;
margin: 10px;
text-decoration: none;
}
.btn-close-modal:hover {
color: #999;
}
.keyboard-shortcuts li {
margin-left: 25px;
list-style-type: square;
color: var(--keyboard-shortcuts-li-color);
font-size: 0.95em;
line-height: 1.45em;
}
.keyboard-shortcuts p {
line-height: 1.9em;
}
.login-form {
margin: 50px auto 0;
max-width: 280px;
}
.unread-counter-wrapper,
.error-feeds-counter-wrapper {
font-size: 0.9em;
font-weight: 300;
color: var(--counter-color);
}
.category {
font-size: 0.75em;
background-color: var(--category-background-color);
border: 1px solid var(--category-border-color);
border-radius: 5px;
margin-left: 0.25em;
padding: 1px 0.4em;
white-space: nowrap;
color: var(--category-color);
}
.category a {
color: var(--category-link-color);
text-decoration: none;
}
.category a:hover,
.category a:focus {
color: var(--category-link-hover-color);
}
.pagination {
font-size: 1.0em;
display: flex;
align-items: center;
}
.pagination-top {
padding-bottom: 8px;
}
.pagination-bottom {
padding-top: 8px;
}
.pagination-entry-top {
padding-top: 8px;
}
.pagination-entry-bottom {
border-top: 1px dotted var(--pagination-border-color);
margin-bottom: 15px;
margin-top: 50px;
padding-top: 8px;
}
.pagination > div {
flex: 1;
}
.pagination-next {
text-align: right;
}
.pagination-prev:before {
content: "« ";
}
.pagination-next:after {
content: " »";
}
.pagination a {
color: var(--pagination-link-color);
}
.pagination a:hover,
.pagination a:focus {
text-decoration: none;
}
.item {
border: 1px dotted var(--item-border-color);
margin-bottom: 20px;
padding: var(--item-padding);
overflow: hidden;
}
.item.current-item {
border: var(--current-item-border-width) solid
var(--current-item-border-color);
padding: 3px;
box-shadow: var(--current-item-box-shadow);
}
.item-title a {
text-decoration: none;
font-weight: var(--item-title-link-font-weight);
}
.item-status-read .item-title a {
color: var(--item-status-read-title-link-color);
}
.item-meta {
color: var(--item-meta-focus-color);
font-size: 0.8em;
}
.item-meta a {
color: #777;
text-decoration: none;
}
.item-meta a:hover,
.item-meta a:focus {
color: #333;
}
.item-meta ul {
margin-top: 5px;
}
.item-meta li {
display: inline-block;
}
.item-meta-info {
font-size: 0.85em;
}
.item-meta-info li:after {
content: "|";
color: var(--item-meta-li-color);
}
.item-meta-info li:last-child:after {
content: "";
}
.item-meta-icons li {
margin-right: 8px;
margin-top: 4px;
}
.item-meta-icons li:last-child {
margin-right: 0;
}
.items {
overflow-x: hidden;
touch-action: pan-y;
}
.hide-read-items .item-status-read:not(.current-item) {
display: none;
}
.entry-swipe {
transition-property: transform;
transition-duration: 0s;
transition-timing-function: ease-out;
}
article.feed-parsing-error {
background-color: var(--feed-parsing-error-background-color);
border-style: var(--feed-parsing-error-border-style);
border-color: var(--feed-parsing-error-border-color);
}
article.feed-has-unread {
background-color: var(--feed-has-unread-background-color);
border-style: var(--feed-has-unread-border-style);
border-color: var(--feed-has-unread-border-color);
}
.parsing-error {
font-size: 0.85em;
margin-top: 2px;
color: var(--parsing-error-color);
}
.parsing-error-count {
cursor: pointer;
}
article.category-has-unread {
background-color: var(--category-has-unread-background-color);
border-style: var(--category-has-unread-border-style);
border-color: var(--category-has-unread-border-color);
}
.icon,
.icon-label {
vertical-align: middle;
display: inline-block;
padding-right: 2px;
}
.icon {
width: 16px;
height: 16px;
}
.entry header {
padding-bottom: 5px;
border-bottom: 1px dotted var(--entry-header-border-color);
}
.entry header h1 {
font-size: 2em;
line-height: 1.25em;
margin: 5px 0 30px;
}
.entry header h1 a {
text-decoration: none;
color: var(--entry-header-title-link-color);
}
.entry header h1 a:hover,
.entry header h1 a:focus {
color: #666;
}
.entry-actions {
margin-bottom: 20px;
}
.entry-actions a {
text-decoration: none;
}
.entry-actions li {
display: inline-block;
margin-right: 15px;
line-height: 1.7em;
}
.entry-meta {
font-size: 0.95em;
margin: 0 0 20px;
color: #666;
overflow-wrap: break-word;
}
.entry-website img {
vertical-align: top;
}
.entry-website a {
color: #666;
vertical-align: top;
text-decoration: none;
}
.entry-website a:hover,
.entry-website a:focus {
text-decoration: underline;
}
.entry-date {
font-size: 0.65em;
font-style: italic;
color: #555;
}
.entry-content {
padding-top: 15px;
font-size: 1.2em;
font-weight: var(--entry-content-font-weight);
font-family: var(--entry-content-font-family);
color: var(--entry-content-color);
line-height: 1.4em;
overflow-wrap: break-word;
}
.entry-content h1,
h2,
h3,
h4,
h5,
h6 {
margin-top: 15px;
margin-bottom: 10px;
}
.entry-content iframe,
.entry-content video,
.entry-content img {
max-width: 100%;
}
.entry-content figure {
margin-top: 15px;
margin-bottom: 15px;
}
.entry-content figure img {
border: 1px solid #000;
}
.entry-content figcaption {
font-size: 0.75em;
text-transform: uppercase;
color: #777;
}
.entry-content p {
margin-top: 10px;
margin-bottom: 15px;
}
.entry-content a {
overflow-wrap: break-word;
}
.entry-content a:visited {
color: var(--link-visited-color);
}
.entry-content dt {
font-weight: 500;
margin-top: 15px;
color: #555;
}
.entry-content dd {
margin-left: 15px;
margin-top: 5px;
padding-left: 20px;
border-left: 3px solid #ddd;
color: #777;
font-weight: 300;
line-height: 1.4em;
}
.entry-content blockquote {
border-left: 4px solid #ddd;
padding-left: 25px;
margin-left: 20px;
margin-top: 20px;
margin-bottom: 20px;
line-height: 1.4em;
font-family: var(--entry-content-quote-font-family);
}
.entry-content q {
color: var(--entry-content-quote-color);
font-family: var(--entry-content-quote-font-family);
font-style: italic;
}
.entry-content q:before {
content: "“";
}
.entry-content q:after {
content: "”";
}
.entry-content pre {
padding: 5px;
overflow: auto;
overflow-wrap: initial;
border-width: 1px;
border-style: solid;
}
.entry-content pre,
.entry-content code {
color: var(--entry-content-code-color);
background: var(--entry-content-code-background);
border-color: var(--entry-content-code-border-color);
}
.entry-content table {
max-width: 100%;
}
.entry-content ul,
.entry-content ol {
margin-left: 30px;
margin-top: 15px;
margin-bottom: 15px;
}
.entry-content li ul,
.entry-content li ol {
margin-top: 0;
margin-bottom: 0;
}
.entry-content ul {
list-style-type: square;
}
.entry-content strong {
font-weight: 600;
}
.entry-content sub,
.entry-content sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
.entry-content sub {
bottom: -0.25em;
}
.entry-content sup {
top: -0.5em;
}
.entry-content abbr {
cursor: pointer;
text-decoration: none;
border-bottom: 1px dashed var(--entry-content-abbr-border-color);
}
details.entry-enclosures {
margin-top: 25px;
}
.entry-enclosures summary {
font-weight: 500;
font-size: 1.2em;
}
.entry-enclosure {
border: 1px dotted var(--entry-enclosure-border-color);
padding: 5px;
margin-top: 10px;
max-width: 100%;
}
.entry-enclosure-download {
font-size: 0.85em;
overflow-wrap: break-word;
}
.enclosure-video video,
.enclosure-image img {
max-width: 100%;
}
.confirm {
font-weight: 500;
color: #ed2d04;
}
.confirm a {
color: #ed2d04;
}
.loading {
font-style: italic;
}
.bookmarklet {
border: 1px dashed #ccc;
border-radius: 5px;
padding: 15px;
margin: 15px;
text-align: center;
}
.bookmarklet a {
font-weight: 600;
text-decoration: none;
font-size: 1.2em;
}
.disabled {
opacity: 20%;
}
Miniflux 简洁的外表下有着丰富的自定义功能和拓展,比如推送文章更新到 Telegram、使用 API Key 和各种 RSS 客户端集成、多用户支持……请尽情探索吧!