Merge branch 'develop' into app/bookstack

This commit is contained in:
ArneNaessens 2022-06-15 21:31:21 +02:00 committed by GitHub
commit 921cf86880
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
252 changed files with 4960 additions and 1291 deletions

67
.all-contributorsrc Normal file
View file

@ -0,0 +1,67 @@
{
"files": [
"README.md"
],
"imageSize": 100,
"commit": false,
"contributors": [
{
"login": "meienberger",
"name": "Nicolas Meienberger",
"avatar_url": "https://avatars.githubusercontent.com/u/47644445?v=4",
"profile": "https://meienberger.dev/",
"contributions": [
"code",
"infra",
"test",
"doc"
]
},
{
"login": "ArneNaessens",
"name": "ArneNaessens",
"avatar_url": "https://avatars.githubusercontent.com/u/16622722?v=4",
"profile": "https://github.com/ArneNaessens",
"contributions": [
"code",
"ideas",
"test"
]
},
{
"login": "DrMxrcy",
"name": "DrMxrcy",
"avatar_url": "https://avatars.githubusercontent.com/u/58747968?v=4",
"profile": "https://github.com/DrMxrcy",
"contributions": [
"code",
"ideas",
"test"
]
},
{
"login": "CobreDev",
"name": "Cooper",
"avatar_url": "https://avatars.githubusercontent.com/u/36574329?v=4",
"profile": "https://cobre.dev",
"contributions": [
"code"
]
},
{
"login": "JTruj1ll0923",
"name": "JTruj1ll0923",
"avatar_url": "https://avatars.githubusercontent.com/u/6656643?v=4",
"profile": "https://github.com/JTruj1ll0923",
"contributions": [
"code"
]
}
],
"contributorsPerLine": 7,
"projectName": "runtipi",
"projectOwner": "meienberger",
"repoType": "github",
"repoHost": "https://github.com",
"skipCi": true
}

6
.dockerignore Normal file
View file

@ -0,0 +1,6 @@
**/node_modules
**/.next
/node_modules
/.next
node_modules
.next

View file

@ -42,7 +42,22 @@ jobs:
- name: Install dependencies
run: pnpm install
- name: Run tests
- name: Build packages/common
run: |
cd ./packages/common
npm run build
cd ../..
- name: Install dependencies
run: pnpm install
- name: Build packages
run: pnpm -r build
- name: Run global tests
run: pnpm test
- name: Run linter
run: pnpm -r lint
- name: Run tests

View file

