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.
|
||||
|
||||
## Installation
|
||||
Folder structure:
|
||||
```text [Directory tree]
|
||||
root
|
||||
└── docker
|
||||
└── authentik
|
||||
├── .env
|
||||
├── compose.yml
|
||||
├── media
|
||||
├── certs
|
||||
├── custom-template
|
||||
└── ssh
|
||||
```
|
||||
|
||||
::file-tree
|
||||
---
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- authentik:
|
||||
- .env
|
||||
- compose.yml
|
||||
- media/
|
||||
- certs/
|
||||
- custom-template/
|
||||
- ssh/
|
||||
---
|
||||
::
|
||||
|
||||
::steps{level="3"}
|
||||
### Create the folders
|
||||
|
||||
@@ -62,14 +62,16 @@ sudo mkdir /docker
|
||||
|
||||
### Configuration
|
||||
|
||||
File structure we will create:
|
||||
|
||||
```text [Directory tree]
|
||||
root
|
||||
└── docker
|
||||
└── dockge
|
||||
└── compose.yml
|
||||
```
|
||||
::file-tree
|
||||
---
|
||||
label: File structure we will create
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- dockge:
|
||||
- compose.yml
|
||||
---
|
||||
::
|
||||
|
||||
::steps{level="4"}
|
||||
#### 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`.
|
||||
::
|
||||
|
||||
File structure to be modified:
|
||||
|
||||
```text [Directory tree]
|
||||
root
|
||||
└── docker
|
||||
└── swag
|
||||
├── config
|
||||
│ ├── dns-conf
|
||||
│ │ └── ovh.ini
|
||||
│ └── nginx
|
||||
│ ├── dbip.conf
|
||||
│ ├── nginx.conf
|
||||
│ └── proxy-confs
|
||||
│ └── dockge.subdomain.conf
|
||||
├── compose.yml
|
||||
└── .env
|
||||
```
|
||||
::file-tree
|
||||
---
|
||||
label: File structure to modify
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- swag:
|
||||
- config:
|
||||
- dns-conf:
|
||||
- ovh.ini
|
||||
- nginx:
|
||||
- dbip.conf
|
||||
- nginx.conf
|
||||
- proxy-confs:
|
||||
- dockge.subdomain.conf
|
||||
- compose.yml
|
||||
- .env
|
||||
---
|
||||
::
|
||||
|
||||
::steps{level="3"}
|
||||
### Deploy the stack
|
||||
|
||||
@@ -53,15 +53,18 @@ __Warning__: If your IP is not static, use a Dynamic DNS service ([DynDNS](https
|
||||
|
||||
### Folder Structure
|
||||
|
||||
```text [Directory tree]
|
||||
root
|
||||
└── docker
|
||||
└── wg-easy
|
||||
├── config
|
||||
│ └── etc_wireguard
|
||||
├── compose.yaml
|
||||
└── .env
|
||||
```
|
||||
::file-tree
|
||||
---
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- wg-easy:
|
||||
- config:
|
||||
- etc_wireguard/
|
||||
- compose.yaml
|
||||
- .env
|
||||
---
|
||||
::
|
||||
|
||||
::steps{level="3"}
|
||||
### Deploy the stack
|
||||
@@ -190,14 +193,17 @@ We assume the client server runs Linux with Docker installed.
|
||||
|
||||
### Folder Structure
|
||||
|
||||
```text [Directory tree]
|
||||
root
|
||||
└── docker
|
||||
└── wireguard
|
||||
└── config
|
||||
│ └── wg_confs
|
||||
└── compose.yaml
|
||||
```
|
||||
::file-tree
|
||||
---
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- wireguard:
|
||||
- config:
|
||||
- wg_confs/
|
||||
- compose.yaml
|
||||
---
|
||||
::
|
||||
|
||||
::steps{level="3"}
|
||||
### 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)
|
||||
|
||||
## Installation
|
||||
Folder structure:
|
||||
```text [Directory tree]
|
||||
root
|
||||
└── docker
|
||||
└── pocket-id
|
||||
├── compose.yaml
|
||||
├── .env
|
||||
└── data
|
||||
```
|
||||
|
||||
::file-tree
|
||||
---
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- pocket-id:
|
||||
- compose.yaml
|
||||
- .env
|
||||
- data/
|
||||
---
|
||||
::
|
||||
|
||||
::steps{level="3"}
|
||||
### Create the data folder
|
||||
|
||||
@@ -19,15 +19,18 @@ This guide assumes you've already installed [Pocket ID](/serveex/security/pocket
|
||||
::
|
||||
|
||||
## Installation
|
||||
Folder structure:
|
||||
```text [Directory tree]
|
||||
root
|
||||
└── docker
|
||||
└── tinyauth
|
||||
├── compose.yaml
|
||||
├── .env
|
||||
└── data
|
||||
```
|
||||
|
||||
::file-tree
|
||||
---
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- tinyauth:
|
||||
- compose.yaml
|
||||
- .env
|
||||
- data/
|
||||
---
|
||||
::
|
||||
|
||||
::steps{level="3"}
|
||||
### Create the data folder
|
||||
|
||||
@@ -9,15 +9,17 @@ description: Install Uptime-Kuma to monitor your self-hosted services uptime, se
|
||||

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

|
||||
|
||||
## Installation
|
||||
Folder structure
|
||||
|
||||
```text [Directory tree]
|
||||
root
|
||||
└── docker
|
||||
└── dozzle
|
||||
└── data
|
||||
```
|
||||
::file-tree
|
||||
---
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- dozzle:
|
||||
- compose.yaml
|
||||
- .env
|
||||
- data/
|
||||
---
|
||||
::
|
||||
|
||||
::steps{level="3"}
|
||||
### 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/)
|
||||
::
|
||||
|
||||
File structure:
|
||||
::file-tree
|
||||
---
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- speedtest-tracker:
|
||||
- compose.yaml
|
||||
- .env
|
||||
- data:
|
||||
- config/
|
||||
---
|
||||
::
|
||||
|
||||
```text [Directory tree]
|
||||
root
|
||||
└── docker
|
||||
└── speedtest-tracker
|
||||
└── data
|
||||
└── config
|
||||
```
|
||||
::steps{level="3"}
|
||||
### Generate an app key
|
||||
|
||||
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.
|
||||
|
||||
### Deploy the stack
|
||||
|
||||
Open Dockge, click on `compose`, name the stack `speedtest-tracker`, then paste the following:
|
||||
|
||||
```yaml [compose.yaml]
|
||||
@@ -67,6 +75,8 @@ services:
|
||||
- /docker/speedtest-tracker/data/config:/config
|
||||
```
|
||||
|
||||
### Set your environment variables
|
||||
|
||||
Find your `PUID` and `GUID` by running the following command:
|
||||
|
||||
```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!
|
||||
|
||||
## Expose Speedtest Tracker
|
||||
### Done !
|
||||
::
|
||||
|
||||
## Exposing Speedtest Tracker with SWAG
|
||||
::note
|
||||
📋 **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).
|
||||
@@ -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).
|
||||
::
|
||||
|
||||
::steps{level="3"}
|
||||
### Create the subdomain.conf file
|
||||
|
||||
Open the `speedtest.subdomain.conf` file:
|
||||
|
||||
```bash [Terminal]
|
||||
@@ -155,6 +171,8 @@ server {
|
||||
|
||||
Save and exit. The configuration will update in a few seconds.
|
||||
|
||||
### Add Speedtest Tracker's network to SWAG
|
||||
|
||||
::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`.
|
||||
@@ -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`.
|
||||
::
|
||||
|
||||
### 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).
|
||||
|
||||
## 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
|
||||
|
||||
Folder structure
|
||||
|
||||
```text [Directory tree]
|
||||
root
|
||||
└── docker
|
||||
└── beszel
|
||||
├── data
|
||||
└── socket
|
||||
```
|
||||
::file-tree
|
||||
---
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- beszel:
|
||||
- compose.yaml
|
||||
- .env
|
||||
- data/
|
||||
- socket/
|
||||
---
|
||||
::
|
||||
|
||||
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
|
||||
|
||||
Folder structure
|
||||
|
||||
```text [Directory tree]
|
||||
root
|
||||
└── docker
|
||||
└── upsnap
|
||||
└── data
|
||||
```
|
||||
::file-tree
|
||||
---
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- upsnap:
|
||||
- compose.yaml
|
||||
- .env
|
||||
- data/
|
||||
---
|
||||
::
|
||||
|
||||
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
|
||||
Folder structure:
|
||||
```text [Directory tree]
|
||||
root
|
||||
├── docker
|
||||
│ └── jellyfin
|
||||
│ ├── compose.yaml
|
||||
│ ├── .env
|
||||
│ └── config
|
||||
└── media
|
||||
├── tvseries
|
||||
├── movies
|
||||
└── library
|
||||
```
|
||||
|
||||
::file-tree
|
||||
---
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- jellyfin:
|
||||
- compose.yaml
|
||||
- .env
|
||||
- config/
|
||||
- media:
|
||||
- tvseries/
|
||||
- movies/
|
||||
- library/
|
||||
---
|
||||
::
|
||||
|
||||
Create the `movies`, `tvseries`, and `library` folders in `/media`:
|
||||
|
||||
|
||||
@@ -29,23 +29,24 @@ Here’s the system we’ll set up:
|
||||

|
||||
|
||||
## Configuration
|
||||
Folder structure
|
||||
|
||||
```text [Directory tree]
|
||||
root
|
||||
├── docker
|
||||
│ └── seedbox
|
||||
│ ├── qbittorrent
|
||||
│ │ └── config
|
||||
│ ├── gluetun
|
||||
│ ├── compose.yaml
|
||||
│ └── .env
|
||||
│
|
||||
└── media #linked to Jellyfin and Qbittorrent
|
||||
├── downloads #generic downloads, selected in settings
|
||||
├── movies #used for downloading movies
|
||||
└── tvseries #used for downloading TV shows
|
||||
```
|
||||
::file-tree
|
||||
---
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- seedbox:
|
||||
- qbittorrent:
|
||||
- config/
|
||||
- gluetun/
|
||||
- compose.yaml
|
||||
- .env
|
||||
- "media # linked to Jellyfin and Qbittorrent":
|
||||
- "downloads/ # generic downloads, selected in settings"
|
||||
- "movies/ # used for downloading movies"
|
||||
- "tvseries/ # used for downloading TV shows"
|
||||
---
|
||||
::
|
||||
|
||||
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
|
||||
|
||||
Folder structure:
|
||||
|
||||
```text [Directory tree]
|
||||
root
|
||||
├── docker
|
||||
│ ├── jellyfin
|
||||
│ │ ├── compose.yml
|
||||
│ │ └── config
|
||||
│ ├── sonarr
|
||||
│ │ └── config
|
||||
│ ├── radarr
|
||||
│ │ └── config
|
||||
│ ├── bazarr
|
||||
│ │ └── config
|
||||
│ ├── prowlarr
|
||||
│ │ └── config
|
||||
│ └── seerr
|
||||
│ └── config
|
||||
└── media
|
||||
├── downloads
|
||||
├── tvseries
|
||||
├── movies
|
||||
└── library
|
||||
```
|
||||
::file-tree
|
||||
---
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- jellyfin:
|
||||
- compose.yml
|
||||
- .env
|
||||
- config/
|
||||
- sonarr:
|
||||
- config/
|
||||
- radarr:
|
||||
- config/
|
||||
- bazarr:
|
||||
- config/
|
||||
- prowlarr:
|
||||
- config/
|
||||
- seerr:
|
||||
- config/
|
||||
- media:
|
||||
- downloads/
|
||||
- tvseries/
|
||||
- movies/
|
||||
- library/
|
||||
---
|
||||
::
|
||||
|
||||
::warning
|
||||
|
||||
|
||||
@@ -16,16 +16,18 @@ description: Install Immich, a self-hosted alternative to Google Photos and iClo
|
||||

|
||||
|
||||
## Installation
|
||||
Folder structure
|
||||
|
||||
```text [Directory tree]
|
||||
root
|
||||
└── docker
|
||||
└── immich
|
||||
├── library
|
||||
├── compose.yaml
|
||||
└── .env
|
||||
```
|
||||
::file-tree
|
||||
---
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- immich:
|
||||
- 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).
|
||||
|
||||
|
||||
@@ -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/)
|
||||
::
|
||||
|
||||
File structure:
|
||||
|
||||
```text [Directory tree]
|
||||
root
|
||||
└── docker
|
||||
└── nextcloud
|
||||
├── config
|
||||
├── data
|
||||
├── compose.yaml
|
||||
└── .env
|
||||
```
|
||||
::file-tree
|
||||
---
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- nextcloud:
|
||||
- config/
|
||||
- data/
|
||||
- compose.yaml
|
||||
- .env
|
||||
---
|
||||
::
|
||||
|
||||
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.
|
||||
|
||||
## Installation
|
||||
Folder structure:
|
||||
```text [Directory tree]
|
||||
root
|
||||
└── docker
|
||||
└── filebrowser-quantum
|
||||
├── compose.yaml
|
||||
└── data
|
||||
├── config.yaml
|
||||
└── filebrowser.sqlite
|
||||
```
|
||||
|
||||
::file-tree
|
||||
---
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- filebrowser-quantum:
|
||||
- compose.yaml
|
||||
- data:
|
||||
- config.yaml
|
||||
- filebrowser.sqlite
|
||||
---
|
||||
::
|
||||
|
||||
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/).
|
||||
::
|
||||
|
||||
Folder structure
|
||||
|
||||
```text [Directory tree]
|
||||
root
|
||||
├── docker
|
||||
│ └── code-server
|
||||
│ └── config
|
||||
└── #any folder you want to mount in VS Code
|
||||
```
|
||||
::file-tree
|
||||
---
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- code-server:
|
||||
- compose.yaml
|
||||
- .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:
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
## Installation
|
||||
Folder structure
|
||||
|
||||
```text [Directory tree]
|
||||
root
|
||||
└── docker
|
||||
└── forgejo
|
||||
└── data
|
||||
```
|
||||
::file-tree
|
||||
---
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- forgejo:
|
||||
- compose.yaml
|
||||
- .env
|
||||
- data/
|
||||
---
|
||||
::
|
||||
|
||||
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
|
||||
Folder structure:
|
||||
|
||||
```text [Directory tree]
|
||||
root
|
||||
└── docker
|
||||
└── adguard
|
||||
├── confdir
|
||||
├── workdir
|
||||
├── compose.yaml
|
||||
└── .env
|
||||
```
|
||||
::file-tree
|
||||
---
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- adguard:
|
||||
- confdir/
|
||||
- workdir/
|
||||
- compose.yaml
|
||||
- .env
|
||||
---
|
||||
::
|
||||
|
||||
::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/).
|
||||
|
||||
## Installation
|
||||
Folder structure:
|
||||
|
||||
```text [Directory tree]
|
||||
root
|
||||
└── docker
|
||||
└── vaultwarden
|
||||
├── data
|
||||
├── compose.yaml
|
||||
└── .env
|
||||
```
|
||||
::file-tree
|
||||
---
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- vaultwarden:
|
||||
- data/
|
||||
- compose.yaml
|
||||
- .env
|
||||
---
|
||||
::
|
||||
|
||||
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.
|
||||
|
||||
My directory structure:
|
||||
|
||||
```text [Directory tree]
|
||||
.
|
||||
└── media
|
||||
├── seedbox
|
||||
├── radarr
|
||||
│ └── tv-radarr
|
||||
├── movies
|
||||
└── tvseries
|
||||
```
|
||||
::file-tree
|
||||
---
|
||||
label: My directory structure
|
||||
tree:
|
||||
.:
|
||||
- media:
|
||||
- seedbox/
|
||||
- radarr:
|
||||
- tv-radarr/
|
||||
- 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.
|
||||
|
||||
|
||||
@@ -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.
|
||||
::
|
||||
|
||||
Folder structure:
|
||||
|
||||
```text [Directory tree]
|
||||
root
|
||||
└── docker
|
||||
└── wg-easy
|
||||
├── config
|
||||
│ └── etc_wireguard
|
||||
├── compose.yaml
|
||||
└── .env
|
||||
```
|
||||
::file-tree
|
||||
---
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- wg-easy:
|
||||
- config:
|
||||
- etc_wireguard/
|
||||
- compose.yaml
|
||||
- .env
|
||||
---
|
||||
::
|
||||
|
||||
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
|
||||
::
|
||||
|
||||
Folder structure:
|
||||
|
||||
```text [Directory tree]
|
||||
root
|
||||
└── docker
|
||||
└── wireguard
|
||||
└── config
|
||||
│ └── wg_confs
|
||||
└── compose.yaml
|
||||
```
|
||||
::file-tree
|
||||
---
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- wireguard:
|
||||
- config:
|
||||
- wg_confs/
|
||||
- compose.yaml
|
||||
---
|
||||
::
|
||||
|
||||
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
|
||||
Folder structure:
|
||||
```text [Directory tree]
|
||||
root
|
||||
├── docker
|
||||
│ ├── plex
|
||||
│ │ ├── compose.yml
|
||||
│ │ ├── .env
|
||||
│ │ ├── config
|
||||
│ │ └── transcode
|
||||
│ └── tautulli
|
||||
│ └── config
|
||||
└── media
|
||||
├── tvseries
|
||||
├── movies
|
||||
└── library
|
||||
```
|
||||
|
||||
::file-tree
|
||||
---
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- plex:
|
||||
- compose.yml
|
||||
- .env
|
||||
- config/
|
||||
- transcode/
|
||||
- tautulli:
|
||||
- config/
|
||||
- media:
|
||||
- tvseries/
|
||||
- movies/
|
||||
- library/
|
||||
---
|
||||
::
|
||||
|
||||
Create the `movies`, `tvseries`, and `library` folders in `/media`:
|
||||
|
||||
|
||||
@@ -29,23 +29,24 @@ Here’s the system we’ll set up:
|
||||

