Compare commits
No commits in common. "develop" and "release/0.4.2" have entirely different histories.
develop
...
release/0.
806 changed files with 18928 additions and 36290 deletions
|
@ -36,11 +36,7 @@
|
|||
"contributions": [
|
||||
"code",
|
||||
"ideas",
|
||||
"test",
|
||||
"content",
|
||||
"promotion",
|
||||
"question",
|
||||
"review"
|
||||
"test"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -69,345 +65,12 @@
|
|||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "blushell",
|
||||
"name": "Jones_Town",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/3621606?v=4",
|
||||
"profile": "https://github.com/blushell",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "rushic24",
|
||||
"name": "Rushi Chaudhari",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/6279035?v=4",
|
||||
"profile": "https://rushichaudhari.github.io/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "rblaine95",
|
||||
"name": "Robert Blaine",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/4052340?v=4",
|
||||
"profile": "https://github.com/rblaine95",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "sethforprivacy",
|
||||
"name": "Seth For Privacy",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/40500387?v=4",
|
||||
"profile": "https://sethforprivacy.com",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "hqwuzhaoyi",
|
||||
"name": "Prajna",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/44605072?v=4",
|
||||
"profile": "https://github.com/hqwuzhaoyi",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "justincmoy",
|
||||
"name": "Justin Moy",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/14875982?v=4",
|
||||
"profile": "https://github.com/justincmoy",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "dextreem",
|
||||
"name": "dextreem",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/11060652?v=4",
|
||||
"profile": "https://github.com/dextreem",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "iBicha",
|
||||
"name": "Brahim Hadriche",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/17722782?v=4",
|
||||
"profile": "https://github.com/iBicha",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "andrewbrereton",
|
||||
"name": "Andrew Brereton",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/682893?v=4",
|
||||
"profile": "https://andrewbrereton.com",
|
||||
"contributions": [
|
||||
"content"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "fsackur",
|
||||
"name": "Freddie Sackur",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/3678789?v=4",
|
||||
"profile": "https://fsackur.github.io/",
|
||||
"contributions": [
|
||||
"code",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "innocentius",
|
||||
"name": "Innocentius",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/5344432?v=4",
|
||||
"profile": "http://innocentius.github.io",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "TetrisIQ",
|
||||
"name": "Alex",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/24246993?v=4",
|
||||
"profile": "https://github.com/TetrisIQ",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "ruibaby",
|
||||
"name": "Ryan Wang",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/21301288?v=4",
|
||||
"profile": "https://ryanc.cc",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "simonandr",
|
||||
"name": "simonandr",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/48092304?v=4",
|
||||
"profile": "https://github.com/simonandr",
|
||||
"contributions": [
|
||||
"content"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "demizeu",
|
||||
"name": "iepure",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/121183951?v=4",
|
||||
"profile": "https://github.com/demizeu",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "SergeyKodolov",
|
||||
"name": "Sergey Kodolov",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/35339452?v=4",
|
||||
"profile": "https://github.com/SergeyKodolov",
|
||||
"contributions": [
|
||||
"translation",
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "sclaren",
|
||||
"name": "sclaren",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/915292?v=4",
|
||||
"profile": "https://github.com/sclaren",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "mcmeel",
|
||||
"name": "mcmeel",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/13773536?v=4",
|
||||
"profile": "https://github.com/mcmeel",
|
||||
"contributions": [
|
||||
"question",
|
||||
"ideas",
|
||||
"code",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "NoisyFridge",
|
||||
"name": "NoisyFridge",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/73795785?v=4",
|
||||
"profile": "https://github.com/NoisyFridge",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Bvoxl",
|
||||
"name": "Bvoxl",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/67489519?v=4",
|
||||
"profile": "https://github.com/Bvoxl",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "m-lab-0",
|
||||
"name": "m-lab-0",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/116570617?v=4",
|
||||
"profile": "https://github.com/m-lab-0",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "dannkunt",
|
||||
"name": "dannkunt",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/32395839?v=4",
|
||||
"profile": "https://github.com/dannkunt",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Schmanko",
|
||||
"name": "Schmanko",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/94195393?v=4",
|
||||
"profile": "https://github.com/Schmanko",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "nghialele",
|
||||
"name": "Nghia Lele",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/129353223?v=4",
|
||||
"profile": "https://micro.nghialele.com",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "amusingimpala75",
|
||||
"name": "amusingimpala75",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/69653100?v=4",
|
||||
"profile": "https://github.com/amusingimpala75",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "M1n-4d316e",
|
||||
"name": "David",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/54779580?v=4",
|
||||
"profile": "http://m1n.omg.lol",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "steveiliop56",
|
||||
"name": "Stavros Iliopoulos",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/106091011?v=4",
|
||||
"profile": "https://github.com/steveiliop56",
|
||||
"contributions": [
|
||||
"translation",
|
||||
"code",
|
||||
"test"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "loxiry",
|
||||
"name": "loxiry",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/86959495?v=4",
|
||||
"profile": "https://github.com/loxiry",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "JigSawFr",
|
||||
"name": "JigSaw",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/5781907?v=4",
|
||||
"profile": "https://github.com/JigSawFr",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "DireMunchkin",
|
||||
"name": "DireMunchkin",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1665676?v=4",
|
||||
"profile": "https://github.com/DireMunchkin",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "FabioCingottini",
|
||||
"name": "Fabio Cingottini",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/32102735?v=4",
|
||||
"profile": "https://github.com/FabioCingottini",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "itsrllyhim",
|
||||
"name": "him",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/143047010?v=4",
|
||||
"profile": "https://github.com/itsrllyhim",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "cchalop1",
|
||||
"name": "CHALOPIN Clément",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/28163855?v=4",
|
||||
"profile": "http://cchalop1.com",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "geetansh",
|
||||
"name": "Geetansh Jindal",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/9976198?v=4",
|
||||
"profile": "https://github.com/geetansh",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "0livier",
|
||||
"name": "Olivier Garcia",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/10607?v=4",
|
||||
"profile": "https://github.com/0livier",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "qcoudeyr",
|
||||
"name": "qcoudeyr",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/124463277?v=4",
|
||||
"profile": "https://github.com/qcoudeyr",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
"projectName": "runtipi",
|
||||
"projectOwner": "runtipi",
|
||||
"projectOwner": "meienberger",
|
||||
"repoType": "github",
|
||||
"repoHost": "https://github.com",
|
||||
"skipCi": true,
|
||||
"commitConvention": "angular",
|
||||
"commitType": "docs"
|
||||
"skipCi": true
|
||||
}
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"image": "mcr.microsoft.com/vscode/devcontainers/javascript-node",
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/docker-in-docker": {
|
||||
"version": "latest",
|
||||
"moby": true
|
||||
}
|
||||
},
|
||||
"extensions": [
|
||||
"ms-azuretools.vscode-docker",
|
||||
"ms-vscode.vscode-typescript-next",
|
||||
"waderyan.gitblame"
|
||||
],
|
||||
"postCreateCommand": "./.devcontainer/postCreateCommand.sh"
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# We need to change the owner of the files in the app-data folder
|
||||
# if this failes we have to change the permission your self
|
||||
fswatch --event=Created /workspaces/runtipi/app-data/ | \
|
||||
xargs -l1 sh -c 'echo "$1" && sudo chown node "$1" -R' -- &
|
|
@ -1,12 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
echo '{
|
||||
"appsRepoUrl": "https://github.com/runtipi/runtipi-appstore.git/"
|
||||
}' > state/settings.json
|
||||
npm i -g pnpm
|
||||
pnpm i
|
||||
sudo apt-get update
|
||||
sudo apt-get install jq fswatch -y
|
||||
mkdir logs
|
||||
mkdir data
|
||||
sudo chown node logs
|
||||
sudo chown node data
|
|
@ -5,22 +5,5 @@
|
|||
node_modules
|
||||
.next
|
||||
dist/
|
||||
|
||||
# all docker-compose files
|
||||
docker-compose*.yml
|
||||
Dockerfile*
|
||||
.dockerignore
|
||||
|
||||
# Tipi folder
|
||||
logs/
|
||||
state/
|
||||
templates/
|
||||
scripts/
|
||||
screenshots/
|
||||
repos/
|
||||
media/
|
||||
data/
|
||||
apps/
|
||||
app-data/
|
||||
.github/
|
||||
__mocks__/
|
||||
**/dist/
|
||||
**/next/
|
||||
|
|
22
.env.example
22
.env.example
|
@ -1,22 +0,0 @@
|
|||
APPS_REPO_ID=7a92c8307e0a8074763c80be1fcfa4f87da6641daea9211aea6743b0116aba3b
|
||||
APPS_REPO_URL=https://github.com/runtipi/runtipi-appstore
|
||||
TZ=Etc/UTC
|
||||
INTERNAL_IP=localhost
|
||||
DNS_IP=9.9.9.9
|
||||
ARCHITECTURE=arm64
|
||||
TIPI_VERSION=1.5.2
|
||||
JWT_SECRET=secret
|
||||
ROOT_FOLDER_HOST=/path/to/runtipi
|
||||
STORAGE_PATH=/path/to/runtipi
|
||||
NGINX_PORT=7000
|
||||
NGINX_PORT_SSL=443
|
||||
DOMAIN=tipi.localhost
|
||||
POSTGRES_HOST=tipi-db
|
||||
POSTGRES_DBNAME=tipi
|
||||
POSTGRES_USERNAME=tipi
|
||||
POSTGRES_PASSWORD=postgres
|
||||
POSTGRES_PORT=5432
|
||||
REDIS_HOST=tipi-redis
|
||||
REDIS_PASSWORD=redis
|
||||
DEMO_MODE=false
|
||||
LOCAL_DOMAIN=tipi.lan
|
14
.env.test
14
.env.test
|
@ -1,14 +0,0 @@
|
|||
POSTGRES_HOST=localhost
|
||||
POSTGRES_DBNAME=postgres
|
||||
POSTGRES_USERNAME=postgres
|
||||
POSTGRES_PASSWORD=postgres
|
||||
POSTGRES_PORT=5433
|
||||
APPS_REPO_ID=repo-id
|
||||
APPS_REPO_URL=https://test.com/test
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PASSWORD=redis
|
||||
INTERNAL_IP=localhost
|
||||
TIPI_VERSION=1
|
||||
JWT_SECRET=secret
|
||||
DOMAIN=tipi.localhost
|
||||
LOCAL_DOMAIN=tipi.lan
|
80
.eslintrc.js
80
.eslintrc.js
|
@ -1,80 +0,0 @@
|
|||
module.exports = {
|
||||
plugins: ['@typescript-eslint', 'import', 'react', 'jest', 'jsx-a11y', 'testing-library', 'jest-dom'],
|
||||
extends: [
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'next/core-web-vitals',
|
||||
'next',
|
||||
'airbnb',
|
||||
'airbnb-typescript',
|
||||
'eslint:recommended',
|
||||
'plugin:import/typescript',
|
||||
'prettier',
|
||||
'plugin:react/recommended',
|
||||
'plugin:jsx-a11y/recommended',
|
||||
],
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
sourceType: 'module',
|
||||
project: './tsconfig.json',
|
||||
tsconfigRootDir: __dirname,
|
||||
},
|
||||
rules: {
|
||||
'no-restricted-exports': 0,
|
||||
'no-redeclare': 0, // already handled by @typescript-eslint/no-redeclare
|
||||
'react/display-name': 0,
|
||||
'react/prop-types': 0,
|
||||
'react/function-component-definition': 0,
|
||||
'react/require-default-props': 0,
|
||||
'import/prefer-default-export': 0,
|
||||
'react/jsx-props-no-spreading': 0,
|
||||
'react/no-unused-prop-types': 0,
|
||||
'react/button-has-type': 0,
|
||||
'import/no-extraneous-dependencies': [
|
||||
'error',
|
||||
{
|
||||
devDependencies: [
|
||||
'esbuild.js',
|
||||
'e2e/**',
|
||||
'**/*.test.{ts,tsx}',
|
||||
'**/*.spec.{ts,tsx}',
|
||||
'**/*.factory.{ts,tsx}',
|
||||
'**/mocks/**',
|
||||
'**/__mocks__/**',
|
||||
'tests/**',
|
||||
'**/*.d.ts',
|
||||
'**/*.workspace.ts',
|
||||
'**/*.setup.{ts,js}',
|
||||
'**/*.config.{ts,js}',
|
||||
],
|
||||
},
|
||||
],
|
||||
'no-underscore-dangle': 0,
|
||||
'arrow-body-style': 0,
|
||||
'class-methods-use-this': 0,
|
||||
'import/extensions': [
|
||||
'error',
|
||||
'ignorePackages',
|
||||
{
|
||||
'': 'never',
|
||||
js: 'never',
|
||||
jsx: 'never',
|
||||
ts: 'never',
|
||||
tsx: 'never',
|
||||
},
|
||||
],
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ['*.test.ts', '*.test.tsx'],
|
||||
extends: ['plugin:jest-dom/recommended', 'plugin:testing-library/react'],
|
||||
},
|
||||
],
|
||||
globals: {
|
||||
JSX: true,
|
||||
NodeJS: true,
|
||||
},
|
||||
env: {
|
||||
'jest/globals': true,
|
||||
},
|
||||
};
|
13
.github/FUNDING.yml
vendored
13
.github/FUNDING.yml
vendored
|
@ -1,13 +0,0 @@
|
|||
# These are supported funding model platforms
|
||||
|
||||
github: [meienberger] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: meienberger # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
12
.github/ISSUE_TEMPLATE/app-request.md
vendored
12
.github/ISSUE_TEMPLATE/app-request.md
vendored
|
@ -1,13 +1,17 @@
|
|||
---
|
||||
name: App Request
|
||||
about: Suggest an app to be added
|
||||
title: "[APP REQUEST]"
|
||||
title: "[REQUEST]"
|
||||
labels: app request
|
||||
assignees: meienberger
|
||||
|
||||
---
|
||||
|
||||
## Read before submitting
|
||||
Apps are now hosted in a secondary repository. Please open your app request issues [there](https://github.com/meienberger/runtipi-appstore)
|
||||
**Describe app**
|
||||
A clear and concise description of what the app consists of and how it would benefit the users of Tipi.
|
||||
|
||||
You can also easily contribute and propose a new app or update. Please check out our [Wiki](https://github.com/meienberger/runtipi/wiki/Adding-your-own-app) on how to do so
|
||||
**Links**
|
||||
Include links to all the available resources for the app. (eg: github repo, website, license)
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the app request here.
|
||||
|
|
22
.github/ISSUE_TEMPLATE/bug_report.md
vendored
22
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
@ -7,12 +7,6 @@ assignees: meienberger
|
|||
|
||||
---
|
||||
|
||||
### Checklist
|
||||
Before opening your issue be sure to have completed all those tasks.
|
||||
- [ ] I have searched for an already existing issue with similar context and errors. My issue has not yet been reported.
|
||||
- [ ] I have included a clear description and steps to reproduce.
|
||||
- [ ] I have included logs from the file `runtipi/logs/error.log` if relevant
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
|
@ -29,10 +23,16 @@ A clear and concise description of what you expected to happen.
|
|||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Server (please complete the following information):**
|
||||
- OS: [e.g. Ubuntu 20.04]
|
||||
- Tipi Version [e.g. 2.0.5] (can be found in settings page)
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Smartphone (please complete the following information):**
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Please include logs here `runtipi/logs/error.log` and add any other context about the problem here. Like results of the `start` script or container logs `docker logs ...`
|
||||
|
||||
Add any other context about the problem here.
|
||||
|
|
20
.github/dependabot.yml
vendored
20
.github/dependabot.yml
vendored
|
@ -1,20 +0,0 @@
|
|||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: 'npm'
|
||||
directory: '/'
|
||||
versioning-strategy: increase
|
||||
schedule:
|
||||
interval: 'daily'
|
||||
open-pull-requests-limit: 10
|
||||
rebase-strategy: 'auto'
|
||||
|
||||
- package-ecosystem: 'github-actions'
|
||||
directory: '/'
|
||||
schedule:
|
||||
interval: 'daily'
|
||||
rebase-strategy: 'auto'
|
17
.github/stale.yml
vendored
17
.github/stale.yml
vendored
|
@ -1,17 +0,0 @@
|
|||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 30
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- pinned
|
||||
- security
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: stale
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions. If you feel this issue should remain open, please
|
||||
add a comment with the requested information and we will keep it open.
|
||||
closeComment: false
|
165
.github/workflows/alpha-release.yml
vendored
165
.github/workflows/alpha-release.yml
vendored
|
@ -1,165 +0,0 @@
|
|||
name: Alpha Release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: 'Alpha version tag (1, 2, 3, ...)'
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
create-tag:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
tagname: ${{ steps.get_tag.outputs.tagname }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Get tag from package.json
|
||||
id: get_tag
|
||||
run: |
|
||||
VERSION=$(npm run version --silent)
|
||||
echo "tagname=v${VERSION}-alpha.${{ github.event.inputs.tag }}" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: rickstaa/action-create-tag@v1
|
||||
with:
|
||||
tag: ${{ steps.get_tag.outputs.tagname }}
|
||||
|
||||
build-worker:
|
||||
runs-on: ubuntu-latest
|
||||
needs: create-tag
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push images
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: ./packages/worker/Dockerfile
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
tags: ghcr.io/${{ github.repository_owner }}/worker:${{ needs.create-tag.outputs.tagname }}
|
||||
cache-from: type=registry,ref=ghcr.io/${{ github.repository_owner }}/worker:buildcache
|
||||
cache-to: type=registry,ref=ghcr.io/${{ github.repository_owner }}/worker:buildcache,mode=max
|
||||
|
||||
build-images:
|
||||
runs-on: ubuntu-latest
|
||||
needs: create-tag
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push images
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
tags: ghcr.io/${{ github.repository_owner }}/runtipi:${{ needs.create-tag.outputs.tagname }}
|
||||
cache-from: type=registry,ref=ghcr.io/${{ github.repository_owner }}/runtipi:buildcache
|
||||
cache-to: type=registry,ref=ghcr.io/${{ github.repository_owner }}/runtipi:buildcache,mode=max
|
||||
|
||||
build-cli:
|
||||
runs-on: ubuntu-latest
|
||||
needs: create-tag
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
- uses: pnpm/action-setup@v2.4.0
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
with:
|
||||
version: 8
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: |
|
||||
echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Set version
|
||||
run: pnpm -r --filter cli set-version ${{ needs.create-tag.outputs.tagname }}
|
||||
|
||||
- name: Build CLI
|
||||
run: pnpm -r --filter cli package
|
||||
|
||||
- name: Upload CLI
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: cli
|
||||
path: packages/cli/dist
|
||||
|
||||
publish-release:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [create-tag, build-images, build-cli, build-worker]
|
||||
|
||||
steps:
|
||||
- name: Download CLI
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: cli
|
||||
path: cli
|
||||
|
||||
- name: Rename CLI
|
||||
run: |
|
||||
mv cli/bin/cli-x64 ./runtipi-cli-linux-x64
|
||||
|
||||
- name: Create alpha release
|
||||
id: create_release
|
||||
uses: softprops/action-gh-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
body: |
|
||||
**${{ needs.create-tag.outputs.tagname }}**
|
||||
tag_name: ${{ needs.create-tag.outputs.tagname }}
|
||||
name: ${{ needs.create-tag.outputs.tagname }}
|
||||
draft: false
|
||||
prerelease: true
|
||||
files: |
|
||||
runtipi-cli-linux-x64
|
175
.github/workflows/beta-release.yml
vendored
175
.github/workflows/beta-release.yml
vendored
|
@ -1,175 +0,0 @@
|
|||
name: Beta Release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: 'Beta version tag (1, 2, 3, ...)'
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
create-tag:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
tagname: ${{ steps.get_tag.outputs.tagname }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Get tag from package.json
|
||||
id: get_tag
|
||||
run: |
|
||||
VERSION=$(npm run version --silent)
|
||||
echo "tagname=v${VERSION}-beta.${{ github.event.inputs.tag }}" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: rickstaa/action-create-tag@v1
|
||||
with:
|
||||
tag: ${{ steps.get_tag.outputs.tagname }}
|
||||
|
||||
build-worker:
|
||||
runs-on: ubuntu-latest
|
||||
needs: create-tag
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push images
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: ./packages/worker/Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ghcr.io/${{ github.repository_owner }}/worker:${{ needs.create-tag.outputs.tagname }}
|
||||
cache-from: type=registry,ref=ghcr.io/${{ github.repository_owner }}/worker:buildcache
|
||||
cache-to: type=registry,ref=ghcr.io/${{ github.repository_owner }}/worker:buildcache,mode=max
|
||||
|
||||
build-images:
|
||||
needs: create-tag
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push images
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ghcr.io/${{ github.repository_owner }}/runtipi:${{ needs.create-tag.outputs.tagname }}
|
||||
cache-from: type=registry,ref=ghcr.io/${{ github.repository_owner }}/runtipi:buildcache
|
||||
cache-to: type=registry,ref=ghcr.io/${{ github.repository_owner }}/runtipi:buildcache,mode=max
|
||||
|
||||
build-cli:
|
||||
runs-on: ubuntu-latest
|
||||
needs: create-tag
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
- uses: pnpm/action-setup@v2.4.0
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
with:
|
||||
version: 8
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: |
|
||||
echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Set version
|
||||
run: pnpm -r --filter cli set-version ${{ needs.create-tag.outputs.tagname }}
|
||||
|
||||
- name: Build CLI
|
||||
run: pnpm -r --filter cli package
|
||||
|
||||
- name: Upload CLI
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: cli
|
||||
path: packages/cli/dist
|
||||
|
||||
publish-release:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [create-tag, build-images, build-cli, build-worker]
|
||||
outputs:
|
||||
id: ${{ steps.create_release.outputs.id }}
|
||||
steps:
|
||||
- name: Download CLI
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: cli
|
||||
path: cli
|
||||
|
||||
- name: Rename CLI
|
||||
run: |
|
||||
mv cli/bin/cli-x64 ./runtipi-cli-linux-x64
|
||||
mv cli/bin/cli-arm64 ./runtipi-cli-linux-arm64
|
||||
|
||||
- name: Create beta release
|
||||
id: create_release
|
||||
uses: softprops/action-gh-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
body: |
|
||||
**${{ needs.create-tag.outputs.tagname }}**
|
||||
tag_name: ${{ needs.create-tag.outputs.tagname }}
|
||||
name: ${{ needs.create-tag.outputs.tagname }}
|
||||
draft: false
|
||||
prerelease: true
|
||||
files: |
|
||||
runtipi-cli-linux-x64
|
||||
runtipi-cli-linux-arm64
|
||||
|
||||
e2e-tests:
|
||||
needs: [create-tag, publish-release]
|
||||
uses: './.github/workflows/e2e.yml'
|
||||
secrets: inherit
|
||||
with:
|
||||
version: ${{ needs.create-tag.outputs.tagname }}
|
116
.github/workflows/ci.yml
vendored
116
.github/workflows/ci.yml
vendored
|
@ -1,35 +1,22 @@
|
|||
name: Tipi CI
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
|
||||
env:
|
||||
ROOT_FOLDER: /runtipi
|
||||
JWT_SECRET: 'secret'
|
||||
ROOT_FOLDER_HOST: /runtipi
|
||||
APPS_REPO_ID: repo-id
|
||||
INTERNAL_IP: localhost
|
||||
REDIS_HOST: redis
|
||||
REDIS_PASSWORD: redis
|
||||
APPS_REPO_URL: https://repo.github.com/
|
||||
DOMAIN: localhost
|
||||
LOCAL_DOMAIN: tipi.lan
|
||||
TIPI_VERSION: 0.0.1
|
||||
POSTGRES_HOST: localhost
|
||||
POSTGRES_DBNAME: postgres
|
||||
POSTGRES_USERNAME: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_PORT: 5433
|
||||
|
||||
ROOT_FOLDER: /test
|
||||
JWT_SECRET: "secret"
|
||||
ROOT_FOLDER_HOST: /tipi
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
ci:
|
||||
runs-on: ubuntu-latest
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:14
|
||||
image: postgres:latest
|
||||
env:
|
||||
POSTGRES_PASSWORD: postgres
|
||||
ports:
|
||||
- 5433:5432
|
||||
- 5432:5432
|
||||
# set health checks to wait until postgres has started
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
|
@ -38,24 +25,24 @@ jobs:
|
|||
--health-retries 5
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 20
|
||||
node-version: 16
|
||||
|
||||
- uses: pnpm/action-setup@v2.4.0
|
||||
- uses: pnpm/action-setup@v2.0.1
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
with:
|
||||
version: 8
|
||||
version: 7
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: |
|
||||
echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
echo "::set-output name=pnpm_cache_dir::$(pnpm store path)"
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
|
@ -68,74 +55,19 @@ jobs:
|
|||
- 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 run lint
|
||||
|
||||
- name: Run linter on packages
|
||||
run: pnpm -r run lint
|
||||
|
||||
- name: Get number of CPU cores
|
||||
id: cpu-cores
|
||||
uses: SimenB/github-actions-cpu-cores@v2
|
||||
|
||||
run: pnpm -r lint
|
||||
|
||||
- name: Run tests
|
||||
run: pnpm run test --max-workers ${{ steps.cpu-cores.outputs.count }}
|
||||
|
||||
- uses: codecov/codecov-action@v3
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: ./coverage/lcov.info
|
||||
flags: app
|
||||
|
||||
- name: Run packages tests
|
||||
run: pnpm -r test
|
||||
|
||||
- name: Upload CLI coverage
|
||||
uses: codecov/codecov-action@v3
|
||||
- uses: codecov/codecov-action@v2
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: ./packages/cli/coverage/lcov.info
|
||||
flags: cli
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
- uses: pnpm/action-setup@v2.4.0
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
with:
|
||||
version: 8
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: |
|
||||
echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Build client
|
||||
run: npm run build
|
||||
|
||||
- name: Run tsc
|
||||
run: pnpm run tsc
|
||||
|
||||
- name: Run packages tsc
|
||||
run: pnpm -r run tsc
|
||||
files: ./packages/system-api/coverage/clover.xml,./packages/dashboard/coverage/clover.xml
|
4
.github/workflows/dependency-review.yml
vendored
4
.github/workflows/dependency-review.yml
vendored
|
@ -15,6 +15,6 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 'Checkout Repository'
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v3
|
||||
- name: 'Dependency Review'
|
||||
uses: actions/dependency-review-action@v3
|
||||
uses: actions/dependency-review-action@v1
|
||||
|
|
203
.github/workflows/e2e.yml
vendored
203
.github/workflows/e2e.yml
vendored
|
@ -1,203 +0,0 @@
|
|||
name: E2E Tests
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
version:
|
||||
required: true
|
||||
type: string
|
||||
description: 'Version to test (e.g. v1.6.0-beta.1)'
|
||||
outputs:
|
||||
page_url:
|
||||
description: 'URL of the deployed report'
|
||||
value: ${{ jobs.report-deployment.outputs.page_url }}
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
required: true
|
||||
type: string
|
||||
description: 'Version to test (e.g. v1.6.0-beta.1)'
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
timeout-minutes: 15
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
droplet_id: ${{ steps.create-droplet.outputs.droplet_id }}
|
||||
droplet_ip: ${{ steps.get-droplet-ip.outputs.droplet_ip }}
|
||||
postgres_password: ${{ steps.get-postgres-password.outputs.postgres_password }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install SSH key
|
||||
uses: shimataro/ssh-key-action@v2
|
||||
with:
|
||||
key: ${{ secrets.SSH_KEY }}
|
||||
known_hosts: unnecessary
|
||||
name: id_rsa
|
||||
|
||||
- name: Get sha of last commit
|
||||
id: get-sha
|
||||
run: echo "sha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Install doctl
|
||||
uses: digitalocean/action-doctl@v2
|
||||
with:
|
||||
token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
|
||||
|
||||
- name: Create new Droplet
|
||||
id: create-droplet
|
||||
run: |
|
||||
droplet_id=$(doctl compute droplet create runtipi-${{ steps.get-sha.outputs.sha }} \
|
||||
--image ubuntu-20-04-x64 \
|
||||
--size s-1vcpu-1gb \
|
||||
--format ID \
|
||||
--no-header \
|
||||
--ssh-keys ${{ secrets.SSH_KEY_FINGERPRINT }})
|
||||
echo "droplet_id=$droplet_id" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Wait for Droplet to become active
|
||||
run: |
|
||||
while ! doctl compute droplet get ${{ steps.create-droplet.outputs.droplet_id }} --format Status --no-header | grep -q "active"; do sleep 5; done
|
||||
|
||||
- name: Get Droplet IP address
|
||||
id: get-droplet-ip
|
||||
run: |
|
||||
droplet_ip=$(doctl compute droplet get ${{ steps.create-droplet.outputs.droplet_id }} --format PublicIPv4 --no-header)
|
||||
echo "droplet_ip=$droplet_ip" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Wait for SSH to be ready on Droplet
|
||||
run: |
|
||||
while ! ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa root@${{ steps.get-droplet-ip.outputs.droplet_ip }} "echo 'SSH is ready'"; do sleep 5; done
|
||||
|
||||
- name: Create docker group on Droplet
|
||||
uses: fifsky/ssh-action@master
|
||||
with:
|
||||
command: |
|
||||
groupadd docker
|
||||
usermod -aG docker root
|
||||
host: ${{ steps.get-droplet-ip.outputs.droplet_ip }}
|
||||
user: root
|
||||
key: ${{ secrets.SSH_KEY }}
|
||||
|
||||
- name: Wait 90 seconds for Docker to be ready on Droplet
|
||||
run: sleep 90
|
||||
|
||||
- name: Deploy app to Droplet
|
||||
uses: fifsky/ssh-action@master
|
||||
with:
|
||||
command: |
|
||||
echo 'Downloading install script from GitHub'
|
||||
curl -s https://raw.githubusercontent.com/runtipi/runtipi/${{ inputs.version }}/scripts/install.sh > install.sh
|
||||
chmod +x install.sh
|
||||
echo 'Running install script'
|
||||
./install.sh --version ${{ inputs.version }}
|
||||
echo 'App deployed'
|
||||
host: ${{ steps.get-droplet-ip.outputs.droplet_ip }}
|
||||
user: root # TODO: use non-root user
|
||||
key: ${{ secrets.SSH_KEY }}
|
||||
|
||||
- name: Get POSTGRES_PASSWORD from .env file
|
||||
id: get-postgres-password
|
||||
run: |
|
||||
postgres_password=$(ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa root@${{ steps.get-droplet-ip.outputs.droplet_ip }} "cat ./runtipi/.env | grep POSTGRES_PASSWORD | cut -d '=' -f2")
|
||||
echo "postgres_password=$postgres_password" >> $GITHUB_OUTPUT
|
||||
|
||||
e2e:
|
||||
timeout-minutes: 30
|
||||
runs-on: ubuntu-latest
|
||||
needs: [deploy]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: pnpm/action-setup@v2.4.0
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
with:
|
||||
version: 8
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: |
|
||||
echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
- name: Create .env.e2e file with Droplet IP
|
||||
run: |
|
||||
echo "SERVER_IP=${{ needs.deploy.outputs.droplet_ip }}" > .env.e2e
|
||||
echo "POSTGRES_PASSWORD=${{ needs.deploy.outputs.postgres_password }}" >> .env.e2e
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Install Playwright Browsers
|
||||
run: npx playwright install --with-deps
|
||||
|
||||
- name: Run Playwright tests
|
||||
id: run-e2e
|
||||
run: npm run test:e2e
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
name: playwright-report
|
||||
path: playwright-report/
|
||||
retention-days: 7
|
||||
|
||||
report-deployment:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [e2e]
|
||||
outputs:
|
||||
page_url: ${{ steps.deployment.outputs.page_url }}
|
||||
permissions:
|
||||
pages: write # to deploy to Pages
|
||||
id-token: write # to verify the deployment originates from an appropriate source
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
if: always()
|
||||
steps:
|
||||
- name: Download report artifact
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: playwright-report
|
||||
path: playwright-report/
|
||||
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v3
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v2
|
||||
with:
|
||||
path: playwright-report/
|
||||
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v2
|
||||
|
||||
teardown:
|
||||
runs-on: ubuntu-latest
|
||||
if: always()
|
||||
needs: [e2e, deploy]
|
||||
steps:
|
||||
- name: Install doctl
|
||||
uses: digitalocean/action-doctl@v2
|
||||
with:
|
||||
token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
|
||||
|
||||
- name: Delete Droplet
|
||||
run: doctl compute droplet delete ${{ needs.deploy.outputs.droplet_id }} --force
|
43
.github/workflows/release-candidate.yml
vendored
Normal file
43
.github/workflows/release-candidate.yml
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
name: Release candidate
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- release/*
|
||||
|
||||
jobs:
|
||||
# Build images and publish RCs to DockerHub
|
||||
build-images:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- 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
|
||||
id: meta
|
||||
run: |
|
||||
VERSION=$(npm run version --silent)
|
||||
TAG=${VERSION}
|
||||
echo "::set-output name=tag::${TAG}"
|
||||
|
||||
- name: Build and push images
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
push: true
|
||||
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
|
209
.github/workflows/release.yml
vendored
209
.github/workflows/release.yml
vendored
|
@ -1,192 +1,61 @@
|
|||
|
||||
name: Publish release
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
create-tag:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build-images, build-cli]
|
||||
outputs:
|
||||
tagname: ${{ steps.get_tag.outputs.tagname }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Get tag from package.json
|
||||
id: get_tag
|
||||
run: |
|
||||
VERSION=$(npm run version --silent)
|
||||
echo "tagname=v${VERSION}" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: rickstaa/action-create-tag@v1
|
||||
with:
|
||||
tag: ${{ steps.get_tag.outputs.tagname }}
|
||||
|
||||
build-images:
|
||||
if: github.repository == 'runtipi/runtipi'
|
||||
needs: create-tag
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Get tag from VERSION file
|
||||
id: meta
|
||||
run: |
|
||||
VERSION=$(npm run version --silent)
|
||||
TAG=${VERSION}
|
||||
echo "::set-output name=tag::${TAG}"
|
||||
|
||||
- name: Build and push images
|
||||
uses: docker/build-push-action@v5
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
push: true
|
||||
tags: ghcr.io/${{ github.repository_owner }}/runtipi:${{ needs.create-tag.outputs.tagname }},ghcr.io/${{ github.repository_owner }}/runtipi:latest
|
||||
cache-from: type=registry,ref=ghcr.io/${{ github.repository_owner }}/runtipi:buildcache
|
||||
cache-to: type=registry,ref=ghcr.io/${{ github.repository_owner }}/runtipi:buildcache,mode=max
|
||||
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
|
||||
|
||||
build-worker:
|
||||
runs-on: ubuntu-latest
|
||||
needs: create-tag
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
- name: Create Tag
|
||||
id: create_tag
|
||||
uses: jaywcjlove/create-tag-action@v1.1.5
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push images
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: ./packages/worker/Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ghcr.io/${{ github.repository_owner }}/worker:${{ needs.create-tag.outputs.tagname }},ghcr.io/${{ github.repository_owner }}/worker:latest
|
||||
cache-from: type=registry,ref=ghcr.io/${{ github.repository_owner }}/worker:buildcache
|
||||
cache-to: type=registry,ref=ghcr.io/${{ github.repository_owner }}/worker:buildcache,mode=max
|
||||
|
||||
build-cli:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
needs: create-tag
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
- uses: pnpm/action-setup@v2.4.0
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
with:
|
||||
version: 8
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: |
|
||||
echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Set version
|
||||
run: pnpm -r --filter cli set-version ${{ needs.create-tag.outputs.tagname }}
|
||||
|
||||
- name: Build CLI
|
||||
run: pnpm -r --filter cli package
|
||||
|
||||
- name: Upload CLI
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: cli
|
||||
path: packages/cli/dist
|
||||
|
||||
publish-release:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [create-tag, build-images, build-worker, build-cli]
|
||||
outputs:
|
||||
id: ${{ steps.create_release.outputs.id }}
|
||||
steps:
|
||||
- name: Download CLI
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: cli
|
||||
path: cli
|
||||
|
||||
- name: Rename CLI
|
||||
run: |
|
||||
mv cli/bin/cli-x64 ./runtipi-cli-linux-x64
|
||||
mv cli/bin/cli-arm64 ./runtipi-cli-linux-arm64
|
||||
|
||||
- name: Create release
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
package-path: ./package.json
|
||||
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
uses: softprops/action-gh-release@v1
|
||||
uses: actions/create-release@latest
|
||||
if: steps.create_tag.outputs.successful
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
body: |
|
||||
**${{ needs.create-tag.outputs.tagname }}**
|
||||
tag_name: ${{ needs.create-tag.outputs.tagname }}
|
||||
name: ${{ needs.create-tag.outputs.tagname }}
|
||||
tag_name: ${{ steps.create_tag.outputs.version }}
|
||||
release_name: ${{ steps.create_tag.outputs.version }}
|
||||
draft: false
|
||||
prerelease: true
|
||||
files: |
|
||||
runtipi-cli-linux-x64
|
||||
runtipi-cli-linux-arm64
|
||||
|
||||
e2e-tests:
|
||||
needs: [create-tag, publish-release]
|
||||
uses: './.github/workflows/e2e.yml'
|
||||
secrets: inherit
|
||||
with:
|
||||
version: ${{ needs.create-tag.outputs.tagname }}
|
||||
|
||||
# Promote release if e2e tests succeed
|
||||
promote:
|
||||
needs: [publish-release, e2e-tests]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Promote release
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const id = '${{ needs.publish-release.outputs.id }}';
|
||||
github.rest.repos.updateRelease({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
release_id: id,
|
||||
draft: false,
|
||||
prerelease: false
|
||||
});
|
||||
prerelease: false
|
||||
|
|
87
.gitignore
vendored
87
.gitignore
vendored
|
@ -1,69 +1,32 @@
|
|||
*.swo
|
||||
*.swp
|
||||
|
||||
.DS_Store
|
||||
.vscode
|
||||
.idea
|
||||
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
|
||||
# production
|
||||
/build
|
||||
/dist
|
||||
server-preload.js
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# local env files
|
||||
.env*.local
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
|
||||
logs
|
||||
.pnpm-debug.log
|
||||
.env*
|
||||
!.env.example
|
||||
!.env.test
|
||||
github.secrets
|
||||
node_modules/
|
||||
/app-data/
|
||||
/data/
|
||||
/repos/
|
||||
/apps/
|
||||
/traefik/
|
||||
app-data/*
|
||||
data/postgres
|
||||
traefik/ssl/*
|
||||
!traefik/ssl/.gitkeep
|
||||
!app-data/.gitkeep
|
||||
|
||||
# media folder
|
||||
media
|
||||
scripts/pacapt
|
||||
|
||||
/state/
|
||||
/test-results/
|
||||
/playwright-report/
|
||||
/playwright/.cache/
|
||||
temp
|
||||
state/*
|
||||
!state/.gitkeep
|
||||
|
||||
./traefik/
|
||||
/user-config/
|
||||
media/data/movies/*
|
||||
media/data/tv/*
|
||||
media/data/books/spoken/*
|
||||
media/data/books/ebooks/*
|
||||
!media/data/movies/.gitkeep
|
||||
!media/data/tv/.gitkeep
|
||||
!media/data/books/metadata.db
|
||||
!media/data/books/ebooks/.gitkeep
|
||||
!media/data/books/spoken/.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
|
||||
|
|
6
.husky/pre-commit
Executable file
6
.husky/pre-commit
Executable file
|
@ -0,0 +1,6 @@
|
|||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
pnpm test
|
||||
pnpm -r test
|
||||
pnpm -r lint:fix
|
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"yaml.schemas": {
|
||||
"https://raw.githubusercontent.com/ansible-community/schemas/main/f/ansible-playbook.json": "file:///Users/nicolas/Projects/runtipi/ansible/playbooks/install-dependencies.yml"
|
||||
}
|
||||
}
|
72
Dockerfile
72
Dockerfile
|
@ -1,49 +1,45 @@
|
|||
ARG NODE_VERSION="20.10"
|
||||
ARG ALPINE_VERSION="3.18"
|
||||
FROM node:18 AS build
|
||||
|
||||
FROM node:${NODE_VERSION}-alpine${ALPINE_VERSION} AS node_base
|
||||
RUN npm install node-gyp -g
|
||||
|
||||
FROM node_base AS builder_base
|
||||
|
||||
RUN npm install pnpm -g
|
||||
|
||||
# BUILDER
|
||||
FROM builder_base AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY ./pnpm-lock.yaml ./
|
||||
COPY ./pnpm-workspace.yaml ./
|
||||
COPY ./patches ./patches
|
||||
RUN pnpm fetch --no-scripts
|
||||
|
||||
COPY ./package*.json ./
|
||||
COPY ./packages/shared ./packages/shared
|
||||
|
||||
RUN pnpm install -r --prefer-offline
|
||||
COPY ./src ./src
|
||||
COPY ./tsconfig.json ./tsconfig.json
|
||||
COPY ./next.config.mjs ./next.config.mjs
|
||||
COPY ./public ./public
|
||||
COPY ./tests ./tests
|
||||
WORKDIR /api
|
||||
COPY ./packages/system-api/package.json /api/package.json
|
||||
RUN npm i
|
||||
# ---
|
||||
WORKDIR /dashboard
|
||||
COPY ./packages/dashboard/package.json /dashboard/package.json
|
||||
RUN npm i
|
||||
|
||||
WORKDIR /api
|
||||
COPY ./packages/system-api /api
|
||||
RUN npm run build
|
||||
# ---
|
||||
WORKDIR /dashboard
|
||||
COPY ./packages/dashboard /dashboard
|
||||
RUN npm run build
|
||||
|
||||
# APP
|
||||
FROM node_base AS app
|
||||
|
||||
ENV NODE_ENV production
|
||||
FROM alpine:3.16.0 as app
|
||||
|
||||
USER node
|
||||
WORKDIR /
|
||||
|
||||
WORKDIR /app
|
||||
# Install dependencies
|
||||
RUN apk --no-cache add docker-compose nodejs npm bash g++ make
|
||||
|
||||
COPY --from=builder /app/next.config.mjs ./
|
||||
COPY --from=builder /app/public ./public
|
||||
COPY --from=builder /app/package.json ./package.json
|
||||
COPY --from=builder --chown=node:node /app/.next/standalone ./
|
||||
COPY --from=builder --chown=node:node /app/.next/static ./.next/static
|
||||
RUN npm install node-gyp -g
|
||||
|
||||
EXPOSE 3000
|
||||
WORKDIR /api
|
||||
COPY ./packages/system-api/package*.json /api/
|
||||
RUN npm install --production
|
||||
|
||||
CMD ["npm", "run", "start"]
|
||||
WORKDIR /dashboard
|
||||
COPY ./packages/dashboard/package*.json /dashboard/
|
||||
RUN npm install --production
|
||||
|
||||
COPY --from=build /api/dist /api/dist
|
||||
COPY ./packages/system-api /api
|
||||
|
||||
COPY --from=build /dashboard/.next /dashboard/.next
|
||||
COPY ./packages/dashboard /dashboard
|
||||
|
||||
WORKDIR /
|
||||
|
|
|
@ -1,23 +1,21 @@
|
|||
ARG NODE_VERSION="20.10"
|
||||
ARG ALPINE_VERSION="3.18"
|
||||
FROM alpine:3.16.0 as app
|
||||
|
||||
FROM node:${NODE_VERSION}-alpine${ALPINE_VERSION}
|
||||
WORKDIR /
|
||||
|
||||
RUN npm install pnpm -g
|
||||
# Install docker
|
||||
RUN apk --no-cache add docker-compose nodejs npm bash g++ make
|
||||
|
||||
WORKDIR /app
|
||||
RUN npm install node-gyp -g
|
||||
|
||||
COPY ./pnpm-lock.yaml ./
|
||||
COPY ./patches ./patches
|
||||
RUN pnpm fetch --ignore-scripts
|
||||
WORKDIR /api
|
||||
COPY ./packages/system-api/package*.json /api/
|
||||
RUN npm install
|
||||
|
||||
COPY ./package*.json ./
|
||||
COPY ./packages/shared ./packages/shared
|
||||
WORKDIR /dashboard
|
||||
COPY ./packages/dashboard/package*.json /dashboard/
|
||||
RUN npm install
|
||||
|
||||
RUN pnpm install -r --prefer-offline
|
||||
COPY ./packages/system-api /api
|
||||
COPY ./packages/dashboard /dashboard
|
||||
|
||||
COPY ./tsconfig.json ./tsconfig.json
|
||||
COPY ./next.config.mjs ./next.config.mjs
|
||||
COPY ./public ./public
|
||||
|
||||
CMD ["npm", "run", "dev"]
|
||||
WORKDIR /
|
||||
|
|
171
README.md
171
README.md
|
@ -1,63 +1,106 @@
|
|||
# Tipi — A personal homeserver for everyone
|
||||
|
||||
# ⛺️ Tipi — A personal homeserver for everyone
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
||||
[](#contributors-)
|
||||
[](#contributors-)
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
||||
|
||||
[](https://github.com/runtipi/runtipi/blob/master/LICENSE)
|
||||
[](https://github.com/runtipi/runtipi/releases)
|
||||

|
||||
[](https://github.com/meienberger/runtipi/blob/master/LICENSE)
|
||||
[](https://github.com/meienberger/runtipi/releases)
|
||||

|
||||
[](https://hub.docker.com/r/meienberger/runtipi/)
|
||||
[](https://hub.docker.com/r/meienberger/runtipi/)
|
||||

|
||||
[](https://crowdin.com/project/runtipi)
|
||||
|
||||
> 💡 Tipi is built with TypeScript, Next.js app router and Drizzle ORM! If you want to collaborate on a cool project, join the discussion on Discord!
|
||||
|
||||

|
||||
#### Join the discussion
|
||||
|
||||
[](https://discord.gg/Bu9qEPnHsc)
|
||||
[](https://matrix.to/#/#runtipi:matrix.org)
|
||||
|
||||

|
||||
|
||||

|
||||
> ⚠️ 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 that makes it easy to manage and run multiple services on a single server. It is based on Docker and comes with a simple web interface to manage your services. Tipi is designed to be easy to use, so you don't have to worry about manual configuration or networking. Simply install Tipi on your server and use the web interface to add and manage services. You can see a list of available services in the [App Store repo](https://github.com/runtipi/runtipi-appstore) and request new ones if you don't see what you need. To get started, follow the installation instructions below.
|
||||
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.
|
||||
|
||||
## Getting started
|
||||
Check our demo instance : **95.179.210.152** / username: **user@runtipi.com** / password: **runtipi**
|
||||
|
||||
Visit our website [runtipi.io](https://www.runtipi.io/docs/getting-started/installation?utm_source=github&utm_medium=README&utm_campaign=getting-started) for installation instructions, documentation and guides.
|
||||
## 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/coder/code-server) - Web VS Code
|
||||
- [Filebrowser](https://github.com/filebrowser/filebrowser) - Web File Browser
|
||||
- [Firefly III](https://github.com/firefly-iii/firefly-iii) - A personal finances manager
|
||||
- [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
|
||||
- [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
|
||||
- [Overseerr](https://github.com/sct/overseerr) - Request management and media discovery tool for the Plex ecosystem
|
||||
- [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
|
||||
- [Plex](https://github.com/plexinc/pms-docker) - Stream Movies & TV Shows
|
||||
- [Portainer](https://github.com/portainer/portainer) - Making Docker and Kubernetes management easy.
|
||||
- [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
|
||||
- [Readarr](https://github.com/Readarr/Readarr) - Book Manager and Automation (Sonarr for Ebooks)
|
||||
- [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
|
||||
- [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
|
||||
- [Vaultwarden](https://github.com/dani-garcia/vaultwarden) - Unofficial Bitwarden compatible server
|
||||
|
||||
## Demo
|
||||
## 🛠 Installation
|
||||
|
||||
You can try out a demo of Tipi at [demo.runtipi.io](https://demo.runtipi.io) using the following credentials:
|
||||
### Installation Requirements
|
||||
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.
|
||||
|
||||
username: user@runtipi.io
|
||||
password: password
|
||||
### Step 1. Download Tipi
|
||||
Run this in an empty directory where you want to install Tipi.
|
||||
|
||||
## 📚 Documentation
|
||||
```bash
|
||||
git clone https://github.com/meienberger/runtipi.git
|
||||
```
|
||||
|
||||
For a detailed guide on how to install Tipi. This amazing article by @kycfree [Running a Home Server with Tipi](https://kyc3.life/running-a-home-server-with-tipi/)
|
||||
### Step 2. Run Tipi
|
||||
cd into the downloaded directory and run the start script.
|
||||
|
||||
You can find more documentation and tutorials / FAQ on [runtipi.io](https://www.runtipi.io/docs/introduction?utm_source=github&utm_medium=README&utm_campaign=main-repo-docs)
|
||||
```bash
|
||||
cd runtipi
|
||||
sudo ./scripts/start.sh
|
||||
```
|
||||
|
||||
The script will prompt you the ip address of the dashboard once configured.
|
||||
Tipi will run by default on port 80. To select another port you can run the start script with the `--port` argument
|
||||
|
||||
```bash
|
||||
sudo ./scripts/start.sh --port 7000
|
||||
```
|
||||
|
||||
To stop Tipi, run the stop script.
|
||||
|
||||
```bash
|
||||
sudo ./scripts/stop.sh
|
||||
```
|
||||
|
||||
## ❤️ Contributing
|
||||
|
||||
Tipi is made to be very easy to plug in new apps. We welcome and appreciate new contributions.
|
||||
|
||||
If you want to add a new app or feature, you can follow the [Contribution guide](https://www.runtipi.io/docs/contributing/adding-a-new-app) for instructions on how to do so.
|
||||
|
||||
We are looking for contributions of all kinds. If you know design, development, or have ideas for new features, please get in touch.
|
||||
If you want to add a new app or feature, you can follow the [Contribution guide](https://github.com/meienberger/runtipi/wiki/Contributing-to-Tipi) for instructions on how to do so.
|
||||
|
||||
## 📜 License
|
||||
|
||||
[](https://github.com/runtipi/runtipi/blob/master/LICENSE)
|
||||
[](https://github.com/meienberger/runtipi/blob/master/LICENSE)
|
||||
|
||||
Tipi is licensed under the GNU General Public License v3.0. TL;DR — You may copy, distribute and modify the software as long as you track changes/dates in source files. Any modifications to or software including (via compiler) GPL-licensed code must also be made available under the GPL along with build & install instructions.
|
||||
|
||||
## 🗣 Community
|
||||
|
||||
- [Matrix](https://matrix.to/#/#runtipi:matrix.org)<br />
|
||||
- [Twitter](https://twitter.com/runtipi)
|
||||
- [Telegram](https://t.me/+72-y10MnLBw2ZGI0)
|
||||
|
@ -71,62 +114,14 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|||
<!-- prettier-ignore-start -->
|
||||
<!-- markdownlint-disable -->
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://meienberger.dev/"><img src="https://avatars.githubusercontent.com/u/47644445?v=4?s=100" width="100px;" alt="Nicolas Meienberger"/><br /><sub><b>Nicolas Meienberger</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=meienberger" title="Code">💻</a> <a href="#infra-meienberger" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="https://github.com/runtipi/runtipi/commits?author=meienberger" title="Tests">⚠️</a> <a href="https://github.com/runtipi/runtipi/commits?author=meienberger" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ArneNaessens"><img src="https://avatars.githubusercontent.com/u/16622722?v=4?s=100" width="100px;" alt="ArneNaessens"/><br /><sub><b>ArneNaessens</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=ArneNaessens" title="Code">💻</a> <a href="#ideas-ArneNaessens" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/runtipi/runtipi/commits?author=ArneNaessens" title="Tests">⚠️</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DrMxrcy"><img src="https://avatars.githubusercontent.com/u/58747968?v=4?s=100" width="100px;" alt="DrMxrcy"/><br /><sub><b>DrMxrcy</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=DrMxrcy" title="Code">💻</a> <a href="#ideas-DrMxrcy" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/runtipi/runtipi/commits?author=DrMxrcy" title="Tests">⚠️</a> <a href="#content-DrMxrcy" title="Content">🖋</a> <a href="#promotion-DrMxrcy" title="Promotion">📣</a> <a href="#question-DrMxrcy" title="Answering Questions">💬</a> <a href="https://github.com/runtipi/runtipi/pulls?q=is%3Apr+reviewed-by%3ADrMxrcy" title="Reviewed Pull Requests">👀</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://cobre.dev"><img src="https://avatars.githubusercontent.com/u/36574329?v=4?s=100" width="100px;" alt="Cooper"/><br /><sub><b>Cooper</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=CobreDev" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/JTruj1ll0923"><img src="https://avatars.githubusercontent.com/u/6656643?v=4?s=100" width="100px;" alt="JTruj1ll0923"/><br /><sub><b>JTruj1ll0923</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=JTruj1ll0923" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Stetsed"><img src="https://avatars.githubusercontent.com/u/33891782?v=4?s=100" width="100px;" alt="Stetsed"/><br /><sub><b>Stetsed</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=Stetsed" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/blushell"><img src="https://avatars.githubusercontent.com/u/3621606?v=4?s=100" width="100px;" alt="Jones_Town"/><br /><sub><b>Jones_Town</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=blushell" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://rushichaudhari.github.io/"><img src="https://avatars.githubusercontent.com/u/6279035?v=4?s=100" width="100px;" alt="Rushi Chaudhari"/><br /><sub><b>Rushi Chaudhari</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=rushic24" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/rblaine95"><img src="https://avatars.githubusercontent.com/u/4052340?v=4?s=100" width="100px;" alt="Robert Blaine"/><br /><sub><b>Robert Blaine</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=rblaine95" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://sethforprivacy.com"><img src="https://avatars.githubusercontent.com/u/40500387?v=4?s=100" width="100px;" alt="Seth For Privacy"/><br /><sub><b>Seth For Privacy</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=sethforprivacy" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hqwuzhaoyi"><img src="https://avatars.githubusercontent.com/u/44605072?v=4?s=100" width="100px;" alt="Prajna"/><br /><sub><b>Prajna</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=hqwuzhaoyi" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/justincmoy"><img src="https://avatars.githubusercontent.com/u/14875982?v=4?s=100" width="100px;" alt="Justin Moy"/><br /><sub><b>Justin Moy</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=justincmoy" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/dextreem"><img src="https://avatars.githubusercontent.com/u/11060652?v=4?s=100" width="100px;" alt="dextreem"/><br /><sub><b>dextreem</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=dextreem" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/iBicha"><img src="https://avatars.githubusercontent.com/u/17722782?v=4?s=100" width="100px;" alt="Brahim Hadriche"/><br /><sub><b>Brahim Hadriche</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=iBicha" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://andrewbrereton.com"><img src="https://avatars.githubusercontent.com/u/682893?v=4?s=100" width="100px;" alt="Andrew Brereton"/><br /><sub><b>Andrew Brereton</b></sub></a><br /><a href="#content-andrewbrereton" title="Content">🖋</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://fsackur.github.io/"><img src="https://avatars.githubusercontent.com/u/3678789?v=4?s=100" width="100px;" alt="Freddie Sackur"/><br /><sub><b>Freddie Sackur</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=fsackur" title="Code">💻</a> <a href="https://github.com/runtipi/runtipi/commits?author=fsackur" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://innocentius.github.io"><img src="https://avatars.githubusercontent.com/u/5344432?v=4?s=100" width="100px;" alt="Innocentius"/><br /><sub><b>Innocentius</b></sub></a><br /><a href="#translation-innocentius" title="Translation">🌍</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TetrisIQ"><img src="https://avatars.githubusercontent.com/u/24246993?v=4?s=100" width="100px;" alt="Alex"/><br /><sub><b>Alex</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=TetrisIQ" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://ryanc.cc"><img src="https://avatars.githubusercontent.com/u/21301288?v=4?s=100" width="100px;" alt="Ryan Wang"/><br /><sub><b>Ryan Wang</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=ruibaby" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/simonandr"><img src="https://avatars.githubusercontent.com/u/48092304?v=4?s=100" width="100px;" alt="simonandr"/><br /><sub><b>simonandr</b></sub></a><br /><a href="#content-simonandr" title="Content">🖋</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/demizeu"><img src="https://avatars.githubusercontent.com/u/121183951?v=4?s=100" width="100px;" alt="iepure"/><br /><sub><b>iepure</b></sub></a><br /><a href="#translation-demizeu" title="Translation">🌍</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/SergeyKodolov"><img src="https://avatars.githubusercontent.com/u/35339452?v=4?s=100" width="100px;" alt="Sergey Kodolov"/><br /><sub><b>Sergey Kodolov</b></sub></a><br /><a href="#translation-SergeyKodolov" title="Translation">🌍</a> <a href="https://github.com/runtipi/runtipi/commits?author=SergeyKodolov" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sclaren"><img src="https://avatars.githubusercontent.com/u/915292?v=4?s=100" width="100px;" alt="sclaren"/><br /><sub><b>sclaren</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=sclaren" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mcmeel"><img src="https://avatars.githubusercontent.com/u/13773536?v=4?s=100" width="100px;" alt="mcmeel"/><br /><sub><b>mcmeel</b></sub></a><br /><a href="#question-mcmeel" title="Answering Questions">💬</a> <a href="#ideas-mcmeel" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/runtipi/runtipi/commits?author=mcmeel" title="Code">💻</a> <a href="https://github.com/runtipi/runtipi/commits?author=mcmeel" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/NoisyFridge"><img src="https://avatars.githubusercontent.com/u/73795785?v=4?s=100" width="100px;" alt="NoisyFridge"/><br /><sub><b>NoisyFridge</b></sub></a><br /><a href="#translation-NoisyFridge" title="Translation">🌍</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Bvoxl"><img src="https://avatars.githubusercontent.com/u/67489519?v=4?s=100" width="100px;" alt="Bvoxl"/><br /><sub><b>Bvoxl</b></sub></a><br /><a href="#translation-Bvoxl" title="Translation">🌍</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/m-lab-0"><img src="https://avatars.githubusercontent.com/u/116570617?v=4?s=100" width="100px;" alt="m-lab-0"/><br /><sub><b>m-lab-0</b></sub></a><br /><a href="#translation-m-lab-0" title="Translation">🌍</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/dannkunt"><img src="https://avatars.githubusercontent.com/u/32395839?v=4?s=100" width="100px;" alt="dannkunt"/><br /><sub><b>dannkunt</b></sub></a><br /><a href="#translation-dannkunt" title="Translation">🌍</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Schmanko"><img src="https://avatars.githubusercontent.com/u/94195393?v=4?s=100" width="100px;" alt="Schmanko"/><br /><sub><b>Schmanko</b></sub></a><br /><a href="#translation-Schmanko" title="Translation">🌍</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://micro.nghialele.com"><img src="https://avatars.githubusercontent.com/u/129353223?v=4?s=100" width="100px;" alt="Nghia Lele"/><br /><sub><b>Nghia Lele</b></sub></a><br /><a href="#translation-nghialele" title="Translation">🌍</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/amusingimpala75"><img src="https://avatars.githubusercontent.com/u/69653100?v=4?s=100" width="100px;" alt="amusingimpala75"/><br /><sub><b>amusingimpala75</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=amusingimpala75" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://m1n.omg.lol"><img src="https://avatars.githubusercontent.com/u/54779580?v=4?s=100" width="100px;" alt="David"/><br /><sub><b>David</b></sub></a><br /><a href="#translation-M1n-4d316e" title="Translation">🌍</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/steveiliop56"><img src="https://avatars.githubusercontent.com/u/106091011?v=4?s=100" width="100px;" alt="Stavros Iliopoulos"/><br /><sub><b>Stavros Iliopoulos</b></sub></a><br /><a href="#translation-steveiliop56" title="Translation">🌍</a> <a href="https://github.com/runtipi/runtipi/commits?author=steveiliop56" title="Code">💻</a> <a href="https://github.com/runtipi/runtipi/commits?author=steveiliop56" title="Tests">⚠️</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/loxiry"><img src="https://avatars.githubusercontent.com/u/86959495?v=4?s=100" width="100px;" alt="loxiry"/><br /><sub><b>loxiry</b></sub></a><br /><a href="#translation-loxiry" title="Translation">🌍</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/JigSawFr"><img src="https://avatars.githubusercontent.com/u/5781907?v=4?s=100" width="100px;" alt="JigSaw"/><br /><sub><b>JigSaw</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=JigSawFr" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DireMunchkin"><img src="https://avatars.githubusercontent.com/u/1665676?v=4?s=100" width="100px;" alt="DireMunchkin"/><br /><sub><b>DireMunchkin</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=DireMunchkin" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/FabioCingottini"><img src="https://avatars.githubusercontent.com/u/32102735?v=4?s=100" width="100px;" alt="Fabio Cingottini"/><br /><sub><b>Fabio Cingottini</b></sub></a><br /><a href="#translation-FabioCingottini" title="Translation">🌍</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/itsrllyhim"><img src="https://avatars.githubusercontent.com/u/143047010?v=4?s=100" width="100px;" alt="him"/><br /><sub><b>him</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=itsrllyhim" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://cchalop1.com"><img src="https://avatars.githubusercontent.com/u/28163855?v=4?s=100" width="100px;" alt="CHALOPIN Clément"/><br /><sub><b>CHALOPIN Clément</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=cchalop1" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/geetansh"><img src="https://avatars.githubusercontent.com/u/9976198?v=4?s=100" width="100px;" alt="Geetansh Jindal"/><br /><sub><b>Geetansh Jindal</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=geetansh" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/0livier"><img src="https://avatars.githubusercontent.com/u/10607?v=4?s=100" width="100px;" alt="Olivier Garcia"/><br /><sub><b>Olivier Garcia</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=0livier" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/qcoudeyr"><img src="https://avatars.githubusercontent.com/u/124463277?v=4?s=100" width="100px;" alt="qcoudeyr"/><br /><sub><b>qcoudeyr</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=qcoudeyr" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<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>
|
||||
<td align="center"><a href="https://github.com/Stetsed"><img src="https://avatars.githubusercontent.com/u/33891782?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Stetsed</b></sub></a><br /><a href="https://github.com/meienberger/runtipi/commits?author=Stetsed" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- markdownlint-restore -->
|
||||
|
@ -134,4 +129,4 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|||
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
||||
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
|
@ -1,35 +0,0 @@
|
|||
import { fs, vol } from 'memfs';
|
||||
|
||||
const copyFolderRecursiveSync = (src: string, dest: string) => {
|
||||
const exists = vol.existsSync(src);
|
||||
const stats = vol.statSync(src);
|
||||
const isDirectory = exists && stats.isDirectory();
|
||||
if (isDirectory) {
|
||||
vol.mkdirSync(dest, { recursive: true });
|
||||
vol.readdirSync(src).forEach((childItemName) => {
|
||||
copyFolderRecursiveSync(`${src}/${childItemName}`, `${dest}/${childItemName}`);
|
||||
});
|
||||
} else {
|
||||
vol.copyFileSync(src, dest);
|
||||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
...fs,
|
||||
copySync: (src: string, dest: string) => {
|
||||
copyFolderRecursiveSync(src, dest);
|
||||
},
|
||||
__resetAllMocks: () => {
|
||||
vol.reset();
|
||||
},
|
||||
__applyMockFiles: (newMockFiles: Record<string, string>) => {
|
||||
// Create folder tree
|
||||
vol.fromJSON(newMockFiles, 'utf8');
|
||||
},
|
||||
__createMockFiles: (newMockFiles: Record<string, string>) => {
|
||||
vol.reset();
|
||||
// Create folder tree
|
||||
vol.fromJSON(newMockFiles, 'utf8');
|
||||
},
|
||||
__printVol: () => console.log(vol.toTree()),
|
||||
};
|
|
@ -1,29 +0,0 @@
|
|||
const values = new Map();
|
||||
const expirations = new Map();
|
||||
|
||||
export const createClient = jest.fn(() => {
|
||||
return {
|
||||
isOpen: true,
|
||||
connect: jest.fn(),
|
||||
set: (key: string, value: string, exp: number) => {
|
||||
values.set(key, value);
|
||||
expirations.set(key, exp);
|
||||
},
|
||||
get: (key: string) => values.get(key),
|
||||
quit: jest.fn(),
|
||||
del: (key: string) => values.delete(key),
|
||||
ttl: (key: string) => expirations.get(key),
|
||||
on: jest.fn(),
|
||||
keys: (key: string) => {
|
||||
const keyprefix = key.substring(0, key.length - 1);
|
||||
const keys = [];
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const [k] of values) {
|
||||
if (k.startsWith(keyprefix)) {
|
||||
keys.push(k);
|
||||
}
|
||||
}
|
||||
return keys;
|
||||
},
|
||||
};
|
||||
});
|
176
apps/__tests__/apps.test.ts
Normal file
176
apps/__tests__/apps.test.ts
Normal 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",
|
||||
]);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
16
apps/adguard/config.json
Normal file
16
apps/adguard/config.json
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "Adguard",
|
||||
"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": "AdguardTeam",
|
||||
"source": "https://github.com/AdguardTeam",
|
||||
"image": "/logos/apps/adguard.jpg",
|
||||
"requirements": {
|
||||
"ports": [53]
|
||||
},
|
||||
"form_fields": []
|
||||
}
|
131
apps/adguard/data/conf/AdGuardHome.yaml
Normal file
131
apps/adguard/data/conf/AdGuardHome.yaml
Normal file
|
@ -0,0 +1,131 @@
|
|||
bind_host: 0.0.0.0
|
||||
bind_port: 80
|
||||
beta_bind_port: 0
|
||||
users: []
|
||||
auth_attempts: 5
|
||||
block_auth_min: 15
|
||||
http_proxy: ""
|
||||
language: ""
|
||||
debug_pprof: false
|
||||
web_session_ttl: 720
|
||||
dns:
|
||||
bind_hosts:
|
||||
- 0.0.0.0
|
||||
port: 53
|
||||
statistics_interval: 1
|
||||
querylog_enabled: true
|
||||
querylog_file_enabled: true
|
||||
querylog_interval: 2160h
|
||||
querylog_size_memory: 1000
|
||||
anonymize_client_ip: false
|
||||
protection_enabled: true
|
||||
blocking_mode: default
|
||||
blocking_ipv4: ""
|
||||
blocking_ipv6: ""
|
||||
blocked_response_ttl: 10
|
||||
parental_block_host: family-block.dns.adguard.com
|
||||
safebrowsing_block_host: standard-block.dns.adguard.com
|
||||
ratelimit: 20
|
||||
ratelimit_whitelist: []
|
||||
refuse_any: true
|
||||
upstream_dns:
|
||||
- https://dns10.quad9.net/dns-query
|
||||
upstream_dns_file: ""
|
||||
bootstrap_dns:
|
||||
- 9.9.9.10
|
||||
- 149.112.112.10
|
||||
- 2620:fe::10
|
||||
- 2620:fe::fe:10
|
||||
all_servers: false
|
||||
fastest_addr: false
|
||||
fastest_timeout: 1s
|
||||
allowed_clients: []
|
||||
disallowed_clients: []
|
||||
blocked_hosts:
|
||||
- version.bind
|
||||
- id.server
|
||||
- hostname.bind
|
||||
trusted_proxies:
|
||||
- 127.0.0.0/8
|
||||
- ::1/128
|
||||
cache_size: 4194304
|
||||
cache_ttl_min: 0
|
||||
cache_ttl_max: 0
|
||||
cache_optimistic: false
|
||||
bogus_nxdomain: []
|
||||
aaaa_disabled: false
|
||||
enable_dnssec: false
|
||||
edns_client_subnet: false
|
||||
max_goroutines: 300
|
||||
ipset: []
|
||||
filtering_enabled: true
|
||||
filters_update_interval: 24
|
||||
parental_enabled: false
|
||||
safesearch_enabled: false
|
||||
safebrowsing_enabled: false
|
||||
safebrowsing_cache_size: 1048576
|
||||
safesearch_cache_size: 1048576
|
||||
parental_cache_size: 1048576
|
||||
cache_time: 30
|
||||
rewrites: []
|
||||
blocked_services: []
|
||||
upstream_timeout: 10s
|
||||
local_domain_name: lan
|
||||
resolve_clients: true
|
||||
use_private_ptr_resolvers: true
|
||||
local_ptr_upstreams: []
|
||||
tls:
|
||||
enabled: false
|
||||
server_name: ""
|
||||
force_https: false
|
||||
port_https: 443
|
||||
port_dns_over_tls: 853
|
||||
port_dns_over_quic: 784
|
||||
port_dnscrypt: 0
|
||||
dnscrypt_config_file: ""
|
||||
allow_unencrypted_doh: false
|
||||
strict_sni_check: false
|
||||
certificate_chain: ""
|
||||
private_key: ""
|
||||
certificate_path: ""
|
||||
private_key_path: ""
|
||||
filters:
|
||||
- enabled: true
|
||||
url: https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt
|
||||
name: AdGuard DNS filter
|
||||
id: 1
|
||||
- enabled: false
|
||||
url: https://adaway.org/hosts.txt
|
||||
name: AdAway Default Blocklist
|
||||
id: 2
|
||||
whitelist_filters: []
|
||||
user_rules: []
|
||||
dhcp:
|
||||
enabled: false
|
||||
interface_name: ""
|
||||
dhcpv4:
|
||||
gateway_ip: ""
|
||||
subnet_mask: ""
|
||||
range_start: ""
|
||||
range_end: ""
|
||||
lease_duration: 86400
|
||||
icmp_timeout_msec: 1000
|
||||
options: []
|
||||
dhcpv6:
|
||||
range_start: ""
|
||||
lease_duration: 86400
|
||||
ra_slaac_only: false
|
||||
ra_allow_slaac: false
|
||||
clients: []
|
||||
log_compress: false
|
||||
log_localtime: false
|
||||
log_max_backups: 0
|
||||
log_max_size: 100
|
||||
log_max_age: 3
|
||||
log_file: ""
|
||||
verbose: false
|
||||
os:
|
||||
group: ""
|
||||
user: ""
|
||||
rlimit_nofile: 0
|
||||
schema_version: 12
|
16
apps/adguard/docker-compose.yml
Normal file
16
apps/adguard/docker-compose.yml
Normal file
|
@ -0,0 +1,16 @@
|
|||
|
||||
version: "3.7"
|
||||
services:
|
||||
adguard:
|
||||
image: adguard/adguardhome:v0.107.7
|
||||
container_name: adguard
|
||||
volumes:
|
||||
- "${APP_DATA_DIR}/data/work:/opt/adguardhome/work"
|
||||
- "${APP_DATA_DIR}/data/conf:/opt/adguardhome/conf"
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- tipi_main_network
|
||||
ports:
|
||||
- 53:53/tcp
|
||||
- 53:53/udp
|
||||
- ${APP_PORT}:80
|
6
apps/adguard/metadata/description.md
Normal file
6
apps/adguard/metadata/description.md
Normal 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.
|
||||
|
||||

|
47
apps/anonaddy/config.json
Normal file
47
apps/anonaddy/config.json
Normal file
|
@ -0,0 +1,47 @@
|
|||
{
|
||||
"name": "Anonaddy",
|
||||
"port": 8084,
|
||||
"available": false,
|
||||
"categories": ["utilities"],
|
||||
"id": "anonaddy",
|
||||
"description": "",
|
||||
"short_desc": "Anonymous email forwarding",
|
||||
"author": "",
|
||||
"source": "https://github.com/anonaddy/anonaddy",
|
||||
"image": "https://avatars.githubusercontent.com/u/51450862?s=200&v=4",
|
||||
"requirements": {
|
||||
"ports": [25]
|
||||
},
|
||||
"form_fields": [
|
||||
{
|
||||
"type": "text",
|
||||
"label": "Username",
|
||||
"required": true,
|
||||
"env_variable": "ANONADDY_USERNAME"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "App key",
|
||||
"hint": "Application key for encrypter service. Generate one with : echo \"base64:$(openssl rand -base64 32)\"",
|
||||
"required": true,
|
||||
"env_variable": "ANONADDY_KEY"
|
||||
},
|
||||
{
|
||||
"type": "fqdn",
|
||||
"label": "Your email domain (eg. example.com)",
|
||||
"max": 50,
|
||||
"min": 3,
|
||||
"required": true,
|
||||
"env_variable": "ANONADDY_DOMAIN"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "App secret",
|
||||
"hint": "Long random string used when hashing data for the anonymous replies",
|
||||
"max": 50,
|
||||
"min": 3,
|
||||
"required": true,
|
||||
"env_variable": "ANONADDY_SECRET"
|
||||
}
|
||||
]
|
||||
}
|
80
apps/anonaddy/docker-compose.yml
Normal file
80
apps/anonaddy/docker-compose.yml
Normal file
|
@ -0,0 +1,80 @@
|
|||
version: "3.7"
|
||||
services:
|
||||
db:
|
||||
image: mariadb:10.5
|
||||
container_name: db-anonaddy
|
||||
command:
|
||||
- "mysqld"
|
||||
- "--character-set-server=utf8mb4"
|
||||
- "--collation-server=utf8mb4_unicode_ci"
|
||||
volumes:
|
||||
- "${APP_DATA_DIR}/db:/var/lib/mysql"
|
||||
environment:
|
||||
MARIADB_DATABASE: anonaddy
|
||||
MARIADB_USER: anonaddy
|
||||
MARIADB_ROOT_PASSWORD: anonaddy
|
||||
MARIADB_PASSWORD: anonaddy
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- tipi_main_network
|
||||
|
||||
redis:
|
||||
image: redis:4.0-alpine
|
||||
container_name: redis-anonaddy
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- tipi_main_network
|
||||
|
||||
anonaddy:
|
||||
image: anonaddy/anonaddy:0.11.1
|
||||
container_name: anonaddy
|
||||
ports:
|
||||
- 25:25
|
||||
- ${APP_PORT}:8000
|
||||
depends_on:
|
||||
- db
|
||||
- redis
|
||||
volumes:
|
||||
- "${APP_DATA_DIR}/data:/data"
|
||||
environment:
|
||||
TZ: ${TZ}
|
||||
DB_HOST: db-anonaddy
|
||||
DB_PASSWORD: anonaddy
|
||||
REDIS_HOST: redis-anonaddy
|
||||
APP_KEY: ${ANONADDY_KEY}
|
||||
ANONADDY_DOMAIN: ${ANONADDY_DOMAIN}
|
||||
ANONADDY_SECRET: ${ANONADDY_SECRET}
|
||||
ANONADDY_ADMIN_USERNAME: ${ANONADDY_USERNAME}
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- tipi_main_network
|
||||
# labels:
|
||||
# traefik.enable: true
|
||||
# traefik.http.routers.anonaddy.rule: Host(`anonaddy.tipi.home`)
|
||||
# traefik.http.routers.anonaddy.tls: true
|
||||
# traefik.http.routers.anonaddy.entrypoints: websecure
|
||||
# traefik.http.routers.anonaddy.service: anonaddy
|
||||
# traefik.http.services.anonaddy.loadbalancer.server.port: 8000
|
||||
# labels:
|
||||
# traefik.enable: true
|
||||
# traefik.http.routers.anonaddy.rule: PathPrefix(`/anonaddy`)
|
||||
|
||||
# # Redirect to ending /
|
||||
# traefik.http.middlewares.anonaddy-redirect.redirectregex.regex: ^(http:\/\/(\[[\w:.]+\]|[\w\._-]+)(:\d+)?)\/anonaddy$$
|
||||
# traefik.http.middlewares.anonaddy-redirect.redirectregex.replacement: $${1}/anonaddy/
|
||||
|
||||
# # Strip /anonaddy/ from URL
|
||||
# traefik.http.middlewares.anonaddy-stripprefix.stripprefixregex.regex: (/anonaddy/|/anonaddy)
|
||||
|
||||
# traefik.http.middlewares.anonaddy-headers.headers.customrequestheaders.Host: $$host
|
||||
# traefik.http.middlewares.anonaddy-headers.headers.customrequestheaders.X-Forwarded-Proto: $$scheme
|
||||
# traefik.http.middlewares.anonaddy-headers.headers.customrequestheaders.X-Forwarded-For: $$proxy_add_x_forwarded_for
|
||||
# traefik.http.middlewares.anonaddy-headers.headers.customrequestheaders.X-Real-IP: $$remote_addr
|
||||
# traefik.http.middlewares.anonaddy-headers.headers.customrequestheaders.X-Frame-Options: "SAMEORIGIN"
|
||||
|
||||
# # Apply middleware
|
||||
# traefik.http.routers.anonaddy.middlewares: anonaddy-redirect, anonaddy-stripprefix, anonaddy-headers
|
||||
|
||||
# traefik.http.routers.anonaddy.entrypoints: http
|
||||
# traefik.http.routers.anonaddy.service: anonaddy
|
||||
# traefik.http.services.anonaddy.loadbalancer.server.port: 8000
|
13
apps/calibre-web/config.json
Normal file
13
apps/calibre-web/config.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "Calibre-Web - EBook Reader",
|
||||
"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": "/logos/apps/calibre-web.jpg",
|
||||
"form_fields": []
|
||||
}
|
BIN
apps/calibre-web/data/books/metadata.db
Normal file
BIN
apps/calibre-web/data/books/metadata.db
Normal file
Binary file not shown.
17
apps/calibre-web/docker-compose.yml
Normal file
17
apps/calibre-web/docker-compose.yml
Normal file
|
@ -0,0 +1,17 @@
|
|||
version: "3.7"
|
||||
services:
|
||||
calibre-web:
|
||||
image: lscr.io/linuxserver/calibre-web:0.6.18
|
||||
container_name: calibre-web
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=${TZ}
|
||||
volumes:
|
||||
- ${APP_DATA_DIR}/data/config:/config
|
||||
- ${ROOT_FOLDER_HOST}/media/data/books:/books
|
||||
ports:
|
||||
- ${APP_PORT}:8083
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- tipi_main_network
|
7
apps/calibre-web/metadata/description.md
Normal file
7
apps/calibre-web/metadata/description.md
Normal 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 />
|
22
apps/code-server/config.json
Normal file
22
apps/code-server/config.json
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "Code-Server - Web VS Code",
|
||||
"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",
|
||||
"source": "https://github.com/linuxserver/docker-code-server",
|
||||
"image": "https://avatars.githubusercontent.com/u/95932066",
|
||||
"form_fields": [
|
||||
{
|
||||
"type": "password",
|
||||
"label": "Password",
|
||||
"max": 50,
|
||||
"min": 3,
|
||||
"required": true,
|
||||
"env_variable": "CODESERVER_PASSWORD"
|
||||
}
|
||||
]
|
||||
}
|
19
apps/code-server/docker-compose.yml
Normal file
19
apps/code-server/docker-compose.yml
Normal file
|
@ -0,0 +1,19 @@
|
|||
version: "3.7"
|
||||
services:
|
||||
code-server:
|
||||
image: lscr.io/linuxserver/code-server:4.5.1
|
||||
container_name: code-server
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=${TZ}
|
||||
- PASSWORD=${CODESERVER_PASSWORD}
|
||||
- DEFAULT_WORKSPACE=/config/workspace #optional
|
||||
volumes:
|
||||
- ${APP_DATA_DIR}/data/config:/config #config dir
|
||||
- ${APP_DATA_DIR}/data/projects:/projects
|
||||
ports:
|
||||
- ${APP_PORT}:8443
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- tipi_main_network
|
7
apps/code-server/metadata/description.md
Normal file
7
apps/code-server/metadata/description.md
Normal 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
|
||||
|
||||

|
6
apps/docker-compose.common.yml
Normal file
6
apps/docker-compose.common.yml
Normal file
|
@ -0,0 +1,6 @@
|
|||
version: "3.7"
|
||||
|
||||
networks:
|
||||
tipi_main_network:
|
||||
external:
|
||||
name: runtipi_tipi_main_network
|
14
apps/filebrowser/config.json
Normal file
14
apps/filebrowser/config.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"name": "File Browser",
|
||||
"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": "filebrowser.org",
|
||||
"website": "https://filebrowser.org/",
|
||||
"source": "https://github.com/filebrowser/filebrowser",
|
||||
"image": "/logos/apps/filebrowser.jpg",
|
||||
"form_fields": []
|
||||
}
|
8
apps/filebrowser/data/config/settings.json
Normal file
8
apps/filebrowser/data/config/settings.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"port": 80,
|
||||
"baseURL": "",
|
||||
"address": "",
|
||||
"log": "stdout",
|
||||
"database": "/database/filebrowser.db",
|
||||
"root": "/srv"
|
||||
}
|
17
apps/filebrowser/docker-compose.yml
Normal file
17
apps/filebrowser/docker-compose.yml
Normal file
|
@ -0,0 +1,17 @@
|
|||
version: "3.7"
|
||||
services:
|
||||
filebrowser:
|
||||
container_name: filebrowser
|
||||
image: filebrowser/filebrowser:s6
|
||||
ports:
|
||||
- ${APP_PORT}:80
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
volumes:
|
||||
- ${ROOT_FOLDER_HOST}/app-data:/srv/app-data
|
||||
- ${ROOT_FOLDER_HOST}/media:/srv/media
|
||||
- ${APP_DATA_DIR}/data/db:/database
|
||||
- ${APP_DATA_DIR}/data/config:/config
|
||||
networks:
|
||||
- tipi_main_network
|
12
apps/filebrowser/metadata/description.md
Normal file
12
apps/filebrowser/metadata/description.md
Normal 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)
|
||||
|
||||

|
12
apps/filerun/config.json
Normal file
12
apps/filerun/config.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "FileRun",
|
||||
"port": 8087,
|
||||
"available": false,
|
||||
"id": "filerun",
|
||||
"description": "Reliable and Performant File Management Desktop Sync and File Sharing",
|
||||
"short_desc": "Access your homeserver files from your browser",
|
||||
"author": "FileRun, LDA - Portugal",
|
||||
"source": "https://www.filerun.com/",
|
||||
"image": "https://avatars.githubusercontent.com/u/6422152?v=4",
|
||||
"form_fields": []
|
||||
}
|
38
apps/filerun/docker-compose.yml
Normal file
38
apps/filerun/docker-compose.yml
Normal file
|
@ -0,0 +1,38 @@
|
|||
services:
|
||||
filerun-db:
|
||||
container_name: filerun-db
|
||||
user: 1000:1000
|
||||
image: mariadb:10.1
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: tipi
|
||||
MYSQL_USER: tipi
|
||||
MYSQL_PASSWORD: tipi
|
||||
MYSQL_DATABASE: tipi
|
||||
volumes:
|
||||
- ${APP_DATA_DIR}/data/db:/var/lib/mysql
|
||||
networks:
|
||||
- tipi_main_network
|
||||
|
||||
filerun:
|
||||
container_name: filerun
|
||||
image: filerun/filerun:arm64v8
|
||||
environment:
|
||||
FR_DB_HOST: filerun-db
|
||||
FR_DB_PORT: 3306
|
||||
FR_DB_NAME: tipi
|
||||
FR_DB_USER: tipi
|
||||
FR_DB_PASS: tipi
|
||||
APACHE_RUN_USER: 1000
|
||||
APACHE_RUN_GROUP: 1000
|
||||
APACHE_RUN_USER_ID: 33
|
||||
APACHE_RUN_GROUP_ID: 33
|
||||
depends_on:
|
||||
- db
|
||||
links:
|
||||
- db:db
|
||||
ports:
|
||||
- ${APP_PORT}:80
|
||||
volumes:
|
||||
- ${ROOT_FOLDER_HOST}/app-data/medias:/user-files
|
||||
networks:
|
||||
- tipi_main_network
|
35
apps/firefly-iii/config.json
Normal file
35
apps/firefly-iii/config.json
Normal file
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"name": "Firefly III",
|
||||
"available": true,
|
||||
"port": 8115,
|
||||
"id": "firefly-iii",
|
||||
"categories": ["finance"],
|
||||
"description": "",
|
||||
"short_desc": "Firefly III: a personal finances manager ",
|
||||
"author": "JC5",
|
||||
"website": "https://www.firefly-iii.org/",
|
||||
"source": "https://github.com/firefly-iii/firefly-iii",
|
||||
"image": "/logos/apps/firefly-iii.jpg",
|
||||
"form_fields": [
|
||||
{
|
||||
"type": "email",
|
||||
"label": "Your email",
|
||||
"required": true,
|
||||
"env_variable": "EMAIL"
|
||||
},
|
||||
{
|
||||
"type": "random",
|
||||
"min": 32,
|
||||
"max": 32,
|
||||
"label": "Random key",
|
||||
"env_variable": "APP_KEY"
|
||||
},
|
||||
{
|
||||
"type": "random",
|
||||
"min": 32,
|
||||
"max": 32,
|
||||
"label": "Database password",
|
||||
"env_variable": "MYSQL_PASSWORD"
|
||||
}
|
||||
]
|
||||
}
|
59
apps/firefly-iii/docker-compose.yml
Normal file
59
apps/firefly-iii/docker-compose.yml
Normal file
|
@ -0,0 +1,59 @@
|
|||
version: '3.9'
|
||||
|
||||
services:
|
||||
firefly-iii:
|
||||
image: fireflyiii/core:latest
|
||||
container_name: firefly-iii
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ${APP_DATA_DIR}/data/uplodad:/var/www/html/storage/upload
|
||||
ports:
|
||||
- ${APP_PORT}:8080
|
||||
depends_on:
|
||||
- firefly-iii-db
|
||||
environment:
|
||||
- APP_ENV=local
|
||||
- APP_DEBUG=false
|
||||
- SITE_OWNER=${EMAIL}
|
||||
- APP_KEY=${APP_KEY}
|
||||
- TZ=${TZ}
|
||||
- TRUSTED_PROXIES=**
|
||||
|
||||
# Database
|
||||
- DB_CONNECTION=mysql
|
||||
- DB_HOST=firefly-iii-db
|
||||
- DB_PORT=3306
|
||||
- DB_DATABASE=firefly
|
||||
- DB_USERNAME=firefly
|
||||
- DB_PASSWORD=${MYSQL_PASSWORD}
|
||||
|
||||
# Cookie settings
|
||||
- COOKIE_PATH="/"
|
||||
- COOKIE_DOMAIN=
|
||||
- COOKIE_SECURE=false
|
||||
- COOKIE_SAMESITE=lax
|
||||
|
||||
- APP_NAME=FireflyIII
|
||||
- BROADCAST_DRIVER=log
|
||||
- QUEUE_DRIVER=sync
|
||||
- CACHE_PREFIX=firefly
|
||||
- IS_HEROKU=false
|
||||
- FIREFLY_III_LAYOUT=v1
|
||||
- APP_URL=http://localhost:${APP_PORT}
|
||||
networks:
|
||||
- tipi_main_network
|
||||
|
||||
firefly-iii-db:
|
||||
container_name: firefly-iii-db
|
||||
image: mariadb
|
||||
hostname: fireflyiii-db
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- MYSQL_RANDOM_ROOT_PASSWORD=yes
|
||||
- MYSQL_USER=firefly
|
||||
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
|
||||
- MYSQL_DATABASE=firefly
|
||||
volumes:
|
||||
- ${APP_DATA_DIR}/data/db:/var/lib/mysql
|
||||
networks:
|
||||
- tipi_main_network
|
26
apps/firefly-iii/metadata/description.md
Normal file
26
apps/firefly-iii/metadata/description.md
Normal file
|
@ -0,0 +1,26 @@
|
|||
"Firefly III" is a (self-hosted) manager for your personal finances. It can help you keep track of your expenses and income, so you can spend less and save more. Firefly III supports the use of budgets, categories and tags. Using a bunch of external tools, you can import data. It also has many neat financial reports available.
|
||||
|
||||
Firefly III should give you **insight** into and **control** over your finances. Money should be useful, not scary. You should be able to *see* where it is going, to *feel* your expenses and to... wow, I'm going overboard with this aren't I?
|
||||
|
||||
But you get the idea: this is your money. These are your expenses. Stop them from controlling you. I built this tool because I started to dislike money. Having money, not having money, paying bills with money, you get the idea. But no more. I want to feel "safe", whatever my balance is. And I hope this tool can help you. I know it helps me.
|
||||
|
||||

|
||||
|
||||
### Purpose
|
||||
|
||||
Personal financial management is pretty difficult, and everybody has their own approach to it. Some people make budgets, other people limit their cashflow by throwing away their credit cards, others try to increase their current cashflow. There are tons of ways to save and earn money. Firefly III works on the principle that if you know where your money is going, you can stop it from going there.
|
||||
|
||||
By keeping track of your expenses and your income you can budget accordingly and save money. Stop living from paycheck to paycheck but give yourself the financial wiggle room you need.
|
||||
|
||||
You can read more about the purpose of Firefly III in the [documentation](https://docs.firefly-iii.org/).
|
||||
|
||||

|
||||
|
||||
## Need help?
|
||||
|
||||
If you need support using Firefly III or the associated tools, come find us!
|
||||
|
||||
- [GitHub Discussions for questions and support](https://github.com/firefly-iii/firefly-iii/discussions/)
|
||||
- [Gitter.im for a good chat and a quick answer](https://gitter.im/firefly-iii/firefly-iii)
|
||||
- [GitHub Issues for bugs and issues](https://github.com/firefly-iii/firefly-iii/issues)
|
||||
- [Follow me around for news and updates on Twitter](https://twitter.com/Firefly_iii)
|
13
apps/freshrss/config.json
Normal file
13
apps/freshrss/config.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "FreshRSS",
|
||||
"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": "/logos/apps/freshrss.jpg",
|
||||
"form_fields": []
|
||||
}
|
25
apps/freshrss/docker-compose.yml
Normal file
25
apps/freshrss/docker-compose.yml
Normal file
|
@ -0,0 +1,25 @@
|
|||
version: "3.7"
|
||||
|
||||
services:
|
||||
freshrss:
|
||||
image: lscr.io/linuxserver/freshrss:1.19.2
|
||||
container_name: freshrss
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=${TZ}
|
||||
volumes:
|
||||
- ${APP_DATA_DIR}/data/freshrss:/config
|
||||
ports:
|
||||
- ${APP_PORT}:80
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- tipi_main_network
|
||||
|
||||
# labels:
|
||||
# traefik.enable: true
|
||||
# traefik.http.routers.freshrss.rule: Host(`freshrss.tipi.home`)
|
||||
# traefik.http.routers.freshrss.service: freshrss
|
||||
# traefik.http.routers.freshrss.tls: true
|
||||
# traefik.http.routers.freshrss.entrypoints: websecure
|
||||
# traefik.http.services.freshrss.loadbalancer.server.port: 80
|
27
apps/freshrss/metadata/description.md
Normal file
27
apps/freshrss/metadata/description.md
Normal 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)
|
||||
|
||||

|
||||
|
13
apps/gitea/config.json
Normal file
13
apps/gitea/config.json
Normal 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": []
|
||||
}
|
88
apps/gitea/data/gitea/gitea/conf/app.ini
Normal file
88
apps/gitea/data/gitea/gitea/conf/app.ini
Normal 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
|
||||
|
37
apps/gitea/docker-compose.yml
Normal file
37
apps/gitea/docker-compose.yml
Normal 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
|
5
apps/gitea/metadata/description.md
Normal file
5
apps/gitea/metadata/description.md
Normal 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.
|
||||
|
||||

|
14
apps/homarr/config.json
Normal file
14
apps/homarr/config.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"name": "Homarr",
|
||||
"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": "ajnart",
|
||||
"source": "https://github.com/ajnart/homarr",
|
||||
"website": "https://discord.gg/C2WTXkzkwK",
|
||||
"image": "/logos/apps/homarr.jpg",
|
||||
"form_fields": []
|
||||
}
|
12
apps/homarr/docker-compose.yml
Normal file
12
apps/homarr/docker-compose.yml
Normal file
|
@ -0,0 +1,12 @@
|
|||
version: "3.7"
|
||||
services:
|
||||
homarr:
|
||||
container_name: homarr
|
||||
image: ghcr.io/ajnart/homarr:0.8.0
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ${APP_DATA_DIR}/data/config:/app/data/configs
|
||||
ports:
|
||||
- ${APP_PORT}:7575
|
||||
networks:
|
||||
- tipi_main_network
|
10
apps/homarr/metadata/description.md
Normal file
10
apps/homarr/metadata/description.md
Normal 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)
|
||||
|
||||

|
13
apps/homeassistant/config.json
Normal file
13
apps/homeassistant/config.json
Normal 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": []
|
||||
}
|
13
apps/homeassistant/docker-compose.yml
Normal file
13
apps/homeassistant/docker-compose.yml
Normal 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
|
7
apps/homeassistant/metadata/description.md
Normal file
7
apps/homeassistant/metadata/description.md
Normal 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/)
|
||||
|
||||

|
13
apps/invidious/config.json
Normal file
13
apps/invidious/config.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "Invidious",
|
||||
"available": true,
|
||||
"port": 8095,
|
||||
"id": "invidious",
|
||||
"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": []
|
||||
}
|
12
apps/invidious/data/init/init-invidious-db.sh
Normal file
12
apps/invidious/data/init/init-invidious-db.sh
Normal 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
|
12
apps/invidious/data/init/sql/annotations.sql
Normal file
12
apps/invidious/data/init/sql/annotations.sql
Normal 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;
|
30
apps/invidious/data/init/sql/channel_videos.sql
Normal file
30
apps/invidious/data/init/sql/channel_videos.sql
Normal 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");
|
||||
|
25
apps/invidious/data/init/sql/channels.sql
Normal file
25
apps/invidious/data/init/sql/channels.sql
Normal 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");
|
||||
|
22
apps/invidious/data/init/sql/nonces.sql
Normal file
22
apps/invidious/data/init/sql/nonces.sql
Normal 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");
|
||||
|
19
apps/invidious/data/init/sql/playlist_videos.sql
Normal file
19
apps/invidious/data/init/sql/playlist_videos.sql
Normal 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;
|
29
apps/invidious/data/init/sql/playlists.sql
Normal file
29
apps/invidious/data/init/sql/playlists.sql
Normal 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;
|
23
apps/invidious/data/init/sql/session_ids.sql
Normal file
23
apps/invidious/data/init/sql/session_ids.sql
Normal 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");
|
||||
|
29
apps/invidious/data/init/sql/users.sql
Normal file
29
apps/invidious/data/init/sql/users.sql
Normal 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");
|
||||
|
23
apps/invidious/data/init/sql/videos.sql
Normal file
23
apps/invidious/data/init/sql/videos.sql
Normal 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");
|
||||
|
0
apps/invidious/data/postgres/.gitkeep
Normal file
0
apps/invidious/data/postgres/.gitkeep
Normal file
0
apps/invidious/data/sql/.gitkeep
Normal file
0
apps/invidious/data/sql/.gitkeep
Normal file
47
apps/invidious/docker-compose.arm.yml
Normal file
47
apps/invidious/docker-compose.arm.yml
Normal file
|
@ -0,0 +1,47 @@
|
|||
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:
|
||||
INVIDIOUS_CONFIG: |
|
||||
db:
|
||||
dbname: invidious
|
||||
user: tipi
|
||||
password: tipi
|
||||
host: invidious-db
|
||||
port: 5432
|
||||
check_tables: true
|
||||
healthcheck:
|
||||
test: wget -nv --tries=1 --spider http://127.0.0.1:3000/api/v1/comments/jNQXAC9IVRw || exit 1
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 2
|
||||
depends_on:
|
||||
- invidious-db
|
||||
networks:
|
||||
- tipi_main_network
|
||||
|
||||
invidious-db:
|
||||
user: 1000:1000
|
||||
container_name: invidious-db
|
||||
image: docker.io/library/postgres:14
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ${APP_DATA_DIR}/data/postgres:/var/lib/postgresql/data
|
||||
- ${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
|
48
apps/invidious/docker-compose.yml
Normal file
48
apps/invidious/docker-compose.yml
Normal file
|
@ -0,0 +1,48 @@
|
|||
version: "3.7"
|
||||
services:
|
||||
invidious:
|
||||
user: 1000:1000
|
||||
container_name: invidious
|
||||
image: quay.io/invidious/invidious:latest
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${APP_PORT}:3000"
|
||||
environment:
|
||||
# Please read the following file for a comprehensive list of all available
|
||||
# configuration options and their associated syntax:
|
||||
# https://github.com/iv-org/invidious/blob/master/config/config.example.yml
|
||||
INVIDIOUS_CONFIG: |
|
||||
db:
|
||||
dbname: invidious
|
||||
user: tipi
|
||||
password: tipi
|
||||
host: invidious-db
|
||||
port: 5432
|
||||
check_tables: true
|
||||
healthcheck:
|
||||
test: wget -nv --tries=1 --spider http://127.0.0.1:3000/api/v1/comments/jNQXAC9IVRw || exit 1
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 2
|
||||
depends_on:
|
||||
- invidious-db
|
||||
networks:
|
||||
- tipi_main_network
|
||||
|
||||
invidious-db:
|
||||
user: 1000:1000
|
||||
container_name: invidious-db
|
||||
image: docker.io/library/postgres:14
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ${APP_DATA_DIR}/data/postgres:/var/lib/postgresql/data
|
||||
- ${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
|
27
apps/invidious/metadata/description.md
Normal file
27
apps/invidious/metadata/description.md
Normal 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)
|
13
apps/jackett/config.json
Normal file
13
apps/jackett/config.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "Jackett",
|
||||
"available": true,
|
||||
"port": 8097,
|
||||
"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": "/logos/apps/jackett.jpg",
|
||||
"form_fields": []
|
||||
}
|
20
apps/jackett/docker-compose.yml
Normal file
20
apps/jackett/docker-compose.yml
Normal file
|
@ -0,0 +1,20 @@
|
|||
version: "3.7"
|
||||
services:
|
||||
jackett:
|
||||
image: lscr.io/linuxserver/jackett:0.20.1342
|
||||
container_name: jackett
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=${TZ}
|
||||
- AUTO_UPDATE=true
|
||||
dns:
|
||||
- ${DNS_IP}
|
||||
volumes:
|
||||
- ${APP_DATA_DIR}/data:/config
|
||||
- ${ROOT_FOLDER_HOST}/media/torrents:/media/torrents
|
||||
ports:
|
||||
- ${APP_PORT}:9117
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- tipi_main_network
|
5
apps/jackett/metadata/description.md
Normal file
5
apps/jackett/metadata/description.md
Normal 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.
|
||||
|
||||

|
13
apps/jellyfin/config.json
Normal file
13
apps/jellyfin/config.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "Jellyfin",
|
||||
"available": true,
|
||||
"port": 8091,
|
||||
"id": "jellyfin",
|
||||
"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": []
|
||||
}
|
0
apps/jellyfin/data/config/.gitkeep
Normal file
0
apps/jellyfin/data/config/.gitkeep
Normal file
18
apps/jellyfin/docker-compose.yml
Normal file
18
apps/jellyfin/docker-compose.yml
Normal file
|
@ -0,0 +1,18 @@
|
|||
version: "3.7"
|
||||
|
||||
services:
|
||||
jellyfin:
|
||||
image: lscr.io/linuxserver/jellyfin:10.8.1
|
||||
container_name: jellyfin
|
||||
volumes:
|
||||
- ${APP_DATA_DIR}/data/config:/config
|
||||
- ${ROOT_FOLDER_HOST}/media/data:/media/data
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=${TZ}
|
||||
restart: "unless-stopped"
|
||||
ports:
|
||||
- ${APP_PORT}:8096
|
||||
networks:
|
||||
- tipi_main_network
|
5
apps/jellyfin/metadata/description.md
Normal file
5
apps/jellyfin/metadata/description.md
Normal 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).
|
13
apps/joplin/README.md
Normal file
13
apps/joplin/README.md
Normal file
|
@ -0,0 +1,13 @@
|
|||
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.
|
||||
|
||||
## Credentials
|
||||
|
||||
Username: admin@localhost
|
||||
Password: admin
|
14
apps/joplin/config.json
Normal file
14
apps/joplin/config.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"name": "Joplin Server",
|
||||
"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": "/logos/apps/joplin.jpg",
|
||||
"form_fields": []
|
||||
}
|
38
apps/joplin/docker-compose.yml
Normal file
38
apps/joplin/docker-compose.yml
Normal file
|
@ -0,0 +1,38 @@
|
|||
version: "3.7"
|
||||
|
||||
services:
|
||||
db-joplin:
|
||||
container_name: db-joplin
|
||||
image: postgres:14.2
|
||||
volumes:
|
||||
- ${APP_DATA_DIR}/data/postgres:/var/lib/postgresql/data
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- POSTGRES_PASSWORD=tipi
|
||||
- POSTGRES_USER=tipi
|
||||
- POSTGRES_DB=joplin
|
||||
networks:
|
||||
- tipi_main_network
|
||||
|
||||
joplin:
|
||||
container_name: joplin
|
||||
image: florider89/joplin-server:2.7.4
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- db-joplin
|
||||
ports:
|
||||
- ${APP_PORT}:22300
|
||||
dns:
|
||||
- ${DNS_IP}
|
||||
environment:
|
||||
- APP_PORT=22300
|
||||
- APP_BASE_URL=http://${INTERNAL_IP}:${APP_PORT}
|
||||
- DB_CLIENT=pg
|
||||
- POSTGRES_PASSWORD=tipi
|
||||
- POSTGRES_USER=tipi
|
||||
- POSTGRES_DATABASE=joplin
|
||||
- POSTGRES_PORT=5432
|
||||
- POSTGRES_HOST=db-joplin
|
||||
- MAX_TIME_DRIFT=0
|
||||
networks:
|
||||
- tipi_main_network
|
17
apps/joplin/metadata/description.md
Normal file
17
apps/joplin/metadata/description.md
Normal 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.
|
||||
|
||||

|
13
apps/libreddit/config.json
Normal file
13
apps/libreddit/config.json
Normal 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": []
|
||||
}
|
12
apps/libreddit/docker-compose.arm.yml
Normal file
12
apps/libreddit/docker-compose.arm.yml
Normal 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
|
12
apps/libreddit/docker-compose.yml
Normal file
12
apps/libreddit/docker-compose.yml
Normal 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
|
12
apps/libreddit/metadata/description.md
Normal file
12
apps/libreddit/metadata/description.md
Normal 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 />
|
||||
|
||||

|
13
apps/mealie/config.json
Normal file
13
apps/mealie/config.json
Normal 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": []
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue