Migrate to gitbook (#357)

This PR facilities the migration from the old Writerside documentation
platform to Gitbook.

## motivation

Gitbook supports serving multiple versions of the documentation, e.g.
v1.12.1, v1.13.0, and master.
This commit is contained in:
Maximilian Dorninger
2026-01-05 21:39:18 +01:00
committed by GitHub
parent 940c1ea2d1
commit fd2befd2a1
53 changed files with 10 additions and 2145 deletions

View File

@@ -53,5 +53,5 @@ YOUR CONFIG HERE
```
- [ ] I understand, that without logs and/or screenshots and a detailed description of the problem, it is very hard to fix bugs.
- [ ] I have checked the [documentation](https://maxdorninger.github.io/MediaManager/introduction.html) for help.
- [ ] I have checked the [documentation](https://maximilian-dorninger.gitbook.io/mediamanager) for help.
- [ ] I have searched the [issues](https://github.com/maxdorninger/MediaManager/issues) for similar issues and found none.

View File

@@ -1,139 +0,0 @@
name: Build documentation
on:
push:
branches: [ "master" ]
paths:
- 'Writerside/**'
- '.github/workflows/build-docs.yml'
workflow_dispatch:
permissions:
contents: read
id-token: write
pages: write
env:
INSTANCE: 'Writerside/mm'
DOCKER_VERSION: '2025.04.8412'
ALGOLIA_APP_NAME: '5SXJTW5J6S'
ALGOLIA_INDEX_NAME: 'MediaManagerDocs'
CONFIG_JSON_PRODUCT: 'MM'
jobs:
build:
runs-on: ubuntu-latest
outputs:
algolia_artifact: ${{ steps.define-ids.outputs.algolia_artifact }}
artifact: ${{ steps.define-ids.outputs.artifact }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Define instance id and artifacts
id: define-ids
run: |
INSTANCE=${INSTANCE#*/}
INSTANCE_ID_UPPER=$(echo "$INSTANCE" | tr '[:lower:]' '[:upper:]')
ARTIFACT="webHelp${INSTANCE_ID_UPPER}2-all.zip"
ALGOLIA_ARTIFACT="algolia-indexes-${INSTANCE_ID_UPPER}.zip"
# Print the values
echo "INSTANCE_ID_UPPER: $INSTANCE_ID_UPPER"
echo "ARTIFACT: $ARTIFACT"
echo "ALGOLIA_ARTIFACT: $ALGOLIA_ARTIFACT"
# Set the environment variables and outputs
echo "INSTANCE_ID_UPPER=$INSTANCE_ID_UPPER" >> $GITHUB_ENV
echo "ARTIFACT=$ARTIFACT" >> $GITHUB_ENV
echo "ALGOLIA_ARTIFACT=$ALGOLIA_ARTIFACT" >> $GITHUB_ENV
echo "artifact=$ARTIFACT" >> $GITHUB_OUTPUT
echo "algolia_artifact=$ALGOLIA_ARTIFACT" >> $GITHUB_OUTPUT
- name: Build docs using Writerside Docker builder
uses: JetBrains/writerside-github-action@v4
with:
instance: ${{ env.INSTANCE }}
docker-version: ${{ env.DOCKER_VERSION }}
- name: Save artifact with build results
uses: actions/upload-artifact@v4
with:
name: docs
path: |
artifacts/${{ steps.define-ids.outputs.artifact }}
artifacts/report.json
artifacts/${{ steps.define-ids.outputs.algolia_artifact }}
retention-days: 7
test:
needs: build
runs-on: ubuntu-latest
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: docs
path: artifacts
- name: Test documentation
uses: JetBrains/writerside-checker-action@v1
with:
instance: ${{ env.INSTANCE }}
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
needs: [ build, test ]
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: docs
path: artifacts
- name: Unzip artifact
run: unzip -O UTF-8 -qq "artifacts/${{ needs.build.outputs.artifact }}" -d dir
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Package and upload Pages artifact
uses: actions/upload-pages-artifact@v3
with:
path: dir
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
publish-indexes:
needs: [ build, test, deploy ]
runs-on: ubuntu-latest
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
container:
image: registry.jetbrains.team/p/writerside/builder/algolia-publisher:2.0.32-3
steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: docs
path: artifacts
- name: Unzip Algolia artifact
run: unzip -O UTF-8 -qq "artifacts/${{ needs.build.outputs.algolia_artifact }}" -d algolia-indexes
- name: Update Algolia Index
run: |
if [ -z "${{ secrets.ALGOLIA_KEY }}" ]; then
echo "ALGOLIA_KEY secret is not set in GitHub Secrets"
exit 1
else
env "algolia-key=${{ secrets.ALGOLIA_KEY }}" java -jar /opt/builder/help-publication-agent.jar \
update-index \
--application-name ${{ env.ALGOLIA_APP_NAME }} \
--index-name ${{ env.ALGOLIA_INDEX_NAME }} \
--product ${{ env.CONFIG_JSON_PRODUCT }} \
--index-directory algolia-indexes/ \
2>&1 | tee algolia-update-index-log.txt
fi

View File

@@ -18,7 +18,7 @@ Generally, if you have any questions or need help on the implementation side of
just ask in the issue, or in a draft PR.
Also, see the contribution guide in the docs for information on how to setup the dev environment:
https://maxdorninger.github.io/MediaManager/developer-guide.html
https://maximilian-dorninger.gitbook.io/mediamanager
### For something that is a one or two line fix:

View File

@@ -1,6 +1,6 @@
<br />
<div align="center">
<a href="https://maxdorninger.github.io/MediaManager">
<a href="https://maximilian-dorninger.gitbook.io/mediamanager">
<img src="https://raw.githubusercontent.com/maxdorninger/MediaManager/refs/heads/master/Writerside/images/logo.svg" alt="Logo" width="260" height="260">
</a>
@@ -9,7 +9,7 @@
<p align="center">
Modern management system for your media library
<br />
<a href="https://maxdorninger.github.io/MediaManager/introduction.html"><strong>Explore the docs »</strong></a>
<a href="https://maximilian-dorninger.gitbook.io/mediamanager"><strong>Explore the docs »</strong></a>
<br />
<a href="https://github.com/maxdorninger/MediaManager/issues/new?labels=bug&template=bug_report.md">Report Bug</a>
&middot;
@@ -37,7 +37,7 @@ wget -O ./config/config.toml https://raw.githubusercontent.com/maxdorninger/Medi
docker compose up -d
```
### [View the docs for installation instructions and more](https://maxdorninger.github.io/MediaManager/configuration-overview.html#configuration-overview)
### [View the docs for installation instructions and more](https://maximilian-dorninger.gitbook.io/mediamanager)
## Support MediaManager
@@ -82,7 +82,7 @@ docker compose up -d
## Developer Quick Start
For the developer guide see the [Developer Guide](https://maxdorninger.github.io/MediaManager/developer-guide.html).
For the developer guide see the [Developer Guide](https://maximilian-dorninger.gitbook.io/mediamanager).
<!-- LICENSE -->

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE instance-profile
SYSTEM "https://resources.jetbrains.com/writerside/1.0/product-profile.dtd">
<instance-profile id="Writerside_libraries"
name="Writerside_libraries" is-library="true" start-page="notes.topic">
<toc-element topic="notes.topic"/>
</instance-profile>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE categories
SYSTEM "https://resources.jetbrains.com/writerside/1.0/categories.dtd">
<categories>
<category id="wrs" name="Writerside documentation" order="1"/>
</categories>

View File

@@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE buildprofiles SYSTEM "https://resources.jetbrains.com/writerside/1.0/build-profiles.dtd">
<buildprofiles xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/build-profiles.xsd">
<sitemap priority="0.35" change-frequency="monthly"/>
<variables>
</variables>
<build-profile instance="mm">
<variables>
<noindex-content>false</noindex-content>
<custom-favicons>favicon.ico</custom-favicons>
<header-logo>logo.svg</header-logo>
<download-title>Get MediaManager</download-title>
<download-page>https://maxdorninger.github.io/MediaManager/configuration-overview.html</download-page>
<showDownloadButton>true</showDownloadButton>
<product-web-url>https://github.com/maxdorninger/MediaManager</product-web-url>
<algolia-id>5SXJTW5J6S</algolia-id>
<algolia-api-key>ed89153df615ded46c214c9390539f3b</algolia-api-key>
<algolia-show-logo>true</algolia-show-logo>
<algolia-index>MediaManagerDocs</algolia-index>
</variables>
<footer>
<copyright>Maximilian Dorninger 2025</copyright>
<social type="github" href="https://github.com/maxdorninger/MediaManager" />
<social type="reddit" href="https://www.reddit.com/r/MediaManager/" />
<link href="https://github.com/maxdorninger/MediaManager/issues">Report an Issue</link>
<link href="https://github.com/maxdorninger">Maximilian Dorninger</link>
<link href="https://github.com/sponsors/maxdorninger">Donate</link>
</footer>
</build-profile>
</buildprofiles>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,158 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:svg="http://www.w3.org/2000/svg"
version="1.1"
id="svg1"
width="2000"
height="2000"
viewBox="0 0 2000 2000"
sodipodi:docname="logo2.svg"
inkscape:version="1.4.2 (f4327f4, 2025-05-13)"
xmlns="http://www.w3.org/2000/svg">
<defs
id="defs1">
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath1">
<path
d="M 0,1500 H 1500 V 0 H 0 Z"
id="path1"/>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath3">
<path
d="M 0,0 H 1500 V 1500 H 0 Z"
transform="matrix(1.3333333,0,0,-1.3333333,0,2000)"
id="path3"/>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath4">
<path
d="M -17.6886,1032.99 H 1106.27 V 238.53 H -17.6886 Z"
transform="translate(-319.61281,-1032.9941)"
id="path4"/>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath6">
<path
d="M 0,0 H 1500 V 1500 H 0 Z"
transform="matrix(1.3333333,0,0,-1.3333333,0,2000)"
id="path6"/>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath7">
<path
d="M 223.314,1226.85 H 1182.49 V 548.867 H 223.314 Z"
transform="translate(-894.64255,-548.86681)"
id="path7"/>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath9">
<path
d="M 0,0 H 1500 V 1500 H 0 Z"
transform="matrix(1.3333333,0,0,-1.3333333,0,2000)"
id="path9"/>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath10">
<path
d="M 301.561,1098.17 H 1517.73 V 238.53 H 301.561 Z"
transform="translate(-666.53282,-1098.1678)"
id="path10"/>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath12">
<path
d="M 0,0 H 1500 V 1500 H 0 Z"
transform="matrix(1.3333333,0,0,-1.3333333,0,2000)"
id="path12"/>
</clipPath>
</defs>
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="0.9075"
inkscape:cx="999.44904"
inkscape:cy="1000"
inkscape:window-width="3840"
inkscape:window-height="2054"
inkscape:window-x="3373"
inkscape:window-y="199"
inkscape:window-maximized="1"
inkscape:current-layer="g1">
<inkscape:page
x="0"
y="0"
inkscape:label="1"
id="page1"
width="2000"
height="2000"
margin="0"
bleed="0"/>
</sodipodi:namedview>
<g
id="g1"
inkscape:groupmode="layer"
inkscape:label="1">
<g
id="g2"
clip-path="url(#clipPath3)">
<path
d="M 0,0 H 1500 V 1500 H 0 Z"
style="fill:#9ed8f7;fill-opacity:0;fill-rule:nonzero;stroke:none"
transform="matrix(1.3333333,0,0,-1.3333333,0,2000)"
clip-path="url(#clipPath1)"
id="path2"/>
</g>
<g
opacity="0.720001"
id="g5"
clip-path="url(#clipPath6)">
<path
d="m 0,0 h 669.787 c 68.994,0 116.873,-68.746 92.95,-133.46 L 542.309,-729.728 c -14.382,-38.904 -51.472,-64.736 -92.95,-64.736 h -669.787 c -68.994,0 -116.873,68.746 -92.949,133.46 L -92.949,-64.736 C -78.567,-25.832 -41.478,0 0,0"
style="fill:#2842fc;fill-opacity:1;fill-rule:nonzero;stroke:none"
transform="matrix(1.3333333,0,0,-1.3333333,426.1504,622.67453)"
clip-path="url(#clipPath4)"
id="path5"/>
</g>
<g
opacity="0.720001"
id="g8"
clip-path="url(#clipPath9)">
<path
d="m 0,0 h -571.59 c -58.879,0 -99.738,58.667 -79.322,113.893 l 188.111,508.849 c 12.274,33.201 43.925,55.246 79.322,55.246 h 571.59 c 58.879,0 99.739,-58.667 79.322,-113.894 L 79.322,55.245 C 67.049,22.045 35.397,0 0,0"
style="fill:#ff5e00;fill-opacity:1;fill-rule:nonzero;stroke:none"
transform="matrix(1.3333333,0,0,-1.3333333,1192.8567,1268.1776)"
clip-path="url(#clipPath7)"
id="path8"/>
</g>
<g
opacity="0.75"
id="g11"
clip-path="url(#clipPath12)">
<path
d="m 0,0 h 724.733 c 74.654,0 126.46,-74.386 100.575,-144.408 L 586.797,-789.591 c -15.562,-42.096 -55.694,-70.047 -100.575,-70.047 h -724.733 c -74.654,0 -126.461,74.386 -100.574,144.409 l 238.511,645.182 C -85.013,-27.952 -44.88,0 0,0"
style="fill:#f20a4c;fill-opacity:1;fill-rule:nonzero;stroke:none"
transform="matrix(1.3333333,0,0,-1.3333333,888.7104,535.77627)"
clip-path="url(#clipPath10)"
id="path11"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 KiB

View File

@@ -1,35 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE instance-profile
SYSTEM "https://resources.jetbrains.com/writerside/1.0/product-profile.dtd">
<instance-profile id="mm"
name="MediaManager" start-page="Introduction.topic">
<toc-element topic="Introduction.topic"/>
<toc-element topic="configuration-overview.md"/>
<toc-element topic="User-Guide.md">
<toc-element topic="Importing-existing-media.md"/>
</toc-element>
<toc-element topic="Configuration.md">
<toc-element topic="configuration-backend.md"/>
<toc-element topic="authentication-setup.md"/>
<toc-element topic="database-configuration.md"/>
<toc-element topic="download-client-configuration.md"/>
<toc-element topic="Indexer-Settings.md"/>
<toc-element topic="Scoring-Rulesets.md"/>
<toc-element topic="Notifications.md"/>
<toc-element topic="Custom-Libraries.md"/>
<toc-element topic="Logging.md"/>
</toc-element>
<toc-element topic="Advanced-Features.md">
<toc-element topic="qBittorrent-Category.md"/>
<toc-element topic="url-prefix.md"/>
<toc-element topic="metadata-provider-configuration.md"/>
<toc-element topic="Custom-port.md"/>
<toc-element topic="Follow-symlinks-in-frontend-files.md"/>
</toc-element>
<toc-element topic="troubleshooting.md"/>
<toc-element topic="developer-guide.md"/>
<toc-element topic="api-reference.md"/>
<toc-element topic="Screenshots.md"/>
</instance-profile>

View File

@@ -1,45 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rules SYSTEM "https://resources.jetbrains.com/writerside/1.0/redirection-rules.dtd">
<rules>
<!-- format is as follows
<rule id="<unique id>">
<accepts>page.html</accepts>
</rule>
-->
<rule id="63c34f28">
<description>Created after removal of "Installation" from MediaManager</description>
<accepts>installation.html</accepts>
</rule>
<rule id="440cb672">
<description>Created after removal of "About MediaManager" from MediaManager</description>
<accepts>starter-topic.html</accepts>
</rule>
<rule id="666c8c31">
<description>Created after removal of "User Guide" from MediaManager</description>
<accepts>user-guide.html</accepts>
</rule>
<rule id="6822e619">
<description>Created after removal of "Quick Start Guide" from MediaManager</description>
<accepts>Quick-Start-Guide.html</accepts>
</rule>
<rule id="570cb9d1">
<description>Created after removal of "user-guide" from MediaManager</description>
<accepts>user-guide.html</accepts>
</rule>
<rule id="7cb7d801">
<description>Created after removal of "MetadataRelay" from MediaManager</description>
<accepts>MetadataRelay.html</accepts>
</rule>
<rule id="52a1fe89">
<description>Created after removal of "Frontend" from MediaManager</description>
<accepts>configuration-frontend.html</accepts>
</rule>
<rule id="6242074">
<description>Created after removal of "Reverse Proxy" from MediaManager</description>
<accepts>Reverse-Proxy.html</accepts>
</rule>
<rule id="7683f141">
<description>Created after removal of "Other Settings" from MediaManager</description>
<accepts>Other-Settings.html</accepts>
</rule>
</rules>

View File

@@ -1,4 +0,0 @@
# Advanced Features
The features in this section are not required to run MediaManager and serve their purpose in very specific environments,
but they can enhance your experience and provide additional functionality.

View File

@@ -1,75 +0,0 @@
# Configuration
MediaManager uses a TOML configuration file (`config.toml`) for all backend settings.
This centralized configuration approach makes it easier to manage, backup, and share your MediaManager setup.
Frontend settings are configured through environment variables in your `docker-compose.yaml` file.
## Configuration File Location
<warning>Note that MediaManager may need to be restarted for changes in the config file to take effect.</warning>
Your `config.toml` file should be in the directory that's mounted to `/app/config/config.toml` inside the container:
```yaml
volumes:
- ./config:/app/config
```
Though you can change the location of the configuration file's directory by setting the `CONFIG_DIR` env variable to
another path,
e.g. `/etc/mediamanager/`.
## Configuration Sections
The configuration is organized into the following sections:
- `[misc]` - General settings
- `[database]` - Database settings
- `[auth]` - Authentication settings
- `[notifications]` - Notification settings (Email, Gotify, Ntfy, Pushover)
- `[torrents]` - Download client settings (qBittorrent, Transmission, SABnzbd)
- `[indexers]` - Indexer settings (Prowlarr and Jackett )
- `[metadata]` - TMDB and TVDB settings
## Configuring Secrets
For sensitive information like API keys, passwords, and secrets, you _should_ use environment variables.
You can actually set every configuration value through environment variables.
For example, to set the `token_secret` value for authentication, with a .toml file you would use:
```toml
[auth]
token_secret = "your_super_secret_key_here"
```
But you can also set it through an environment variable:
```
MEDIAMANAGER_AUTH__TOKEN_SECRET = "your_super_secret_key_here"
```
or another example with the OIDC client secret:
```toml
[auth]
...
[auth.openid_connect]
client_secret = "your_client_secret_from_provider"
```
env variable:
```
MEDIAMANAGER_AUTH__OPENID_CONNECT__CLIENT_SECRET = "your_client_secret_from_provider"
```
So for every config "level", you basically have to take the name of the value and prepend it with the section names in
uppercase with 2 underscores as delimiters and `MEDIAMANAGER_` as the prefix.
<warning>Note that not every env variable starts with <code>MEDIAMANAGER_</code>,
this prefix only applies to env variables which replace/overwrite values in the config file.
Variables like the <code>CONFIG_DIR</code> env variable must not be prefixed.
</warning>

View File

@@ -1,54 +0,0 @@
# Custom Libraries
MediaManager supports custom libraries, allowing you to add multiple folders for your movies and TV series. This feature is useful if you organize your media into different directories. For example, you might have separate folders for "Action" movies and "Comedy" movies, or "Live Action" TV shows and "Animated" TV shows.
## Configuration
Custom libraries are configured in the `mis` section in the `config.toml` file. You can add as many libraries as you need.
<note>
You are not limited to `/data/tv` or `/data/movies`, you can choose the entire path freely!
</note>
### Movie Libraries
To add custom movie libraries, you need to add a `[[misc.movie_libraries]]` section for each library. Each library requires a `name` and a `path`.
Here is an example of how to configure two movie libraries:
```toml
[misc]
# ... other misc settings
[[misc.movie_libraries]]
name = "Action"
path = "/data/movies/action"
[[misc.movie_libraries]]
name = "Comedy"
path = "/data/movies/comedy"
```
In this example, MediaManager will scan both `/data/movies/action` and `/data/movies/comedy` for movies.
### TV Show Libraries
Similarly, to add custom TV show libraries, you need to add a `[[misc.tv_libraries]]` section for each library. Each library requires a `name` and a `path`.
Here is an example of how to configure two TV show libraries:
```toml
[misc]
# ... other misc settings
[[misc.tv_libraries]]
name = "Live Action"
path = "/data/tv/live-action"
[[misc.tv_libraries]]
name = "Animation"
path = "/data/tv/animation"
```

View File

@@ -1,4 +0,0 @@
# Custom port
With the env variable `PORT`, you can change the port that MediaManager listens on. The default port is `8000`.
Note that this setting only works if you are using the Docker Image.

View File

@@ -1,6 +0,0 @@
# Follow symlinks in frontend files
MediaManager can be configured to follow symlinks when serving frontend files. This is useful if you have a setup where
your frontend files are stored in a different location, and you want to symlink them into the MediaManager frontend directory.
To enable this feature, set the `FRONTEND_FOLLOW_SYMLINKS` environment variable to `true`.

View File

@@ -1,78 +0,0 @@
# Importing existing media
In order for MediaManager to be able to import existing media (e.g. downloaded by Sonarr or Radarr)
2 conditions have to be met:
1. The folder's name must not start with a dot.
2. The media must be in the root tv/movie library
Here is an example, using these rules:
```
/
└── data/
├── tv/
│ ├── Rick and Morty # WILL be imported
│ ├── Stranger Things (2016) {tvdb_12345} [x265] # WILL be imported
│ ├── Breaking Bad (2008) [tmdbid-1396] # WILL be imported
│ ├── .The Office (2013) # WILL NOT
│ │
│ └── my-custom-library/
│ └── The Simpsons # WILL NOT be imported
└── movie/
└── Oppenheimer (2023) # WILL be imported
```
Is your folder structure in the correct format, you can start importing. For this,
you just need to login as an administrator and go to the TV/movie dashboard.
<note>
When importing, no files will be deleted, moved or copied! Instead, they will be hard linked.
</note>
After importing, MediaManager will automatically prefix the old root TV show/movie folders with a dot,
in order to mark them as 'imported'.
So after importing, the directory would look like this (using the above directory structure):
```
/
└── data/
├── tv/
│ ├── .Rick and Morty # RENAMED
│ ├── Rick and Morty (2013) [tmdbid-60625] # IMPORTED
│ │
│ ├── .Stranger Things (2016) {tvdb_12345} [x265]
│ ├── Stranger Things (2016) [tmdbid-66732] # IMPORTED
│ │
│ ├── .The Office (2013) # IGNORED
│ │
│ ├── .Breaking Bad (2008) [tmdbid-1396]
│ ├── Breaking Bad (2008) [tmdbid-1396] # IMPORTED
│ │
│ └── my-custom-library/
│ └── The Simpsons # IGNORED
└── movie/
├── .Oppenheimer (2023)
└── Oppenheimer (2023) [tmdbid-872585] # IMPORTED
```
## More criteria for importing
These are the criteria specifically for the files themselves:
- movie folders (e.g. `Oppenheimer (2023)`) must not contain more or less than one video file (an .mp4 or .mkv, etc.
file)
- the specific structure of season folders or episode folders or naming of them does not matter
- Episode files (video and subtitle files) must contain the season and episode number in their name, e.g. `S01E01.mp4`
or `S03E07 Rick and Morty.mkv`
<tip>
In any usual Sonarr/Radarr setup these file criteria should already be met by default.
</tip>
## Miscellaneous information
- make MediaManager ignore directories by prefixing them with a dot
- after importing, especially TV shows, manually check if all files are in the right place
- MediaManager outputs in the logs if an episode/movie could not be imported

View File

@@ -1,74 +0,0 @@
# Indexers
Indexer settings are configured in the `[indexers]` section of your `config.toml` file. MediaManager supports both
Prowlarr and Jackett as indexer providers.
## Prowlarr (`[indexers.prowlarr]`)
- `enabled`
Set to `true` to enable Prowlarr. Default is `false`.
- `url`
Base URL of your Prowlarr instance.
- `api_key`
API key for Prowlarr. You can find this in Prowlarr's settings under General.
- `timeout_seconds`
Timeout in seconds for requests to Prowlarr. Default is `60` seconds.
Symptoms of timeouts are typically no search results (*"No torrents found!"*) in conjunction with logs like these:
```
DEBUG - media_manager.indexer.utils -
follow_redirects_to_final_torrent_url():
An error occurred during the request for <some-url>:
HTTPConnectionPool(host='<some-host>', port=<some-port>):
Read timed out. (read timeout=10)
```
## Jackett (`[indexers.jackett]`)
- `enabled`
Set to `true` to enable Jackett. Default is `false`.
- `url`
Base URL of your Jackett instance.
- `api_key`
API key for Jackett. You can find this in Jackett's dashboard.
- `indexers`
List of indexer names to use with Jackett. You can specify which indexers Jackett should search through.
- `timeout_seconds`
Refer to the Prowlarr section for details.
## Example Configuration
Here's a complete example of the indexers section in your `config.toml`:
```toml
[indexers]
[indexers.prowlarr]
enabled = true
url = "http://prowlarr:9696"
api_key = "your_prowlarr_api_key"
timeout_seconds = 60
[indexers.jackett]
enabled = false
url = "http://jackett:9117"
api_key = "your_jackett_api_key"
indexers = ["1337x", "rarbg"]
timeout_seconds = 60
```

View File

@@ -1,74 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE topic
SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
title="Introduction" id="Introduction">
<section-starting-page>
<title>MediaManager</title>
<description>
MediaManager is modern software to manage your TV and movie library. It is designed to be a replacement for Sonarr,
Radarr, Overseer, Unpackerr and Jellyseer.
It supports TVDB and TMDB for metadata, supports OIDC and OAuth 2.0 for authentication and supports Prowlarr and
Jackett.
</description>
<spotlight>
<card href="configuration-overview.md" badge="start"
summary="Installation Guide"/>
<card href="Configuration.md" badge="settings"
summary="Configuration Overview"/>
</spotlight>
<primary>
<title>Other Topics</title>
<card href="developer-guide.md" badge="development"
summary="Developer Guide"/>
<card href="troubleshooting.md" badge="support"
summary="Troubleshooting Guide"/>
<card href="Advanced-Features.md"
summary="Advanced Features"/>
<card href="Screenshots.md"
summary="Screenshots"/>
</primary>
<secondary>
<title>Support MediaManager &amp; Maximilian Dorninger</title>
<card href="https://github.com/sponsors/maxdorninger"
summary="Sponsor me on Github Sponsors :)"/>
<card href="https://buymeacoffee.com/maxdorninger"
summary="Buy me a coffee :)"/>
</secondary>
<misc>
<cards narrow="true">
<title>MediaManager Sponsors</title>
<card href="https://github.com/ldrrp"
summary="ldrrp" image="https://github.com/ldrrp.png" />
<card href="https://fosstodon.org/@aljazmerzen"
summary="aljamerzen" image="https://cdn.fosstodon.org/accounts/avatars/107/626/197/378/907/137/original/e93602705171fd0a.jpg"/>
<card href="https://github.com/SeimusS"
summary="SeimusS" image="https://github.com/SeimusS.png" />
<card href="https://github.com/HadrienKerlero"
summary="HadrienKerlero" image="https://github.com/HadrienKerlero.png" />
<card href="https://github.com/brandon-dacrib"
summary="brandon-dacrib" image="https://github.com/brandon-dacrib.png" />
<card href="https://github.com/keyxmakerx"
summary="keyxmakerx" image="https://github.com/keyxmakerx.png" />
<card href="https://github.com/LITUATUI"
summary="LITUATUI" image="https://github.com/LITUATUI.png" />
<card href="https://buymeacoffee.com/maxdorninger"
summary="Nicolas" image="https://cdn.buymeacoffee.com/uploads/profile_pictures/default/v2/B6CDBD/NI.png" />
<card href="https://buymeacoffee.com/maxdorninger"
summary="Josh" image="https://cdn.buymeacoffee.com/uploads/profile_pictures/default/v2/DEBBB9/JO.png" />
<card href="https://buymeacoffee.com/maxdorninger"
summary="PuppiestDoggo" image="https://cdn.buymeacoffee.com/uploads/profile_pictures/2025/11/2VeQ8sTGPhj4tiLy.jpg" />
<card href="https://github.com/seferino-fernandez"
summary="Seferino" image="https://avatars.githubusercontent.com/u/5546622" />
</cards>
<links>
<group>
<title>MediaManager Repository</title>
<a href="https://github.com/maxdorninger/MediaManager"
summary="MediaManager Repository"/>
</group>
</links>
</misc>
</section-starting-page>
</topic>

View File

@@ -1,17 +0,0 @@
# Logging
MediaManager automatically logs events and errors to help with troubleshooting and monitoring. These logs are emitted to
the console (stdout) by default, and to a json-formatted log file.
## Configuring Logging
The location of the log file can be configured with the `LOG_FILE` environment variable. By default, the log file is
located at
`/app/config/media_manager.log`. When changing the log file location, ensure that the directory exists, is writable by the
MediaManager container and that it is a full path.
With the `MEDIAMANAGER_LOG_LEVEL` environment variable, you can set the logging level. The available levels are:
- `DEBUG` - Detailed information, typically of interest only when diagnosing problems.
- `INFO` - The default level, for general operational entries about what's going on inside the application.
- `WARNING`
- `ERROR`

View File

@@ -1,121 +0,0 @@
# Notifications
These settings are configured in the `[notifications]` section of your `config.toml` file.
### SMTP Configuration (`[notifications.smtp_config]`)
For sending emails, MediaManager uses the SMTP protocol. You can use any SMTP server, like Gmail or SMTP2GO.
- `smtp_host`
Hostname of the SMTP server.
- `smtp_port`
Port of the SMTP server.
- `smtp_user`
Username for the SMTP server.
- `smtp_password`
Password or app password for the SMTP server.
- `from_email`
Email address from which emails will be sent.
- `use_tls`
Set to `true` to use TLS for the SMTP connection. Default is `true`.
### Email Notifications (`[notifications.email_notifications]`)
- `enabled`
Set to `true` to enable email notifications. Default is `false`.
- `emails`
List of email addresses to send notifications to.
### Gotify Notifications (`[notifications.gotify]`)
- `enabled`
Set to `true` to enable Gotify notifications. Default is `false`.
- `api_key`
API key for Gotify.
- `url`
Base URL of your Gotify instance. Note the lack of a trailing slash.
### Ntfy Notifications (`[notifications.ntfy]`)
- `enabled`
Set to `true` to enable Ntfy notifications. Default is `false`.
- `url`
URL of your ntfy instance plus the topic.
### Pushover Notifications (`[notifications.pushover]`)
- `enabled`
Set to `true` to enable Pushover notifications. Default is `false`.
- `api_key`
API key for Pushover.
- `user`
User key for Pushover.
## Example Configuration
Here's a complete example of the notifications section in your `config.toml`:
```toml
[notifications]
# SMTP settings for email notifications and password resets
[notifications.smtp_config]
smtp_host = "smtp.gmail.com"
smtp_port = 587
smtp_user = "your-email@gmail.com"
smtp_password = "your-app-password"
from_email = "mediamanager@example.com"
use_tls = true
# Email notification settings
[notifications.email_notifications]
enabled = true
emails = ["admin@example.com", "notifications@example.com"]
# Gotify notification settings
[notifications.gotify]
enabled = true
api_key = "your_gotify_api_key"
url = "https://gotify.example.com"
# Ntfy notification settings
[notifications.ntfy]
enabled = false
url = "https://ntfy.sh/your-private-topic"
# Pushover notification settings
[notifications.pushover]
enabled = false
api_key = "your_pushover_api_key"
user = "your_pushover_user_key"
```
<note>
You can enable multiple notification methods simultaneously. For example, you could have both email and Gotify notifications enabled at the same time.
</note>

View File

@@ -1,141 +0,0 @@
# Scoring Rulesets
Scoring rulesets in MediaManager allow you to flexibly control which releases are preferred or avoided when searching
for media. Each ruleset is a collection of scoring rules that can be assigned to one or more libraries. When
MediaManager evaluates releases, it applies the relevant ruleset(s) to adjust the score of each result, influencing
which releases are selected for download.
## How Rulesets Work
- **Rulesets** are defined in the configuration and contain a list of rule names and the libraries they apply to.
- **Scoring rules** can target keywords in release titles or specific indexer flags.
- When searching for a release, MediaManager checks which library the media belongs to and applies the corresponding
ruleset.
## Rules
Rules define how MediaManager scores releases based on their titles or indexer flags. You can create rules that:
- Prefer releases with specific codecs (e.g., H.265 over H.264).
- Avoid releases with certain keywords (e.g., "CAM", "TS", "Nuked").
- Reject releases that do not meet certain criteria (e.g., non-freeleech releases).
- and more.
<note>
The keywords and flags are compared case-insensitively.
</note>
### Title Rules
Title rules allow you to adjust the score of a release based on the presence (or absence) of specific keywords in the release title. This is useful for preferring or avoiding certain encodings, sources, or other characteristics that are typically included in release names.
Each title rule consists of:
- `name`: A unique identifier for the rule.
- `keywords`: A list of keywords to search for in the release title.
- `score_modifier`: The amount to add or subtract from the score if a keyword matches.
- `negate`: If true, the rule applies when none of the keywords are present.
#### Examples for Title Rules
```toml
[[indexers.title_scoring_rules]]
name = "prefer_h265"
keywords = ["h265", "hevc", "x265"]
score_modifier = 100
negate = false
[[indexers.title_scoring_rules]]
name = "avoid_cam"
keywords = ["cam", "ts"]
score_modifier = -10000
negate = false
```
- The first rule increases the score for releases containing "h265", "hevc", or "x265".
- The second rule heavily penalizes releases containing "cam" or "ts".
If `negate` is set to `true`, the `score_modifier` is applied only if none of the keywords are found in the title.
### Indexer Flag Rules
Indexer flag rules adjust the score based on flags provided by the indexer (such as `freeleech`, `nuked`, etc). These flags are often used to indicate special properties or warnings about a release.
Each indexer flag rule consists of:
- `name`: A unique identifier for the rule.
- `flags`: A list of indexer flags to match.
- `score_modifier`: The amount to add or subtract from the score if a flag matches.
- `negate`: If true, the rule applies when none of the flags are present.
#### Examples for Indexer Flag Rules
```toml
[[indexers.indexer_flag_scoring_rules]]
name = "reject_non_freeleech"
flags = ["freeleech", "freeleech75"]
score_modifier = -10000
negate = true
[[indexers.indexer_flag_scoring_rules]]
name = "reject_nuked"
flags = ["nuked"]
score_modifier = -10000
negate = false
```
- The first rule penalizes releases that do **not** have the "freeleech" or "freeleech75" flag.
- The second rule penalizes releases that are marked as "nuked".
If `negate` is set to `true`, the `score_modifier` is applied only if none of the flags are present on the release.
## Example
```toml
[[indexers.scoring_rule_sets]]
name = "default"
libraries = ["ALL_TV", "ALL_MOVIES"]
rule_names = ["prefer_h265", "avoid_cam", "reject_nuked"]
[[indexers.scoring_rule_sets]]
name = "strict_quality"
libraries = ["ALL_MOVIES"]
rule_names = ["prefer_h265", "avoid_cam", "reject_non_freeleech"]
```
## Libraries
The libraries that are mentioned in the preceding example are explained in greater detail in
the [Library config section](Custom-Libraries.md).
### Special Libraries
You can use special library names in your rulesets:
- `ALL_TV`: Applies the ruleset to all TV libraries.
- `ALL_MOVIES`: Applies the ruleset to all movie libraries.
- `Default`: Applies the ruleset to all media that is not part of a custom library.
This allows you to set global rules for all TV or movie content, or provide fallback rules for uncategorized media.
<tip>
You don't need to create lots of libraries with different directories, multiple libraries can share the same directory.
You can set multiple (unlimited) libraries to the default directory `/data/movies` or `/data/tv` and use different
rulesets with them.
</tip>
## Relation to Sonarr/Radarr Profiles
MediaManager's scoring rules and rulesets system is an alternative to Sonarr's Quality, Custom, and Release Profiles. I
designed this system with the goal of being more intuitive and flexible, since I noticed that a lot of people are
overwhelmed by Sonarrs/Radarrs system.
- **Quality Profiles**: Use scoring rules to prefer or avoid certain codecs, resolutions, or other quality indicators.
- **Custom/Release Profiles**: Use title or flag-based rules to match or exclude releases based on keywords or indexer
flags.
This approach provides a powerful and transparent way to fine-tune your automation.

View File

@@ -1,17 +0,0 @@
# Screenshots
<note> MediaManager also supports darkmode!</note>
![screenshot-dashboard.png](screenshot-dashboard.png)
![screenshot-tv-dashboard.png](screenshot-tv-dashboard.png)
![screenshot-download-season.png](screenshot-download-season.png)
![screenshot-request-season.png](screenshot-request-season.png)
![screenshot-tv-torrents.png](screenshot-tv-torrents.png)
![screenshot-settings.png](screenshot-settings.png)
![screenshot-login.png](screenshot-login.png)

View File

@@ -1,51 +0,0 @@
# Usage
If you are coming from Radarr or Sonarr you will find that MediaManager does things a bit differently.
Instead of completely automatically downloading and managing your media, MediaManager focuses on providing an
easy-to-use interface to guide you through the process of finding and downloading media. Advanced features like multiple
qualities of a show/movie necessitate such a paradigm shift.
__So here is a quick step-by-step guide to get you started:__
<tabs>
<tab id="as-a-user" title="as a user">
<procedure title="Downloading/Requesting a show" id="request-show-user">
<step>Add a show on the "Add Show" page</step>
<step>After adding the show you will be redirected to the show's page.</step>
<step>There you can click the "Request Season" button.</step>
<step>Select one or more seasons that you want to download</step>
<step>Then select the "Min Quality", this will be the minimum resolution of the content to download.</step>
<step>Then select the "Wanted Quality", this will be the <strong>maximum</strong> resolution of the content to download.</step>
<step>Finally click Submit request, though this is not the last step!</step>
<step>An administrator first has to approve your request for download, only then will the requested content be downloaded.</step>
<p>Congratulation! You've downloaded a show.</p>
</procedure>
</tab>
<tab id="as-an-admin" title="as an admin">
<procedure title="Requesting a show" id="request-show-admin">
<step>Add a show on the "Add Show" page</step>
<step>After adding the show you will be redirected to the show's page.</step>
<step>There you can click the "Request Season" button.</step>
<step>Select one or more seasons that you want to download</step>
<step>Then select the "Min Quality", this will be the minimum resolution of the content to download.</step>
<step>Then select the "Wanted Quality", this will be the <strong>maximum</strong> resolution of the content to download.</step>
<step>Finally click Submit request, as you are an admin, your request will be automatically approved.</step>
<p>Congratulation! You've downloaded a show.</p>
</procedure>
<procedure title="Downloading a show" id="download-show-admin">
<p>You can only directly download a show if you are an admin!</p>
<step>Go to a show's page.</step>
<step>There you can click the "Download Season" button.</step>
<step>Enter the season's number that you want to download</step>
<step>Then optionally select the "File Path Suffix", <strong>it needs to be unique per season per show!</strong> </step>
<step>Then click "Download" on a torrent that you want to download.</step>
<p>Congratulation! You've downloaded a show.</p>
</procedure>
<procedure title="Managing requests" id="approving-request-admin">
<p>Users need their requests to be approved by an admin, to do this follow these steps:</p>
<step>Go to the "Requests" page.</step>
<step>There you can approve, delete or modify a user's request.</step>
</procedure>
</tab>
</tabs>

View File

@@ -1,8 +0,0 @@
# API Reference
Media Manager's backend is built with FastAPI, which automatically generates interactive API documentation.
* **Swagger UI** (typically available at `http://localhost:8000/docs`).
* **ReDoc** (typically available at `http://localhost:8000/redoc`).

View File

@@ -1,95 +0,0 @@
# Authentication
MediaManager supports multiple authentication methods. Email/password authentication is the default, but you can also
enable OpenID Connect (OAuth 2.0) for integration with external identity providers.
All authentication settings are configured in the `[auth]` section of your `config.toml` file.
## General Authentication Settings (`[auth]`)
- `token_secret`
Strong secret key for signing JWTs (create with `openssl rand -hex 32`). This is a required field.
- `session_lifetime`
Lifetime of user sessions in seconds. Default is `86400` (1 day).
- `admin_emails`
A list of email addresses for administrator accounts. This is a required field.
- `email_password_resets`
Toggle for enabling password resets via email. If users request a password reset because they forgot their password,
they will be sent an email with a link to reset it. Default is `false`.
<note>
To use email password resets, you must also configure SMTP settings in the <code>[notifications.smtp_config]</code> section.
</note>
<include from="notes.topic" element-id="auth-admin-emails"></include>
## OpenID Connect Settings (`[auth.openid_connect]`)
OpenID Connect allows you to integrate with external identity providers like Google, Microsoft Azure AD, Keycloak, or
any other OIDC-compliant provider.
- `enabled`
Set to `true` to enable OpenID Connect authentication. Default is `false`.
- `client_id`
Client ID provided by your OpenID Connect provider.
- `client_secret`
Client secret provided by your OpenID Connect provider.
- `configuration_endpoint`
OpenID Connect configuration endpoint URL. Note the lack of a trailing slash - this is important. It usually ends with
`.well-known/openid-configuration`.
- `name`
Display name for the OpenID Connect provider that will be shown on the login page.
### Configuration for your OpenID Connect Provider
#### Redirect URI
The OpenID server will likely require a redirect URI. This URL will usually look something like this:
```
{MEDIAMANAGER_URL}/api/v1/auth/oauth/callback
```
<warning>It is very important that you set the correct callback URI, otherwise it won't work!</warning>
#### Authentik Example {collapsible="true"}
Here is an example configuration for the OpenID Connect provider for Authentik.
![authentik-redirect-url-example](authentik-redirect-url-example.png)
## Example Configuration
Here's a complete example of the authentication section in your `config.toml`:
```toml
[auth]
token_secret = "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6"
session_lifetime = 604800 # 1 week
admin_emails = ["admin@example.com", "manager@example.com"]
email_password_resets = true
[auth.openid_connect]
enabled = true
client_id = "mediamanager-client"
client_secret = "your-secret-key-here"
configuration_endpoint = "https://auth.example.com/.well-known/openid-configuration"
name = "Authentik"
```

View File

@@ -1,48 +0,0 @@
# Backend
These settings configure the core backend application through the `config.toml` file. All backend configuration is now
centralized in this TOML file instead of environment variables.
## General Settings (`[misc]`)
- `frontend_url`
The URL the frontend will be accessed from. This is a required field and must not include a trailing slash. The default
path is `http://localhost:8000`.
E.g. if you are accessing MediaManager at `http://example.com/media` where `/media` is the base path, set this to: `http://example.com/media`.
If you are accessing MediaManager at the root of a domain, e.g. `https://mediamanager.example.com`, set this to `https://mediamanager.example.com`.
Make sure to change this to the URL you will use to access the application in your browser.
<tip>
Note that this doesn't affect where the server binds, nor does it affect the base URL prefix. See the page on <a href="url-prefix.md"><code>BASE_PATH</code></a> for information on how to configure a prefix.
</tip>
- `cors_urls`
A list of origins you are going to access the API from. Note the lack of trailing slashes.
- `development`
Set to `true` to enable development mode. Default is `false`.
## Example Configuration
Here's a complete example of the general settings section in your `config.toml`:
```toml
[misc]
# REQUIRED: Change this to match your actual frontend domain.
frontend_url = "http://mediamanager.dev"
cors_urls = ["http://localhost:8000"]
# Optional: Development mode (set to true for debugging)
development = false
```
<note>
The <code>frontend_url</code> is the most important settings to configure correctly. Make sure it matches your actual deployment URLs.
</note>

View File

@@ -1,64 +0,0 @@
# Installation Guide
The recommended way to install and run Media Manager is using Docker and Docker Compose.
## Prerequisites
* Ensure Docker and Docker Compose are installed on your system.
* If you plan to use OAuth 2.0 / OpenID Connect for authentication, you will need an account and client credentials
from an OpenID provider (e.g., Authentik, Pocket ID).
## Setup
* Download the `docker-compose.yaml` from the MediaManager repo with the following command:
```bash
wget -O docker-compose.yaml https://raw.githubusercontent.com/maxdorninger/MediaManager/refs/heads/master/docker-compose.yaml
mkdir config
wget -O ./config/config.toml https://raw.githubusercontent.com/maxdorninger/MediaManager/refs/heads/master/config.example.toml
# you probably need to edit the config.toml file in the ./config directory, for more help see the documentation
docker compose up -d
```
* Upon first run, MediaManager will create a default `config.toml` file in the `./config` directory.
* You can edit this file to configure MediaManager according to your needs.
* Upon first run, MediaManager will also create a default admin user with the email, it's recommended to change the
password of this user after the first login. The credentials of the default admin user will be printed in the logs of
the container.
* For more information on the available configuration options, see the [Configuration section](Configuration.md) of the
documentation.
<include from="notes.topic" element-id="auth-admin-emails"></include>
## MediaManager and MetadataRelay Docker Images
MediaManager is available as a Docker image on both Red Hat Quay.io and GitHub Container Registry (GHCR):
- `quay.io/maxdorninger/mediamanager`
- `ghcr.io/maxdorninger/mediamanager/mediamanager`
MetadataRelay Images are also available on both registries:
- `quay.io/maxdorninger/metadata_relay`
- `ghcr.io/maxdorninger/mediamanager/metadata_relay`
From v1.12.1 onwards, both MediaManager and MetadataRelay images are available on both Quay.io and GHCR.
The reason for the switch to Quay.io as the primary image registry is due
to [GHCR's continued slow performance](https://github.com/orgs/community/discussions/173607).
<note>
You can use either the Quay.io or GHCR images interchangeably,
as they are built from the same source and the tags are the same across both registries.
</note>
### Tags
Both registries support the following tags:
- `latest`: Points to the latest stable release.
- `master`: Points to the latest commit on the master branch (may be unstable).
- `X.Y.Z`: Specific version tags (e.g., `1.12.0`).
- `X.Y`: Points to the latest release in the X.Y series (e.g., `1.12`).
- `X`: Points to the latest release in the X series (e.g., `1`).
- `pr-<number>`: Points to the latest commit in the specified pull request (e.g., `pr-67`).

View File

@@ -1 +0,0 @@
# Contributing

View File

@@ -1,42 +0,0 @@
# Database
Database settings are configured in the `[database]` section of your `config.toml` file. MediaManager uses PostgreSQL as its database backend.
## Database Settings (`[database]`)
- `host`
Hostname or IP of the PostgreSQL server. Default is `localhost`.
- `port`
Port number of the PostgreSQL server. Default is `5432`.
- `user`
Username for PostgreSQL connection. Default is `MediaManager`.
- `password`
Password for the PostgreSQL user. Default is `MediaManager`.
- `dbname`
Name of the PostgreSQL database. Default is `MediaManager`.
## Example Configuration
Here's a complete example of the database section in your `config.toml`:
```toml
[database]
host = "db"
port = 5432
user = "MediaManager"
password = "your_secure_password"
dbname = "MediaManager"
```
<tip>
In docker-compose deployments the containers name is simultaneously its hostname, so you can use "db" or "postgres" as host.
</tip>

View File

@@ -1,349 +0,0 @@
# Developer Guide
This section is for those who want to contribute to Media Manager or understand its internals.
## Source Code directory structure
- `media_manager/`: Backend FastAPI application
- `web/`: Frontend SvelteKit application
- `Writerside/`: Documentation
- `metadata_relay/`: Metadata relay service, also FastAPI
## Special Dev Configuration
### Environment Variables
MediaManager uses various environment variables for configuration. In the Docker development setup (
`docker-compose.dev.yaml`), most of these are automatically configured for you.
#### Backend Variables
- `BASE_PATH`: Sets the base path for the app (e.g., for subdirectory deployments)
- `PUBLIC_VERSION`: Version string displayed in `/api/v1/health` endpoint
- `FRONTEND_FILES_DIR`: Directory for built frontend files (e.g., `/app/web/build` in Docker)
- `MEDIAMANAGER_MISC__DEVELOPMENT`: When set to `TRUE`, enables FastAPI hot-reloading in Docker
#### Frontend Variables
- `PUBLIC_API_URL`: API URL for backend communication (automatically configured via Vite proxy in Docker)
- `PUBLIC_VERSION`: Version string displayed in the frontend UI
- `BASE_PATH`: Base path for frontend routing (matches backend BASE_PATH)
#### Docker Development Variables
- `DISABLE_FRONTEND_MOUNT`: When `TRUE`, disables mounting built frontend files (allows separate frontend container)
<tip>
This is automatically set in <code>docker-compose.dev.yaml</code> to enable the separate frontend development container
</tip>
#### Configuration Files
- Backend: `res/config/config.toml` (created from `config.dev.toml`)
- Frontend: `web/.env` (created from `.env.example`)
## Contributing
- Consider opening an issue to discuss changes before starting work
## Setting up the Development Environment
I use IntellijIdea with the Pycharm and Webstorm plugins to develop this, but this guide should also work with VSCode.
Normally I'd recommend Intellij, but unfortunately only Intellij Ultimate has support for FastAPI and some other
features.
### Recommended VSCode Plugins
- Python
- Svelte for VSCode
- and probably more, but I don't use VSCode myself, so I can't recommend anymore.
### Recommended Intellij/Pycharm Plugins
- Python
- Svelte
- Pydantic
- Ruff
- VirtualKit
- Writerside (for writing documentation)
### Recommended Development Workflow
The **recommended way** to develop MediaManager is using the fully Dockerized setup with `docker-compose.dev.yaml`.
This ensures you're working in the same environment as production and makes it easy for new contributors to get started
without installing Python, Node.js, or other dependencies locally.
The development environment includes:
- **Backend (FastAPI)** with automatic hot-reloading for Python code changes
- **Frontend (SvelteKit/Vite)** with Hot Module Replacement (HMR) for instant updates
- **Database (PostgreSQL)** pre-configured and ready to use
#### What supports hot reloading and what does not
- Python code changes (.py files), Frontend code changes (.svelte, .ts, .css) and configuration changes (config.toml)
reload automatically.
- Changing the backend dependencies (pyproject.toml) requires rebuilding:
`docker compose -f docker-compose.dev.yaml build mediamanager`
- Changing the frontend dependencies (package.json) requires restarting the frontend container:
`docker compose -f docker-compose.dev.yaml restart frontend`
- Database migrations: Automatically run on backend container startup
This approach eliminates the need for container restarts during normal development and provides the best developer
experience with instant feedback for code changes.
#### How the Frontend Connects to the Backend
In the Docker development setup, the frontend and backend communicate through Vite's proxy configuration:
- **Frontend runs on**: `http://localhost:5173` (exposed from Docker)
- **Backend runs on**: `http://mediamanager:8000` (Docker internal network)
- **Vite proxy**: Automatically forwards all `/api/*` requests from frontend to backend
This means when your browser makes a request to `http://localhost:5173/api/v1/tv/shows`, Vite automatically proxies it
to `http://mediamanager:8000/api/v1/tv/shows`. The `PUBLIC_API_URL` environment variable is set to use this proxy, so
you don't need to configure anything manually.
### Setting up the full development environment with Docker (Recommended)
This is the easiest and recommended way to get started. Everything runs in Docker with hot-reloading enabled.
1. Copy the example config & .env:
```bash
mkdir -p res/config # Only needed on first run
cp config.dev.toml res/config/config.toml
cp web/.env.example web/.env
```
2. Start all services:
```bash
# Recommended: Use make commands for easy development
make up
# Alternative: Use docker compose directly (if make is not available)
docker compose -f docker-compose.dev.yaml up
```
<tip> Run <code>make help</code> to see all available development commands including <code>make down</code>, <code>make logs</code>, <code>make app</code> (
shell into backend), and more.</tip>
3. Access the application:
- Frontend (with HMR): <http://localhost:5173>
- Backend API: <http://localhost:8000>
- Database: localhost:5432
The default user email is `admin@example.com` and password is `admin`, these are printed out in the logs accessible with `make logs`.
That's it! Now you can edit code and see changes instantly:
- Edit Python files → Backend auto-reloads
- Edit Svelte/TypeScript files → Frontend HMR updates in browser
- Edit config.toml → Changes apply immediately
### Setting up the backend development environment (Local)
1. Clone the repository
2. cd into repo root
3. [Install `uv`.](https://docs.astral.sh/uv/getting-started/installation/)
4. run `uv --version` to verify that `uv` is installed correctly
5. Install python if you haven't already:
```bash
uv python install 3.13
```
6. Create a virtual environment with uv
```bash
uv venv --python 3.13
```
7. Install dependencies:
```bash
uv sync
```
8. run db migrations with
```bash
uv run alembic upgrade head
```
9. run the backend with
```bash
uv run fastapi run media_manager/main.py --reload --port 8000
```
- format code with `uv run ruff format .`
- lint code with `uv run ruff check .`
### Setting up the frontend development environment (Local, Optional)
<note>
Using the Docker setup above is recommended. This section is for those who prefer to run the frontend locally outside of Docker.
</note>
1. Clone the repository
2. cd into repo root
3. cd into `web` directory
4. Install Node.js and npm if you haven't already, I
used [nvm-windows](https://github.com/coreybutler/nvm-windows?tab=readme-ov-file):
```powershell
nvm install 24.1.0
nvm use 24.1.0
```
I also needed to run the following command to be able to use `npm`:
```powershell
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
```
5. Create a `.env` file in the `web` directory:
```bash
cp .env.example .env
```
Update `PUBLIC_API_URL` if your backend is not at `http://localhost:8000`
6. Install the dependencies with npm: `npm install`
7. Start the frontend development server: `npm run dev`
<tip>If running frontend locally, make sure to add <code>http://localhost:5173</code> to the <code>cors_urls</code> in your backend
config file.</tip>
- Format the code with `npm run format`
- Lint the code with `npm run lint`
## Troubleshooting
### Common Docker Development Issues
#### Port already in use errors
- Check if ports 5173, 8000, or 5432 are already in use: `lsof -i :5173` (macOS/Linux) or
`netstat -ano | findstr :5173` (Windows)
- Stop conflicting services or change ports in `docker-compose.dev.yaml`
#### Container not showing code changes
- Verify volume mounts are correct in `docker-compose.dev.yaml`
- For backend: Ensure `./media_manager:/app/media_manager` is mounted
- For frontend: Ensure `./web:/app` is mounted
- On Windows: Check that file watching is enabled in Docker Desktop settings
#### Frontend changes not updating
- Check that the frontend container is running: `make ps` or `docker compose -f docker-compose.dev.yaml ps`
- Verify Vite's file watching is working (should see HMR updates in browser console)
- Try restarting the frontend container: `docker compose -f docker-compose.dev.yaml restart frontend`
#### Backend changes not reloading
- Verify `MEDIAMANAGER_MISC__DEVELOPMENT=TRUE` is set in `docker-compose.dev.yaml`
- Check backend logs: `make logs ARGS="--follow mediamanager"` or
`docker compose -f docker-compose.dev.yaml logs -f mediamanager`
- If dependencies changed, rebuild: `docker compose -f docker-compose.dev.yaml build mediamanager`
#### Database migration issues
- Migrations run automatically on container startup
- To run manually: `make app` then `uv run alembic upgrade head`
- To create new migration: `make app` then `uv run alembic revision --autogenerate -m "description"`
#### Viewing logs
- All services: `make logs`
- Follow logs in real-time: `make logs ARGS="--follow"`
- Specific service: `make logs ARGS="mediamanager --follow"`
#### Interactive debugging
- Shell into backend: `make app` (or `docker compose -f docker-compose.dev.yaml exec -it mediamanager bash`)
- Shell into frontend: `make frontend` (or `docker compose -f docker-compose.dev.yaml exec -it frontend sh`)
- Once inside, you can run commands like `uv run alembic upgrade head`, `npm install`, etc.
#### Volume permission issues (Linux)
- Docker containers may create files as root, causing permission issues, which can make the login page fail to show up.
- Solution: `sudo chown -R $USER:$USER res/` to reclaim ownership.
- Alternatively: Run containers with your user ID or use Docker's `user:` directive, this may fail though.
#### Complete reset
If all else fails, you can completely reset your development environment:
```bash
make down
docker compose -f docker-compose.dev.yaml down -v # Remove volumes
docker compose -f docker-compose.dev.yaml build --no-cache # Rebuild without cache
make up
```
## Sequence Diagrams
```mermaid
sequenceDiagram
title Step-by-step: going from adding a show to importing a torrent of one of its seasons
User->>TV Router: Add a show (POST /tv/shows)
TV Router->>TV Service: Receive Show Request
TV Service->>MetadataProviderService: Get Metadata for Show
MetadataProviderService->>File System: Save Poster Image
TV Service->>Database: Store show information
User->>TV Router: Get Available Torrents for a Season (GET /tv/torrents)
TV Router->>TV Service: Receive Request
TV Service->>Indexer Service: Search for torrents
TV Service->>User: Returns Public Indexer Results
User->>TV Router: Download Torrent (POST /tv/torrents)
TV Router->>TV Service: Receive Request
Note over Database: This associates a season with a torrent id and the file_path_suffix
TV Service->>Database: Saves a SeasonFile object
TV Service->>Torrent Service: Download Torrent
Torrent Service->>File System: Save Torrentfile
Torrent Service->>QBittorrent: Download Torrent
Note over Scheduler: Hourly scheduler trigger
Scheduler->>TV Service: auto_import_all_show_torrents()
TV Service->>Database: Get all Shows and seasons which are associated with a torrent
TV Service->>Torrent Service: Update Torrent download statuses
Note over TV Service: if a torrent is finished downloading it will be imported
TV Service->>Torrent Service: get all files in the torrents directory
Note over Torrent Service: Extracts archives, guesses mimetype (Video/Subtitle/Other)
Note over TV Service: filters files based on some regex and renames them
TV Service->>File System: Move/Hardlink video and subtitle files
Note over User: User can now access the show in e.g. Jellyfin
```
## Tech Stack
### Backend
- Python
- FastAPI
- SQLAlchemy
- Pydantic and Pydantic-Settings
- Alembic
### Frontend
- TypeScript
- SvelteKit
- Tailwind CSS
- shadcn-svelte
- openapi-ts
- openapi-fetch
### CI/CD
- GitHub Actions

View File

@@ -1,161 +0,0 @@
# Download Clients
Download client settings are configured in the `[torrents]` section of your `config.toml` file. MediaManager supports both qBittorrent and SABnzbd as download clients.
## qBittorrent Settings (`[torrents.qbittorrent]`)
qBittorrent is a popular BitTorrent client that MediaManager can integrate with for downloading torrents.
- `enabled`
Set to `true` to enable qBittorrent integration. Default is `false`.
- `host`
Hostname or IP of the qBittorrent server. Include the protocol (http/https).
- `port`
Port of the qBittorrent Web UI/API. Default is `8080`.
- `username`
Username for qBittorrent Web UI authentication. Default is `admin`.
- `password`
Password for qBittorrent Web UI authentication. Default is `admin`.
## Transmission Settings (`[torrents.transmission]`)
<note>
The downloads path in Transmission and MediaManager __must__ be the same, i.e. the path `/data/torrents` must link to the same volume for both containers.
</note>
Transmission is a BitTorrent client that MediaManager can integrate with for downloading torrents.
- `enabled`
Set to `true` to enable Transmission integration. Default is `false`.
- `username`
Username for Transmission RPC authentication.
- `password`
Password for Transmission RPC authentication.
- `https_enabled`
Set to `true` if your Transmission RPC endpoint uses HTTPS. Default is `true`.
- `host`
Hostname or IP of the Transmission server (without protocol).
- `port`
Port of the Transmission RPC endpoint. Default is `9091`.
- `path`
RPC request path target. Usually `/transmission/rpc`.
## SABnzbd Settings (`[torrents.sabnzbd]`)
SABnzbd is a Usenet newsreader that MediaManager can integrate with for downloading NZB files.
- `enabled`
Set to `true` to enable SABnzbd integration. Default is `false`.
- `host`
Hostname or IP of the SABnzbd server, it needs to include `http(s)://`.
- `port`
Port of the SABnzbd API. Default is `8080`.
- `api_key`
API key for SABnzbd. You can find this in SABnzbd's configuration under "General" → "API Key".
- `base_path`
API base path for SABnzbd. It usually ends with `/api`, the default is `/api`.
## Example Configuration
Here's a complete example of the download clients section in your `config.toml`:
```toml
[torrents]
# qBittorrent configuration
[torrents.qbittorrent]
enabled = true
host = "http://qbittorrent"
port = 8080
username = "admin"
password = "your_secure_password"
# Transmission configuration
[torrents.transmission]
enabled = false
username = "admin"
password = "your_secure_password"
https_enabled = true
host = "transmission"
port = 9091
path = "/transmission/rpc"
# SABnzbd configuration
[torrents.sabnzbd]
enabled = false
host = "http://sabnzbd"
port = 8080
api_key = "your_sabnzbd_api_key"
```
## Docker Compose Integration
When using Docker Compose, make sure your download clients are accessible from the MediaManager backend:
```yaml
services:
# MediaManager backend
backend:
image: ghcr.io/maxdorninger/mediamanager/backend:latest
# ... other configuration ...
# qBittorrent service
qbittorrent:
image: lscr.io/linuxserver/qbittorrent:latest
ports:
- "8080:8080"
environment:
- WEBUI_PORT=8080
volumes:
- ./data/torrents:/downloads
# ... other configuration ...
# SABnzbd service
sabnzbd:
image: lscr.io/linuxserver/sabnzbd:latest
ports:
- "8081:8080"
volumes:
- ./data/usenet:/downloads
# ... other configuration ...
```
<note>
You should enable only one BitTorrent and only one Usenet Download Client at any time.
</note>
<tip>
Make sure the download directories in your download clients are accessible to MediaManager for proper file management and organization.
</tip>

View File

@@ -1,89 +0,0 @@
# Metadata Provider Configuration
Metadata provider settings are configured in the `[metadata]` section of your `config.toml` file. These settings control how MediaManager retrieves information about movies and TV shows.
## TMDB Settings (`[metadata.tmdb]`)
TMDB (The Movie Database) is the primary metadata provider for MediaManager. It provides detailed information about movies and TV shows.
<tip>
Other software like Jellyfin use TMDB as well, so there won't be any metadata discrepancies.
</tip>
### `tmdb_relay_url`
If you want to use your own TMDB relay service, set this to the URL of your own MetadataRelay. Otherwise, use the default relay.
- **Default:** `https://metadata-relay.dorninger.co/tmdb`
- **Example:** `https://your-own-relay.example.com/tmdb`
### `primary_languages`
If a TV show/movie's original language is in this list, metadata will be displayed and fetched in that language. Torrent searches done in Standard Mode uses the same fetched metadata, so if you use any language-specific tracker, you may enter the language here to get the desired search results.
Otherwise, `default_language` will be used.
**Format: ISO 639-1 codes (2 letters). Full list: https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes**
- **Default:** `[]`
- **Example:** `["no", "de", "es"]`
### `default_language`
<warning>
`default_language` sets the TMDB `language` paramater when searching and adding TV shows and movies. If TMDB does not find a matching translation, metadata in the <strong>original language</strong> will be fetched with no option for a fallback language. It is therefore highly advised to only use "broad" languages. For most use cases, the default setting is safest.
</warning>
**Format: ISO 639-1 codes (2 letters).**
- **Default:** `en`
## TVDB Settings (`[metadata.tvdb]`)
<warning>
The TVDB might provide false metadata and doesn't support some features of MediaManager like showing overviews. Therefore, TMDB is the preferred metadata provider.
</warning>
### `tvdb_relay_url`
If you want to use your own TVDB relay service, set this to the URL of your own MetadataRelay. Otherwise, use the default relay.
- **Default:** `https://metadata-relay.dorninger.co/tvdb`
- **Example:** `https://your-own-relay.example.com/tvdb`
## MetadataRelay
<note>
To use MediaManager <strong>you don't need to set up your own MetadataRelay</strong>, as the default relay hosted by the developer should be sufficient for most purposes.
</note>
The MetadataRelay is a service that provides metadata for MediaManager. It acts as a proxy for TMDB and TVDB, allowing you to use your own API keys if needed, but the default relay means you don't need to create accounts for API keys yourself.
You might want to use your own relay if you want to avoid rate limits, protect your privacy, or for other reasons. If you know Sonarr's Skyhook, this is similar to that.
### Where to get API keys
- Get a TMDB API key from [The Movie Database](https://www.themoviedb.org/settings/api)
- Get a TVDB API key from [The TVDB](https://thetvdb.com/auth/register)
<tip>
If you want to use your own MetadataRelay, you can set the <code>tmdb_relay_url</code> and/or <code>tvdb_relay_url</code> to your own relay service.
</tip>
## Example Configuration
Here's a complete example of the metadata section in your `config.toml`:
```toml
[metadata]
# TMDB configuration
[metadata.tmdb]
tmdb_relay_url = "https://metadata-relay.dorninger.co/tmdb"
# TVDB configuration
[metadata.tvdb]
tvdb_relay_url = "https://metadata-relay.dorninger.co/tvdb"
```
<note>
In most cases, you can simply use the default values and don't need to specify these settings in your config file at all.
</note>

View File

@@ -1,19 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE topic SYSTEM "https://resources.jetbrains.com/writerside/1.0/html-entities.dtd">
<topic id="notes"
is-library="true" title="notes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd">
<snippet id="list-format">
Lists have to be formatted like this: <code>["item1", "item2", "item3"]</code>. Note the double quotes.
</snippet>
<snippet id="auth-admin-emails">
<tip>
<p>When setting up MediaManager for the first time, you should add your email to <code>admin_emails</code>
in the <code>[auth]</code> config
section, MediaManager will then use this email instead of the default admin email. Your account will automatically be
created as an admin account, allowing you to manage other
users, media and
settings.</p>
</tip>
</snippet>
</topic>

View File

@@ -1,12 +0,0 @@
# qBittorrent Category
qBittorrent supports saving Torrents to subdirectories based on the category of the Torrent.
The default category name that MediaManager uses is `MediaManager`.
With the variable `torrents.qbittorrent.category_name` you can change the category name that MediaManager uses when
adding Torrents to qBittorrent.
With the variable `torrents.qbittorrent.category_save_path` you can change the path where the Torrents are saved to. By
default, no subdirectory is used. Note that qBittorrent saves torrents to this path, so it must be a
valid path that qBittorrent can write to. Example value: `/data/torrents/MediaManager`. Note that for MediaManager to be
able to successfully import torrents, you must add the subdirectory to the `misc.torrent_directory` variable.

View File

@@ -1,57 +0,0 @@
# Troubleshooting
<tip>
Always check the container and browser logs for more specific error messages
</tip>
## Authentication Issues
<procedure title="I can't log in with OAuth/OIDC?" id="procedure-i-cannot-log-in-with-oauth">
<step>Verify your OAuth provider's configuration. <a href="authentication-setup.md" anchor="openid-connect-settings-auth-openid-connect">See the OAuth documentation</a></step>
<step>Check if the callback URI you set in your OIDC providers settings is correct. <a href="authentication-setup.md" anchor="redirect-uri">See the callback URI documentation</a> </step>
<step>Check the frontend url in your config file. It should match the URL you use to access MediaManager.</step>
</procedure>
<procedure title="I cannot log in?" id="procedure-i-cannot-log-in">
<step>Make sure you are logging in, not signing up.</step>
<step>Try logging in with the following credentials:
<list>
<li>Email: admin@mediamanager.local or admin@example.com</li>
<li>Password: admin</li>
</list>
</step>
</procedure>
## Hard linking Issues
- Make sure you are using only one volumes for TV, Movies and Downloads.
<a href="https://raw.githubusercontent.com/maxdorninger/MediaManager/refs/heads/master/docker-compose.yaml"> See the configuration in the example <code>docker-compose.yaml</code> file.</a>
The reason is that hard linking only works within the same filesystem. If your downloads are on a different volume than
your media library, hard linking will not work.
## Torrent Search Issues
<procedure title="I get no search results for torrents?" id="procedure-i-get-no-search-results">
<step>Try switching to the advanced tab when searching for torrents.</step>
<step><a href="Indexer-Settings.md">If you use "slow" indexers, try increasing the timeout threshold.</a></step>
<step>If you still don't get any search results, check the logs, they will provide more information on what is going wrong.</step>
</procedure>
## Import and download Issues
- If you configured a category with a special save path,
<a href="qBittorrent-Category.md">carefully read this page about MM with qBittorrent save paths.</a>
<note>If it still doesn't work, <a href="https://github.com/maxdorninger/MediaManager/issues">please open an Issue.</a> It is possible that a bug is causing the issue.</note>
## Docker Image Pull Issues
- If you get a 401 or 403 error when pulling the image from GHCR, this is not a permission issue with the
repository/image. It errors because your Docker client is misconfigured.
- This is not a MediaManager issue per se, so please don't open an issue about this on the MediaManager GitHub repo.
### Possible Fixes:
- [Unable to pull image from GitHub Container Registry (Stack Overflow)](https://stackoverflow.com/questions/74656167/unable-to-pull-image-from-github-container-registry-ghcr)
- [Try pulling the image from Quay.io](configuration-overview.md#mediamanager-and-metadatarelay-docker-images)

View File

@@ -1,34 +0,0 @@
# URL Prefix
MediaManager, by default, expects to run at the base of a domain, e.g. `maxdorninger.github.io`.
In order to run it on a prefixed path, like `maxdorninger.github.io/media`, the docker image must be built with a special build argument. That's because SvelteKit needs to know the base URL at build time.
In short, clone the repository, then run:
```
docker build \
--build-arg BASE_PATH=/media \
--build-arg VERSION=my-custom-version \
-t MediaManager:my-custom-version \
-f Dockerfile .
```
You also need to set the `BASE_PATH` environment variable at runtime in `docker-compose.yaml`:
```yaml
services:
mediamanager:
image: MediaManager:my-custom-version
ports:
- "8000:8000"
environment:
BASE_PATH: /media
...
```
<note>
Make sure to include the base path in the frontend_url field in the config file. For more information see the page on <a href="configuration-backend.md"><code>frontend_url</code></a>.
</note>
Finally, ensure that whatever reverse proxy you're using leaves the incoming path unchanged; that is, you should not strip the `/media` from `/media/web/`.

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE vars SYSTEM "https://resources.jetbrains.com/writerside/1.0/vars.dtd">
<vars>
<var name="product" value="Writerside"/>
</vars>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ihp SYSTEM "https://resources.jetbrains.com/writerside/1.0/ihp.dtd">
<ihp version="2.0">
<topics dir="topics" web-path="topics"/>
<images dir="images" web-path="MediaManager"/>
<instance src="mm.tree"/>
<instance src="Writerside_libraries.tree"/>
</ihp>

View File

@@ -1,6 +1,6 @@
# MediaManager Dev Configuration File
# This file contains all available configuration options for MediaManager
# Documentation: https://maxdorninger.github.io/MediaManager/introduction.html
# Documentation: https://maximilian-dorninger.gitbook.io/mediamanager
#
# This is an example configuration file that gets copied to your config folder
# on first boot. You should modify the values below to match your setup.

View File

@@ -1,6 +1,6 @@
# MediaManager Example Configuration File
# This file contains all available configuration options for MediaManager
# Documentation: https://maxdorninger.github.io/MediaManager/introduction.html
# Documentation: https://maximilian-dorninger.gitbook.io/mediamanager
#
# This is an example configuration file that gets copied to your config folder
# on first boot. You should modify the values below to match your setup.

View File

@@ -46,7 +46,7 @@
explore trending content—all in one place.
</p>
<p class="mb-2 text-sm text-muted-foreground">
Version: v{PUBLIC_VERSION}
Version: {PUBLIC_VERSION}
</p>
<h2
class="mt-10 scroll-m-20 pb-2 text-3xl font-semibold tracking-tight transition-colors first:mt-0"

View File

@@ -31,7 +31,7 @@
<a
target="_blank"
class="underline"
href="https://maxdorninger.github.io/MediaManager/troubleshooting.html"
href="https://maximilian-dorninger.gitbook.io/mediamanager/troubleshooting"
>
Trouble logging in?
</a>