|
||||
|
||||
## Configuration
|
||||
Folder structure
|
||||
|
||||
```text [Directory tree]
|
||||
root
|
||||
├── docker
|
||||
│ └── seedbox
|
||||
│ ├── qbittorrent
|
||||
│ │ └── config
|
||||
│ ├── gluetun
|
||||
│ ├── compose.yaml
|
||||
│ └── .env
|
||||
│
|
||||
└── media #linked to Plex and Qbittorrent
|
||||
├── downloads #generic downloads, selected in settings
|
||||
├── movies #used for downloading movies
|
||||
└── tvseries #used for downloading TV shows
|
||||
```
|
||||
::file-tree
|
||||
---
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- seedbox:
|
||||
- qbittorrent:
|
||||
- config/
|
||||
- gluetun/
|
||||
- compose.yaml
|
||||
- .env
|
||||
- "media # linked to Plex and Qbittorrent":
|
||||
- "downloads/ # generic downloads, selected in settings"
|
||||
- "movies/ # used for downloading movies"
|
||||
- "tvseries/ # used for downloading TV shows"
|
||||
---
|
||||
::
|
||||
|
||||
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
|
||||
|
||||
Folder structure:
|
||||
|
||||
```text [Directory tree]
|
||||
root
|
||||
├── docker
|
||||
│ ├── plex
|
||||
│ │ ├── compose.yml
|
||||
│ │ ├── config
|
||||
│ │ └── transcode
|
||||
│ ├── tautulli
|
||||
│ │ └── config
|
||||
│ ├── sonarr
|
||||
│ │ └── config
|
||||
│ ├── radarr
|
||||
│ │ └── config
|
||||
│ ├── bazarr
|
||||
│ │ └── config
|
||||
│ ├── prowlarr
|
||||
│ │ └── config
|
||||
│ └── overseerr
|
||||
│ └── config
|
||||
└── media
|
||||
├── downloads
|
||||
├── tvseries
|
||||
├── movies
|
||||
└── library
|
||||
```
|
||||
::file-tree
|
||||
---
|
||||
tree:
|
||||
/:
|
||||
- docker:
|
||||
- plex:
|
||||
- compose.yml
|
||||
- config/
|
||||
- transcode/
|
||||
- tautulli:
|
||||
- config/
|
||||
- sonarr:
|
||||
- config/
|
||||
- radarr:
|
||||
- config/
|
||||
- bazarr:
|
||||
- config/
|
||||
- prowlarr:
|
||||
- config/
|
||||
- overseerr:
|
||||
- config/
|
||||
- media:
|
||||
- downloads/
|
||||
- tvseries/
|
||||
- movies/
|
||||
- library/
|
||||
---
|
||||
::
|
||||
|
||||
::warning
|
||||
|
||||
|
||||
@@ -19,14 +19,16 @@ description: Install Gitea, a lightweight self-hosted Git service to manage your
|
||||

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