Add a FileTree component and convert every directory tree to it
This commit is contained in:
@@ -0,0 +1,37 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
export type FileTreeEntry = string | Record<string, FileTreeEntry[]>
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<{
|
||||||
|
tree: FileTreeEntry
|
||||||
|
label?: string
|
||||||
|
collapsed?: boolean
|
||||||
|
}>(), {
|
||||||
|
label: 'Folder structure',
|
||||||
|
collapsed: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
// `collapsed` only sets the initial state; the header click below then
|
||||||
|
// toggles this independently of the prop.
|
||||||
|
const isOpen = ref(!props.collapsed)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="not-prose my-5 rounded-lg overflow-hidden bg-elevated/50 ring ring-default divide-y divide-default">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="flex items-center gap-1.5 w-full px-4 py-3 text-muted hover:text-default hover:bg-elevated/50 transition-colors cursor-pointer"
|
||||||
|
@click="isOpen = !isOpen"
|
||||||
|
>
|
||||||
|
<UIcon name="i-lucide-folder-tree" class="size-4 shrink-0" />
|
||||||
|
<span class="text-sm/6">{{ label }}</span>
|
||||||
|
<UIcon
|
||||||
|
name="i-lucide-chevron-down"
|
||||||
|
class="size-4 shrink-0 ms-auto transition-transform"
|
||||||
|
:class="isOpen ? '' : '-rotate-90'"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<ul v-show="isOpen" class="text-sm leading-relaxed px-2 py-2 list-none">
|
||||||
|
<FileTreeNode :entry="tree" root />
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { useClipboard } from '@vueuse/core'
|
||||||
|
import codeIconTheme from '#build/ui/prose/code-icon'
|
||||||
|
import type { FileTreeEntry } from './FileTree.vue'
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<{
|
||||||
|
entry: FileTreeEntry
|
||||||
|
root?: boolean
|
||||||
|
parentPath?: string
|
||||||
|
}>(), {
|
||||||
|
root: false,
|
||||||
|
parentPath: '',
|
||||||
|
})
|
||||||
|
|
||||||
|
// Splits a trailing " # comment" off a raw label (space-prefixed, like a
|
||||||
|
// real code comment), so authors can annotate a tree entry the same way
|
||||||
|
// they'd annotate a line of code.
|
||||||
|
function splitComment(raw: string) {
|
||||||
|
const index = raw.indexOf(' #')
|
||||||
|
if (index === -1) return { text: raw, comment: undefined as string | undefined }
|
||||||
|
return { text: raw.slice(0, index).trimEnd(), comment: raw.slice(index + 2).trim() }
|
||||||
|
}
|
||||||
|
|
||||||
|
const rawEntry = computed(() => typeof props.entry === 'object' ? Object.keys(props.entry)[0] : props.entry as string)
|
||||||
|
const parsed = computed(() => splitComment(rawEntry.value))
|
||||||
|
|
||||||
|
const isFolder = computed(() => typeof props.entry === 'object' || parsed.value.text.endsWith('/'))
|
||||||
|
|
||||||
|
// Strip a trailing "/" marker, except when it's the whole name: that's the
|
||||||
|
// filesystem root itself, written as a bare "/".
|
||||||
|
const name = computed(() => {
|
||||||
|
const text = parsed.value.text
|
||||||
|
return text.length > 1 && text.endsWith('/') ? text.slice(0, -1) : text
|
||||||
|
})
|
||||||
|
const comment = computed(() => parsed.value.comment)
|
||||||
|
|
||||||
|
const children = computed<FileTreeEntry[]>(() => {
|
||||||
|
if (typeof props.entry !== 'object') return []
|
||||||
|
return Object.values(props.entry)[0] || []
|
||||||
|
})
|
||||||
|
|
||||||
|
// The root's own name is "/" already; every other node just appends its
|
||||||
|
// name to its parent's path, without doubling that leading slash.
|
||||||
|
const fullPath = computed(() => {
|
||||||
|
if (props.root) return name.value
|
||||||
|
return props.parentPath === '/' ? `/${name.value}` : `${props.parentPath}/${name.value}`
|
||||||
|
})
|
||||||
|
|
||||||
|
const { copy, copied } = useClipboard({ source: fullPath })
|
||||||
|
|
||||||
|
function onClick() {
|
||||||
|
copy()
|
||||||
|
}
|
||||||
|
|
||||||
|
const appConfig = useAppConfig()
|
||||||
|
|
||||||
|
// Same lookup order as Nuxt UI's own CodeIcon.vue (exact filename match,
|
||||||
|
// then extension, then the vscode-icons fallback), so a file gets the same
|
||||||
|
// icon here as it would in a labeled code fence.
|
||||||
|
const icon = computed(() => {
|
||||||
|
if (isFolder.value) return 'i-lucide-folder'
|
||||||
|
|
||||||
|
const filename = name.value
|
||||||
|
const icons = { ...codeIconTheme, ...(appConfig.ui?.prose?.codeIcon || {}) } as Record<string, string>
|
||||||
|
const extension = filename.includes('.') ? filename.split('.').pop() : undefined
|
||||||
|
|
||||||
|
return icons[filename.toLowerCase()]
|
||||||
|
?? (extension && icons[extension])
|
||||||
|
?? (extension && `i-vscode-icons-file-type-${extension}`)
|
||||||
|
?? 'i-lucide-file'
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<li class="relative" :class="root ? '' : 'ps-3'">
|
||||||
|
<span
|
||||||
|
class="group flex items-center gap-1.5 py-1 px-1.5 -mx-1.5 rounded-md relative hover:bg-elevated/50 transition-colors cursor-pointer"
|
||||||
|
title="Copy path"
|
||||||
|
@click="onClick"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
v-if="!root"
|
||||||
|
class="absolute -start-1.5 top-1/2 -translate-y-1/2 w-3 h-px bg-white/20"
|
||||||
|
/>
|
||||||
|
<UIcon
|
||||||
|
:name="icon"
|
||||||
|
class="shrink-0 size-4"
|
||||||
|
:class="isFolder ? 'text-[var(--ui-primary)]' : 'text-[var(--ui-text-dimmed)]'"
|
||||||
|
/>
|
||||||
|
<span>{{ name }}</span>
|
||||||
|
<span v-if="comment" class="text-xs text-muted italic">{{ comment }}</span>
|
||||||
|
<UIcon
|
||||||
|
:name="copied ? 'i-lucide-check' : 'i-lucide-copy'"
|
||||||
|
class="size-3.5 shrink-0 opacity-0 group-hover:opacity-100 transition-opacity text-muted"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<ul v-if="children.length" class="ms-2 ps-0 list-none border-s border-white/20">
|
||||||
|
<FileTreeNode v-for="(child, i) in children" :key="i" :entry="child" :parent-path="fullPath" />
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
@@ -29,18 +29,21 @@ There are two main modes you should know:
|
|||||||
Both modes can be configured on a per-application basis.
|
Both modes can be configured on a per-application basis.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
Folder structure:
|
|
||||||
```text [Directory tree]
|
::file-tree
|
||||||
root
|
---
|
||||||
└── docker
|
tree:
|
||||||
└── authentik
|
/:
|
||||||
├── .env
|
- docker:
|
||||||
├── compose.yml
|
- authentik:
|
||||||
├── media
|
- .env
|
||||||
├── certs
|
- compose.yml
|
||||||
├── custom-template
|
- media/
|
||||||
└── ssh
|
- certs/
|
||||||
```
|
- custom-template/
|
||||||
|
- ssh/
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
::steps{level="3"}
|
::steps{level="3"}
|
||||||
### Create the folders
|
### Create the folders
|
||||||
|
|||||||
@@ -62,14 +62,16 @@ sudo mkdir /docker
|
|||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
|
|
||||||
File structure we will create:
|
::file-tree
|
||||||
|
---
|
||||||
```text [Directory tree]
|
label: File structure we will create
|
||||||
root
|
tree:
|
||||||
└── docker
|
/:
|
||||||
└── dockge
|
- docker:
|
||||||
└── compose.yml
|
- dockge:
|
||||||
```
|
- compose.yml
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
::steps{level="4"}
|
::steps{level="4"}
|
||||||
#### Create the stack folder
|
#### Create the stack folder
|
||||||
|
|||||||
@@ -26,23 +26,25 @@ Below is an example exposing Dockge. We will install SWAG along with the dbip mo
|
|||||||
This tutorial assumes you have a domain name pointing to your server, and that your router has a NAT rule forwarding port `443` to your server's IP and port `443`. The example domain will be `mydomain.com`.
|
This tutorial assumes you have a domain name pointing to your server, and that your router has a NAT rule forwarding port `443` to your server's IP and port `443`. The example domain will be `mydomain.com`.
|
||||||
::
|
::
|
||||||
|
|
||||||
File structure to be modified:
|
::file-tree
|
||||||
|
---
|
||||||
```text [Directory tree]
|
label: File structure to modify
|
||||||
root
|
tree:
|
||||||
└── docker
|
/:
|
||||||
└── swag
|
- docker:
|
||||||
├── config
|
- swag:
|
||||||
│ ├── dns-conf
|
- config:
|
||||||
│ │ └── ovh.ini
|
- dns-conf:
|
||||||
│ └── nginx
|
- ovh.ini
|
||||||
│ ├── dbip.conf
|
- nginx:
|
||||||
│ ├── nginx.conf
|
- dbip.conf
|
||||||
│ └── proxy-confs
|
- nginx.conf
|
||||||
│ └── dockge.subdomain.conf
|
- proxy-confs:
|
||||||
├── compose.yml
|
- dockge.subdomain.conf
|
||||||
└── .env
|
- compose.yml
|
||||||
```
|
- .env
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
::steps{level="3"}
|
::steps{level="3"}
|
||||||
### Deploy the stack
|
### Deploy the stack
|
||||||
|
|||||||
@@ -53,15 +53,18 @@ __Warning__: If your IP is not static, use a Dynamic DNS service ([DynDNS](https
|
|||||||
|
|
||||||
### Folder Structure
|
### Folder Structure
|
||||||
|
|
||||||
```text [Directory tree]
|
::file-tree
|
||||||
root
|
---
|
||||||
└── docker
|
tree:
|
||||||
└── wg-easy
|
/:
|
||||||
├── config
|
- docker:
|
||||||
│ └── etc_wireguard
|
- wg-easy:
|
||||||
├── compose.yaml
|
- config:
|
||||||
└── .env
|
- etc_wireguard/
|
||||||
```
|
- compose.yaml
|
||||||
|
- .env
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
::steps{level="3"}
|
::steps{level="3"}
|
||||||
### Deploy the stack
|
### Deploy the stack
|
||||||
@@ -190,14 +193,17 @@ We assume the client server runs Linux with Docker installed.
|
|||||||
|
|
||||||
### Folder Structure
|
### Folder Structure
|
||||||
|
|
||||||
```text [Directory tree]
|
::file-tree
|
||||||
root
|
---
|
||||||
└── docker
|
tree:
|
||||||
└── wireguard
|
/:
|
||||||
└── config
|
- docker:
|
||||||
│ └── wg_confs
|
- wireguard:
|
||||||
└── compose.yaml
|
- config:
|
||||||
```
|
- wg_confs/
|
||||||
|
- compose.yaml
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
::steps{level="3"}
|
::steps{level="3"}
|
||||||
### Create the folder
|
### Create the folder
|
||||||
|
|||||||
@@ -14,15 +14,18 @@ This makes it a good fit if you just need a simple, fast SSO backend, for exampl
|
|||||||
- [Pocket ID on GitHub](https://github.com/pocket-id/pocket-id)
|
- [Pocket ID on GitHub](https://github.com/pocket-id/pocket-id)
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
Folder structure:
|
|
||||||
```text [Directory tree]
|
::file-tree
|
||||||
root
|
---
|
||||||
└── docker
|
tree:
|
||||||
└── pocket-id
|
/:
|
||||||
├── compose.yaml
|
- docker:
|
||||||
├── .env
|
- pocket-id:
|
||||||
└── data
|
- compose.yaml
|
||||||
```
|
- .env
|
||||||
|
- data/
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
::steps{level="3"}
|
::steps{level="3"}
|
||||||
### Create the data folder
|
### Create the data folder
|
||||||
|
|||||||
@@ -19,15 +19,18 @@ This guide assumes you've already installed [Pocket ID](/serveex/security/pocket
|
|||||||
::
|
::
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
Folder structure:
|
|
||||||
```text [Directory tree]
|
::file-tree
|
||||||
root
|
---
|
||||||
└── docker
|
tree:
|
||||||
└── tinyauth
|
/:
|
||||||
├── compose.yaml
|
- docker:
|
||||||
├── .env
|
- tinyauth:
|
||||||
└── data
|
- compose.yaml
|
||||||
```
|
- .env
|
||||||
|
- data/
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
::steps{level="3"}
|
::steps{level="3"}
|
||||||
### Create the data folder
|
### Create the data folder
|
||||||
|
|||||||
@@ -9,15 +9,17 @@ description: Install Uptime-Kuma to monitor your self-hosted services uptime, se
|
|||||||

|

|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
Folder structure
|
|
||||||
|
|
||||||
```text [Directory tree]
|
::file-tree
|
||||||
root
|
---
|
||||||
└── docker
|
tree:
|
||||||
└── uptime-kuma
|
/:
|
||||||
├── date
|
- docker:
|
||||||
└── compose.yaml
|
- uptime-kuma:
|
||||||
```
|
- data/
|
||||||
|
- compose.yaml
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
::steps{level="3"}
|
::steps{level="3"}
|
||||||
### Deploy the stack
|
### Deploy the stack
|
||||||
|
|||||||
@@ -12,14 +12,18 @@ description: Install Dozzle to monitor Docker container logs in real time from a
|
|||||||

|

|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
Folder structure
|
|
||||||
|
|
||||||
```text [Directory tree]
|
::file-tree
|
||||||
root
|
---
|
||||||
└── docker
|
tree:
|
||||||
└── dozzle
|
/:
|
||||||
└── data
|
- docker:
|
||||||
```
|
- dozzle:
|
||||||
|
- compose.yaml
|
||||||
|
- .env
|
||||||
|
- data/
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
::steps{level="3"}
|
::steps{level="3"}
|
||||||
### Deploy the stack
|
### Deploy the stack
|
||||||
|
|||||||
@@ -24,15 +24,21 @@ description: Install Speedtest Tracker to automatically measure and log your int
|
|||||||
We will use the Docker image maintained by [LinuxServer.io](https://docs.linuxserver.io/images/docker-speedtest-tracker/)
|
We will use the Docker image maintained by [LinuxServer.io](https://docs.linuxserver.io/images/docker-speedtest-tracker/)
|
||||||
::
|
::
|
||||||
|
|
||||||
File structure:
|
::file-tree
|
||||||
|
---
|
||||||
|
tree:
|
||||||
|
/:
|
||||||
|
- docker:
|
||||||
|
- speedtest-tracker:
|
||||||
|
- compose.yaml
|
||||||
|
- .env
|
||||||
|
- data:
|
||||||
|
- config/
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
```text [Directory tree]
|
::steps{level="3"}
|
||||||
root
|
### Generate an app key
|
||||||
└── docker
|
|
||||||
└── speedtest-tracker
|
|
||||||
└── data
|
|
||||||
└── config
|
|
||||||
```
|
|
||||||
|
|
||||||
In a terminal, generate a key using the following command:
|
In a terminal, generate a key using the following command:
|
||||||
|
|
||||||
@@ -42,6 +48,8 @@ echo -n 'base64:'; openssl rand -base64 32;
|
|||||||
|
|
||||||
Take note of the key.
|
Take note of the key.
|
||||||
|
|
||||||
|
### Deploy the stack
|
||||||
|
|
||||||
Open Dockge, click on `compose`, name the stack `speedtest-tracker`, then paste the following:
|
Open Dockge, click on `compose`, name the stack `speedtest-tracker`, then paste the following:
|
||||||
|
|
||||||
```yaml [compose.yaml]
|
```yaml [compose.yaml]
|
||||||
@@ -67,6 +75,8 @@ services:
|
|||||||
- /docker/speedtest-tracker/data/config:/config
|
- /docker/speedtest-tracker/data/config:/config
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Set your environment variables
|
||||||
|
|
||||||
Find your `PUID` and `GUID` by running the following command:
|
Find your `PUID` and `GUID` by running the following command:
|
||||||
|
|
||||||
```bash [Terminal]
|
```bash [Terminal]
|
||||||
@@ -89,7 +99,10 @@ PORT=3225 # port to access the web UI
|
|||||||
|
|
||||||
Deploy the container and go to `http://yourserverip:3225`. Log in with the account `admin@exemple.com` and the password `password`. Don’t forget to change your ID and password once logged in!
|
Deploy the container and go to `http://yourserverip:3225`. Log in with the account `admin@exemple.com` and the password `password`. Don’t forget to change your ID and password once logged in!
|
||||||
|
|
||||||
## Expose Speedtest Tracker
|
### Done !
|
||||||
|
::
|
||||||
|
|
||||||
|
## Exposing Speedtest Tracker with SWAG
|
||||||
::note
|
::note
|
||||||
📋 **Prerequisites:**
|
📋 **Prerequisites:**
|
||||||
We assume that you've already created a subdomain like `speedtest.yourdomain.com` in your [DNS zone](/general/networking/dns) with a `CNAME` pointing to `yourdomain.com`, and [unless you’re using Cloudflare Zero Trust](/serveex/security/cloudflare), you've also forwarded port `443` from your router to port `443` of your server in your [NAT rules](/general/networking/nat).
|
We assume that you've already created a subdomain like `speedtest.yourdomain.com` in your [DNS zone](/general/networking/dns) with a `CNAME` pointing to `yourdomain.com`, and [unless you’re using Cloudflare Zero Trust](/serveex/security/cloudflare), you've also forwarded port `443` from your router to port `443` of your server in your [NAT rules](/general/networking/nat).
|
||||||
@@ -102,6 +115,9 @@ Now we want to expose Speedtest Tracker to the internet so you can access it rem
|
|||||||
Speedtest Tracker does not use multi-factor authentication. Exposing it on the internet could compromise connected devices. Do so only if you use a multi-factor system like [TinyAuth](/serveex/security/tinyauth) or [Authentik](/serveex/advanced/authentik/). Otherwise, avoid using SWAG and prefer a VPN like [Wireguard](/serveex/security/wireguard).
|
Speedtest Tracker does not use multi-factor authentication. Exposing it on the internet could compromise connected devices. Do so only if you use a multi-factor system like [TinyAuth](/serveex/security/tinyauth) or [Authentik](/serveex/advanced/authentik/). Otherwise, avoid using SWAG and prefer a VPN like [Wireguard](/serveex/security/wireguard).
|
||||||
::
|
::
|
||||||
|
|
||||||
|
::steps{level="3"}
|
||||||
|
### Create the subdomain.conf file
|
||||||
|
|
||||||
Open the `speedtest.subdomain.conf` file:
|
Open the `speedtest.subdomain.conf` file:
|
||||||
|
|
||||||
```bash [Terminal]
|
```bash [Terminal]
|
||||||
@@ -155,6 +171,8 @@ server {
|
|||||||
|
|
||||||
Save and exit. The configuration will update in a few seconds.
|
Save and exit. The configuration will update in a few seconds.
|
||||||
|
|
||||||
|
### Add Speedtest Tracker's network to SWAG
|
||||||
|
|
||||||
::note
|
::note
|
||||||
|
|
||||||
By default, SWAG doesn’t know the name "speedtest-tracker". To allow access, you need to add Speedtest Tracker’s network to SWAG’s `compose.yml`.
|
By default, SWAG doesn’t know the name "speedtest-tracker". To allow access, you need to add Speedtest Tracker’s network to SWAG’s `compose.yml`.
|
||||||
@@ -186,6 +204,9 @@ Restart the stack by clicking "Deploy" and wait for SWAG to be fully up.
|
|||||||
This assumes the Speedtest Tracker network is named `speedtest-tracker_default`. You can verify the connection by visiting SWAG’s dashboard at `http://yourserverip:81`.
|
This assumes the Speedtest Tracker network is named `speedtest-tracker_default`. You can verify the connection by visiting SWAG’s dashboard at `http://yourserverip:81`.
|
||||||
::
|
::
|
||||||
|
|
||||||
|
### Done !
|
||||||
|
::
|
||||||
|
|
||||||
Wait a moment, then visit `https://speedtest.yourdomain.com` in your browser. You should be redirected to Speedtest Tracker. You can check service status via the dashboard (`http://yourserverip:81` from the local network).
|
Wait a moment, then visit `https://speedtest.yourdomain.com` in your browser. You should be redirected to Speedtest Tracker. You can check service status via the dashboard (`http://yourserverip:81` from the local network).
|
||||||
|
|
||||||
## Protecting Speedtest Tracker with TinyAuth
|
## Protecting Speedtest Tracker with TinyAuth
|
||||||
|
|||||||
@@ -24,15 +24,18 @@ Beszel includes a hub with a web UI and an agent that collects data from your se
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Folder structure
|
::file-tree
|
||||||
|
---
|
||||||
```text [Directory tree]
|
tree:
|
||||||
root
|
/:
|
||||||
└── docker
|
- docker:
|
||||||
└── beszel
|
- beszel:
|
||||||
├── data
|
- compose.yaml
|
||||||
└── socket
|
- .env
|
||||||
```
|
- data/
|
||||||
|
- socket/
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
Open Dockge, click `compose`, name the stack `beszel`, and paste the following:
|
Open Dockge, click `compose`, name the stack `beszel`, and paste the following:
|
||||||
|
|
||||||
|
|||||||
@@ -20,14 +20,17 @@ description: Install UpSnap to remotely wake up machines on your local network v
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Folder structure
|
::file-tree
|
||||||
|
---
|
||||||
```text [Directory tree]
|
tree:
|
||||||
root
|
/:
|
||||||
└── docker
|
- docker:
|
||||||
└── upsnap
|
- upsnap:
|
||||||
└── data
|
- compose.yaml
|
||||||
```
|
- .env
|
||||||
|
- data/
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
Open Dockge, click on `compose`, name the stack `upsnap`, then copy and paste the following:
|
Open Dockge, click on `compose`, name the stack `upsnap`, then copy and paste the following:
|
||||||
|
|
||||||
|
|||||||
@@ -26,19 +26,22 @@ Unlike Plex, Jellyfin has no cloud relay: to access your server outside your loc
|
|||||||
::
|
::
|
||||||
|
|
||||||
## Install Jellyfin
|
## Install Jellyfin
|
||||||
Folder structure:
|
|
||||||
```text [Directory tree]
|
::file-tree
|
||||||
root
|
---
|
||||||
├── docker
|
tree:
|
||||||
│ └── jellyfin
|
/:
|
||||||
│ ├── compose.yaml
|
- docker:
|
||||||
│ ├── .env
|
- jellyfin:
|
||||||
│ └── config
|
- compose.yaml
|
||||||
└── media
|
- .env
|
||||||
├── tvseries
|
- config/
|
||||||
├── movies
|
- media:
|
||||||
└── library
|
- tvseries/
|
||||||
```
|
- movies/
|
||||||
|
- library/
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
Create the `movies`, `tvseries`, and `library` folders in `/media`:
|
Create the `movies`, `tvseries`, and `library` folders in `/media`:
|
||||||
|
|
||||||
|
|||||||
@@ -29,23 +29,24 @@ Here’s the system we’ll set up:
|
|||||||

|

|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
Folder structure
|
|
||||||
|
|
||||||
```text [Directory tree]
|
::file-tree
|
||||||
root
|
---
|
||||||
├── docker
|
tree:
|
||||||
│ └── seedbox
|
/:
|
||||||
│ ├── qbittorrent
|
- docker:
|
||||||
│ │ └── config
|
- seedbox:
|
||||||
│ ├── gluetun
|
- qbittorrent:
|
||||||
│ ├── compose.yaml
|
- config/
|
||||||
│ └── .env
|
- gluetun/
|
||||||
│
|
- compose.yaml
|
||||||
└── media #linked to Jellyfin and Qbittorrent
|
- .env
|
||||||
├── downloads #generic downloads, selected in settings
|
- "media # linked to Jellyfin and Qbittorrent":
|
||||||
├── movies #used for downloading movies
|
- "downloads/ # generic downloads, selected in settings"
|
||||||
└── tvseries #used for downloading TV shows
|
- "movies/ # used for downloading movies"
|
||||||
```
|
- "tvseries/ # used for downloading TV shows"
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
If not already done, create the `downloads` folder under `/media`:
|
If not already done, create the `downloads` folder under `/media`:
|
||||||
|
|
||||||
|
|||||||
@@ -28,30 +28,32 @@ We’ll start by deploying the stack and then proceed to configure each app and
|
|||||||
|
|
||||||
### Docker Compose
|
### Docker Compose
|
||||||
|
|
||||||
Folder structure:
|
::file-tree
|
||||||
|
---
|
||||||
```text [Directory tree]
|
tree:
|
||||||
root
|
/:
|
||||||
├── docker
|
- docker:
|
||||||
│ ├── jellyfin
|
- jellyfin:
|
||||||
│ │ ├── compose.yml
|
- compose.yml
|
||||||
│ │ └── config
|
- .env
|
||||||
│ ├── sonarr
|
- config/
|
||||||
│ │ └── config
|
- sonarr:
|
||||||
│ ├── radarr
|
- config/
|
||||||
│ │ └── config
|
- radarr:
|
||||||
│ ├── bazarr
|
- config/
|
||||||
│ │ └── config
|
- bazarr:
|
||||||
│ ├── prowlarr
|
- config/
|
||||||
│ │ └── config
|
- prowlarr:
|
||||||
│ └── seerr
|
- config/
|
||||||
│ └── config
|
- seerr:
|
||||||
└── media
|
- config/
|
||||||
├── downloads
|
- media:
|
||||||
├── tvseries
|
- downloads/
|
||||||
├── movies
|
- tvseries/
|
||||||
└── library
|
- movies/
|
||||||
```
|
- library/
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
::warning
|
::warning
|
||||||
|
|
||||||
|
|||||||
@@ -16,16 +16,18 @@ description: Install Immich, a self-hosted alternative to Google Photos and iClo
|
|||||||

|

|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
Folder structure
|
|
||||||
|
|
||||||
```text [Directory tree]
|
::file-tree
|
||||||
root
|
---
|
||||||
└── docker
|
tree:
|
||||||
└── immich
|
/:
|
||||||
├── library
|
- docker:
|
||||||
├── compose.yaml
|
- immich:
|
||||||
└── .env
|
- library/
|
||||||
```
|
- compose.yaml
|
||||||
|
- .env
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
Open Dockge, click on `compose`, name the stack `immich`, then copy and paste the latest `docker-compose.yml` [published here](https://github.com/immich-app/immich/blob/main/docker/docker-compose.yml).
|
Open Dockge, click on `compose`, name the stack `immich`, then copy and paste the latest `docker-compose.yml` [published here](https://github.com/immich-app/immich/blob/main/docker/docker-compose.yml).
|
||||||
|
|
||||||
|
|||||||
@@ -21,17 +21,18 @@ description: Install Nextcloud to self-host your files, photos, and calendar, a
|
|||||||
We'll be using the Docker image maintained by [LinuxServer.io](https://docs.linuxserver.io/images/docker-nextcloud/)
|
We'll be using the Docker image maintained by [LinuxServer.io](https://docs.linuxserver.io/images/docker-nextcloud/)
|
||||||
::
|
::
|
||||||
|
|
||||||
File structure:
|
::file-tree
|
||||||
|
---
|
||||||
```text [Directory tree]
|
tree:
|
||||||
root
|
/:
|
||||||
└── docker
|
- docker:
|
||||||
└── nextcloud
|
- nextcloud:
|
||||||
├── config
|
- config/
|
||||||
├── data
|
- data/
|
||||||
├── compose.yaml
|
- compose.yaml
|
||||||
└── .env
|
- .env
|
||||||
```
|
---
|
||||||
|
::
|
||||||
|
|
||||||
Open Dockge, click on `compose`, name the stack `nextcloud` and paste the following:
|
Open Dockge, click on `compose`, name the stack `nextcloud` and paste the following:
|
||||||
|
|
||||||
|
|||||||
@@ -19,16 +19,19 @@ description: Install File Browser Quantum, a modernized fork of File Browser, to
|
|||||||
If you're already using File Browser and it fits your needs, there's no need to switch. The two are independent projects with their own configuration and can't share data directly.
|
If you're already using File Browser and it fits your needs, there's no need to switch. The two are independent projects with their own configuration and can't share data directly.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
Folder structure:
|
|
||||||
```text [Directory tree]
|
::file-tree
|
||||||
root
|
---
|
||||||
└── docker
|
tree:
|
||||||
└── filebrowser-quantum
|
/:
|
||||||
├── compose.yaml
|
- docker:
|
||||||
└── data
|
- filebrowser-quantum:
|
||||||
├── config.yaml
|
- compose.yaml
|
||||||
└── filebrowser.sqlite
|
- data:
|
||||||
```
|
- config.yaml
|
||||||
|
- filebrowser.sqlite
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
Create the data folder:
|
Create the data folder:
|
||||||
|
|
||||||
|
|||||||
@@ -25,15 +25,18 @@ description: Install code-server to run VS Code in your browser from your homela
|
|||||||
For this setup, we’ll use the [image maintained by LinuxServer.io](https://docs.linuxserver.io/images/docker-code-server/).
|
For this setup, we’ll use the [image maintained by LinuxServer.io](https://docs.linuxserver.io/images/docker-code-server/).
|
||||||
::
|
::
|
||||||
|
|
||||||
Folder structure
|
::file-tree
|
||||||
|
---
|
||||||
```text [Directory tree]
|
tree:
|
||||||
root
|
/:
|
||||||
├── docker
|
- docker:
|
||||||
│ └── code-server
|
- code-server:
|
||||||
│ └── config
|
- compose.yaml
|
||||||
└── #any folder you want to mount in VS Code
|
- .env
|
||||||
```
|
- config/
|
||||||
|
- (any folder you want to mount in VS Code)/
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
Open Dockge, click on `compose`, name the stack `code-server`, and paste the following:
|
Open Dockge, click on `compose`, name the stack `code-server`, and paste the following:
|
||||||
|
|
||||||
|
|||||||
@@ -17,14 +17,18 @@ description: Install Forgejo, a lightweight self-hosted Git service to manage yo
|
|||||||
[Forgejo](https://forgejo.org/) is a self-hosted DevOps platform that allows you to manage repositories much like GitHub, but on your own infrastructure. It's a community-driven fork of Gitea.
|
[Forgejo](https://forgejo.org/) is a self-hosted DevOps platform that allows you to manage repositories much like GitHub, but on your own infrastructure. It's a community-driven fork of Gitea.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
Folder structure
|
|
||||||
|
|
||||||
```text [Directory tree]
|
::file-tree
|
||||||
root
|
---
|
||||||
└── docker
|
tree:
|
||||||
└── forgejo
|
/:
|
||||||
└── data
|
- docker:
|
||||||
```
|
- forgejo:
|
||||||
|
- compose.yaml
|
||||||
|
- .env
|
||||||
|
- data/
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
Open Dockge, click on `compose`, name the stack `forgejo`, and paste the following content:
|
Open Dockge, click on `compose`, name the stack `forgejo`, and paste the following content:
|
||||||
|
|
||||||
|
|||||||
@@ -38,17 +38,19 @@ This is how ads and malicious domains are blocked: Adguard blocks only the bad d
|
|||||||

|

|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
Folder structure:
|
|
||||||
|
|
||||||
```text [Directory tree]
|
::file-tree
|
||||||
root
|
---
|
||||||
└── docker
|
tree:
|
||||||
└── adguard
|
/:
|
||||||
├── confdir
|
- docker:
|
||||||
├── workdir
|
- adguard:
|
||||||
├── compose.yaml
|
- confdir/
|
||||||
└── .env
|
- workdir/
|
||||||
```
|
- compose.yaml
|
||||||
|
- .env
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
::note
|
::note
|
||||||
|
|
||||||
|
|||||||
@@ -18,16 +18,18 @@ description: Install Vaultwarden, a self-hosted Bitwarden-compatible password ma
|
|||||||
Vaultwarden is a fork of [Bitwarden](https://bitwarden.com/fr-fr/help/).
|
Vaultwarden is a fork of [Bitwarden](https://bitwarden.com/fr-fr/help/).
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
Folder structure:
|
|
||||||
|
|
||||||
```text [Directory tree]
|
::file-tree
|
||||||
root
|
---
|
||||||
└── docker
|
tree:
|
||||||
└── vaultwarden
|
/:
|
||||||
├── data
|
- docker:
|
||||||
├── compose.yaml
|
- vaultwarden:
|
||||||
└── .env
|
- data/
|
||||||
```
|
- compose.yaml
|
||||||
|
- .env
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
Open Dockge, click on `compose`, name the stack `vaultwarden`, and paste the following:
|
Open Dockge, click on `compose`, name the stack `vaultwarden`, and paste the following:
|
||||||
|
|
||||||
|
|||||||
@@ -11,17 +11,19 @@ Six months after downloading terabytes of media, I realized that Sonarr and Rada
|
|||||||
|
|
||||||
So I restructured my directories, manually updated every path in Qbittorrent, Plex, and others. The last challenge was finding a way to detect existing duplicates, delete them, and automatically create hardlinks instead, to save space.
|
So I restructured my directories, manually updated every path in Qbittorrent, Plex, and others. The last challenge was finding a way to detect existing duplicates, delete them, and automatically create hardlinks instead, to save space.
|
||||||
|
|
||||||
My directory structure:
|
::file-tree
|
||||||
|
---
|
||||||
```text [Directory tree]
|
label: My directory structure
|
||||||
.
|
tree:
|
||||||
└── media
|
.:
|
||||||
├── seedbox
|
- media:
|
||||||
├── radarr
|
- seedbox/
|
||||||
│ └── tv-radarr
|
- radarr:
|
||||||
├── movies
|
- tv-radarr/
|
||||||
└── tvseries
|
- movies/
|
||||||
```
|
- tvseries/
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
The originals are in `seedbox` and must not be modified to keep seeding. The copies (duplicates) are in `movies` and `tvseries`. To complicate things, there are also unique originals in `movies` and `tvseries`. And within those, there can be subfolders, sub-subfolders, etc.
|
The originals are in `seedbox` and must not be modified to keep seeding. The copies (duplicates) are in `movies` and `tvseries`. To complicate things, there are also unique originals in `movies` and `tvseries`. And within those, there can be subfolders, sub-subfolders, etc.
|
||||||
|
|
||||||
|
|||||||
@@ -59,17 +59,18 @@ So only VPN-connected devices can communicate with each other on the VPN, not wi
|
|||||||
__Warning:__ This guide uses version `14` of [wg-easy](https://wg-easy.github.io/wg-easy/latest/). Version `15` introduces breaking changes incompatible with this configuration.
|
__Warning:__ This guide uses version `14` of [wg-easy](https://wg-easy.github.io/wg-easy/latest/). Version `15` introduces breaking changes incompatible with this configuration.
|
||||||
::
|
::
|
||||||
|
|
||||||
Folder structure:
|
::file-tree
|
||||||
|
---
|
||||||
```text [Directory tree]
|
tree:
|
||||||
root
|
/:
|
||||||
└── docker
|
- docker:
|
||||||
└── wg-easy
|
- wg-easy:
|
||||||
├── config
|
- config:
|
||||||
│ └── etc_wireguard
|
- etc_wireguard/
|
||||||
├── compose.yaml
|
- compose.yaml
|
||||||
└── .env
|
- .env
|
||||||
```
|
---
|
||||||
|
::
|
||||||
|
|
||||||
The container runs in `HOST` mode, meaning it uses the host’s network stack directly.
|
The container runs in `HOST` mode, meaning it uses the host’s network stack directly.
|
||||||
|
|
||||||
@@ -171,16 +172,17 @@ If it fails, check firewall rules.
|
|||||||
Assumes the client is a Linux server with Docker installed
|
Assumes the client is a Linux server with Docker installed
|
||||||
::
|
::
|
||||||
|
|
||||||
Folder structure:
|
::file-tree
|
||||||
|
---
|
||||||
```text [Directory tree]
|
tree:
|
||||||
root
|
/:
|
||||||
└── docker
|
- docker:
|
||||||
└── wireguard
|
- wireguard:
|
||||||
└── config
|
- config:
|
||||||
│ └── wg_confs
|
- wg_confs/
|
||||||
└── compose.yaml
|
- compose.yaml
|
||||||
```
|
---
|
||||||
|
::
|
||||||
|
|
||||||
Create the folder `/docker/wireguard/config/wg_confs`:
|
Create the folder `/docker/wireguard/config/wg_confs`:
|
||||||
|
|
||||||
|
|||||||
@@ -32,22 +32,25 @@ You’ll need to create a *Plex.tv* account. You don’t need to expose your Ple
|
|||||||
::
|
::
|
||||||
|
|
||||||
## Install Plex
|
## Install Plex
|
||||||
Folder structure:
|
|
||||||
```text [Directory tree]
|
::file-tree
|
||||||
root
|
---
|
||||||
├── docker
|
tree:
|
||||||
│ ├── plex
|
/:
|
||||||
│ │ ├── compose.yml
|
- docker:
|
||||||
│ │ ├── .env
|
- plex:
|
||||||
│ │ ├── config
|
- compose.yml
|
||||||
│ │ └── transcode
|
- .env
|
||||||
│ └── tautulli
|
- config/
|
||||||
│ └── config
|
- transcode/
|
||||||
└── media
|
- tautulli:
|
||||||
├── tvseries
|
- config/
|
||||||
├── movies
|
- media:
|
||||||
└── library
|
- tvseries/
|
||||||
```
|
- movies/
|
||||||
|
- library/
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
Create the `movies`, `tvseries`, and `library` folders in `/media`:
|
Create the `movies`, `tvseries`, and `library` folders in `/media`:
|
||||||
|
|
||||||
|
|||||||
@@ -29,23 +29,24 @@ Here’s the system we’ll set up:
|
|||||||

|

|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
Folder structure
|
|
||||||
|
|
||||||
```text [Directory tree]
|
::file-tree
|
||||||
root
|
---
|
||||||
├── docker
|
tree:
|
||||||
│ └── seedbox
|
/:
|
||||||
│ ├── qbittorrent
|
- docker:
|
||||||
│ │ └── config
|
- seedbox:
|
||||||
│ ├── gluetun
|
- qbittorrent:
|
||||||
│ ├── compose.yaml
|
- config/
|
||||||
│ └── .env
|
- gluetun/
|
||||||
│
|
- compose.yaml
|
||||||
└── media #linked to Plex and Qbittorrent
|
- .env
|
||||||
├── downloads #generic downloads, selected in settings
|
- "media # linked to Plex and Qbittorrent":
|
||||||
├── movies #used for downloading movies
|
- "downloads/ # generic downloads, selected in settings"
|
||||||
└── tvseries #used for downloading TV shows
|
- "movies/ # used for downloading movies"
|
||||||
```
|
- "tvseries/ # used for downloading TV shows"
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
If not already done, create the `downloads` folder under `/media`:
|
If not already done, create the `downloads` folder under `/media`:
|
||||||
|
|
||||||
|
|||||||
@@ -28,33 +28,34 @@ We’ll start by deploying the stack and then proceed to configure each app and
|
|||||||
|
|
||||||
### Docker Compose
|
### Docker Compose
|
||||||
|
|
||||||
Folder structure:
|
::file-tree
|
||||||
|
---
|
||||||
```text [Directory tree]
|
tree:
|
||||||
root
|
/:
|
||||||
├── docker
|
- docker:
|
||||||
│ ├── plex
|
- plex:
|
||||||
│ │ ├── compose.yml
|
- compose.yml
|
||||||
│ │ ├── config
|
- config/
|
||||||
│ │ └── transcode
|
- transcode/
|
||||||
│ ├── tautulli
|
- tautulli:
|
||||||
│ │ └── config
|
- config/
|
||||||
│ ├── sonarr
|
- sonarr:
|
||||||
│ │ └── config
|
- config/
|
||||||
│ ├── radarr
|
- radarr:
|
||||||
│ │ └── config
|
- config/
|
||||||
│ ├── bazarr
|
- bazarr:
|
||||||
│ │ └── config
|
- config/
|
||||||
│ ├── prowlarr
|
- prowlarr:
|
||||||
│ │ └── config
|
- config/
|
||||||
│ └── overseerr
|
- overseerr:
|
||||||
│ └── config
|
- config/
|
||||||
└── media
|
- media:
|
||||||
├── downloads
|
- downloads/
|
||||||
├── tvseries
|
- tvseries/
|
||||||
├── movies
|
- movies/
|
||||||
└── library
|
- library/
|
||||||
```
|
---
|
||||||
|
::
|
||||||
|
|
||||||
::warning
|
::warning
|
||||||
|
|
||||||
|
|||||||
@@ -19,14 +19,16 @@ description: Install Gitea, a lightweight self-hosted Git service to manage your
|
|||||||

|

|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
Folder structure
|
|
||||||
|
|
||||||
```text [Directory tree]
|
::file-tree
|
||||||
root
|
---
|
||||||
└── docker
|
tree:
|
||||||
└── gitea
|
/:
|
||||||
└── data
|
- docker:
|
||||||
```
|
- gitea:
|
||||||
|
- data/
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
Open Dockge, click on `compose`, name the stack `gitea`, and paste the following content:
|
Open Dockge, click on `compose`, name the stack `gitea`, and paste the following content:
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user