@ -1,9 +1,9 @@
name: Release candidate
on:
pull_request:
push:
branches:
- master
- release/*
jobs:
# Build images and publish RCs to DockerHub
@ -12,41 +12,15 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 2
- uses: technote-space/get-diff-action@v6
with:
FILES: |
VERSION
- name: Ensure env.MATCHED_FILES has VERSION in it
id: check-version
run: |
if [[ -z "${{ env.MATCHED_FILES }}" ]]; then
echo "::error::VERSION not modified"
exit 1
fi
if [[ ! "${{ env.MATCHED_FILES }}" =~ VERSION ]]; then
echo "::error::VERSION not modified"
exit 1
fi
- uses: vishnudxb/cancel-workflow@v1.2
if: failure()
with:
repo: meienberger/runtipi
workflow_id: ${{ github.run_id }}
access_token: ${{ github.token }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v2
- name: Login to DockerHub
uses: docker/login-action@v1
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
@ -58,41 +32,15 @@ jobs:
TAG=${VERSION}
echo "::set-output name=tag::${TAG}"
- name: Build and push dashboard
uses: docker/build-push-action@v2
- name: Build and push images
uses: docker/build-push-action@v3
with:
context: ./packages/dashboard
platforms: linux/amd64,linux/arm64
context: .
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true
tags: meienberger/tipi-dashboard:rc-${{ steps.meta.outputs.TAG }}
cache-from: type=registry,ref=meienberger/tipi-dashboard:latest
cache-to: type=inline
- name: Build and push api
uses: docker/build-push-action@v2
with:
context: ./packages/system-api
platforms: linux/amd64,linux/arm64
push: true
tags: meienberger/tipi-api:rc-${{ steps.meta.outputs.TAG }}
cache-from: type=registry,ref=meienberger/tipi-api:latest
cache-to: type=inline
tags: meienberger/runtipi:rc-${{ steps.meta.outputs.TAG }}
cache-from: type=registry,ref=meienberger/runtipi:buildcache
cache-to: type=registry,ref=meienberger/runtipi:buildcache,mode=max
# Test installation script
# test-install:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@master
# - name: Check if user id 1000 exists
# run: |
# if [[ ! $(id -u 1000) -eq 1000 ]]; then
# echo "Creating user 1000"
# sudo useradd -u 1000 test
# fi
# id: check-user-id
# - name: Run install script
# run: sudo ./scripts/start.sh --rc --ci

View file

@ -34,45 +34,34 @@ jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
- name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v1
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
-
name: Login to DockerHub
uses: docker/login-action@v1
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Get tag from VERSION file
- name: Get tag from VERSION file
id: meta
run: |
VERSION=$(cat VERSION)
TAG=${VERSION}
echo "::set-output name=tag::${TAG}"
-
name: Build and push dashboard
uses: docker/build-push-action@v2
- name: Build and push images
uses: docker/build-push-action@v3
with:
context: ./packages/dashboard
platforms: linux/amd64,linux/arm64
context: .
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true
tags: meienberger/tipi-dashboard:latest,meienberger/tipi-dashboard:${{ steps.meta.outputs.TAG }}
cache-from: type=registry,ref=meienberger/tipi-dashboard:latest
cache-to: type=inline
-
name: Build and push api
uses: docker/build-push-action@v2
with:
context: ./packages/system-api
platforms: linux/amd64,linux/arm64
push: true
tags: meienberger/tipi-api:latest,meienberger/tipi-api:${{ steps.meta.outputs.TAG }}
cache-from: type=registry,ref=meienberger/tipi-api:latest
cache-to: type=inline
tags: meienberger/runtipi:latest,meienberger/runtipi:${{ steps.meta.outputs.TAG }}
cache-from: type=registry,ref=meienberger/runtipi:buildcache
cache-to: type=registry,ref=meienberger/runtipi:buildcache,mode=max

22
.gitignore vendored
View file

@ -1,28 +1,28 @@
.pnpm-debug.log
.env
.env*
github.secrets
node_modules/
nginx/*
letsencrypt/*
app-data/*
traefik/ssl/*
!traefik/ssl/.gitkeep
!app-data/.gitkeep
!letsencrypt/mkcert/.gitkeep
scripts/pacapt
state/*
!state/.gitkeep
tipi.config.json
# Commit empty directories
!nignx/.gitkeep
media/data/movies/*
media/data/tv/*
media/data/books/*
!media/data/movies/.gitkeep
!media/data/tv/.gitkeep
!media/data/books/metadata.db
media/torrents/*
!media/torrents/.gitkeep
media/torrents/complete/*
!media/torrents/complete/.gitkeep
media/torrents/incomplete/*
!media/torrents/incomplete/.gitkeep
media/torrents/watch/*
!media/torrents/watch/.gitkeep
packages/dashboard/package-lock.json

View file

@ -1,5 +1,6 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
pnpm test
pnpm -r test
pnpm -r lint

View file

@ -1,7 +1,29 @@
FROM node:18 AS build
RUN npm install node-gyp -g
WORKDIR /common
COPY ./packages/common /common
RUN npm i
RUN npm run build
WORKDIR /api
COPY ./packages/system-api/package.json /api/package.json
RUN npm i
COPY ./packages/system-api /api
RUN npm run build
WORKDIR /dashboard
COPY ./packages/dashboard/package.json /dashboard/package.json
RUN npm i
COPY ./packages/dashboard /dashboard
RUN npm run build
FROM ubuntu:20.04
ARG DEBIAN_FRONTEND=noninteractive
WORKDIR /app
WORKDIR /
# Install docker
RUN apt-get update && apt-get install -y \
@ -10,6 +32,9 @@ RUN apt-get update && apt-get install -y \
gnupg \
lsb-release
RUN apt-get install -y \
g++ gcc make python
RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
RUN echo \
@ -20,17 +45,25 @@ RUN apt-get update
RUN apt-get install -y docker-ce docker-ce-cli containerd.io
# Install node
RUN curl -sL https://deb.nodesource.com/setup_14.x | bash -
RUN curl -sL https://deb.nodesource.com/setup_18.x | bash -
RUN apt-get install -y nodejs
RUN npm install node-gyp -g
# Install docker-compose
RUN curl -L "https://github.com/docker/compose/releases/download/v2.5.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
RUN chmod +x /usr/local/bin/docker-compose
COPY ./package.json ./
COPY --from=build /common /common
RUN npm install
WORKDIR /api
COPY ./packages/system-api/package.json /api/package.json
RUN npm install --omit=dev
COPY ./ ./
WORKDIR /dashboard
COPY ./packages/dashboard/package.json /dashboard/package.json
RUN npm install --omit=dev
CMD ["npm", "run", "dev"]
COPY --from=build /api /api
COPY --from=build /dashboard /dashboard
WORKDIR /

View file

@ -1,7 +1,7 @@
FROM ubuntu:20.04
ARG DEBIAN_FRONTEND=noninteractive
WORKDIR /app
WORKDIR /
# Install docker
RUN apt-get update && apt-get install -y \
@ -20,19 +20,24 @@ RUN apt-get update
RUN apt-get install -y docker-ce docker-ce-cli containerd.io
# Install node
RUN curl -sL https://deb.nodesource.com/setup_14.x | bash -
RUN curl -sL https://deb.nodesource.com/setup_18.x | bash -
RUN apt-get install -y nodejs
# Install docker-compose
RUN curl -L "https://github.com/docker/compose/releases/download/v2.5.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
RUN chmod +x /usr/local/bin/docker-compose
COPY ./package.json ./
COPY ./packages/common /common
WORKDIR /api
COPY ./packages/system-api/package.json /api/package.json
RUN npm install
COPY ./ ./
WORKDIR /dashboard
COPY ./packages/dashboard/package.json /dashboard/package.json
RUN npm install
RUN npm run build
COPY ./packages/system-api /api
COPY ./packages/dashboard /dashboard
CMD ["npm", "run", "start"]
WORKDIR /

View file

@ -1,42 +1,63 @@
# ⛺️ Tipi — A personal homeserver for everyone
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-5-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->
[![License](https://img.shields.io/github/license/meienberger/runtipi)](https://github.com/meienberger/runtipi/blob/master/LICENSE)
[![Version](https://img.shields.io/github/v/release/meienberger/runtipi?color=%235351FB&label=version)](https://github.com/meienberger/runtipi/releases)
![Issues](https://img.shields.io/github/issues/meienberger/runtipi)
[![Docker Pulls](https://badgen.net/docker/pulls/meienberger/tipi-dashboard?icon=docker&label=pulls)](https://hub.docker.com/r/meienberger/tipi-dashboard/)
[![Docker Image Size](https://badgen.net/docker/size/meienberger/tipi-dashboard?icon=docker&label=image%20size)](https://hub.docker.com/r/meienberger/tipi-dashboard/)
![RunsOn](https://img.shields.io/badge/Debian-Supported-green?logo=debian)
![RunsOn](https://img.shields.io/badge/Ubuntu-Supported-green?logo=ubuntu)
[![Docker Pulls](https://badgen.net/docker/pulls/meienberger/runtipi?icon=docker&label=pulls)](https://hub.docker.com/r/meienberger/runtipi/)
[![Docker Image Size](https://badgen.net/docker/size/meienberger/runtipi?icon=docker&label=image%20size)](https://hub.docker.com/r/meienberger/runtipi/)
![Build](https://github.com/meienberger/runtipi/workflows/Tipi%20CI/badge.svg)
![Preview](https://raw.githubusercontent.com/meienberger/runtipi/develop/screenshots/1.png)
#### Join the discussion
[![Discord](https://img.shields.io/discord/976934649643294750?label=discord&logo=discord)](https://discord.gg/Bu9qEPnHsc)
[![Matrix](https://img.shields.io/matrix/runtipi:matrix.org?label=matrix&logo=matrix)](https://matrix.to/#/#runtipi:matrix.org)
![Preview](https://raw.githubusercontent.com/meienberger/runtipi/develop/screenshots/appstore.png)
> ⚠️ Tipi is still at an early stage of development and issues are to be expected. Feel free to open an issue or pull request if you find a bug.
Tipi is a personal homeserver orchestrator. It is running docker containers under the hood and provides a simple web interface to manage them. Every service comes with an opinionated configuration in order to remove the need for manual configuration and network setup.
Check our demo instance : **95.179.210.152** / username: **user@runtipi.com** / password: **runtipi**
## Apps available
- [Adguard Home](https://github.com/AdguardTeam/AdGuardHome) - Adguard Home DNS adblocker
- [Calibre-Web](https://github.com/janeczku/calibre-web) - Web Ebook Reader
- [Code-Server](https://github.com/filebrowser/filebrowser) - Web VS Code
- [Code-Server](https://github.com/coder/code-server) - Web VS Code
- [Filebrowser](https://github.com/filebrowser/filebrowser) - Web File Browser
- [Freshrss](https://github.com/FreshRSS/FreshRSS) - A free, self-hostable RSS aggregator
- [Gitea](https://github.com/go-gitea/gitea) - Gitea - A painless self-hosted Git service
- [Homarr](https://github.com/ajnart/homarr) - A homepage for your server
- [Home Assistant](https://github.com/home-assistant/core) - Open source home automation that puts local control and privacy first
- [Invidious](https://github.com/iv-org/invidious) - An alternative front-end to YouTube
- [Homarr](https://github.com/ajnart/homarr) - A homepage for your server.
- [Jackett](https://github.com/Jackett/Jackett) - API Support for your favorite torrent trackers
- [Jellyfin](https://github.com/jellyfin/jellyfin) - A media server for your home collection
- [Joplin](https://github.com/laurent22/joplin) - Privacy focused note-taking app
- [Libreddit](https://github.com/spikecodes/libreddit) - Private front-end for Reddit
- [Mealie](https://github.com/hay-kot/mealie) - Self-hosted recipe manager and meal planner.
- [n8n](https://github.com/n8n-io/n8n) - Workflow Automation Tool
- [Nextcloud](https://github.com/nextcloud/server) - A safe home for all your data
- [Nitter](https://github.com/zedeus/nitter) - Alternative Twitter front-end
- [Node-RED](https://github.com/node-red/node-red) - Low-code programming for event-driven applications
- [Photoprism](https://github.com/photoprism/photoprism) - AI-Powered Photos App for the Decentralized Web. We are on a mission to protect your freedom and privacy.
- [Pihole](https://github.com/pi-hole/pi-hole) - A black hole for Internet advertisements
- [Radarr](https://github.com/Radarr/Radarr) - Movie collection manager for Usenet and BitTorrent users.
- [Plex](https://github.com/plexinc/pms-docker) - Stream Movies & TV Shows
- [Prowlarr](https://github.com/Prowlarr/Prowlarr/) - A torrent/usenet indexer manager/proxy
- [Radarr](https://github.com/Radarr/Radarr) - Movie collection manager for Usenet and BitTorrent users
- [Resilio Sync](https://github.com/bt-sync) - Fast, reliable, and simple file sync and share solution
- [Sonarr](https://github.com/Sonarr/Sonarr) - TV show manager for Usenet and BitTorrent
- [Syncthing](https://github.com/syncthing/syncthing) - Continuous File Synchronization
- [Tailscale](https://github.com/tailscale/tailscale) - The easiest, most secure way to use WireGuard and 2FA.
- [Tailscale](https://github.com/tailscale/tailscale) - The easiest, most secure way to use WireGuard and 2FA
- [Tautulli](https://github.com/Tautulli/Tautulli) - A Python based monitoring and tracking tool for Plex Media Server
- [Transmission](https://github.com/transmission/transmission) - Fast, easy, and free BitTorrent client
- [Wireguard Easy](https://github.com/WeeJeWel/wg-easy) - WireGuard VPN + Web-based Admin UI
- [Adguard Home](https://github.com/AdguardTeam/AdGuardHome) - Adguard Home DNS adblocker
- [Bookstack](https://github.com/BookStackApp/BookStack) - BookStack is a simple, self-hosted, easy-to-use platform for organising and storing information.
- [Vaultwarden](https://github.com/dani-garcia/vaultwarden) - Unofficial Bitwarden compatible server
## 🛠 Installation
### Installation Requirements
- Ubuntu 18.04 LTS or higher (or Debian 10)
Ubuntu 18.04 LTS or higher is recommended. However other major Linux distribution are supported but may lead to installation issues. Please file an issue if you encounter one.
### Step 1. Download Tipi
Run this in an empty directory where you want to install Tipi.
@ -49,7 +70,8 @@ git clone https://github.com/meienberger/runtipi.git
cd into the downloaded directory and run the start script.
```bash
cd runtipi && sudo ./scripts/start.sh
cd runtipi
sudo ./scripts/start.sh
```
The script will prompt you the ip address of the dashboard once configured.
@ -80,3 +102,28 @@ Tipi is licensed under the GNU General Public License v3.0. TL;DR — You may co
- [Matrix](https://matrix.to/#/#runtipi:matrix.org)<br />
- [Twitter](https://twitter.com/runtipi)
- [Telegram](https://t.me/+72-y10MnLBw2ZGI0)
- [Discord](https://discord.gg/Bu9qEPnHsc)
## Contributors ✨
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
<tr>
<td align="center"><a href="https://meienberger.dev/"><img src="https://avatars.githubusercontent.com/u/47644445?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nicolas Meienberger</b></sub></a><br /><a href="https://github.com/meienberger/runtipi/commits?author=meienberger" title="Code">💻</a> <a href="#infra-meienberger" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="https://github.com/meienberger/runtipi/commits?author=meienberger" title="Tests">⚠️</a> <a href="https://github.com/meienberger/runtipi/commits?author=meienberger" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/ArneNaessens"><img src="https://avatars.githubusercontent.com/u/16622722?v=4?s=100" width="100px;" alt=""/><br /><sub><b>ArneNaessens</b></sub></a><br /><a href="https://github.com/meienberger/runtipi/commits?author=ArneNaessens" title="Code">💻</a> <a href="#ideas-ArneNaessens" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/meienberger/runtipi/commits?author=ArneNaessens" title="Tests">⚠️</a></td>
<td align="center"><a href="https://github.com/DrMxrcy"><img src="https://avatars.githubusercontent.com/u/58747968?v=4?s=100" width="100px;" alt=""/><br /><sub><b>DrMxrcy</b></sub></a><br /><a href="https://github.com/meienberger/runtipi/commits?author=DrMxrcy" title="Code">💻</a> <a href="#ideas-DrMxrcy" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/meienberger/runtipi/commits?author=DrMxrcy" title="Tests">⚠️</a></td>
<td align="center"><a href="https://cobre.dev"><img src="https://avatars.githubusercontent.com/u/36574329?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Cooper</b></sub></a><br /><a href="https://github.com/meienberger/runtipi/commits?author=CobreDev" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/JTruj1ll0923"><img src="https://avatars.githubusercontent.com/u/6656643?v=4?s=100" width="100px;" alt=""/><br /><sub><b>JTruj1ll0923</b></sub></a><br /><a href="https://github.com/meienberger/runtipi/commits?author=JTruj1ll0923" title="Code">💻</a></td>
</tr>
</table>
<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!

View file

@ -1 +1 @@
0.1.5
0.3.0

View file

@ -1,2 +0,0 @@
[defaults]
INVENTORY = hosts

View file

@ -1,4 +0,0 @@
packages:
- jq
- coreutils
- docker

View file

@ -1,2 +0,0 @@
[localhost]
tipi ansible_connection=local

View file

@ -1,9 +0,0 @@
---
- hosts: tipi
become: yes
tasks:
- import_tasks: ./tasks/common/essential.yml
- import_tasks: ./tasks/common/docker.yml
# - name: Reboot machine
# reboot:

View file

@ -1,6 +0,0 @@
---
- hosts: tipi
become: yes
tasks:
- import_tasks: ./tasks/common/teardown.yml

View file

@ -1,67 +0,0 @@
- name: Install docker
package:
name:
- docker
- ca-certificates
- curl
- gnupg
- lsb-release
state: latest
- name: Check lsb_release -cs
shell: lsb_release -is
register: lsb_release
- name: Add docker gpg key (Ubuntu)
shell: curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
when: lsb_release.stdout == 'Ubuntu'
- name: Add docker gpg key (Debian)
shell: curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
when: lsb_release.stdout == 'Debian'
- name: Add deb repo for docker (Ubuntu)
shell: echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
when: lsb_release.stdout == 'Ubuntu'
- name: Add deb repo for docker (Debian)
shell: echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
when: lsb_release.stdout == 'Debian'
- name: Update packages
apt:
update_cache: yes
upgrade: yes
- name: Install essential packages
package:
name:
- docker-ce
- docker-ce-cli
- containerd.io
state: latest
- name: Check if docker-compose is installed
stat:
path: /usr/local/bin/docker-compose
register: docker_compose_status
- name: Install docker-compose
shell: 'curl -L "https://github.com/docker/compose/releases/download/v2.3.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose'
when: not docker_compose_status.stat.exists
- name: Make docker-compose executable
shell: chmod +x /usr/local/bin/docker-compose
- name: Create group docker
group:
name: docker
- name: Put user in docker group
shell: usermod -aG docker {{ username }}
- name: Start docker service
service:
enabled: yes
name: docker
state: started

View file

@ -1,33 +0,0 @@
- name: Update packages
apt:
update_cache: yes
upgrade: yes
- name: Install essential packages
package:
name: "{{ packages }}"
state: latest
- name: Upgrade packages
apt:
upgrade: yes
- name: Add user to root group
user:
name: "{{ username }}"
group: root
- name: "Enable passwordless sudo for {{ username }}"
lineinfile:
dest: /etc/sudoers
regexp: "^%wheel"
line: "{{ username }} ALL=(ALL) NOPASSWD: ALL"
validate: "/usr/sbin/visudo -cf %s"
- name: Create cron every minute running system-info.sh
cron:
name: "system-info"
user: "{{ username }}"
minute: "*/1"
job: "{{ playbook_dir }}/../scripts/system-info.sh"
ignore_errors: yes

View file

@ -1,18 +0,0 @@
- name: Check if pm2 is installed
become_user: "{{ username }}"
stat:
path: /usr/local/bin/pm2
register: pm2_status
- name: Check if app is already running
become_user: "{{ username }}"
shell: pm2 list
register: pm2_result
when: pm2_status.stat.exists
- name: Stop app
become_user: "{{ username }}"
shell: pm2 stop "system-api"
when:
- pm2_status.stat.exists
- pm2_result.stdout.find("system-api") != -1

View file

@ -1,44 +0,0 @@
# Network
- name: Install avahi
package:
name: avahi
state: latest
when: ansible_os_family == "Arch"
- name: Install avahi
package:
name: avahi-daemon
state: latest
when: ansible_os_family == "Debian"
- name: Disable and stop sytemd-resolved
service:
name: systemd-resolved
state: stopped
enabled: no
- name: Replace line in /etc/nsswitch.conf
lineinfile:
path: /etc/nsswitch.conf
regexp: '^hosts:.*'
line: 'hosts: mymachines mdns_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] files myhostname dns'
- name: Allow port 5353 in UFW
community.general.ufw:
rule: allow
port: 5353
proto: udp
- name: Copy avahi template to /etc/avahi/services/tipi.service
copy:
src: "{{ playbook_dir }}/templates/avahi/tipi.service"
dest: /etc/avahi/services/tipi.service
group: avahi
owner: avahi
- name: Start and enable avahi-daemon
service:
name: avahi-daemon
state: restarted
enabled: yes
###

View file

@ -1,16 +0,0 @@
<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
<name replace-wildcards="yes">%h</name>
<service>
<type>_http._tcp</type>
<port>80</port>
</service>
</service-group>
<!-- <service-group>
<name replace-wildcards="yes">%h</name>
<service>
<type>_http._tcp</type>
<port>443</port>
</service>
</service-group> -->

176
apps/__tests__/apps.test.ts Normal file
View file

@ -0,0 +1,176 @@
import fs from "fs";
import jsyaml from "js-yaml";
interface AppConfig {
id: string;
port: number;
categories: string[];
requirements?: {
ports?: number[];
};
name: string;
description: string;
version: string;
image: string;
short_desc: string;
author: string;
source: string;
available: boolean;
}
const networkExceptions = ["pihole", "tailscale", "homeassistant", "plex"];
const getAppConfigs = (): AppConfig[] => {
const apps: AppConfig[] = [];
const appsDir = fs.readdirSync("./apps");
appsDir.forEach((app) => {
const path = `./apps/${app}/config.json`;
if (fs.existsSync(path)) {
const configFile = fs.readFileSync(path).toString();
try {
const config: AppConfig = JSON.parse(configFile);
if (config.available) {
apps.push(config);
}
} catch (e) {
console.error("Error parsing config file", app);
}
}
});
return apps;
};
describe("App configs", () => {
it("Get app config should return at least one app", () => {
const apps = getAppConfigs();
expect(apps.length).toBeGreaterThan(0);
});
it("Each app should have an id", () => {
const apps = getAppConfigs();
apps.forEach((app) => {
expect(app.id).toBeDefined();
});
});
it("Each app should have a md description", () => {
const apps = getAppConfigs();
apps.forEach((app) => {
const path = `./apps/${app.id}/metadata/description.md`;
if (fs.existsSync(path)) {
const description = fs.readFileSync(path).toString();
expect(description).toBeDefined();
} else {
console.error(`Missing description for app ${app.id}`);
expect(true).toBe(false);
}
});
});
it("Each app should have categories defined as an array", () => {
const apps = getAppConfigs();
apps.forEach((app) => {
expect(app.categories).toBeDefined();
expect(app.categories).toBeInstanceOf(Array);
});
});
it("Each app should have a name", () => {
const apps = getAppConfigs();
apps.forEach((app) => {
expect(app.name).toBeDefined();
});
});
it("Each app should have a description", () => {
const apps = getAppConfigs();
apps.forEach((app) => {
expect(app.description).toBeDefined();
});
});
it("Each app should have a port", () => {
const apps = getAppConfigs();
apps.forEach((app) => {
expect(app.port).toBeDefined();
expect(app.port).toBeGreaterThan(999);
expect(app.port).toBeLessThan(65535);
});
});
it("Each app should have a different port", () => {
const appConfigs = getAppConfigs();
const ports = appConfigs.map((app) => app.port);
expect(new Set(ports).size).toBe(appConfigs.length);
});
it("Each app should have a unique id", () => {
const appConfigs = getAppConfigs();
const ids = appConfigs.map((app) => app.id);
expect(new Set(ids).size).toBe(appConfigs.length);
});
it("Each app should have a docker-compose file beside it", () => {
const apps = getAppConfigs();
apps.forEach((app) => {
expect(fs.existsSync(`./apps/${app.id}/docker-compose.yml`)).toBe(true);
});
});
it("Each app should have a container name equals to its id", () => {
const apps = getAppConfigs();
apps.forEach((app) => {
const dockerComposeFile = fs
.readFileSync(`./apps/${app.id}/docker-compose.yml`)
.toString();
const dockerCompose: any = jsyaml.load(dockerComposeFile);
if (!dockerCompose.services[app.id]) {
console.error(app.id);
}
expect(dockerCompose.services[app.id]).toBeDefined();
expect(dockerCompose.services[app.id].container_name).toBe(app.id);
});
});
it("Each app should have network tipi_main_network", () => {
const apps = getAppConfigs();
apps.forEach((app) => {
if (!networkExceptions.includes(app.id)) {
const dockerComposeFile = fs
.readFileSync(`./apps/${app.id}/docker-compose.yml`)
.toString();
const dockerCompose: any = jsyaml.load(dockerComposeFile);
expect(dockerCompose.services[app.id]).toBeDefined();
if (!dockerCompose.services[app.id].networks) {
console.error(app.id);
}
expect(dockerCompose.services[app.id].networks).toBeDefined();
expect(dockerCompose.services[app.id].networks).toStrictEqual([
"tipi_main_network",
]);
}
});
});
});

View file

@ -3,14 +3,14 @@
"available": true,
"port": 8104,
"id": "adguard",
"categories": ["network", "security"],
"description": "Adguard is the best way to get rid of annoying ads and online tracking and protect your computer from malware. Make your web surfing fast, safe and ad-free.",
"short_desc": "World's most advanced adblocker!",
"author": "ArneNaessens",
"author": "AdguardTeam",
"source": "https://github.com/AdguardTeam",
"image": "https://avatars.githubusercontent.com/u/8361145?s=200&v=4",
"image": "/logos/apps/adguard.jpg",
"requirements": {
"ports": [53]
},
"form_fields": {
}
"form_fields": {}
}

View file

@ -1,9 +1,8 @@
version: "3.5"
version: "3.7"
services:
adguardhome:
image: adguard/adguardhome:v0.107.6
adguard:
image: adguard/adguardhome:v0.107.7
container_name: adguard
volumes:
- "${APP_DATA_DIR}/data/work:/opt/adguardhome/work"

View file

@ -0,0 +1,6 @@
## AdGuard Home is a network-wide software for blocking ads & tracking.
After you set it up, it'll cover ALL your home devices, and you don't need any client-side software for that.
It operates as a DNS server that re-routes tracking domains to a "black hole", thus preventing your devices from connecting to those servers. It's based on software we use for our public AdGuard DNS servers -- both share a lot of common code.
![Screenshot](https://cdn.adguard.com/public/Adguard/Common/adguard_home.gif)

View file

@ -1,6 +1,4 @@
version: "3.5"
version: "3.7"
services:
db:
image: mariadb:10.5
@ -80,4 +78,4 @@ services:
# traefik.http.routers.anonaddy.entrypoints: http
# traefik.http.routers.anonaddy.service: anonaddy
# traefik.http.services.anonaddy.loadbalancer.server.port: 8000
# traefik.http.services.anonaddy.loadbalancer.server.port: 8000

View file

@ -3,10 +3,11 @@
"available": true,
"port": 8100,
"id": "calibre-web",
"categories": ["books"],
"description": "On the initial setup screen, enter /books as your calibre library location. \n Default admin login: Username: admin Password: admin123",
"short_desc": "Calibre-web is a web app providing a clean interface for browsing, reading and downloading eBooks using an existing Calibre database.",
"author": "https://github.com/janeczku/",
"source": "https://github.com/janeczku/calibre-web",
"image": "https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/calibre-web-icon.png",
"image": "/logos/apps/calibre-web.jpg",
"form_fields": {}
}

View file

@ -1,7 +1,7 @@
version: "2.1"
version: "3.7"
services:
calibre-web:
image: lscr.io/linuxserver/calibre-web:latest
image: lscr.io/linuxserver/calibre-web:0.6.18
container_name: calibre-web
environment:
- PUID=1000
@ -9,9 +9,9 @@ services:
- TZ=${TZ}
volumes:
- ${APP_DATA_DIR}/data/config:/config
- ${APP_DATA_DIR}/data/books:/books
- ${ROOT_FOLDER_HOST}/media/data/books:/books
ports:
- ${APP_PORT}:8083
restart: unless-stopped
networks:
- tipi_main_network
- tipi_main_network

View file

@ -0,0 +1,7 @@
Calibre-Web is a web app providing a clean interface for browsing, reading and downloading eBooks using a valid Calibre database.
On the initial setup screen, enter /books as your calibre library location.
- **username**: admin
- **password**: admin123
<br />

View file

@ -3,6 +3,7 @@
"available": true,
"port": 8101,
"id": "code-server",
"categories": ["development"],
"description": "",
"short_desc": "Code-server is VS Code running on a remote server, accessible through the browser.",
"author": "https://github.com/coder",

View file

@ -1,7 +1,7 @@
version: "2.1"
version: "3.7"
services:
code-server:
image: lscr.io/linuxserver/code-server:latest
image: lscr.io/linuxserver/code-server:4.4.0
container_name: code-server
environment:
- PUID=1000
@ -16,4 +16,4 @@ services:
- ${APP_PORT}:8443
restart: unless-stopped
networks:
- tipi_main_network
- tipi_main_network

View file

@ -0,0 +1,7 @@
## Run VS Code on any machine anywhere and access it in the browser.
- Code on any device with a consistent development environment
- Use cloud servers to speed up tests, compilations, downloads, and more
- Preserve battery life when you're on the go; all intensive tasks run on your server
![screenshot](https://raw.githubusercontent.com/coder/code-server/main/docs/assets/screenshot.png)

View file

@ -3,11 +3,12 @@
"available": true,
"port": 8096,
"id": "filebrowser",
"categories": ["utilities"],
"description": "Reliable and Performant File Management Desktop Sync and File Sharing\n Default credentials: admin / admin",
"short_desc": "Access your homeserver files from your browser",
"author": "",
"author": "filebrowser.org",
"website": "https://filebrowser.org/",
"source": "https://github.com/filebrowser/filebrowser",
"image": "https://avatars.githubusercontent.com/u/35781395?s=200&v=4",
"image": "/logos/apps/filebrowser.jpg",
"form_fields": {}
}

View file

@ -1,3 +1,4 @@
version: "3.7"
services:
filebrowser:
container_name: filebrowser

View file

@ -0,0 +1,12 @@
## Access your homeserver files from your browser
filebrowser provides a file managing interface within a specified directory and it can be used to upload, delete, preview, rename and edit your files. It allows the creation of multiple users and each user can have its own directory. It can be used as a standalone app.
- **username**: admin
- **password**: admin
<br />
## Features
Please refer to our docs at [https://filebrowser.org/features](https://filebrowser.org/features)
![Preview](https://user-images.githubusercontent.com/5447088/50716739-ebd26700-107a-11e9-9817-14230c53efd2.gif)

View file

View file

@ -3,10 +3,11 @@
"available": true,
"port": 8086,
"id": "freshrss",
"categories": ["utilities"],
"description": "FreshRSS is a self-hosted RSS feed aggregator like Leed or Kriss Feed.\nIt is lightweight, easy to work with, powerful, and customizable.\n\nIt is a multi-user application with an anonymous reading mode. It supports custom tags. There is an API for (mobile) clients, and a Command-Line Interface.\n\nThanks to the WebSub standard (formerly PubSubHubbub), FreshRSS is able to receive instant push notifications from compatible sources, such as Mastodon, Friendica, WordPress, Blogger, FeedBurner, etc.\n\nFreshRSS natively supports basic Web scraping, based on XPath, for Web sites not providing any RSS / Atom feed.\n\nFinally, it supports extensions for further tuning.",
"short_desc": "A free, self-hostable aggregator… ",
"author": "https://freshrss.org/",
"source": "https://github.com/FreshRSS/FreshRSS",
"image": "https://avatars.githubusercontent.com/u/9414285?s=200&v=4",
"image": "/logos/apps/freshrss.jpg",
"form_fields": {}
}

View file

@ -0,0 +1,27 @@
## A free, self-hostable aggregator…
FreshRSS is a self-hosted RSS feed aggregator like [Leed](https://github.com/LeedRSS/Leed) or [Kriss Feed](https://tontof.net/kriss/feed/).
It is lightweight, easy to work with, powerful, and customizable.
It is a multi-user application with an anonymous reading mode. It supports custom tags.
There is an API for (mobile) clients, and a [Command-Line Interface](cli/README.md).
Thanks to the [WebSub](https://www.w3.org/TR/websub/) standard (formerly [PubSubHubbub](https://github.com/pubsubhubbub/PubSubHubbub)),
FreshRSS is able to receive instant push notifications from compatible sources, such as [Mastodon](https://joinmastodon.org), [Friendica](https://friendi.ca), [WordPress](https://wordpress.org/plugins/pubsubhubbub/), Blogger, FeedBurner, etc.
FreshRSS natively supports basic Web scraping, based on [XPath](https://www.w3.org/TR/xpath-10/), for Web sites not providing any RSS / Atom feed.
Finally, it supports [extensions](#extensions) for further tuning.
Feature requests, bug reports, and other contributions are welcome. The best way to contribute is to [open an issue on GitHub](https://github.com/FreshRSS/FreshRSS/issues).
We are a friendly community.
* Official website: [website](https://freshrss.org)
* Demo: [Demo](https://demo.freshrss.org/)
* License: [GNU AGPL 3](https://www.gnu.org/licenses/agpl-3.0.html)
![Screenshot](https://raw.githubusercontent.com/FreshRSS/FreshRSS/edge/docs/img/FreshRSS-screenshot.png)

13
apps/gitea/config.json Normal file
View file

@ -0,0 +1,13 @@
{
"name": "Gitea",
"port": 8108,
"available": true,
"id": "gitea",
"categories": ["development"],
"description": "Gitea is a painless self-hosted Git service. It is similar to GitHub, Bitbucket, and GitLab. Gitea is a fork of Gogs. See the Gitea Announcement blog post to read about the justification for a fork.",
"short_desc": "Gitea - Git with a cup of tea · A painless self-hosted Git service. · Cross-platform · Easy to install · Lightweight · Open Source.",
"author": "go-gitea",
"source": "https://github.com/go-gitea/gitea",
"image": "/logos/apps/gitea.jpg",
"form_fields": {}
}

View file

@ -0,0 +1,88 @@
APP_NAME = Gitea: Git with a cup of tea
RUN_MODE = prod
RUN_USER = git
[repository]
ROOT = /data/git/repositories
[repository.local]
LOCAL_COPY_PATH = /data/gitea/tmp/local-repo
[repository.upload]
TEMP_PATH = /data/gitea/uploads
[server]
APP_DATA_PATH = /data/gitea
DOMAIN = localhost
SSH_DOMAIN = localhost
HTTP_PORT = 3000
ROOT_URL = http://localhost:8108/
DISABLE_SSH = false
SSH_PORT = 22
SSH_LISTEN_PORT = 22
LFS_START_SERVER = true
LFS_CONTENT_PATH = /data/git/lfs
LFS_JWT_SECRET = wo2G20l0nGsspUp8xsLNSNF7H8U-GQUVth5gj_q5cDk
OFFLINE_MODE = false
[database]
PATH = /data/gitea/gitea.db
DB_TYPE = postgres
HOST = gitea-db:5432
NAME = gitea
USER = gitea
PASSWD = gitea
LOG_SQL = false
SCHEMA =
SSL_MODE = disable
CHARSET = utf8
[indexer]
ISSUE_INDEXER_PATH = /data/gitea/indexers/issues.bleve
[session]
PROVIDER_CONFIG = /data/gitea/sessions
PROVIDER = file
[picture]
AVATAR_UPLOAD_PATH = /data/gitea/avatars
REPOSITORY_AVATAR_UPLOAD_PATH = /data/gitea/repo-avatars
DISABLE_GRAVATAR = false
ENABLE_FEDERATED_AVATAR = true
[attachment]
PATH = /data/gitea/attachments
[log]
MODE = console
LEVEL = info
ROUTER = console
ROOT_PATH = /data/gitea/log
[security]
INSTALL_LOCK = true
SECRET_KEY =
REVERSE_PROXY_LIMIT = 1
REVERSE_PROXY_TRUSTED_PROXIES = *
INTERNAL_TOKEN = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE2NTMyODU5ODh9.l7fPuVA8LSHZvdBum8YDrH47RZjEx_cZLbswO5pMDk8
PASSWORD_HASH_ALGO = pbkdf2
[service]
DISABLE_REGISTRATION = false
REQUIRE_SIGNIN_VIEW = false
REGISTER_EMAIL_CONFIRM = false
ENABLE_NOTIFY_MAIL = false
ALLOW_ONLY_EXTERNAL_REGISTRATION = false
ENABLE_CAPTCHA = false
DEFAULT_KEEP_EMAIL_PRIVATE = false
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
DEFAULT_ENABLE_TIMETRACKING = true
NO_REPLY_ADDRESS = noreply.localhost
[mailer]
ENABLED = false
[openid]
ENABLE_OPENID_SIGNIN = true
ENABLE_OPENID_SIGNUP = true

View file

@ -0,0 +1,37 @@
version: "3.7"
services:
gitea:
image: gitea/gitea:1.16.8
container_name: gitea
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__database__DB_TYPE=postgres
- GITEA__database__HOST=gitea-db:5432
- GITEA__database__NAME=gitea
- GITEA__database__USER=gitea
- GITEA__database__PASSWD=gitea
restart: unless-stopped
networks:
- tipi_main_network
volumes:
- ${APP_DATA_DIR}/data/gitea:/data
ports:
- ${APP_PORT}:3000
- "222:22"
depends_on:
- gitea-db
gitea-db:
container_name: gitea-db
image: postgres:14
restart: unless-stopped
environment:
- POSTGRES_USER=gitea
- POSTGRES_PASSWORD=gitea
- POSTGRES_DB=gitea
volumes:
- ${APP_DATA_DIR}/data/postgres:/var/lib/postgresql/data
networks:
- tipi_main_network

View file

@ -0,0 +1,5 @@
# A painless self-hosted Git service
The goal of this project is to make the easiest, fastest, and most painless way of setting up a self-hosted Git service. Using Go, this can be done with an independent binary distribution across all platforms which Go supports, including Linux, macOS, and Windows on x86, amd64, ARM and PowerPC architectures. Want to try it before doing anything else? Do it with the online demo! This project has been forked from Gogs since 2016.11 but changed a lot.
![Screenshot](https://camo.githubusercontent.com/134f49a62801ab393c211125515d108439c67b59befb2ec3e42e7235af4f5d6c/68747470733a2f2f646c2e67697465612e696f2f73637265656e73686f74732f686f6d655f74696d656c696e652e706e67)

View file

@ -3,11 +3,12 @@
"available": true,
"port": 8102,
"id": "homarr",
"categories": ["utilities"],
"description": "A homepage for your server.",
"short_desc": "Homarr is a simple and lightweight homepage for your server, that helps you easily access all of your services in one place.",
"author": "https://github.com/ajnart/",
"source": "https://github.com/ajnart/homar",
"author": "ajnart",
"source": "https://github.com/ajnart/homarr",
"website": "https://discord.gg/C2WTXkzkwK",
"image": "https://raw.githubusercontent.com/ajnart/homarr/master/public/imgs/logo.png",
"image": "/logos/apps/homarr.jpg",
"form_fields": {}
}

View file

@ -1,4 +1,4 @@
version: '3'
version: "3.7"
services:
homarr:
container_name: homarr
@ -9,4 +9,4 @@ services:
ports:
- ${APP_PORT}:7575
networks:
- tipi_main_network
- tipi_main_network

View file

@ -0,0 +1,10 @@
# Lightweight homepage for your server
Homarr is a simple and lightweight homepage for your server, that helps you easily access all of your services in one place.
It integrates with the services you use to display information on the homepage (E.g. Show upcoming Sonarr/Radarr releases).
If you have any questions about Homarr or want to share information with us, please go to one of the following places:
- [Github Discussions](https://github.com/ajnart/homarr/discussions)
- [Discord Server](https://discord.gg/aCsmEV5RgA)
![Screenshot](https://user-images.githubusercontent.com/71191962/169860380-856634fb-4f41-47cb-ba54-6a9e7b3b9c81.gif)

View file

@ -0,0 +1,13 @@
{
"name": "Home Assistant",
"available": true,
"port": 8123,
"id": "homeassistant",
"categories": ["automation"],
"description": "Open source home automation that puts local control and privacy first. Powered by a worldwide community of tinkerers and DIY enthusiasts. Perfect to run on a Raspberry Pi or a local server.",
"short_desc": "Open source home automation that puts local control and privacy first",
"author": "ArneNaessens",
"source": "https://github.com/home-assistant/core",
"image": "/logos/apps/homeassistant.jpg",
"form_fields": {}
}

View file

@ -0,0 +1,13 @@
version: '3'
services:
homeassistant:
container_name: homeassistant
image: "ghcr.io/home-assistant/home-assistant:stable"
volumes:
- ${APP_DATA_DIR}/config:/config
restart: unless-stopped
privileged: true
ports:
- ${APP_PORT}:8123
network_mode: host

View file

@ -0,0 +1,7 @@
## Open source home automation that puts local control and privacy first
Open source home automation that puts local control and privacy first. Powered by a worldwide community of tinkerers and DIY enthusiasts. Perfect to run on a Raspberry Pi or a local server.
Check out [home-assistant.io](https://home-assistant.io) for a [demo](https://home-assistant.io/demo/), installation [instructions](https://home-assistant.io/getting-started/), [tutorials](https://home-assistant.io/getting-started/automation/) and [documentation](https://home-assistant.io/docs/)
![Screenshot](https://raw.githubusercontent.com/home-assistant/core/master/docs/screenshots.png)

View file

@ -3,9 +3,10 @@
"available": true,
"port": 8095,
"id": "invidious",
"description": "",
"short_desc": "",
"author": "",
"categories": ["media", "social"],
"description": "Invidious is an open source alternative front-end to YouTube.",
"short_desc": "An alternative front-end to YouTube",
"author": "iv-org",
"source": "https://github.com/iv-org/invidious",
"image": "https://raw.githubusercontent.com/iv-org/invidious/master/assets/invidious-colored-vector.svg",
"form_fields": {}

View file

@ -0,0 +1,12 @@
#!/bin/bash
set -eou pipefail
psql --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <config/sql/channels.sql
psql --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <config/sql/videos.sql
psql --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <config/sql/channel_videos.sql
psql --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <config/sql/users.sql
psql --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <config/sql/session_ids.sql
psql --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <config/sql/nonces.sql
psql --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <config/sql/annotations.sql
psql --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <config/sql/playlists.sql
psql --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <config/sql/playlist_videos.sql

View file

@ -0,0 +1,12 @@
-- Table: public.annotations
-- DROP TABLE public.annotations;
CREATE TABLE IF NOT EXISTS public.annotations
(
id text NOT NULL,
annotations xml,
CONSTRAINT annotations_id_key UNIQUE (id)
);
GRANT ALL ON TABLE public.annotations TO current_user;

View file

@ -0,0 +1,30 @@
-- Table: public.channel_videos
-- DROP TABLE public.channel_videos;
CREATE TABLE IF NOT EXISTS public.channel_videos
(
id text NOT NULL,
title text,
published timestamp with time zone,
updated timestamp with time zone,
ucid text,
author text,
length_seconds integer,
live_now boolean,
premiere_timestamp timestamp with time zone,
views bigint,
CONSTRAINT channel_videos_id_key UNIQUE (id)
);
GRANT ALL ON TABLE public.channel_videos TO current_user;
-- Index: public.channel_videos_ucid_idx
-- DROP INDEX public.channel_videos_ucid_idx;
CREATE INDEX IF NOT EXISTS channel_videos_ucid_idx
ON public.channel_videos
USING btree
(ucid COLLATE pg_catalog."default");

View file

@ -0,0 +1,25 @@
-- Table: public.channels
-- DROP TABLE public.channels;
CREATE TABLE IF NOT EXISTS public.channels
(
id text NOT NULL,
author text,
updated timestamp with time zone,
deleted boolean,
subscribed timestamp with time zone,
CONSTRAINT channels_id_key UNIQUE (id)
);
GRANT ALL ON TABLE public.channels TO current_user;
-- Index: public.channels_id_idx
-- DROP INDEX public.channels_id_idx;
CREATE INDEX IF NOT EXISTS channels_id_idx
ON public.channels
USING btree
(id COLLATE pg_catalog."default");

View file

@ -0,0 +1,22 @@
-- Table: public.nonces
-- DROP TABLE public.nonces;
CREATE TABLE IF NOT EXISTS public.nonces
(
nonce text,
expire timestamp with time zone,
CONSTRAINT nonces_id_key UNIQUE (nonce)
);
GRANT ALL ON TABLE public.nonces TO current_user;
-- Index: public.nonces_nonce_idx
-- DROP INDEX public.nonces_nonce_idx;
CREATE INDEX IF NOT EXISTS nonces_nonce_idx
ON public.nonces
USING btree
(nonce COLLATE pg_catalog."default");

View file

@ -0,0 +1,19 @@
-- Table: public.playlist_videos
-- DROP TABLE public.playlist_videos;
CREATE TABLE IF NOT EXISTS public.playlist_videos
(
title text,
id text,
author text,
ucid text,
length_seconds integer,
published timestamptz,
plid text references playlists(id),
index int8,
live_now boolean,
PRIMARY KEY (index,plid)
);
GRANT ALL ON TABLE public.playlist_videos TO current_user;

View file

@ -0,0 +1,29 @@
-- Type: public.privacy
-- DROP TYPE public.privacy;
CREATE TYPE public.privacy AS ENUM
(
'Public',
'Unlisted',
'Private'
);
-- Table: public.playlists
-- DROP TABLE public.playlists;
CREATE TABLE IF NOT EXISTS public.playlists
(
title text,
id text primary key,
author text,
description text,
video_count integer,
created timestamptz,
updated timestamptz,
privacy privacy,
index int8[]
);
GRANT ALL ON public.playlists TO current_user;

View file

@ -0,0 +1,23 @@
-- Table: public.session_ids
-- DROP TABLE public.session_ids;
CREATE TABLE IF NOT EXISTS public.session_ids
(
id text NOT NULL,
email text,
issued timestamp with time zone,
CONSTRAINT session_ids_pkey PRIMARY KEY (id)
);
GRANT ALL ON TABLE public.session_ids TO current_user;
-- Index: public.session_ids_id_idx
-- DROP INDEX public.session_ids_id_idx;
CREATE INDEX IF NOT EXISTS session_ids_id_idx
ON public.session_ids
USING btree
(id COLLATE pg_catalog."default");

View file

@ -0,0 +1,29 @@
-- Table: public.users
-- DROP TABLE public.users;
CREATE TABLE IF NOT EXISTS public.users
(
updated timestamp with time zone,
notifications text[],
subscriptions text[],
email text NOT NULL,
preferences text,
password text,
token text,
watched text[],
feed_needs_update boolean,
CONSTRAINT users_email_key UNIQUE (email)
);
GRANT ALL ON TABLE public.users TO current_user;
-- Index: public.email_unique_idx
-- DROP INDEX public.email_unique_idx;
CREATE UNIQUE INDEX IF NOT EXISTS email_unique_idx
ON public.users
USING btree
(lower(email) COLLATE pg_catalog."default");

View file

@ -0,0 +1,23 @@
-- Table: public.videos
-- DROP TABLE public.videos;
CREATE UNLOGGED TABLE IF NOT EXISTS public.videos
(
id text NOT NULL,
info text,
updated timestamp with time zone,
CONSTRAINT videos_pkey PRIMARY KEY (id)
);
GRANT ALL ON TABLE public.videos TO current_user;
-- Index: public.id_idx
-- DROP INDEX public.id_idx;
CREATE UNIQUE INDEX IF NOT EXISTS id_idx
ON public.videos
USING btree
(id COLLATE pg_catalog."default");

View file

@ -1,10 +1,12 @@
version: "3"
version: "3.7"
services:
invidious:
user: 1000:1000
container_name: invidious
image: quay.io/invidious/invidious:latest-arm64
restart: unless-stopped
dns:
- ${DNS_IP}
ports:
- "${APP_PORT}:3000"
environment:
@ -23,6 +25,8 @@ services:
retries: 2
depends_on:
- invidious-db
networks:
- tipi_main_network
invidious-db:
user: 1000:1000
@ -31,11 +35,13 @@ services:
restart: unless-stopped
volumes:
- ${APP_DATA_DIR}/data/postgres:/var/lib/postgresql/data
- ${APP_DATA_DIR}/data/sql:/config/sql
- ./docker/init-invidious-db.sh:/docker-entrypoint-initdb.d/init-invidious-db.sh
- ${APP_DATA_DIR}/data/init/sql:/config/sql
- ${APP_DATA_DIR}/data/init/init-invidious-db.sh:/docker-entrypoint-initdb.d/init-invidious-db.sh
environment:
POSTGRES_DB: invidious
POSTGRES_USER: tipi
POSTGRES_PASSWORD: tipi
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
networks:
- tipi_main_network

View file

@ -1,4 +1,4 @@
version: "3"
version: "3.7"
services:
invidious:
user: 1000:1000
@ -26,6 +26,8 @@ services:
retries: 2
depends_on:
- invidious-db
networks:
- tipi_main_network
invidious-db:
user: 1000:1000
@ -34,11 +36,13 @@ services:
restart: unless-stopped
volumes:
- ${APP_DATA_DIR}/data/postgres:/var/lib/postgresql/data
- ${APP_DATA_DIR}/data/sql:/config/sql
- ./docker/init-invidious-db.sh:/docker-entrypoint-initdb.d/init-invidious-db.sh
- ${APP_DATA_DIR}/data/init/sql:/config/sql
- ${APP_DATA_DIR}/data/init/init-invidious-db.sh:/docker-entrypoint-initdb.d/init-invidious-db.sh
environment:
POSTGRES_DB: invidious
POSTGRES_USER: tipi
POSTGRES_PASSWORD: tipi
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
networks:
- tipi_main_network

View file

@ -0,0 +1,27 @@
## An open source alternative front-end to YouTube
**User features**
- Lightweight
- No ads
- No tracking
- No JavaScript required
- Light/Dark themes
- Customizable homepage
- Subscriptions independent from Google
- Notifications for all subscribed channels
- Audio-only mode (with background play on mobile)
- Support for Reddit comments
- Available in many languages, thanks to our translators
<br />
**Data import/export**
- Import subscriptions from YouTube, NewPipe and Freetube
- Import watch history from NewPipe
- Export subscriptions to NewPipe and Freetube
- Import/Export Invidious user data
<br />
**Technical features**
- Embedded video support
- [Developer API](https://docs.invidious.io/api/)
- Does not use official YouTube APIs
- No Contributor License Agreement (CLA)

View file

@ -5,8 +5,9 @@
"id": "jackett",
"description": "Jackett works as a proxy server: it translates queries from apps (Sonarr, Radarr, SickRage, CouchPotato, Mylar3, Lidarr, DuckieTV, qBittorrent, Nefarious etc.) into tracker-site-specific http queries, parses the html or json response, and then sends results back to the requesting software. This allows for getting recent uploads (like RSS) and performing searches.",
"short_desc": "API Support for your favorite torrent trackers ",
"categories": ["media", "utilities"],
"author": "",
"source": "https://github.com/Jackett/Jackett",
"image": "https://avatars.githubusercontent.com/u/15383019?s=200&v=4",
"image": "/logos/apps/jackett.jpg",
"form_fields": {}
}

View file

@ -1,7 +1,7 @@
version: "3.7"
services:
jackett:
image: lscr.io/linuxserver/jackett
image: lscr.io/linuxserver/jackett:0.20.1171
container_name: jackett
environment:
- PUID=1000
@ -12,7 +12,7 @@ services:
- ${DNS_IP}
volumes:
- ${APP_DATA_DIR}/data:/config
- ${ROOT_FOLDER_HOST}/media/torrents:/downloads
- ${ROOT_FOLDER_HOST}/media/torrents:/media/torrents
ports:
- ${APP_PORT}:9117
restart: unless-stopped

View file

@ -0,0 +1,5 @@
## API Support for your favorite torrent trackers
Jackett works as a proxy server: it translates queries from apps ([Sonarr](https://github.com/Sonarr/Sonarr), [Radarr](https://github.com/Radarr/Radarr), [SickRage](https://sickrage.github.io/), [CouchPotato](https://couchpota.to/), [Mylar3](https://github.com/mylar3/mylar3), [Lidarr](https://github.com/lidarr/lidarr), [DuckieTV](https://github.com/SchizoDuckie/DuckieTV), [qBittorrent](https://www.qbittorrent.org/), [Nefarious](https://github.com/lardbit/nefarious) etc.) into tracker-site-specific http queries, parses the html or json response, and then sends results back to the requesting software. This allows for getting recent uploads (like RSS) and performing searches. Jackett is a single repository of maintained indexer scraping & translation logic - removing the burden from other apps.
![Screenshot](https://raw.githubusercontent.com/Jackett/Jackett/master/.github/jackett-screenshot1.png)

View file

@ -3,10 +3,11 @@
"available": true,
"port": 8091,
"id": "jellyfin",
"description": "",
"short_desc": "",
"author": "",
"source": "",
"categories": ["media"],
"description": "Jellyfin is a Free Software Media System that puts you in control of managing and streaming your media. It is an alternative to the proprietary Emby and Plex, to provide media from a dedicated server to end-user devices via multiple apps. Jellyfin is descended from Emby's 3.5.2 release and ported to the .NET Core framework to enable full cross-platform support. There are no strings attached, no premium licenses or features, and no hidden agendas: just a team who want to build something better and work together to achieve it. We welcome anyone who is interested in joining us in our quest!",
"short_desc": "A media server for your home collection",
"author": "jellyfin.org",
"source": "https://github.com/jellyfin/jellyfin",
"image": "https://avatars.githubusercontent.com/u/45698031?s=200&v=4",
"form_fields": {}
}

View file

@ -2,11 +2,11 @@ version: "3.7"
services:
jellyfin:
image: lscr.io/linuxserver/jellyfin
image: lscr.io/linuxserver/jellyfin:10.8.0
container_name: jellyfin
volumes:
- ${APP_DATA_DIR}/data/config:/config
- ${ROOT_FOLDER_HOST}/media/data:/data/media
- ${ROOT_FOLDER_HOST}/media/data:/media/data
environment:
- PUID=1000
- PGID=1000

View file

@ -0,0 +1,5 @@
## A media server for your home collection
Jellyfin is a Free Software Media System that puts you in control of managing and streaming your media. It is an alternative to the proprietary Emby and Plex, to provide media from a dedicated server to end-user devices via multiple apps. Jellyfin is descended from Emby's 3.5.2 release and ported to the .NET Core framework to enable full cross-platform support. There are no strings attached, no premium licenses or features, and no hidden agendas: just a team who want to build something better and work together to achieve it. We welcome anyone who is interested in joining us in our quest!
For further details, please see [our documentation page](https://docs.jellyfin.org/). To receive the latest updates, get help with Jellyfin, and join the community, please visit [one of our communication channels](https://docs.jellyfin.org/general/getting-help.html). For more information about the project, please see our [about page](https://docs.jellyfin.org/general/about.html).

View file

@ -3,11 +3,12 @@
"available": true,
"port": 8099,
"id": "joplin",
"categories": ["utilities"],
"description": "Default credentials: admin@localhost / admin",
"short_desc": "Note taking and to-do application with synchronisation",
"author": "https://github.com/laurent22",
"source": "https://github.com/laurent22/joplin",
"website": "https://joplinapp.org",
"image": "https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/LinuxIcons/256x256.png",
"image": "/logos/apps/joplin.jpg",
"form_fields": {}
}

View file

@ -0,0 +1,17 @@
## Note taking and to-do application with synchronisation
- **username**: admin@localhost
- **password**: admin
<br />
Joplin is a free, open source note taking and to-do application, which can handle a large number of notes organised into notebooks. The notes are searchable, can be copied, tagged and modified either from the applications directly or from your own text editor. The notes are in Markdown format.
Notes exported from Evernote can be imported into Joplin, including the formatted content (which is converted to Markdown), resources (images, attachments, etc.) and complete metadata (geolocation, updated time, created time, etc.). Plain Markdown files can also be imported.
The notes can be securely synchronised using end-to-end encryption with various cloud services including Nextcloud, Dropbox, OneDrive and Joplin Cloud.
Full text search is available on all platforms to quickly find the information you need. The app can be customised using plugins and themes, and you can also easily create your own.
The application is available for Windows, Linux, macOS, Android and iOS. A Web Clipper, to save web pages and screenshots from your browser, is also available for Firefox and Chrome.
![Screenshot](https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/home-top-img.png)

View file

@ -0,0 +1,13 @@
{
"name": "LibReddit",
"available": true,
"port": 8105,
"id": "libreddit",
"categories": ["social"],
"description": "LibReddit is a bloat free reddit frontend written in Rust, no ads, no tracking and strong Content Security Policy prevents any request from going to reddit, everything is proxied.",
"short_desc": "Browse reddit without problems!",
"author": "spikecodes",
"source": "https://github.com/spikecodes/libreddit",
"image": "/logos/apps/libreddit.jpg",
"form_fields": {}
}

View file

@ -0,0 +1,12 @@
version: "3.7"
services:
libreddit:
container_name: libreddit
image: spikecodes/libreddit:arm
dns:
- ${DNS_IP}
ports:
- ${APP_PORT}:8080
restart: unless-stopped
networks:
- tipi_main_network

View file

@ -0,0 +1,12 @@
version: "3.7"
services:
libreddit:
container_name: libreddit
image: spikecodes/libreddit
dns:
- ${DNS_IP}
ports:
- ${APP_PORT}:8080
restart: unless-stopped
networks:
- tipi_main_network

View file

@ -0,0 +1,12 @@
## An alternative private front-end to Reddit
**10 second pitch:** Libreddit is a portmanteau of "libre" (meaning freedom) and "Reddit". It is a private front-end like [Invidious](https://github.com/iv-org/invidious) but for Reddit. Browse the coldest takes of [r/unpopularopinion](https://libreddit.spike.codes/r/unpopularopinion) without being [tracked](#reddit).
- 🚀 Fast: written in Rust for blazing-fast speeds and memory safety
- ☁️ Light: no JavaScript, no ads, no tracking, no bloat
- 🕵 Private: all requests are proxied through the server, including media
- 🔒 Secure: strong [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) prevents browser requests to Reddit
<br />
![Screenshot](https://camo.githubusercontent.com/0753860e104fd86d32e13d47b31c8db88ec86bbdc66911480d92d20a96332c51/68747470733a2f2f692e6962622e636f2f515962715451742f6c69627265646469742d727573742e706e67)

13
apps/mealie/config.json Normal file
View file

@ -0,0 +1,13 @@
{
"name": "Mealie",
"port": 8114,
"available": true,
"id": "mealie",
"description": "Mealie is a self-hosted recipe manager and meal planner with a RestAPI backend and a reactive frontend application built in Vue for a pleasant user experience for the whole family. Easily add recipes into your database by providing the url and Mealie will automatically import the relevant data or add a family recipe with the UI editor. Mealie also provides an API for interactions from 3rd party applications. Default username / password is changeme@email.com / MyPassword",
"short_desc": "Mealie is a self-hosted recipe manager and meal planner.",
"author": "hay-kot",
"categories": [],
"source": "https://github.com/hay-kot/mealie",
"image": "https://raw.githubusercontent.com/hay-kot/mealie/mealie-next/frontend/static/icons/android-chrome-512x512.png",
"form_fields": {}
}

View file

@ -0,0 +1,15 @@
version: "3.7"
services:
mealie:
container_name: mealie
image: hkotel/mealie:v0.5.6
restart: unless-stopped
ports:
- ${APP_PORT}:80
environment:
PUID: 1000
PGID: 1000
volumes:
- ${APP_DATA_DIR}/data:/app/data
networks:
- tipi_main_network

View file

@ -0,0 +1,9 @@
## Mealie is a self-hosted recipe manager and meal planner.
- **username**: changeme@email.com
- **password**: MyPassword
<br />
Mealie is a self hosted recipe manager and meal planner with a RestAPI backend and a reactive frontend application built in Vue for a pleasant user experience for the whole family. Easily add recipes into your database by providing the url and Mealie will automatically import the relevant data or add a family recipe with the UI editor. Mealie also provides an API for interactions from 3rd party applications.
[![Product Name Screen Shot](https://raw.githubusercontent.com/hay-kot/mealie/mealie-next/docs/docs/assets/img/home_screenshot.png)](https://docs.mealie.io/)

View file

@ -3,11 +3,12 @@
"available": true,
"port": 8094,
"id": "n8n",
"categories": ["automation"],
"description": "n8n is an extendable workflow automation tool. With a fair-code distribution model, n8n will always have visible source code, be available to self-host, and allow you to add your own custom functions, logic and apps. n8n's node-based approach makes it highly versatile, enabling you to connect anything to everything.",
"short_desc": "Workflow Automation Tool. Alternative to Zapier",
"author": "n8n.io",
"source": "https://github.com/n8n-io/n8n",
"website": "https://n8n.io/",
"image": "https://avatars.githubusercontent.com/u/45487711?s=200&v=4",
"image": "/logos/apps/n8n.jpg",
"form_fields": {}
}

View file

@ -16,7 +16,7 @@ services:
n8n:
container_name: n8n
image: n8nio/n8n:0.174.0
image: n8nio/n8n:0.181.2
restart: unless-stopped
ports:
- ${APP_PORT}:5678

View file

@ -0,0 +1,6 @@
## Easily automate tasks across different services.
n8n is an extendable workflow automation tool. With a fair-code distribution model, n8n will always have visible source code, be available to self-host, and allow you to add your own custom functions, logic and apps. n8n's node-based approach makes it highly
versatile, enabling you to connect anything to everything.
![Screenshot](https://raw.githubusercontent.com/n8n-io/n8n/master/assets/n8n-screenshot.png)

View file

@ -3,6 +3,7 @@
"available": true,
"port": 8083,
"id": "nextcloud",
"categories": ["data"],
"description": "Nextcloud is a self-hosted, open source, and fully-featured cloud storage solution for your personal files, office documents, and photos.",
"short_desc": "Productivity platform that keeps you in control",
"author": "Nextcloud GmbH",

View file

@ -25,7 +25,7 @@ services:
- tipi_main_network
cron:
image: nextcloud:23.0.3-apache
image: nextcloud:24.0.1-apache
restart: on-failure
volumes:
- ${APP_DATA_DIR}/data/nextcloud:/var/www/html
@ -38,7 +38,7 @@ services:
nextcloud:
container_name: nextcloud
image: nextcloud:23.0.3-apache
image: nextcloud:24.0.1-apache
restart: unless-stopped
ports:
- ${APP_PORT}:80

View file

@ -0,0 +1,29 @@
## A safe home for all your data.
* 📁 **Access your Data** You can store your files, contacts, calendars and more on a server of your choosing.
* 🔄 **Sync your Data** You keep your files, contacts, calendars and more synchronized amongst your devices.
* 🙌 **Share your Data** …by giving others access to the stuff you want them to see or to collaborate with.
* 🚀 **Expandable with hundreds of Apps** ...like [Calendar](https://github.com/nextcloud/calendar), [Contacts](https://github.com/nextcloud/contacts), [Mail](https://github.com/nextcloud/mail), [Video Chat](https://github.com/nextcloud/spreed) and all those you can discover in our [App Store](https://apps.nextcloud.com)
* 🔒 **Security** with our encryption mechanisms, [HackerOne bounty program](https://hackerone.com/nextcloud) and two-factor authentication.
You want to learn more about how you can use Nextcloud to access, share and protect your files, calendars, contacts, communication & more at home and at your organization? [**Learn about all our Features**](https://nextcloud.com/athome/).
## Get your Nextcloud 🚚
- ☑️ [**Simply sign up**](https://nextcloud.com/signup/) at one of our providers either through our website or through the apps directly.
- 🖥 [**Install** a server by yourself](https://nextcloud.com/install/#instructions-server) on your own hardware or by using one of our ready to use **appliances**
- 📦 Buy one of the [awesome **devices** coming with a preinstalled Nextcloud](https://nextcloud.com/devices/)
- 🏢 Find a [service **provider**](https://nextcloud.com/providers/) who hosts Nextcloud for you or your company
Enterprise? Public Sector or Education user? You may want to have a look into [**Nextcloud Enterprise**](https://nextcloud.com/enterprise/) provided by Nextcloud GmbH.
## Get in touch 💬
* [📋 Forum](https://help.nextcloud.com)
* [👥 Facebook](https://www.facebook.com/nextclouders)
* [🐣 Twitter](https://twitter.com/Nextclouders)
* [🐘 Mastodon](https://mastodon.xyz/@nextcloud)
You can also [get support for Nextcloud](https://nextcloud.com/support)!
![](https://raw.githubusercontent.com/nextcloud/screenshots/master/files/Files%20Sharing.png)

13
apps/nitter/config.json Normal file
View file

@ -0,0 +1,13 @@
{
"name": "Nitter",
"available": true,
"port": 8106,
"id": "nitter",
"categories": ["social"],
"description": "A free and open source alternative Twitter front-end focused on privacy and performance.",
"short_desc": "Twitter without annoyances!",
"author": "zedeus",
"source": "https://github.com/zedeus/nitter",
"image": "/logos/apps/nitter.jpg",
"form_fields": {}
}

View file

@ -0,0 +1,45 @@
[Server]
address = "0.0.0.0"
port = 8080
https = false # disable to enable cookies when not using https
httpMaxConnections = 100
staticDir = "./public"
title = "nitter"
hostname = ""
[Cache]
listMinutes = 240 # how long to cache list info (not the tweets, so keep it high)
rssMinutes = 10 # how long to cache rss queries
redisHost = "nitter-redis" # Change to "nitter-redis" if using docker-compose
redisPort = 6379
redisPassword = ""
redisConnections = 20 # connection pool size
redisMaxConnections = 30
# max, new connections are opened when none are available, but if the pool size
# goes above this, they're closed when released. don't worry about this unless
# you receive tons of requests per second
[Config]
hmacKey = "secretkey" # random key for cryptographic signing of video urls
base64Media = false # use base64 encoding for proxied media urls
enableRSS = true # set this to false to disable RSS feeds
enableDebug = false # enable request logs and debug endpoints
proxy = "" # http/https url, SOCKS proxies are not supported
proxyAuth = ""
tokenCount = 10
# minimum amount of usable tokens. tokens are used to authorize API requests,
# but they expire after ~1 hour, and have a limit of 187 requests.
# the limit gets reset every 15 minutes, and the pool is filled up so there's
# always at least $tokenCount usable tokens. again, only increase this if
# you receive major bursts all the time
# Change default preferences here, see src/prefs_impl.nim for a complete list
[Preferences]
theme = "Nitter"
replaceTwitter = ""
replaceYouTube = ""
replaceReddit = ""
replaceInstagram = ""
proxyVideos = true
hlsPlayback = true
infiniteScroll = true

View file

@ -0,0 +1,24 @@
version: "3.7"
services:
nitter:
image: zedeus/nitter:latest
container_name: nitter
networks:
- tipi_main_network
ports:
- ${APP_PORT}:8080
volumes:
- "${APP_DATA_DIR}/data/nitter.conf:/src/nitter.conf:ro"
depends_on:
- nitter-redis
restart: unless-stopped
nitter-redis:
image: redis:6-alpine
container_name: nitter-redis
networks:
- tipi_main_network
command: redis-server --save 60 1 --loglevel warning
volumes:
- "${APP_DATA_DIR}/data/redis:/data"
restart: unless-stopped

View file

@ -0,0 +1,16 @@
## Alternative Twitter front-end
A free and open source alternative Twitter front-end focused on privacy and performance. Inspired by the [Invidious](https://github.com/iv-org/invidious) project.
- No JavaScript or ads
- All requests go through the backend, client never talks to Twitter
- Prevents Twitter from tracking your IP or JavaScript fingerprint
- Uses Twitter's unofficial API (no rate limits or developer account required)
- Lightweight (for [@nim_lang](https://nitter.net/nim_lang), 60KB vs 784KB from twitter.com)
- RSS feeds
- Themes
- Mobile support (responsive design)
- AGPLv3 licensed, no proprietary instances permitted
<br />
![Screenshot](https://raw.githubusercontent.com/zedeus/nitter/master/screenshot.png)

13
apps/nodered/config.json Normal file
View file

@ -0,0 +1,13 @@
{
"name": "Node-RED",
"port": 8111,
"available": true,
"id": "nodered",
"categories": ["automation"],
"description": "Node-RED is a programming tool for wiring together hardware devices, APIs and online services in new and interesting ways. It provides a browser-based editor that makes it easy to wire together flows using the wide range of nodes in the palette that can be deployed to its runtime in a single-click.",
"short_desc": "Low-code programming for event-driven applications",
"author": "node-red",
"source": "https://github.com/node-red/node-red",
"image": "https://avatars.githubusercontent.com/u/5375661?s=200&v=4",
"form_fields": {}
}

View file

@ -0,0 +1,499 @@
/**
* This is the default settings file provided by Node-RED.
*
* It can contain any valid JavaScript code that will get run when Node-RED
* is started.
*
* Lines that start with // are commented out.
* Each entry should be separated from the entries above and below by a comma ','
*
* For more information about individual settings, refer to the documentation:
* https://nodered.org/docs/user-guide/runtime/configuration
*
* The settings are split into the following sections:
* - Flow File and User Directory Settings
* - Security
* - Server Settings
* - Runtime Settings
* - Editor Settings
* - Node Settings
*
**/
module.exports = {
/*******************************************************************************
* Flow File and User Directory Settings
* - flowFile
* - credentialSecret
* - flowFilePretty
* - userDir
* - nodesDir
******************************************************************************/
/** The file containing the flows. If not set, defaults to flows_<hostname>.json **/
flowFile: 'flows.json',
/** By default, credentials are encrypted in storage using a generated key. To
* specify your own secret, set the following property.
* If you want to disable encryption of credentials, set this property to false.
* Note: once you set this property, do not change it - doing so will prevent
* node-red from being able to decrypt your existing credentials and they will be
* lost.
*/
//credentialSecret: "a-secret-key",
/** By default, the flow JSON will be formatted over multiple lines making
* it easier to compare changes when using version control.
* To disable pretty-printing of the JSON set the following property to false.
*/
flowFilePretty: true,
/** By default, all user data is stored in a directory called `.node-red` under
* the user's home directory. To use a different location, the following
* property can be used
*/
//userDir: '/home/nol/.node-red/',
/** Node-RED scans the `nodes` directory in the userDir to find local node files.
* The following property can be used to specify an additional directory to scan.
*/
//nodesDir: '/home/nol/.node-red/nodes',
/*******************************************************************************
* Security
* - adminAuth
* - https
* - httpsRefreshInterval
* - requireHttps
* - httpNodeAuth
* - httpStaticAuth
******************************************************************************/
/** To password protect the Node-RED editor and admin API, the following
* property can be used. See http://nodered.org/docs/security.html for details.
*/
//adminAuth: {
// type: "credentials",
// users: [{
// username: "admin",
// password: "$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN.",
// permissions: "*"
// }]
//},
/** The following property can be used to enable HTTPS
* This property can be either an object, containing both a (private) key
* and a (public) certificate, or a function that returns such an object.
* See http://nodejs.org/api/https.html#https_https_createserver_options_requestlistener
* for details of its contents.
*/
/** Option 1: static object */
//https: {
// key: require("fs").readFileSync('privkey.pem'),
// cert: require("fs").readFileSync('cert.pem')
//},
/** Option 2: function that returns the HTTP configuration object */
// https: function() {
// // This function should return the options object, or a Promise
// // that resolves to the options object
// return {
// key: require("fs").readFileSync('privkey.pem'),
// cert: require("fs").readFileSync('cert.pem')
// }
// },
/** If the `https` setting is a function, the following setting can be used
* to set how often, in hours, the function will be called. That can be used
* to refresh any certificates.
*/
//httpsRefreshInterval : 12,
/** The following property can be used to cause insecure HTTP connections to
* be redirected to HTTPS.
*/
//requireHttps: true,
/** To password protect the node-defined HTTP endpoints (httpNodeRoot),
* including node-red-dashboard, or the static content (httpStatic), the
* following properties can be used.
* The `pass` field is a bcrypt hash of the password.
* See http://nodered.org/docs/security.html#generating-the-password-hash
*/
//httpNodeAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."},
//httpStaticAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."},
/*******************************************************************************
* Server Settings
* - uiPort
* - uiHost
* - apiMaxLength
* - httpServerOptions
* - httpAdminRoot
* - httpAdminMiddleware
* - httpNodeRoot
* - httpNodeCors
* - httpNodeMiddleware
* - httpStatic
******************************************************************************/
/** the tcp port that the Node-RED web server is listening on */
uiPort: process.env.PORT || 1880,
/** By default, the Node-RED UI accepts connections on all IPv4 interfaces.
* To listen on all IPv6 addresses, set uiHost to "::",
* The following property can be used to listen on a specific interface. For
* example, the following would only allow connections from the local machine.
*/
//uiHost: "127.0.0.1",
/** The maximum size of HTTP request that will be accepted by the runtime api.
* Default: 5mb
*/
//apiMaxLength: '5mb',
/** The following property can be used to pass custom options to the Express.js
* server used by Node-RED. For a full list of available options, refer
* to http://expressjs.com/en/api.html#app.settings.table
*/
//httpServerOptions: { },
/** By default, the Node-RED UI is available at http://localhost:1880/
* The following property can be used to specify a different root path.
* If set to false, this is disabled.
*/
//httpAdminRoot: '/admin',
/** The following property can be used to add a custom middleware function
* in front of all admin http routes. For example, to set custom http
* headers. It can be a single function or an array of middleware functions.
*/
// httpAdminMiddleware: function(req,res,next) {
// // Set the X-Frame-Options header to limit where the editor
// // can be embedded
// //res.set('X-Frame-Options', 'sameorigin');
// next();
// },
/** Some nodes, such as HTTP In, can be used to listen for incoming http requests.
* By default, these are served relative to '/'. The following property
* can be used to specifiy a different root path. If set to false, this is
* disabled.
*/
//httpNodeRoot: '/red-nodes',
/** The following property can be used to configure cross-origin resource sharing
* in the HTTP nodes.
* See https://github.com/troygoode/node-cors#configuration-options for
* details on its contents. The following is a basic permissive set of options:
*/
//httpNodeCors: {
// origin: "*",
// methods: "GET,PUT,POST,DELETE"
//},
/** If you need to set an http proxy please set an environment variable
* called http_proxy (or HTTP_PROXY) outside of Node-RED in the operating system.
* For example - http_proxy=http://myproxy.com:8080
* (Setting it here will have no effect)
* You may also specify no_proxy (or NO_PROXY) to supply a comma separated
* list of domains to not proxy, eg - no_proxy=.acme.co,.acme.co.uk
*/
/** The following property can be used to add a custom middleware function
* in front of all http in nodes. This allows custom authentication to be
* applied to all http in nodes, or any other sort of common request processing.
* It can be a single function or an array of middleware functions.
*/
//httpNodeMiddleware: function(req,res,next) {
// // Handle/reject the request, or pass it on to the http in node by calling next();
// // Optionally skip our rawBodyParser by setting this to true;
// //req.skipRawBodyParser = true;
// next();
//},
/** When httpAdminRoot is used to move the UI to a different root path, the
* following property can be used to identify a directory of static content
* that should be served at http://localhost:1880/.
*/
//httpStatic: '/home/nol/node-red-static/',
/*******************************************************************************
* Runtime Settings
* - lang
* - logging
* - contextStorage
* - exportGlobalContextKeys
* - externalModules
******************************************************************************/
/** Uncomment the following to run node-red in your preferred language.
* Available languages include: en-US (default), ja, de, zh-CN, zh-TW, ru, ko
* Some languages are more complete than others.
*/
// lang: "de",
/** Configure the logging output */
logging: {
/** Only console logging is currently supported */
console: {
/** Level of logging to be recorded. Options are:
* fatal - only those errors which make the application unusable should be recorded
* error - record errors which are deemed fatal for a particular request + fatal errors
* warn - record problems which are non fatal + errors + fatal errors
* info - record information about the general running of the application + warn + error + fatal errors
* debug - record information which is more verbose than info + info + warn + error + fatal errors
* trace - record very detailed logging + debug + info + warn + error + fatal errors
* off - turn off all logging (doesn't affect metrics or audit)
*/
level: "info",
/** Whether or not to include metric events in the log output */
metrics: false,
/** Whether or not to include audit events in the log output */
audit: false
}
},
/** Context Storage
* The following property can be used to enable context storage. The configuration
* provided here will enable file-based context that flushes to disk every 30 seconds.
* Refer to the documentation for further options: https://nodered.org/docs/api/context/
*/
//contextStorage: {
// default: {
// module:"localfilesystem"
// },
//},
/** `global.keys()` returns a list of all properties set in global context.
* This allows them to be displayed in the Context Sidebar within the editor.
* In some circumstances it is not desirable to expose them to the editor. The
* following property can be used to hide any property set in `functionGlobalContext`
* from being list by `global.keys()`.
* By default, the property is set to false to avoid accidental exposure of
* their values. Setting this to true will cause the keys to be listed.
*/
exportGlobalContextKeys: false,
/** Configure how the runtime will handle external npm modules.
* This covers:
* - whether the editor will allow new node modules to be installed
* - whether nodes, such as the Function node are allowed to have their
* own dynamically configured dependencies.
* The allow/denyList options can be used to limit what modules the runtime
* will install/load. It can use '*' as a wildcard that matches anything.
*/
externalModules: {
// autoInstall: false, /** Whether the runtime will attempt to automatically install missing modules */
// autoInstallRetry: 30, /** Interval, in seconds, between reinstall attempts */
// palette: { /** Configuration for the Palette Manager */
// allowInstall: true, /** Enable the Palette Manager in the editor */
// allowUpdate: true, /** Allow modules to be updated in the Palette Manager */
// allowUpload: true, /** Allow module tgz files to be uploaded and installed */
// allowList: ['*'],
// denyList: [],
// allowUpdateList: ['*'],
// denyUpdateList: []
// },
// modules: { /** Configuration for node-specified modules */
// allowInstall: true,
// allowList: [],
// denyList: []
// }
},
/*******************************************************************************
* Editor Settings
* - disableEditor
* - editorTheme
******************************************************************************/
/** The following property can be used to disable the editor. The admin API
* is not affected by this option. To disable both the editor and the admin
* API, use either the httpRoot or httpAdminRoot properties
*/
//disableEditor: false,
/** Customising the editor
* See https://nodered.org/docs/user-guide/runtime/configuration#editor-themes
* for all available options.
*/
editorTheme: {
/** The following property can be used to set a custom theme for the editor.
* See https://github.com/node-red-contrib-themes/theme-collection for
* a collection of themes to chose from.
*/
//theme: "",
/** To disable the 'Welcome to Node-RED' tour that is displayed the first
* time you access the editor for each release of Node-RED, set this to false
*/
//tours: false,
palette: {
/** The following property can be used to order the categories in the editor
* palette. If a node's category is not in the list, the category will get
* added to the end of the palette.
* If not set, the following default order is used:
*/
//categories: ['subflows', 'common', 'function', 'network', 'sequence', 'parser', 'storage'],
},
projects: {
/** To enable the Projects feature, set this value to true */
enabled: false,
workflow: {
/** Set the default projects workflow mode.
* - manual - you must manually commit changes
* - auto - changes are automatically committed
* This can be overridden per-user from the 'Git config'
* section of 'User Settings' within the editor
*/
mode: "manual"
}
},
codeEditor: {
/** Select the text editor component used by the editor.
* Defaults to "ace", but can be set to "ace" or "monaco"
*/
lib: "ace",
options: {
/** The follow options only apply if the editor is set to "monaco"
*
* theme - must match the file name of a theme in
* packages/node_modules/@node-red/editor-client/src/vendor/monaco/dist/theme
* e.g. "tomorrow-night", "upstream-sunburst", "github", "my-theme"
*/
theme: "vs",
/** other overrides can be set e.g. fontSize, fontFamily, fontLigatures etc.
* for the full list, see https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.istandaloneeditorconstructionoptions.html
*/
//fontSize: 14,
//fontFamily: "Cascadia Code, Fira Code, Consolas, 'Courier New', monospace",
//fontLigatures: true,
}
}
},
/*******************************************************************************
* Node Settings
* - fileWorkingDirectory
* - functionGlobalContext
* - functionExternalModules
* - nodeMessageBufferMaxLength
* - ui (for use with Node-RED Dashboard)
* - debugUseColors
* - debugMaxLength
* - execMaxBufferSize
* - httpRequestTimeout
* - mqttReconnectTime
* - serialReconnectTime
* - socketReconnectTime
* - socketTimeout
* - tcpMsgQueueSize
* - inboundWebSocketTimeout
* - tlsConfigDisableLocalFiles
* - webSocketNodeVerifyClient
******************************************************************************/
/** The working directory to handle relative file paths from within the File nodes
* defaults to the working directory of the Node-RED process.
*/
//fileWorkingDirectory: "",
/** Allow the Function node to load additional npm modules directly */
functionExternalModules: true,
/** The following property can be used to set predefined values in Global Context.
* This allows extra node modules to be made available with in Function node.
* For example, the following:
* functionGlobalContext: { os:require('os') }
* will allow the `os` module to be accessed in a Function node using:
* global.get("os")
*/
functionGlobalContext: {
// os:require('os'),
},
/** The maximum number of messages nodes will buffer internally as part of their
* operation. This applies across a range of nodes that operate on message sequences.
* defaults to no limit. A value of 0 also means no limit is applied.
*/
//nodeMessageBufferMaxLength: 0,
/** If you installed the optional node-red-dashboard you can set it's path
* relative to httpNodeRoot
* Other optional properties include
* readOnly:{boolean},
* middleware:{function or array}, (req,res,next) - http middleware
* ioMiddleware:{function or array}, (socket,next) - socket.io middleware
*/
//ui: { path: "ui" },
/** Colourise the console output of the debug node */
//debugUseColors: true,
/** The maximum length, in characters, of any message sent to the debug sidebar tab */
debugMaxLength: 1000,
/** Maximum buffer size for the exec node. Defaults to 10Mb */
//execMaxBufferSize: 10000000,
/** Timeout in milliseconds for HTTP request connections. Defaults to 120s */
//httpRequestTimeout: 120000,
/** Retry time in milliseconds for MQTT connections */
mqttReconnectTime: 15000,
/** Retry time in milliseconds for Serial port connections */
serialReconnectTime: 15000,
/** Retry time in milliseconds for TCP socket connections */
//socketReconnectTime: 10000,
/** Timeout in milliseconds for TCP server socket connections. Defaults to no timeout */
//socketTimeout: 120000,
/** Maximum number of messages to wait in queue while attempting to connect to TCP socket
* defaults to 1000
*/
//tcpMsgQueueSize: 2000,
/** Timeout in milliseconds for inbound WebSocket connections that do not
* match any configured node. Defaults to 5000
*/
//inboundWebSocketTimeout: 5000,
/** To disable the option for using local files for storing keys and
* certificates in the TLS configuration node, set this to true.
*/
//tlsConfigDisableLocalFiles: true,
/** The following property can be used to verify websocket connection attempts.
* This allows, for example, the HTTP request headers to be checked to ensure
* they include valid authentication information.
*/
//webSocketNodeVerifyClient: function(info) {
// /** 'info' has three properties:
// * - origin : the value in the Origin header
// * - req : the HTTP request
// * - secure : true if req.connection.authorized or req.connection.encrypted is set
// *
// * The function should return true if the connection should be accepted, false otherwise.
// *
// * Alternatively, if this function is defined to accept a second argument, callback,
// * it can be used to verify the client asynchronously.
// * The callback takes three arguments:
// * - result : boolean, whether to accept the connection or not
// * - code : if result is false, the HTTP error status to return
// * - reason: if result is false, the HTTP reason string to return
// */
//},
}

View file

@ -0,0 +1,13 @@
version: "3.7"
services:
nodered:
container_name: nodered
image: nodered/node-red:2.2.2-12
restart: unless-stopped
ports:
- ${APP_PORT}:1880
volumes:
- ${APP_DATA_DIR}/data:/data
networks:
- tipi_main_network

View file

@ -0,0 +1,6 @@
## Low-code programming for event-driven applications.
Node-RED is a programming tool for wiring together hardware devices, APIs and online services in new and interesting ways.
It provides a browser-based editor that makes it easy to wire together flows using the wide range of nodes in the palette that can be deployed to its runtime in a single-click.
![Screenshot](https://camo.githubusercontent.com/c7b6e0b937295c4d2c852130814050eb0caffac5b700ead6de21df6dbf83aa82/687474703a2f2f6e6f64657265642e6f72672f696d616765732f6e6f64652d7265642d73637265656e73686f742e706e67)

View file

@ -0,0 +1,22 @@
{
"name": "PhotoPrism",
"port": 8110,
"available": true,
"id": "photoprism",
"categories": ["photography"],
"description": "PhotoPrism® is an AI-Powered Photos App for the Decentralized Web. It makes use of the latest technologies to tag and find pictures automatically without getting in your way. You can run it at home, on a private server, or in the cloud. Default username: admin",
"short_desc": "AI-Powered Photos App for the Decentralized Web. We are on a mission to protect your freedom and privacy.",
"author": "PhotoPrism",
"source": "https://github.com/photoprism/photoprism",
"image": "/logos/apps/photoprism.jpg",
"form_fields": {
"password": {
"type": "password",
"label": "Photoprism admin password",
"max": 50,
"min": 8,
"required": true,
"env_variable": "PHOTOPRISM_ADMIN_PASSWORD"
}
}
}

View file

@ -0,0 +1,59 @@
version: "3.7"
services:
photoprism:
# TODO: Special image for arm/v7 is available
image: photoprism/photoprism:latest
container_name: photoprism
depends_on:
- photoprism-db
restart: unless-stopped
ports:
- "${APP_PORT}:2342"
environment:
PHOTOPRISM_ADMIN_PASSWORD: ${PHOTOPRISM_ADMIN_PASSWORD}
PHOTOPRISM_SITE_URL: "http://localhost:2342/"
PHOTOPRISM_ORIGINALS_LIMIT: 5000
PHOTOPRISM_HTTP_COMPRESSION: "gzip"
PHOTOPRISM_LOG_LEVEL: "info"
PHOTOPRISM_PUBLIC: "false"
PHOTOPRISM_READONLY: "false"
PHOTOPRISM_EXPERIMENTAL: "false"
PHOTOPRISM_DISABLE_CHOWN: "false"
PHOTOPRISM_DISABLE_WEBDAV: "false"
PHOTOPRISM_DISABLE_SETTINGS: "false"
PHOTOPRISM_DISABLE_TENSORFLOW: "false"
PHOTOPRISM_DISABLE_FACES: "false"
PHOTOPRISM_DISABLE_CLASSIFICATION: "false"
PHOTOPRISM_DISABLE_RAW: "false"
PHOTOPRISM_RAW_PRESETS: "false"
PHOTOPRISM_JPEG_QUALITY: 85
PHOTOPRISM_DETECT_NSFW: "false"
PHOTOPRISM_UPLOAD_NSFW: "true"
PHOTOPRISM_DATABASE_DRIVER: "mysql"
PHOTOPRISM_DATABASE_SERVER: "photoprism-db:3306"
PHOTOPRISM_DATABASE_NAME: "photoprism"
PHOTOPRISM_DATABASE_USER: "photoprism"
PHOTOPRISM_DATABASE_PASSWORD: "photoprism"
PHOTOPRISM_SITE_CAPTION: "AI-Powered Photos App"
working_dir: "/photoprism"
volumes:
- "${APP_DATA_DIR}/data/photoprism/originals:/photoprism/originals"
- "${APP_DATA_DIR}/data/photoprism/storage:/photoprism/storage"
networks:
- tipi_main_network
photoprism-db:
restart: unless-stopped
image: mariadb:10.8.3
container_name: photoprism-db
command: mysqld --innodb-buffer-pool-size=128M --transaction-isolation=READ-COMMITTED --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --max-connections=512 --innodb-rollback-on-timeout=OFF --innodb-lock-wait-timeout=120
volumes:
- "${APP_DATA_DIR}/data/mariadb:/var/lib/mysql"
environment:
MARIADB_DATABASE: "photoprism"
MARIADB_USER: "photoprism"
MARIADB_PASSWORD: "photoprism"
MARIADB_ROOT_PASSWORD: "photoprism"
networks:
- tipi_main_network

View file

@ -0,0 +1,9 @@
## AI-Powered Photos App for the Decentralized Web 🌈💎✨
- **username**: admin
<br />
PhotoPrism® is an AI-Powered Photos App for the Decentralized Web. It makes use of the latest technologies to tag and find pictures automatically without getting in your way. You can run it at home, on a private server, or in the cloud.
To get a first impression, you are welcome to play with our [public demo](https://try.photoprism.app/). Be careful not to upload any private pictures.
![Screenshot](https://camo.githubusercontent.com/5e03a87e47aad26ad7248b8b43eac6471fe96f7b655ac2e532697692753c3ff8/68747470733a2f2f646c2e70686f746f707269736d2e6170702f696d672f75692f6465736b746f702d3130303070782e6a7067)

View file

@ -1,16 +1,17 @@
{
"name": "PiHole",
"name": "Pi-hole",
"available": true,
"port": 8081,
"requirements": {
"ports": [53]
},
"id": "pihole",
"description": "",
"short_desc": "",
"author": "",
"source": "",
"image": "https://avatars.githubusercontent.com/u/16827203?s=200&v=4",
"categories": ["network", "security"],
"description": "The Pi-hole® is a DNS sinkhole that protects your devices from unwanted content without installing any client-side software.",
"short_desc": "A black hole for Internet advertisements",
"author": "pi-hole.net",
"source": "https://github.com/pi-hole/pi-hole",
"image": "/logos/apps/pihole.jpg",
"form_fields": {
"password": {
"type": "password",

View file

@ -14,7 +14,7 @@ services:
pihole:
depends_on: [unbound]
container_name: pihole
image: pihole/pihole:latest
image: pihole/pihole:2022.05
restart: unless-stopped
hostname: pihole
dns:

View file

@ -0,0 +1,14 @@
## A black hole for Internet advertisements
The Pi-hole® is a [DNS sinkhole](https://en.wikipedia.org/wiki/DNS_Sinkhole) that protects your devices from unwanted content without installing any client-side software.
- **Easy-to-install**: our versatile installer walks you through the process and takes less than ten minutes
- **Resolute**: content is blocked in _non-browser locations_, such as ad-laden mobile apps and smart TVs
- **Responsive**: seamlessly speeds up the feel of everyday browsing by caching DNS queries
- **Lightweight**: runs smoothly with [minimal hardware and software requirements](https://docs.pi-hole.net/main/prerequisites/)
- **Robust**: a command line interface that is quality assured for interoperability
- **Insightful**: a beautiful responsive Web Interface dashboard to view and control your Pi-hole
- **Versatile**: can optionally function as a [DHCP server](https://discourse.pi-hole.net/t/how-do-i-use-pi-holes-built-in-dhcp-server-and-why-would-i-want-to/3026), ensuring *all* your devices are protected automatically
- **Scalable**: [capable of handling hundreds of millions of queries](https://pi-hole.net/2017/05/24/how-much-traffic-can-pi-hole-handle/) when installed on server-grade hardware
- **Modern**: blocks ads over both IPv4 and IPv6
- **Free**: open source software that helps ensure _you_ are the sole person in control of your privacy

14
apps/plex/config.json Normal file
View file

@ -0,0 +1,14 @@
{
"name": "Plex",
"available": true,
"port": 32400,
"id": "plex",
"url_suffix": "/web",
"categories": ["media"],
"description": "",
"short_desc": "Stream Movies & TV Shows",
"author": "plexinc",
"source": "https://github.com/plexinc/pms-docker",
"image": "/logos/apps/plex.png",
"form_fields": {}
}

View file

@ -0,0 +1,17 @@
version: "3.7"
services:
plex:
image: lscr.io/linuxserver/plex:1.26.2
container_name: plex
network_mode: host
environment:
- PUID=1000
- PGID=1000
- VERSION=docker
volumes:
- ${APP_DATA_DIR}/data/config:/config
- ${ROOT_FOLDER_HOST}/media/data:/media
restart: unless-stopped
ports:
- ${APP_PORT}:32400

Some files were not shown because too many files have changed in this diff Show more