Compare commits
No commits in common. "develop" and "release/0.1.4" have entirely different histories.
develop
...
release/0.
640 changed files with 11207 additions and 37397 deletions
|
@ -1,413 +0,0 @@
|
|||
{
|
||||
"files": [
|
||||
"README.md"
|
||||
],
|
||||
"imageSize": 100,
|
||||
"commit": false,
|
||||
"contributors": [
|
||||
{
|
||||
"login": "meienberger",
|
||||
"name": "Nicolas Meienberger",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/47644445?v=4",
|
||||
"profile": "https://meienberger.dev/",
|
||||
"contributions": [
|
||||
"code",
|
||||
"infra",
|
||||
"test",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "ArneNaessens",
|
||||
"name": "ArneNaessens",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/16622722?v=4",
|
||||
"profile": "https://github.com/ArneNaessens",
|
||||
"contributions": [
|
||||
"code",
|
||||
"ideas",
|
||||
"test"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "DrMxrcy",
|
||||
"name": "DrMxrcy",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/58747968?v=4",
|
||||
"profile": "https://github.com/DrMxrcy",
|
||||
"contributions": [
|
||||
"code",
|
||||
"ideas",
|
||||
"test",
|
||||
"content",
|
||||
"promotion",
|
||||
"question",
|
||||
"review"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "CobreDev",
|
||||
"name": "Cooper",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/36574329?v=4",
|
||||
"profile": "https://cobre.dev",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "JTruj1ll0923",
|
||||
"name": "JTruj1ll0923",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/6656643?v=4",
|
||||
"profile": "https://github.com/JTruj1ll0923",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Stetsed",
|
||||
"name": "Stetsed",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/33891782?v=4",
|
||||
"profile": "https://github.com/Stetsed",
|
||||
"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",
|
||||
"repoType": "github",
|
||||
"repoHost": "https://github.com",
|
||||
"skipCi": true,
|
||||
"commitConvention": "angular",
|
||||
"commitType": "docs"
|
||||
}
|
|
@ -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
|
|
@ -1,26 +0,0 @@
|
|||
**/node_modules
|
||||
**/.next
|
||||
/node_modules
|
||||
/.next
|
||||
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__/
|
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
|
|
@ -1,5 +0,0 @@
|
|||
*.config.js
|
||||
.eslintrc.js
|
||||
next.config.js
|
||||
jest.config.js
|
||||
packages/
|
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 }}
|
124
.github/workflows/ci.yml
vendored
124
.github/workflows/ci.yml
vendored
|
@ -1,61 +1,35 @@
|
|||
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
|
||||
env:
|
||||
POSTGRES_PASSWORD: postgres
|
||||
ports:
|
||||
- 5433:5432
|
||||
# set health checks to wait until postgres has started
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--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 +42,8 @@ jobs:
|
|||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- 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
|
||||
|
||||
- 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
|
||||
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
|
||||
run: pnpm -r lint
|
||||
|
||||
- name: Run tests
|
||||
run: pnpm -r test
|
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
|
98
.github/workflows/release-candidate.yml
vendored
Normal file
98
.github/workflows/release-candidate.yml
vendored
Normal file
|
@ -0,0 +1,98 @@
|
|||
name: Release candidate
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
# Build images and publish RCs to DockerHub
|
||||
build-images:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- uses: technote-space/get-diff-action@v6
|
||||
with:
|
||||
FILES: |
|
||||
VERSION
|
||||
|
||||
- name: Ensure env.MATCHED_FILES has VERSION in it
|
||||
id: check-version
|
||||
run: |
|
||||
if [[ -z "${{ env.MATCHED_FILES }}" ]]; then
|
||||
echo "::error::VERSION not modified"
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! "${{ env.MATCHED_FILES }}" =~ VERSION ]]; then
|
||||
echo "::error::VERSION not modified"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- uses: vishnudxb/cancel-workflow@v1.2
|
||||
if: failure()
|
||||
with:
|
||||
repo: meienberger/runtipi
|
||||
workflow_id: ${{ github.run_id }}
|
||||
access_token: ${{ github.token }}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Get tag from VERSION file
|
||||
id: meta
|
||||
run: |
|
||||
VERSION=$(cat VERSION)
|
||||
TAG=${VERSION}
|
||||
echo "::set-output name=tag::${TAG}"
|
||||
|
||||
- name: Build and push dashboard
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: ./packages/dashboard
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: meienberger/tipi-dashboard:rc-${{ steps.meta.outputs.TAG }}
|
||||
cache-from: type=registry,ref=meienberger/tipi-dashboard:latest
|
||||
cache-to: type=inline
|
||||
|
||||
- name: Build and push api
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: ./packages/system-api
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: meienberger/tipi-api:rc-${{ steps.meta.outputs.TAG }}
|
||||
cache-from: type=registry,ref=meienberger/tipi-api:latest
|
||||
cache-to: type=inline
|
||||
|
||||
# Test installation script
|
||||
# test-install:
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# - uses: actions/checkout@master
|
||||
|
||||
# - name: Check if user id 1000 exists
|
||||
# run: |
|
||||
# if [[ ! $(id -u 1000) -eq 1000 ]]; then
|
||||
# echo "Creating user 1000"
|
||||
# sudo useradd -u 1000 test
|
||||
# fi
|
||||
# id: check-user-id
|
||||
|
||||
# - name: Run install script
|
||||
# run: sudo ./scripts/start.sh --rc --ci
|
||||
|
||||
|
238
.github/workflows/release.yml
vendored
238
.github/workflows/release.yml
vendored
|
@ -1,192 +1,78 @@
|
|||
|
||||
name: Publish release
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
create-tag:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build-images, build-cli]
|
||||
outputs:
|
||||
tagname: ${{ steps.get_tag.outputs.tagname }}
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
- uses: actions/checkout@master
|
||||
|
||||
- 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
|
||||
- name: Create Tag
|
||||
id: create_tag
|
||||
uses: jaywcjlove/create-tag-action@v1.1.5
|
||||
with:
|
||||
tag: ${{ steps.get_tag.outputs.tagname }}
|
||||
|
||||
build-images:
|
||||
if: github.repository == 'runtipi/runtipi'
|
||||
needs: create-tag
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
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 }},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
|
||||
|
||||
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 }},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
|
||||
prerelease: false
|
||||
|
||||
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]
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Promote release
|
||||
uses: actions/github-script@v7
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
-
|
||||
name: Login to DockerHub
|
||||
uses: docker/login-action@v1
|
||||
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
|
||||
});
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
-
|
||||
name: Get tag from VERSION file
|
||||
id: meta
|
||||
run: |
|
||||
VERSION=$(cat VERSION)
|
||||
TAG=${VERSION}
|
||||
echo "::set-output name=tag::${TAG}"
|
||||
-
|
||||
name: Build and push dashboard
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: ./packages/dashboard
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: meienberger/tipi-dashboard:latest,meienberger/tipi-dashboard:${{ steps.meta.outputs.TAG }}
|
||||
cache-from: type=registry,ref=meienberger/tipi-dashboard:latest
|
||||
cache-to: type=inline
|
||||
-
|
||||
name: Build and push api
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: ./packages/system-api
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: meienberger/tipi-api:latest,meienberger/tipi-api:${{ steps.meta.outputs.TAG }}
|
||||
cache-from: type=registry,ref=meienberger/tipi-api:latest
|
||||
cache-to: type=inline
|
83
.gitignore
vendored
83
.gitignore
vendored
|
@ -1,69 +1,28 @@
|
|||
*.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*
|
||||
!.env.example
|
||||
!.env.test
|
||||
github.secrets
|
||||
node_modules/
|
||||
/app-data/
|
||||
/data/
|
||||
/repos/
|
||||
/apps/
|
||||
/traefik/
|
||||
nginx/*
|
||||
letsencrypt/*
|
||||
app-data/*
|
||||
traefik/ssl/*
|
||||
!traefik/ssl/.gitkeep
|
||||
!app-data/.gitkeep
|
||||
!letsencrypt/mkcert/.gitkeep
|
||||
|
||||
# media folder
|
||||
media
|
||||
state/*
|
||||
!state/.gitkeep
|
||||
|
||||
/state/
|
||||
/test-results/
|
||||
/playwright-report/
|
||||
/playwright/.cache/
|
||||
temp
|
||||
tipi.config.json
|
||||
|
||||
./traefik/
|
||||
/user-config/
|
||||
# Commit empty directories
|
||||
!nignx/.gitkeep
|
||||
|
||||
media/data/movies/*
|
||||
media/data/tv/*
|
||||
!media/data/movies/.gitkeep
|
||||
!media/data/tv/.gitkeep
|
||||
|
||||
media/torrents/*
|
||||
!media/torrents/.gitkeep
|
5
.husky/pre-commit
Executable file
5
.husky/pre-commit
Executable file
|
@ -0,0 +1,5 @@
|
|||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
pnpm -r test
|
||||
pnpm -r lint
|
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"
|
||||
}
|
||||
}
|
49
Dockerfile
49
Dockerfile
|
@ -1,49 +0,0 @@
|
|||
ARG NODE_VERSION="20.10"
|
||||
ARG ALPINE_VERSION="3.18"
|
||||
|
||||
FROM node:${NODE_VERSION}-alpine${ALPINE_VERSION} AS node_base
|
||||
|
||||
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
|
||||
|
||||
RUN npm run build
|
||||
|
||||
# APP
|
||||
FROM node_base AS app
|
||||
|
||||
ENV NODE_ENV production
|
||||
|
||||
USER node
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
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
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
CMD ["npm", "run", "start"]
|
|
@ -1,23 +0,0 @@
|
|||
ARG NODE_VERSION="20.10"
|
||||
ARG ALPINE_VERSION="3.18"
|
||||
|
||||
FROM node:${NODE_VERSION}-alpine${ALPINE_VERSION}
|
||||
|
||||
RUN npm install pnpm -g
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY ./pnpm-lock.yaml ./
|
||||
COPY ./patches ./patches
|
||||
RUN pnpm fetch --ignore-scripts
|
||||
|
||||
COPY ./package*.json ./
|
||||
COPY ./packages/shared ./packages/shared
|
||||
|
||||
RUN pnpm install -r --prefer-offline
|
||||
|
||||
COPY ./tsconfig.json ./tsconfig.json
|
||||
COPY ./next.config.mjs ./next.config.mjs
|
||||
COPY ./public ./public
|
||||
|
||||
CMD ["npm", "run", "dev"]
|
167
README.md
167
README.md
|
@ -1,137 +1,78 @@
|
|||
# Tipi — A personal homeserver for everyone
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
||||
[](#contributors-)
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
||||
|
||||
[](https://github.com/runtipi/runtipi/blob/master/LICENSE)
|
||||
[](https://github.com/runtipi/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 — A personal homeserver for everyone
|
||||
[](https://github.com/meienberger/runtipi/blob/master/LICENSE)
|
||||
[](https://github.com/meienberger/runtipi/releases)
|
||||

|
||||
[](https://hub.docker.com/r/meienberger/tipi-dashboard/)
|
||||
[](https://hub.docker.com/r/meienberger/tipi-dashboard/)
|
||||

|
||||

|
||||

|
||||

|
||||
> ⚠️ 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
|
||||
## Apps available
|
||||
- [Filebrowser](https://github.com/filebrowser/filebrowser) - Web File Browser
|
||||
- [Freshrss](https://github.com/FreshRSS/FreshRSS) - A free, self-hostable RSS aggregator
|
||||
- [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
|
||||
- [n8n](https://github.com/n8n-io/n8n) - Workflow Automation Tool
|
||||
- [Nextcloud](https://github.com/nextcloud/server) - A safe home for all your data
|
||||
- [Pihole](https://github.com/pi-hole/pi-hole) - A black hole for Internet advertisements
|
||||
- [Radarr](https://github.com/Radarr/Radarr) - Movie collection manager for Usenet and BitTorrent users.
|
||||
- [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.
|
||||
- [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
|
||||
## 🛠 Installation
|
||||
### Installation Requirements
|
||||
- Ubuntu 18.04 LTS or higher (or Debian 10)
|
||||
|
||||
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.
|
||||
### Step 1. Download Tipi
|
||||
Run this in an empty directory where you want to install Tipi.
|
||||
|
||||
## Demo
|
||||
```bash
|
||||
git clone https://github.com/meienberger/runtipi.git
|
||||
```
|
||||
|
||||
You can try out a demo of Tipi at [demo.runtipi.io](https://demo.runtipi.io) using the following credentials:
|
||||
### Step 2. Run Tipi
|
||||
cd into the downloaded directory and run the start script.
|
||||
|
||||
username: user@runtipi.io
|
||||
password: password
|
||||
```bash
|
||||
cd runtipi && sudo ./scripts/start.sh
|
||||
```
|
||||
|
||||
## 📚 Documentation
|
||||
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
|
||||
|
||||
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/)
|
||||
```bash
|
||||
sudo ./scripts/start.sh --port 7000
|
||||
```
|
||||
|
||||
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)
|
||||
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 support a new app or feature, you can:
|
||||
- Fork the repository and create a new branch for your changes.
|
||||
- Create a pull request.
|
||||
|
||||
## 📜 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)
|
||||
- [Discord](https://discord.gg/Bu9qEPnHsc)
|
||||
|
||||
## Contributors ✨
|
||||
|
||||
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
||||
<!-- prettier-ignore-start -->
|
||||
<!-- markdownlint-disable -->
|
||||
<table>
|
||||
<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>
|
||||
</table>
|
||||
|
||||
<!-- markdownlint-restore -->
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
||||
|
|
1
VERSION
Normal file
1
VERSION
Normal file
|
@ -0,0 +1 @@
|
|||
0.1.4
|
|
@ -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;
|
||||
},
|
||||
};
|
||||
});
|
2
ansible/ansible.cfg
Normal file
2
ansible/ansible.cfg
Normal file
|
@ -0,0 +1,2 @@
|
|||
[defaults]
|
||||
INVENTORY = hosts
|
4
ansible/host_vars/tipi.yml
Normal file
4
ansible/host_vars/tipi.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
packages:
|
||||
- jq
|
||||
- coreutils
|
||||
- docker
|
2
ansible/hosts
Normal file
2
ansible/hosts
Normal file
|
@ -0,0 +1,2 @@
|
|||
[localhost]
|
||||
tipi ansible_connection=local
|
9
ansible/setup.yml
Normal file
9
ansible/setup.yml
Normal file
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
- hosts: tipi
|
||||
become: yes
|
||||
|
||||
tasks:
|
||||
- import_tasks: ./tasks/common/essential.yml
|
||||
- import_tasks: ./tasks/common/docker.yml
|
||||
# - name: Reboot machine
|
||||
# reboot:
|
6
ansible/stop.yml
Normal file
6
ansible/stop.yml
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
- hosts: tipi
|
||||
become: yes
|
||||
|
||||
tasks:
|
||||
- import_tasks: ./tasks/common/teardown.yml
|
67
ansible/tasks/common/docker.yml
Normal file
67
ansible/tasks/common/docker.yml
Normal file
|
@ -0,0 +1,67 @@
|
|||
- name: Install docker
|
||||
package:
|
||||
name:
|
||||
- docker
|
||||
- ca-certificates
|
||||
- curl
|
||||
- gnupg
|
||||
- lsb-release
|
||||
state: latest
|
||||
|
||||
- name: Check lsb_release -cs
|
||||
shell: lsb_release -is
|
||||
register: lsb_release
|
||||
|
||||
- name: Add docker gpg key (Ubuntu)
|
||||
shell: curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
||||
when: lsb_release.stdout == 'Ubuntu'
|
||||
|
||||
- name: Add docker gpg key (Debian)
|
||||
shell: curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
||||
when: lsb_release.stdout == 'Debian'
|
||||
|
||||
- name: Add deb repo for docker (Ubuntu)
|
||||
shell: echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
when: lsb_release.stdout == 'Ubuntu'
|
||||
|
||||
- name: Add deb repo for docker (Debian)
|
||||
shell: echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
when: lsb_release.stdout == 'Debian'
|
||||
|
||||
- name: Update packages
|
||||
apt:
|
||||
update_cache: yes
|
||||
upgrade: yes
|
||||
|
||||
- name: Install essential packages
|
||||
package:
|
||||
name:
|
||||
- docker-ce
|
||||
- docker-ce-cli
|
||||
- containerd.io
|
||||
state: latest
|
||||
|
||||
- name: Check if docker-compose is installed
|
||||
stat:
|
||||
path: /usr/local/bin/docker-compose
|
||||
register: docker_compose_status
|
||||
|
||||
- name: Install docker-compose
|
||||
shell: 'curl -L "https://github.com/docker/compose/releases/download/v2.3.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose'
|
||||
when: not docker_compose_status.stat.exists
|
||||
|
||||
- name: Make docker-compose executable
|
||||
shell: chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
- name: Create group docker
|
||||
group:
|
||||
name: docker
|
||||
|
||||
- name: Put user in docker group
|
||||
shell: usermod -aG docker {{ username }}
|
||||
|
||||
- name: Start docker service
|
||||
service:
|
||||
enabled: yes
|
||||
name: docker
|
||||
state: started
|
33
ansible/tasks/common/essential.yml
Normal file
33
ansible/tasks/common/essential.yml
Normal file
|
@ -0,0 +1,33 @@
|
|||
- name: Update packages
|
||||
apt:
|
||||
update_cache: yes
|
||||
upgrade: yes
|
||||
|
||||
- name: Install essential packages
|
||||
package:
|
||||
name: "{{ packages }}"
|
||||
state: latest
|
||||
|
||||
- name: Upgrade packages
|
||||
apt:
|
||||
upgrade: yes
|
||||
|
||||
- name: Add user to root group
|
||||
user:
|
||||
name: "{{ username }}"
|
||||
group: root
|
||||
|
||||
- name: "Enable passwordless sudo for {{ username }}"
|
||||
lineinfile:
|
||||
dest: /etc/sudoers
|
||||
regexp: "^%wheel"
|
||||
line: "{{ username }} ALL=(ALL) NOPASSWD: ALL"
|
||||
validate: "/usr/sbin/visudo -cf %s"
|
||||
|
||||
- name: Create cron every minute running system-info.sh
|
||||
cron:
|
||||
name: "system-info"
|
||||
user: "{{ username }}"
|
||||
minute: "*/1"
|
||||
job: "{{ playbook_dir }}/../scripts/system-info.sh"
|
||||
ignore_errors: yes
|
18
ansible/tasks/common/teardown.yml
Normal file
18
ansible/tasks/common/teardown.yml
Normal file
|
@ -0,0 +1,18 @@
|
|||
- name: Check if pm2 is installed
|
||||
become_user: "{{ username }}"
|
||||
stat:
|
||||
path: /usr/local/bin/pm2
|
||||
register: pm2_status
|
||||
|
||||
- name: Check if app is already running
|
||||
become_user: "{{ username }}"
|
||||
shell: pm2 list
|
||||
register: pm2_result
|
||||
when: pm2_status.stat.exists
|
||||
|
||||
- name: Stop app
|
||||
become_user: "{{ username }}"
|
||||
shell: pm2 stop "system-api"
|
||||
when:
|
||||
- pm2_status.stat.exists
|
||||
- pm2_result.stdout.find("system-api") != -1
|
44
ansible/tasks/network/avahi.yml
Normal file
44
ansible/tasks/network/avahi.yml
Normal file
|
@ -0,0 +1,44 @@
|
|||
# Network
|
||||
- name: Install avahi
|
||||
package:
|
||||
name: avahi
|
||||
state: latest
|
||||
when: ansible_os_family == "Arch"
|
||||
|
||||
- name: Install avahi
|
||||
package:
|
||||
name: avahi-daemon
|
||||
state: latest
|
||||
when: ansible_os_family == "Debian"
|
||||
|
||||
- name: Disable and stop sytemd-resolved
|
||||
service:
|
||||
name: systemd-resolved
|
||||
state: stopped
|
||||
enabled: no
|
||||
|
||||
- name: Replace line in /etc/nsswitch.conf
|
||||
lineinfile:
|
||||
path: /etc/nsswitch.conf
|
||||
regexp: '^hosts:.*'
|
||||
line: 'hosts: mymachines mdns_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] files myhostname dns'
|
||||
|
||||
- name: Allow port 5353 in UFW
|
||||
community.general.ufw:
|
||||
rule: allow
|
||||
port: 5353
|
||||
proto: udp
|
||||
|
||||
- name: Copy avahi template to /etc/avahi/services/tipi.service
|
||||
copy:
|
||||
src: "{{ playbook_dir }}/templates/avahi/tipi.service"
|
||||
dest: /etc/avahi/services/tipi.service
|
||||
group: avahi
|
||||
owner: avahi
|
||||
|
||||
- name: Start and enable avahi-daemon
|
||||
service:
|
||||
name: avahi-daemon
|
||||
state: restarted
|
||||
enabled: yes
|
||||
###
|
16
ansible/templates/avahi/tipi.service
Normal file
16
ansible/templates/avahi/tipi.service
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
|
||||
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
|
||||
<service-group>
|
||||
<name replace-wildcards="yes">%h</name>
|
||||
<service>
|
||||
<type>_http._tcp</type>
|
||||
<port>80</port>
|
||||
</service>
|
||||
</service-group>
|
||||
<!-- <service-group>
|
||||
<name replace-wildcards="yes">%h</name>
|
||||
<service>
|
||||
<type>_http._tcp</type>
|
||||
<port>443</port>
|
||||
</service>
|
||||
</service-group> -->
|
45
apps/anonaddy/config.json
Normal file
45
apps/anonaddy/config.json
Normal file
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
"name": "Anonaddy",
|
||||
"port": 8084,
|
||||
"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": {
|
||||
"username": {
|
||||
"type": "text",
|
||||
"label": "Username",
|
||||
"required": true,
|
||||
"env_variable": "ANONADDY_USERNAME"
|
||||
},
|
||||
"key": {
|
||||
"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"
|
||||
},
|
||||
"domain": {
|
||||
"type": "fqdn",
|
||||
"label": "Your email domain (eg. example.com)",
|
||||
"max": 50,
|
||||
"min": 3,
|
||||
"required": true,
|
||||
"env_variable": "ANONADDY_DOMAIN"
|
||||
},
|
||||
"secret": {
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
83
apps/anonaddy/docker-compose.yml
Normal file
83
apps/anonaddy/docker-compose.yml
Normal file
|
@ -0,0 +1,83 @@
|
|||
|
||||
version: "3.5"
|
||||
|
||||
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}
|
||||
POSTFIX_DEBUG: true
|
||||
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
|
5
apps/docker-compose.common.yml
Normal file
5
apps/docker-compose.common.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
version: "3.7"
|
||||
|
||||
networks:
|
||||
tipi_main_network:
|
||||
name: runtipi_tipi_main_network
|
13
apps/filebrowser/config.json
Normal file
13
apps/filebrowser/config.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "File Browser",
|
||||
"available": true,
|
||||
"port": 8096,
|
||||
"id": "filebrowser",
|
||||
"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": "",
|
||||
"website": "https://filebrowser.org/",
|
||||
"source": "https://github.com/filebrowser/filebrowser",
|
||||
"image": "https://avatars.githubusercontent.com/u/35781395?s=200&v=4",
|
||||
"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"
|
||||
}
|
16
apps/filebrowser/docker-compose.yml
Normal file
16
apps/filebrowser/docker-compose.yml
Normal file
|
@ -0,0 +1,16 @@
|
|||
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/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
|
12
apps/freshrss/config.json
Normal file
12
apps/freshrss/config.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "FreshRSS",
|
||||
"available": true,
|
||||
"port": 8086,
|
||||
"id": "freshrss",
|
||||
"description": "FreshRSS is a self-hosted RSS feed aggregator like Leed or Kriss Feed.\nIt is lightweight, easy to work with, powerful, and customizable.\n\nIt is a multi-user application with an anonymous reading mode. It supports custom tags. There is an API for (mobile) clients, and a Command-Line Interface.\n\nThanks to the WebSub standard (formerly PubSubHubbub), FreshRSS is able to receive instant push notifications from compatible sources, such as Mastodon, Friendica, WordPress, Blogger, FeedBurner, etc.\n\nFreshRSS natively supports basic Web scraping, based on XPath, for Web sites not providing any RSS / Atom feed.\n\nFinally, it supports extensions for further tuning.",
|
||||
"short_desc": "A free, self-hostable aggregator… ",
|
||||
"author": "https://freshrss.org/",
|
||||
"source": "https://github.com/FreshRSS/FreshRSS",
|
||||
"image": "https://avatars.githubusercontent.com/u/9414285?s=200&v=4",
|
||||
"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
|
12
apps/invidious/config.json
Normal file
12
apps/invidious/config.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "Invidious",
|
||||
"available": true,
|
||||
"port": 8095,
|
||||
"id": "invidious",
|
||||
"description": "",
|
||||
"short_desc": "",
|
||||
"author": "",
|
||||
"source": "https://github.com/iv-org/invidious",
|
||||
"image": "https://raw.githubusercontent.com/iv-org/invidious/master/assets/invidious-colored-vector.svg",
|
||||
"form_fields": {}
|
||||
}
|
41
apps/invidious/docker-compose.arm.yml
Normal file
41
apps/invidious/docker-compose.arm.yml
Normal file
|
@ -0,0 +1,41 @@
|
|||
version: "3"
|
||||
services:
|
||||
invidious:
|
||||
user: 1000:1000
|
||||
container_name: invidious
|
||||
image: quay.io/invidious/invidious:latest-arm64
|
||||
restart: unless-stopped
|
||||
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
|
||||
|
||||
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/sql:/config/sql
|
||||
- ./docker/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"]
|
44
apps/invidious/docker-compose.yml
Normal file
44
apps/invidious/docker-compose.yml
Normal file
|
@ -0,0 +1,44 @@
|
|||
version: "3"
|
||||
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
|
||||
|
||||
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/sql:/config/sql
|
||||
- ./docker/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"]
|
12
apps/jackett/config.json
Normal file
12
apps/jackett/config.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"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 ",
|
||||
"author": "",
|
||||
"source": "https://github.com/Jackett/Jackett",
|
||||
"image": "https://avatars.githubusercontent.com/u/15383019?s=200&v=4",
|
||||
"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
|
||||
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:/downloads
|
||||
ports:
|
||||
- ${APP_PORT}:9117
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- tipi_main_network
|
12
apps/jellyfin/config.json
Normal file
12
apps/jellyfin/config.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "Jellyfin",
|
||||
"available": true,
|
||||
"port": 8091,
|
||||
"id": "jellyfin",
|
||||
"description": "",
|
||||
"short_desc": "",
|
||||
"author": "",
|
||||
"source": "",
|
||||
"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
|
||||
container_name: jellyfin
|
||||
volumes:
|
||||
- ${APP_DATA_DIR}/data/config:/config
|
||||
- ${ROOT_FOLDER_HOST}/media/data:/data/media
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=${TZ}
|
||||
restart: "unless-stopped"
|
||||
ports:
|
||||
- ${APP_PORT}:8096
|
||||
networks:
|
||||
- tipi_main_network
|
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
|
13
apps/joplin/config.json
Normal file
13
apps/joplin/config.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "Joplin Server",
|
||||
"available": true,
|
||||
"port": 8099,
|
||||
"id": "joplin",
|
||||
"description": "Default credentials: admin@localhost / admin",
|
||||
"short_desc": "Note taking and to-do application with synchronisation",
|
||||
"author": "https://github.com/laurent22",
|
||||
"source": "https://github.com/laurent22/joplin",
|
||||
"website": "https://joplinapp.org",
|
||||
"image": "https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/LinuxIcons/256x256.png",
|
||||
"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
|
13
apps/n8n/config.json
Normal file
13
apps/n8n/config.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "n8n",
|
||||
"available": true,
|
||||
"port": 8094,
|
||||
"id": "n8n",
|
||||
"description": "n8n is an extendable workflow automation tool. With a fair-code distribution model, n8n will always have visible source code, be available to self-host, and allow you to add your own custom functions, logic and apps. n8n's node-based approach makes it highly versatile, enabling you to connect anything to everything.",
|
||||
"short_desc": "Workflow Automation Tool. Alternative to Zapier",
|
||||
"author": "n8n.io",
|
||||
"source": "https://github.com/n8n-io/n8n",
|
||||
"website": "https://n8n.io/",
|
||||
"image": "https://avatars.githubusercontent.com/u/45487711?s=200&v=4",
|
||||
"form_fields": {}
|
||||
}
|
36
apps/n8n/docker-compose.yml
Normal file
36
apps/n8n/docker-compose.yml
Normal file
|
@ -0,0 +1,36 @@
|
|||
version: "3.7"
|
||||
|
||||
services:
|
||||
db-n8n:
|
||||
container_name: db-n8n
|
||||
image: postgres:14.2
|
||||
restart: on-failure
|
||||
volumes:
|
||||
- ${APP_DATA_DIR}/data/db:/var/lib/postgresql/data
|
||||
environment:
|
||||
- POSTGRES_PASSWORD=tipi
|
||||
- POSTGRES_USER=tipi
|
||||
- POSTGRES_DB=n8n
|
||||
networks:
|
||||
- tipi_main_network
|
||||
|
||||
n8n:
|
||||
container_name: n8n
|
||||
image: n8nio/n8n:0.174.0
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- ${APP_PORT}:5678
|
||||
volumes:
|
||||
- ${APP_DATA_DIR}/data/n8n:/home/node/.n8n
|
||||
command: /bin/sh -c "sleep 5; n8n start"
|
||||
environment:
|
||||
- DB-TYPE=postgresdb
|
||||
- DB_POSTGRESDB_DATABASE=n8n
|
||||
- DB_POSTGRESDB_HOST=db-n8n
|
||||
- DB_POSTGRESDB_PORT=5432
|
||||
- DB_POSTGRESDB_USER=tipi
|
||||
- DB_POSTGRESDB_PASSWORD=tipi
|
||||
depends_on:
|
||||
- db-n8n
|
||||
networks:
|
||||
- tipi_main_network
|
29
apps/nextcloud/config.json
Normal file
29
apps/nextcloud/config.json
Normal file
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"name": "Nextcloud",
|
||||
"available": true,
|
||||
"port": 8083,
|
||||
"id": "nextcloud",
|
||||
"description": "Nextcloud is a self-hosted, open source, and fully-featured cloud storage solution for your personal files, office documents, and photos.",
|
||||
"short_desc": "Productivity platform that keeps you in control",
|
||||
"author": "Nextcloud GmbH",
|
||||
"source": "https://github.com/nextcloud/server",
|
||||
"image": "https://avatars.githubusercontent.com/u/19211038?s=200&v=4",
|
||||
"form_fields": {
|
||||
"username": {
|
||||
"type": "text",
|
||||
"label": "Username",
|
||||
"max": 50,
|
||||
"min": 3,
|
||||
"required": true,
|
||||
"env_variable": "NEXTCLOUD_ADMIN_USER"
|
||||
},
|
||||
"password": {
|
||||
"type": "password",
|
||||
"label": "Password",
|
||||
"max": 50,
|
||||
"min": 3,
|
||||
"required": true,
|
||||
"env_variable": "NEXTCLOUD_ADMIN_PASSWORD"
|
||||
}
|
||||
}
|
||||
}
|
0
apps/nextcloud/data/nextcloud/.gitkeep
Normal file
0
apps/nextcloud/data/nextcloud/.gitkeep
Normal file
0
apps/nextcloud/data/redis/.gitkeep
Normal file
0
apps/nextcloud/data/redis/.gitkeep
Normal file
67
apps/nextcloud/docker-compose.yml
Normal file
67
apps/nextcloud/docker-compose.yml
Normal file
|
@ -0,0 +1,67 @@
|
|||
version: "3.7"
|
||||
|
||||
services:
|
||||
db-nextcloud:
|
||||
container_name: db-nextcloud
|
||||
image: postgres:14.2
|
||||
restart: on-failure
|
||||
volumes:
|
||||
- ${APP_DATA_DIR}/data/db:/var/lib/postgresql/data
|
||||
environment:
|
||||
- POSTGRES_PASSWORD=tipi
|
||||
- POSTGRES_USER=tipi
|
||||
- POSTGRES_DB=nextcloud
|
||||
networks:
|
||||
- tipi_main_network
|
||||
|
||||
redis-nextcloud:
|
||||
container_name: redis-nextcloud
|
||||
user: "1000:1000"
|
||||
image: redis:6.2.6
|
||||
restart: on-failure
|
||||
volumes:
|
||||
- "${APP_DATA_DIR}/data/redis:/data"
|
||||
networks:
|
||||
- tipi_main_network
|
||||
|
||||
cron:
|
||||
image: nextcloud:23.0.3-apache
|
||||
restart: on-failure
|
||||
volumes:
|
||||
- ${APP_DATA_DIR}/data/nextcloud:/var/www/html
|
||||
entrypoint: /cron.sh
|
||||
depends_on:
|
||||
- db-nextcloud
|
||||
- redis-nextcloud
|
||||
networks:
|
||||
- tipi_main_network
|
||||
|
||||
nextcloud:
|
||||
container_name: nextcloud
|
||||
image: nextcloud:23.0.3-apache
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- ${APP_PORT}:80
|
||||
volumes:
|
||||
- ${APP_DATA_DIR}/data/nextcloud:/var/www/html
|
||||
environment:
|
||||
- POSTGRES_HOST=db-nextcloud
|
||||
- REDIS_HOST=redis-nextcloud
|
||||
- POSTGRES_PASSWORD=tipi
|
||||
- POSTGRES_USER=tipi
|
||||
- POSTGRES_DB=nextcloud
|
||||
- NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER}
|
||||
- NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD}
|
||||
- NEXTCLOUD_TRUSTED_DOMAINS=${INTERNAL_IP}:${APP_PORT}
|
||||
depends_on:
|
||||
- db-nextcloud
|
||||
- redis-nextcloud
|
||||
networks:
|
||||
- tipi_main_network
|
||||
# labels:
|
||||
# traefik.enable: true
|
||||
# traefik.http.routers.nextcloud.rule: Host(`nextcloud.tipi.home`)
|
||||
# traefik.http.routers.nextcloud.service: nextcloud
|
||||
# traefik.http.routers.nextcloud.tls: true
|
||||
# traefik.http.routers.nextcloud.entrypoints: websecure
|
||||
# traefik.http.services.nextcloud.loadbalancer.server.port: 80
|
24
apps/pihole/config.json
Normal file
24
apps/pihole/config.json
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"name": "PiHole",
|
||||
"available": true,
|
||||
"port": 8081,
|
||||
"requirements": {
|
||||
"ports": [53]
|
||||
},
|
||||
"id": "pihole",
|
||||
"description": "",
|
||||
"short_desc": "",
|
||||
"author": "",
|
||||
"source": "",
|
||||
"image": "https://avatars.githubusercontent.com/u/16827203?s=200&v=4",
|
||||
"form_fields": {
|
||||
"password": {
|
||||
"type": "password",
|
||||
"label": "Password",
|
||||
"max": 50,
|
||||
"min": 3,
|
||||
"required": true,
|
||||
"env_variable": "APP_PASSWORD"
|
||||
}
|
||||
}
|
||||
}
|
6
apps/pihole/data/unbound/a-records.conf
Normal file
6
apps/pihole/data/unbound/a-records.conf
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
# A Record
|
||||
#local-data: "somecomputer.local. A 192.168.1.1"
|
||||
|
||||
# PTR Record
|
||||
#local-data-ptr: "192.168.1.1 somecomputer.local."
|
92
apps/pihole/data/unbound/root.hints
Normal file
92
apps/pihole/data/unbound/root.hints
Normal file
|
@ -0,0 +1,92 @@
|
|||
; This file holds the information on root name servers needed to
|
||||
; initialize cache of Internet domain name servers
|
||||
; (e.g. reference this file in the "cache . <file>"
|
||||
; configuration file of BIND domain name servers).
|
||||
;
|
||||
; This file is made available by InterNIC
|
||||
; under anonymous FTP as
|
||||
; file /domain/named.cache
|
||||
; on server FTP.INTERNIC.NET
|
||||
; -OR- RS.INTERNIC.NET
|
||||
;
|
||||
; last update: December 07, 2021
|
||||
; related version of root zone: 2021120701
|
||||
;
|
||||
; FORMERLY NS.INTERNIC.NET
|
||||
;
|
||||
. 3600000 NS A.ROOT-SERVERS.NET.
|
||||
A.ROOT-SERVERS.NET. 3600000 A 198.41.0.4
|
||||
A.ROOT-SERVERS.NET. 3600000 AAAA 2001:503:ba3e::2:30
|
||||
;
|
||||
; FORMERLY NS1.ISI.EDU
|
||||
;
|
||||
. 3600000 NS B.ROOT-SERVERS.NET.
|
||||
B.ROOT-SERVERS.NET. 3600000 A 199.9.14.201
|
||||
B.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:200::b
|
||||
;
|
||||
; FORMERLY C.PSI.NET
|
||||
;
|
||||
. 3600000 NS C.ROOT-SERVERS.NET.
|
||||
C.ROOT-SERVERS.NET. 3600000 A 192.33.4.12
|
||||
C.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2::c
|
||||
;
|
||||
; FORMERLY TERP.UMD.EDU
|
||||
;
|
||||
. 3600000 NS D.ROOT-SERVERS.NET.
|
||||
D.ROOT-SERVERS.NET. 3600000 A 199.7.91.13
|
||||
D.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2d::d
|
||||
;
|
||||
; FORMERLY NS.NASA.GOV
|
||||
;
|
||||
. 3600000 NS E.ROOT-SERVERS.NET.
|
||||
E.ROOT-SERVERS.NET. 3600000 A 192.203.230.10
|
||||
E.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:a8::e
|
||||
;
|
||||
; FORMERLY NS.ISC.ORG
|
||||
;
|
||||
. 3600000 NS F.ROOT-SERVERS.NET.
|
||||
F.ROOT-SERVERS.NET. 3600000 A 192.5.5.241
|
||||
F.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2f::f
|
||||
;
|
||||
; FORMERLY NS.NIC.DDN.MIL
|
||||
;
|
||||
. 3600000 NS G.ROOT-SERVERS.NET.
|
||||
G.ROOT-SERVERS.NET. 3600000 A 192.112.36.4
|
||||
G.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:12::d0d
|
||||
;
|
||||
; FORMERLY AOS.ARL.ARMY.MIL
|
||||
;
|
||||
. 3600000 NS H.ROOT-SERVERS.NET.
|
||||
H.ROOT-SERVERS.NET. 3600000 A 198.97.190.53
|
||||
H.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:1::53
|
||||
;
|
||||
; FORMERLY NIC.NORDU.NET
|
||||
;
|
||||
. 3600000 NS I.ROOT-SERVERS.NET.
|
||||
I.ROOT-SERVERS.NET. 3600000 A 192.36.148.17
|
||||
I.ROOT-SERVERS.NET. 3600000 AAAA 2001:7fe::53
|
||||
;
|
||||
; OPERATED BY VERISIGN, INC.
|
||||
;
|
||||
. 3600000 NS J.ROOT-SERVERS.NET.
|
||||
J.ROOT-SERVERS.NET. 3600000 A 192.58.128.30
|
||||
J.ROOT-SERVERS.NET. 3600000 AAAA 2001:503:c27::2:30
|
||||
;
|
||||
; OPERATED BY RIPE NCC
|
||||
;
|
||||
. 3600000 NS K.ROOT-SERVERS.NET.
|
||||
K.ROOT-SERVERS.NET. 3600000 A 193.0.14.129
|
||||
K.ROOT-SERVERS.NET. 3600000 AAAA 2001:7fd::1
|
||||
;
|
||||
; OPERATED BY ICANN
|
||||
;
|
||||
. 3600000 NS L.ROOT-SERVERS.NET.
|
||||
L.ROOT-SERVERS.NET. 3600000 A 199.7.83.42
|
||||
L.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:9f::42
|
||||
;
|
||||
; OPERATED BY WIDE
|
||||
;
|
||||
. 3600000 NS M.ROOT-SERVERS.NET.
|
||||
M.ROOT-SERVERS.NET. 3600000 A 202.12.27.33
|
||||
M.ROOT-SERVERS.NET. 3600000 AAAA 2001:dc3::35
|
||||
; End of file
|
9
apps/pihole/data/unbound/root.key
Normal file
9
apps/pihole/data/unbound/root.key
Normal file
|
@ -0,0 +1,9 @@
|
|||
; autotrust trust anchor file
|
||||
;;id: . 1
|
||||
;;last_queried: 1650921300 ;;Mon Apr 25 21:15:00 2022
|
||||
;;last_success: 1650921300 ;;Mon Apr 25 21:15:00 2022
|
||||
;;next_probe_time: 1650962281 ;;Tue Apr 26 08:38:01 2022
|
||||
;;query_failed: 0
|
||||
;;query_interval: 43200
|
||||
;;retry_time: 8640
|
||||
. 86400 IN DNSKEY 257 3 8 AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexTBAvkMgJzkKTOiW1vkIbzxeF3+/4RgWOq7HrxRixHlFlExOLAJr5emLvN7SWXgnLh4+B5xQlNVz8Og8kvArMtNROxVQuCaSnIDdD5LKyWbRd2n9WGe2R8PzgCmr3EgVLrjyBxWezF0jLHwVN8efS3rCj/EWgvIWgb9tarpVUDK/b58Da+sqqls3eNbuv7pr+eoZG+SrDK6nWeL3c6H5Apxz7LjVc1uTIdsIXxuOLYA4/ilBmSVIzuDWfdRUfhHdY6+cn8HFRm+2hM8AnXGXws9555KrUB5qihylGa8subX2Nn6UwNR1AkUTV74bU= ;{id = 20326 (ksk), size = 2048b} ;;state=2 [ VALID ] ;;count=0 ;;lastchange=1650921210 ;;Mon Apr 25 21:13:30 2022
|
136
apps/pihole/data/unbound/unbound.conf
Normal file
136
apps/pihole/data/unbound/unbound.conf
Normal file
|
@ -0,0 +1,136 @@
|
|||
# https://linux.die.net/man/5/unbound.conf
|
||||
# https://docs.pi-hole.net/guides/unbound/
|
||||
|
||||
server:
|
||||
# Enable or disable whether the unbound server forks into the background
|
||||
# as a daemon. Default is yes.
|
||||
do-daemonize: no
|
||||
|
||||
# If given, after binding the port the user privileges are dropped.
|
||||
# Default is "unbound". If you give username: "" no user change is performed.
|
||||
username: ""
|
||||
|
||||
# No need to chroot as this container has been stripped of all other binaries.
|
||||
chroot: ""
|
||||
|
||||
# If "" is given, logging goes to stderr, or nowhere once daemonized.
|
||||
logfile: ""
|
||||
|
||||
# The process id is written to the file. Not required since we are running
|
||||
# in a container with one process.
|
||||
pidfile: ""
|
||||
|
||||
# The verbosity number, level 0 means no verbosity, only errors.
|
||||
# Level 1 gives operational information.
|
||||
# Level 2 gives detailed operational information.
|
||||
# Level 3 gives query level information, output per query.
|
||||
# Level 4 gives algorithm level information.
|
||||
# Level 5 logs client identification for cache misses.
|
||||
# Default is level 1. The verbosity can also be increased from the commandline.
|
||||
verbosity: 1
|
||||
|
||||
# Listen on all ipv4 interfaces, answer queries from the local subnet.
|
||||
interface: 0.0.0.0
|
||||
|
||||
# The port number, default 53, on which the server responds to queries.
|
||||
port: 53
|
||||
|
||||
do-ip4: yes
|
||||
do-udp: yes
|
||||
do-tcp: yes
|
||||
do-ip6: no
|
||||
|
||||
# You want to leave this to no unless you have *native* IPv6. With 6to4 and
|
||||
# Terredo tunnels your web browser should favor IPv4 for the same reasons
|
||||
prefer-ip6: no
|
||||
|
||||
# Trust glue only if it is within the server's authority
|
||||
harden-glue: yes
|
||||
|
||||
# Require DNSSEC data for trust-anchored zones, if such data is absent, the zone becomes BOGUS
|
||||
harden-dnssec-stripped: yes
|
||||
|
||||
# Don't use Capitalization randomization as it known to cause DNSSEC issues sometimes
|
||||
# see https://discourse.pi-hole.net/t/unbound-stubby-or-dnscrypt-proxy/9378 for further details
|
||||
use-caps-for-id: no
|
||||
|
||||
# Reduce EDNS reassembly buffer size (see also https://docs.pi-hole.net/guides/dns/unbound/ )
|
||||
# IP fragmentation is unreliable on the Internet today, and can cause
|
||||
# transmission failures when large DNS messages are sent via UDP. Even
|
||||
# when fragmentation does work, it may not be secure; it is theoretically
|
||||
# possible to spoof parts of a fragmented DNS message, without easy
|
||||
# detection at the receiving end. Recently, there was an excellent study
|
||||
# >>> Defragmenting DNS - Determining the optimal maximum UDP response size for DNS <<<
|
||||
# by Axel Koolhaas, and Tjeerd Slokker (https://indico.dns-oarc.net/event/36/contributions/776/)
|
||||
# in collaboration with NLnet Labs explored DNS using real world data from the
|
||||
# the RIPE Atlas probes and the researchers suggested different values for
|
||||
# IPv4 and IPv6 and in different scenarios. They advise that servers should
|
||||
# be configured to limit DNS messages sent over UDP to a size that will not
|
||||
# trigger fragmentation on typical network links. DNS servers can switch
|
||||
# from UDP to TCP when a DNS response is too big to fit in this limited
|
||||
# buffer size. This value has also been suggested in DNS Flag Day 2020.
|
||||
edns-buffer-size: 1232
|
||||
|
||||
# Perform prefetching of close to expired message cache entries
|
||||
# This only applies to domains that have been frequently queried
|
||||
prefetch: yes
|
||||
|
||||
# One thread should be sufficient, can be increased on beefy machines.
|
||||
# In reality for most users running on small networks or on a single machine,
|
||||
# it should be unnecessary to seek performance enhancement by increasing num-threads above 1.
|
||||
num-threads: 1
|
||||
|
||||
# Ensure kernel buffer is large enough to not lose messages in traffic spikes
|
||||
# (requires CAP_NET_ADMIN or privileged)
|
||||
# so-rcvbuf: 1m
|
||||
|
||||
# The netblock is given as an IP4 or IP6 address with /size appended for a
|
||||
# classless network block. The action can be deny, refuse, allow or allow_snoop.
|
||||
access-control: 127.0.0.1/32 allow
|
||||
access-control: 192.168.0.0/16 allow
|
||||
access-control: 172.16.0.0/12 allow
|
||||
access-control: 10.0.0.0/8 allow
|
||||
access-control: 100.64.0.0/10 allow
|
||||
access-control: 10.21.21.0/24 allow
|
||||
|
||||
# Ensure privacy of local IP ranges
|
||||
private-address: 192.168.0.0/16
|
||||
private-address: 169.254.0.0/16
|
||||
private-address: 172.16.0.0/12
|
||||
private-address: 10.0.0.0/8
|
||||
private-address: fd00::/8
|
||||
private-address: fe80::/10
|
||||
|
||||
# Read the root hints from this file. Default is nothing, using built in
|
||||
# hints for the IN class. The file has the format of zone files, with root
|
||||
# nameserver names and addresses only. The default may become outdated,
|
||||
# when servers change, therefore it is good practice to use a root-hints
|
||||
# file. get one from https://www.internic.net/domain/named.root
|
||||
root-hints: /etc/unbound/root.hints
|
||||
|
||||
# File with trust anchor for one zone, which is tracked with RFC5011 probes.
|
||||
# The probes are several times per month, thus the machine must be online frequently.
|
||||
# The initial file can be one with contents as described in trust-anchor-file.
|
||||
# The file is written to when the anchor is updated, so the unbound user must
|
||||
# have write permission.
|
||||
auto-trust-anchor-file: /etc/unbound/root.key
|
||||
|
||||
# Number of ports to open. This number of file descriptors can be opened per thread.
|
||||
# Must be at least 1. Default depends on compile options. Larger numbers need extra
|
||||
# resources from the operating system. For performance a very large value is best,
|
||||
# use libevent to make this possible.
|
||||
outgoing-range: 8192
|
||||
|
||||
# The number of queries that every thread will service simultaneously. If more queries
|
||||
# arrive that need servicing, and no queries can be jostled out (see jostle-timeout),
|
||||
# then the queries are dropped. This forces the client to resend after a timeout;
|
||||
# allowing the server time to work on the existing queries. Default depends on
|
||||
# compile options, 512 or 1024.
|
||||
num-queries-per-thread: 4096
|
||||
|
||||
include: /etc/unbound/a-records.conf
|
||||
|
||||
# forward-zone:
|
||||
# name: "."
|
||||
# forward-addr: 194.242.2.3@853 # Mullvad primary
|
||||
# forward-addr: 193.19.108.3@853 # Mullvad secondary
|
39
apps/pihole/docker-compose.yml
Normal file
39
apps/pihole/docker-compose.yml
Normal file
|
@ -0,0 +1,39 @@
|
|||
version: "3.7"
|
||||
|
||||
services:
|
||||
unbound:
|
||||
image: "klutchell/unbound"
|
||||
container_name: unbound
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- "${APP_DATA_DIR}/data/unbound:/etc/unbound"
|
||||
networks:
|
||||
tipi_main_network:
|
||||
ipv4_address: 10.21.21.200
|
||||
|
||||
pihole:
|
||||
depends_on: [unbound]
|
||||
container_name: pihole
|
||||
image: pihole/pihole:latest
|
||||
restart: unless-stopped
|
||||
hostname: pihole
|
||||
dns:
|
||||
- 127.0.0.1
|
||||
# - 10.21.21.200 # Points to unbound
|
||||
ports:
|
||||
- 53:53/tcp
|
||||
- 53:53/udp
|
||||
- ${APP_PORT}:80
|
||||
volumes:
|
||||
- ${APP_DATA_DIR}/data/pihole:/etc/pihole
|
||||
- ${APP_DATA_DIR}/data/dnsmasq:/etc/dnsmasq.d
|
||||
environment:
|
||||
TZ: ${TZ}
|
||||
WEBPASSWORD: ${APP_PASSWORD}
|
||||
# PIHOLE_DNS_: 10.21.21.200 # Points to unbound
|
||||
FTLCONF_REPLY_ADDR4: 10.21.21.201
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
networks:
|
||||
tipi_main_network:
|
||||
ipv4_address: 10.21.21.201
|
12
apps/radarr/config.json
Normal file
12
apps/radarr/config.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "Radarr",
|
||||
"available": true,
|
||||
"port": 8088,
|
||||
"id": "radarr",
|
||||
"description": "",
|
||||
"short_desc": "",
|
||||
"author": "",
|
||||
"source": "",
|
||||
"image": "https://avatars.githubusercontent.com/u/25025331?s=200&v=4",
|
||||
"form_fields": {}
|
||||
}
|
20
apps/radarr/docker-compose.yml
Normal file
20
apps/radarr/docker-compose.yml
Normal file
|
@ -0,0 +1,20 @@
|
|||
version: "3.7"
|
||||
services:
|
||||
radarr:
|
||||
image: lscr.io/linuxserver/radarr
|
||||
container_name: radarr
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=${TZ}
|
||||
dns:
|
||||
- ${DNS_IP}
|
||||
volumes:
|
||||
- ${APP_DATA_DIR}/data:/config
|
||||
- ${ROOT_FOLDER_HOST}/media/data/movies:/movies #optional
|
||||
- ${ROOT_FOLDER_HOST}/media/torrents:/downloads #optional
|
||||
ports:
|
||||
- ${APP_PORT}:7878
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- tipi_main_network
|
11
apps/simple-torrent/config.json
Normal file
11
apps/simple-torrent/config.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"name": "Simple Torrent",
|
||||
"port": 8085,
|
||||
"id": "simple-torrent",
|
||||
"description": "SimpleTorrent is a a self-hosted remote torrent client, written in Go (golang). Started torrents remotely, download sets of files on the local disk of the server, which are then retrievable or streamable via HTTP.",
|
||||
"short_desc": "A self-hosted remote torrent client",
|
||||
"author": "",
|
||||
"source": "https://github.com/boypt/simple-torrent",
|
||||
"image": "https://getumbrel.github.io/umbrel-apps-gallery/simple-torrent/icon.svg",
|
||||
"form_fields": {}
|
||||
}
|
25
apps/simple-torrent/docker-compose.yml
Normal file
25
apps/simple-torrent/docker-compose.yml
Normal file
|
@ -0,0 +1,25 @@
|
|||
version: "3.7"
|
||||
|
||||
services:
|
||||
server:
|
||||
container_name: simple-torrent
|
||||
image: boypt/cloud-torrent:1.3.9
|
||||
restart: on-failure
|
||||
ports:
|
||||
- ${APP_PORT}:${APP_PORT}
|
||||
command: >
|
||||
--port=${APP_PORT}
|
||||
--config-path /config/simple-torrent.json
|
||||
volumes:
|
||||
- ${APP_DATA_DIR}/data/torrents:/torrents
|
||||
- ${APP_DATA_DIR}/data/downloads:/downloads
|
||||
- ${APP_DATA_DIR}/data/config:/config
|
||||
networks:
|
||||
- tipi_main_network
|
||||
# labels:
|
||||
# traefik.enable: true
|
||||
# traefik.http.routers.simple-torrent.rule: Host(`simple-torrent.tipi.home`)
|
||||
# traefik.http.routers.simple-torrent.service: simple-torrent
|
||||
# traefik.http.routers.simple-torrent.tls: true
|
||||
# traefik.http.routers.simple-torrent.entrypoints: websecure
|
||||
# traefik.http.services.simple-torrent.loadbalancer.server.port: ${APP_SIMPLETORRENT_PORT}
|
12
apps/sonarr/config.json
Normal file
12
apps/sonarr/config.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "Sonarr",
|
||||
"available": true,
|
||||
"port": 8098,
|
||||
"id": "sonarr",
|
||||
"description": "",
|
||||
"short_desc": "",
|
||||
"author": "",
|
||||
"source": "",
|
||||
"image": "https://avatars.githubusercontent.com/u/1082903?s=200&v=4",
|
||||
"form_fields": {}
|
||||
}
|
20
apps/sonarr/docker-compose.yml
Normal file
20
apps/sonarr/docker-compose.yml
Normal file
|
@ -0,0 +1,20 @@
|
|||
version: "3.7"
|
||||
services:
|
||||
radarr:
|
||||
image: lscr.io/linuxserver/sonarr
|
||||
container_name: sonarr
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=${TZ}
|
||||
dns:
|
||||
- ${DNS_IP}
|
||||
volumes:
|
||||
- ${APP_DATA_DIR}/data:/config
|
||||
- ${ROOT_FOLDER_HOST}/media/data/tv:/tv #optional
|
||||
- ${ROOT_FOLDER_HOST}/media/torrents:/downloads #optional
|
||||
ports:
|
||||
- ${APP_PORT}:8989
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- tipi_main_network
|
13
apps/syncthing/config.json
Normal file
13
apps/syncthing/config.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "Syncthing",
|
||||
"available": true,
|
||||
"port": 8090,
|
||||
"id": "syncthing",
|
||||
"description": "Syncthing is a peer-to-peer continuous file synchronization program. It synchronizes files between two or more computers in real time, safely protected from prying eyes. Your data is your data alone and you deserve to choose where it is stored, whether it is shared with some third party, and how it's transmitted over the internet.\n\nInstall the Syncthing app on your Umbrel and pair it with the Syncthing app on your phone or computer for a self hosted peer-to-peer backup solution.",
|
||||
"short_desc": "Peer-to-peer file synchronization between your devices",
|
||||
"author": "The Syncthing Foundation",
|
||||
"source": "https://github.com/syncthing",
|
||||
"website": "https://syncthing.net",
|
||||
"image": "https://avatars.githubusercontent.com/u/7628018?s=200&v=4",
|
||||
"form_fields": {}
|
||||
}
|
0
apps/syncthing/data/.gitkeep
Normal file
0
apps/syncthing/data/.gitkeep
Normal file
21
apps/syncthing/docker-compose.yml
Normal file
21
apps/syncthing/docker-compose.yml
Normal file
|
@ -0,0 +1,21 @@
|
|||
version: "3.7"
|
||||
|
||||
services:
|
||||
syncthing:
|
||||
container_name: syncthing
|
||||
image: syncthing/syncthing:1.19
|
||||
stop_grace_period: 1m
|
||||
hostname: tipi
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
volumes:
|
||||
- ${APP_DATA_DIR}/data:/var/syncthing
|
||||
ports:
|
||||
- ${APP_PORT}:8384
|
||||
- 22000:22000/tcp # TCP file transfers
|
||||
- 22000:22000/udp # QUIC file transfers
|
||||
- 21027:21027/udp # Receive local discovery broadcasts
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- tipi_main_network
|
13
apps/tailscale/config.json
Normal file
13
apps/tailscale/config.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "Tailscale",
|
||||
"available": true,
|
||||
"port": 8093,
|
||||
"id": "tailscale",
|
||||
"description": "",
|
||||
"short_desc": "",
|
||||
"author": "",
|
||||
"source": "https://github.com/tailscale/tailscale",
|
||||
"website": "https://tailscale.com/",
|
||||
"image": "https://avatars.githubusercontent.com/u/48932923?s=200&v=4",
|
||||
"form_fields": {}
|
||||
}
|
14
apps/tailscale/docker-compose.yml
Normal file
14
apps/tailscale/docker-compose.yml
Normal file
|
@ -0,0 +1,14 @@
|
|||
version: "2"
|
||||
|
||||
services:
|
||||
tailscale:
|
||||
container_name: tailscale
|
||||
network_mode: "host" # TODO: Find a way to remove this
|
||||
image: tailscale/tailscale:v1.24.0
|
||||
privileged: true
|
||||
restart: on-failure
|
||||
stop_grace_period: 1m
|
||||
command: "sh -c 'tailscale web --listen 0.0.0.0:${APP_PORT} & exec tailscaled --tun=userspace-networking'"
|
||||
volumes:
|
||||
- /var/lib:/var/lib
|
||||
- /dev/net/tun:/dev/net/tun
|
32
apps/transmission/config.json
Normal file
32
apps/transmission/config.json
Normal file
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"name": "Transmission",
|
||||
"available": true,
|
||||
"port": 8089,
|
||||
"requirements": {
|
||||
"ports": [51413]
|
||||
},
|
||||
"id": "transmission",
|
||||
"description": "",
|
||||
"short_desc": "",
|
||||
"author": "",
|
||||
"source": "https://transmissionbt.com",
|
||||
"image": "https://avatars.githubusercontent.com/u/223312?s=200&v=4",
|
||||
"form_fields": {
|
||||
"username": {
|
||||
"type": "text",
|
||||
"label": "Username",
|
||||
"max": 50,
|
||||
"min": 3,
|
||||
"required": true,
|
||||
"env_variable": "TRANSMISSION_USERNAME"
|
||||
},
|
||||
"password": {
|
||||
"type": "password",
|
||||
"label": "Password",
|
||||
"max": 50,
|
||||
"min": 3,
|
||||
"required": true,
|
||||
"env_variable": "TRANSMISSION_PASSWORD"
|
||||
}
|
||||
}
|
||||
}
|
0
apps/transmission/data/config/.gitkeep
Normal file
0
apps/transmission/data/config/.gitkeep
Normal file
24
apps/transmission/docker-compose.yml
Normal file
24
apps/transmission/docker-compose.yml
Normal file
|
@ -0,0 +1,24 @@
|
|||
version: "3.7"
|
||||
services:
|
||||
transmission:
|
||||
image: lscr.io/linuxserver/transmission
|
||||
container_name: transmission
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=${TZ}
|
||||
- USER=${TRANSMISSION_USERNAME}
|
||||
- PASS=${TRANSMISSION_PASSWORD}
|
||||
# - WHITELIST=iplist #optional
|
||||
# - PEERPORT=peerport #optional
|
||||
# - HOST_WHITELIST=dnsnane list #optional
|
||||
volumes:
|
||||
- ${APP_DATA_DIR}/data/config:/config
|
||||
- ${ROOT_FOLDER_HOST}/media/torrents:/downloads
|
||||
ports:
|
||||
- ${APP_PORT}:9091
|
||||
- 51413:51413
|
||||
- 51413:51413/udp
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- tipi_main_network
|
29
apps/ttyd/config.json
Normal file
29
apps/ttyd/config.json
Normal file
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"name": "TTYD - Web terminal",
|
||||
"port": 8092,
|
||||
"id": "ttyd",
|
||||
"description": "",
|
||||
"short_desc": "A utility that allows you to access a command line from your web browser",
|
||||
"author": "",
|
||||
"source": "",
|
||||
"image": "",
|
||||
"form_fields": {
|
||||
"username": {
|
||||
"type": "text",
|
||||
"label": "Username",
|
||||
"max": 50,
|
||||
"min": 3,
|
||||
"required": true,
|
||||
"env_variable": "TRANSMISSION_USERNAME"
|
||||
},
|
||||
"password": {
|
||||
"type": "password",
|
||||
"label": "Password",
|
||||
"max": 50,
|
||||
"min": 3,
|
||||
"required": true,
|
||||
"env_variable": "TRANSMISSION_PASSWORD"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
0
apps/ttyd/docker-compose.yml
Normal file
0
apps/ttyd/docker-compose.yml
Normal file
36
apps/wg-easy/config.json
Normal file
36
apps/wg-easy/config.json
Normal file
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"name": "Wireguard",
|
||||
"available": true,
|
||||
"port": 8082,
|
||||
"requirements": {
|
||||
"ports": [51820]
|
||||
},
|
||||
"id": "wg-easy",
|
||||
"description": "Access your homeserver from anywhere even on your mobile device. Wireguard-easy is a simple tool to configure and manage Wireguard VPN servers. It is written in Go and uses the official Wireguard client. You have to open and redirect port 51820 to your homeserver in order to connect.",
|
||||
"short_desc": "VPN server for your homeserver",
|
||||
"author": "WeeJeWel",
|
||||
"source": "https://github.com/WeeJeWel/wg-easy/",
|
||||
"image": "https://avatars.githubusercontent.com/u/13991055?s=200&v=4",
|
||||
"form_fields": {
|
||||
"host": {
|
||||
"type": "fqdnip",
|
||||
"label": "Your public IP address or domain name",
|
||||
"required": true,
|
||||
"env_variable": "WIREGUARD_HOST"
|
||||
},
|
||||
"password": {
|
||||
"type": "password",
|
||||
"label": "Password",
|
||||
"max": 50,
|
||||
"min": 3,
|
||||
"required": true,
|
||||
"env_variable": "WIREGUARD_PASSWORD"
|
||||
},
|
||||
"dns": {
|
||||
"type": "ip",
|
||||
"label": "Default DNS server",
|
||||
"required": false,
|
||||
"env_variable": "WIREGUARD_DNS"
|
||||
}
|
||||
}
|
||||
}
|
0
apps/wg-easy/data/.gitkeep
Normal file
0
apps/wg-easy/data/.gitkeep
Normal file
36
apps/wg-easy/docker-compose.yml
Normal file
36
apps/wg-easy/docker-compose.yml
Normal file
|
@ -0,0 +1,36 @@
|
|||
version: "3.7"
|
||||
services:
|
||||
wg-easy:
|
||||
container_name: wg-easy
|
||||
image: "meienberger/wg-easy:latest"
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ${APP_DATA_DIR}/data:/etc/wireguard
|
||||
- /lib/modules:/lib/modules
|
||||
ports:
|
||||
- 51822:51820/udp
|
||||
- ${APP_PORT}:51821/tcp
|
||||
environment:
|
||||
WG_HOST: "${WIREGUARD_HOST}"
|
||||
PASSWORD: "${WIREGUARD_PASSWORD}"
|
||||
WG_ALLOWED_IPS: 0.0.0.0/0,::/0
|
||||
WG_PORT: 51822
|
||||
WG_DEFAULT_DNS: "${WIREGUARD_DNS:-8.8.8.8}"
|
||||
WG_FWMARK: 51820
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_MODULE
|
||||
dns:
|
||||
- "${WIREGUARD_DNS:-8.8.8.8}"
|
||||
sysctls:
|
||||
- net.ipv4.conf.all.src_valid_mark=1
|
||||
- net.ipv4.ip_forward=1
|
||||
networks:
|
||||
- tipi_main_network
|
||||
# labels:
|
||||
# traefik.enable: true
|
||||
# traefik.http.routers.wireguard.rule: Host(`wireguard.tipi.home`)
|
||||
# traefik.http.routers.wireguard.service: wireguard
|
||||
# traefik.http.routers.wireguard.tls: true
|
||||
# traefik.http.routers.wireguard.entrypoints: websecure
|
||||
# traefik.http.services.wireguard.loadbalancer.server.port: 51821
|
12
codecov.yml
12
codecov.yml
|
@ -1,12 +0,0 @@
|
|||
ignore:
|
||||
- 'public'
|
||||
- 'scripts'
|
||||
- 'templates'
|
||||
- 'screenshots'
|
||||
- '**/*.json'
|
||||
- '**/tests/**'
|
||||
coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
informational: true
|
|
@ -1,3 +0,0 @@
|
|||
files:
|
||||
- source: /src/client/messages/en.json
|
||||
translation: /src/client/messages/%locale%.json
|
|
@ -1,149 +1,55 @@
|
|||
version: '3.7'
|
||||
version: "3.7"
|
||||
|
||||
services:
|
||||
tipi-reverse-proxy:
|
||||
container_name: tipi-reverse-proxy
|
||||
image: traefik:v2.8
|
||||
restart: on-failure
|
||||
ports:
|
||||
- 80:80
|
||||
- 443:443
|
||||
- 8080:8080
|
||||
command: --providers.docker
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- ${PWD}/traefik:/root/.config
|
||||
- ${PWD}/traefik/shared:/shared
|
||||
networks:
|
||||
- tipi_main_network
|
||||
|
||||
tipi-db:
|
||||
container_name: tipi-db
|
||||
image: postgres:14
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 1m
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql/data
|
||||
ports:
|
||||
- 5432:5432
|
||||
environment:
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
POSTGRES_USER: tipi
|
||||
POSTGRES_DB: tipi
|
||||
healthcheck:
|
||||
test: ['CMD-SHELL', 'pg_isready -d tipi -U tipi']
|
||||
interval: 5s
|
||||
timeout: 10s
|
||||
retries: 120
|
||||
networks:
|
||||
- tipi_main_network
|
||||
|
||||
tipi-redis:
|
||||
container_name: tipi-redis
|
||||
image: redis:7.2.0
|
||||
restart: unless-stopped
|
||||
command: redis-server --requirepass ${REDIS_PASSWORD}
|
||||
ports:
|
||||
- 6379:6379
|
||||
volumes:
|
||||
- redisdata:/data
|
||||
healthcheck:
|
||||
test: ['CMD', 'redis-cli', 'ping']
|
||||
interval: 5s
|
||||
timeout: 10s
|
||||
retries: 120
|
||||
networks:
|
||||
- tipi_main_network
|
||||
|
||||
tipi-worker:
|
||||
api:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./packages/worker/Dockerfile.dev
|
||||
container_name: tipi-worker
|
||||
healthcheck:
|
||||
test: ['CMD', 'curl', '-f', 'http://localhost:3000/healthcheck']
|
||||
interval: 5s
|
||||
timeout: 10s
|
||||
retries: 120
|
||||
start_period: 5s
|
||||
depends_on:
|
||||
tipi-db:
|
||||
condition: service_healthy
|
||||
tipi-redis:
|
||||
condition: service_healthy
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
NODE_ENV: development
|
||||
volumes:
|
||||
# Dev mode
|
||||
- ${PWD}/packages/worker/src:/app/packages/worker/src
|
||||
# Production mode
|
||||
- /proc:/host/proc:ro
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- ${PWD}/.env:/app/.env
|
||||
- ${PWD}/state:/app/state
|
||||
- ${PWD}/repos:/app/repos
|
||||
- ${PWD}/apps:/app/apps
|
||||
- ${STORAGE_PATH:-$PWD}/app-data:/storage/app-data
|
||||
- ${PWD}/logs:/app/logs
|
||||
- ${PWD}/traefik:/app/traefik
|
||||
- ${PWD}/user-config:/app/user-config
|
||||
networks:
|
||||
- tipi_main_network
|
||||
|
||||
tipi-dashboard:
|
||||
build:
|
||||
context: .
|
||||
context: ./packages/system-api
|
||||
dockerfile: Dockerfile.dev
|
||||
container_name: tipi-dashboard
|
||||
depends_on:
|
||||
tipi-db:
|
||||
condition: service_healthy
|
||||
tipi-redis:
|
||||
condition: service_healthy
|
||||
tipi-worker:
|
||||
condition: service_healthy
|
||||
env_file:
|
||||
- .env
|
||||
container_name: api
|
||||
ports:
|
||||
- 3001:3001
|
||||
volumes:
|
||||
## Docker sock
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- ${PWD}:/tipi
|
||||
- ${PWD}/packages/system-api:/app
|
||||
- /app/node_modules
|
||||
environment:
|
||||
NODE_ENV: development
|
||||
- INTERNAL_IP=${INTERNAL_IP}
|
||||
- TIPI_VERSION=${TIPI_VERSION}
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- ROOT_FOLDER_HOST=${ROOT_FOLDER_HOST}
|
||||
networks:
|
||||
- tipi_main_network
|
||||
|
||||
dashboard:
|
||||
build:
|
||||
context: ./packages/dashboard
|
||||
dockerfile: Dockerfile.dev
|
||||
container_name: dashboard
|
||||
ports:
|
||||
- 3000:3000
|
||||
networks:
|
||||
- tipi_main_network
|
||||
environment:
|
||||
- INTERNAL_IP=${INTERNAL_IP}
|
||||
volumes:
|
||||
# - /dashboard/node_modules
|
||||
# - /dashboard/.next
|
||||
- ${PWD}/.env:/runtipi/.env
|
||||
- ${PWD}/src:/app/src
|
||||
- ${PWD}/packages:/app/packages
|
||||
- ${PWD}/state:/runtipi/state
|
||||
- ${PWD}/repos:/runtipi/repos:ro
|
||||
- ${PWD}/apps:/runtipi/apps
|
||||
- ${PWD}/logs:/app/logs
|
||||
- ${PWD}/traefik:/runtipi/traefik
|
||||
- ${STORAGE_PATH:-$PWD}:/app/storage
|
||||
- ${PWD}/packages/dashboard:/app
|
||||
- /app/node_modules
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.routers.dashboard.rule: PathPrefix("/") # Host(`tipi.local`) &&
|
||||
traefik.http.routers.dashboard.entrypoints: webinsecure
|
||||
traefik.http.routers.dashboard.service: dashboard
|
||||
traefik.http.services.dashboard.loadbalancer.server.port: 3000
|
||||
traefik.http.middlewares.redirect-to-https.redirectscheme.scheme: https
|
||||
# Local domain
|
||||
traefik.http.routers.dashboard-local-insecure.rule: Host(`${LOCAL_DOMAIN}`)
|
||||
traefik.http.routers.dashboard-local-insecure.entrypoints: web
|
||||
traefik.http.routers.dashboard-local-insecure.service: dashboard
|
||||
traefik.http.routers.dashboard-local-insecure.middlewares: redirect-to-https
|
||||
# secure
|
||||
traefik.http.routers.dashboard-local.rule: Host(`${LOCAL_DOMAIN}`)
|
||||
traefik.http.routers.dashboard-local.entrypoints: websecure
|
||||
traefik.http.routers.dashboard-local.tls: true
|
||||
traefik.http.routers.dashboard-local.service: dashboard
|
||||
|
||||
networks:
|
||||
tipi_main_network:
|
||||
driver: bridge
|
||||
name: runtipi_tipi_main_network
|
||||
|
||||
volumes:
|
||||
pgdata:
|
||||
redisdata:
|
||||
driver_opts:
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
ipam:
|
||||
driver: default
|
||||
config:
|
||||
- subnet: 10.21.21.0/24
|
||||
|
|
|
@ -1,146 +0,0 @@
|
|||
version: '3.7'
|
||||
|
||||
services:
|
||||
tipi-reverse-proxy:
|
||||
container_name: tipi-reverse-proxy
|
||||
image: traefik:v2.8
|
||||
restart: on-failure
|
||||
ports:
|
||||
- 80:80
|
||||
- 443:443
|
||||
- 8080:8080
|
||||
command: --providers.docker
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- ${PWD}/traefik:/root/.config
|
||||
- ${PWD}/traefik/shared:/shared
|
||||
networks:
|
||||
- tipi_main_network
|
||||
|
||||
tipi-db:
|
||||
container_name: tipi-db
|
||||
image: postgres:14
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 1m
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql/data
|
||||
ports:
|
||||
- 5432:5432
|
||||
environment:
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
POSTGRES_USER: tipi
|
||||
POSTGRES_DB: tipi
|
||||
healthcheck:
|
||||
test: ['CMD-SHELL', 'pg_isready -d tipi -U tipi']
|
||||
interval: 5s
|
||||
timeout: 10s
|
||||
retries: 120
|
||||
networks:
|
||||
- tipi_main_network
|
||||
|
||||
tipi-redis:
|
||||
container_name: tipi-redis
|
||||
image: redis:7.2.0
|
||||
restart: unless-stopped
|
||||
command: redis-server --requirepass ${REDIS_PASSWORD}
|
||||
ports:
|
||||
- 6379:6379
|
||||
volumes:
|
||||
- redisdata:/data
|
||||
healthcheck:
|
||||
test: ['CMD', 'redis-cli', 'ping']
|
||||
interval: 5s
|
||||
timeout: 10s
|
||||
retries: 120
|
||||
networks:
|
||||
- tipi_main_network
|
||||
|
||||
tipi-worker:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./packages/worker/Dockerfile
|
||||
container_name: tipi-worker
|
||||
healthcheck:
|
||||
test: ['CMD', 'curl', '-f', 'http://localhost:3000/healthcheck']
|
||||
interval: 5s
|
||||
timeout: 10s
|
||||
retries: 120
|
||||
start_period: 5s
|
||||
depends_on:
|
||||
tipi-db:
|
||||
condition: service_healthy
|
||||
tipi-redis:
|
||||
condition: service_healthy
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
NODE_ENV: production
|
||||
volumes:
|
||||
- /proc:/host/proc
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- ${PWD}/.env:/app/.env
|
||||
- ${PWD}/state:/app/state
|
||||
- ${PWD}/repos:/app/repos
|
||||
- ${PWD}/apps:/app/apps
|
||||
- ${STORAGE_PATH:-$PWD}/app-data:/storage/app-data
|
||||
- ${PWD}/logs:/app/logs
|
||||
- ${PWD}/traefik:/app/traefik
|
||||
- ${PWD}/user-config:/app/user-config
|
||||
networks:
|
||||
- tipi_main_network
|
||||
|
||||
tipi-dashboard:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
container_name: tipi-dashboard
|
||||
depends_on:
|
||||
tipi-db:
|
||||
condition: service_healthy
|
||||
tipi-redis:
|
||||
condition: service_healthy
|
||||
tipi-worker:
|
||||
condition: service_healthy
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
NODE_ENV: development
|
||||
networks:
|
||||
- tipi_main_network
|
||||
ports:
|
||||
- 3000:3000
|
||||
volumes:
|
||||
- ${PWD}/.env:/runtipi/.env
|
||||
- ${PWD}/state:/runtipi/state
|
||||
- ${PWD}/repos:/runtipi/repos:ro
|
||||
- ${PWD}/apps:/runtipi/apps
|
||||
- ${PWD}/logs:/app/logs
|
||||
- ${PWD}/traefik:/runtipi/traefik
|
||||
- ${STORAGE_PATH}:/app/storage
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.services.dashboard.loadbalancer.server.port: 3000
|
||||
traefik.http.middlewares.redirect-to-https.redirectscheme.scheme: https
|
||||
# Local ip
|
||||
traefik.http.routers.dashboard.rule: PathPrefix("/")
|
||||
traefik.http.routers.dashboard.service: dashboard
|
||||
traefik.http.routers.dashboard.entrypoints: web
|
||||
# Local domain
|
||||
traefik.http.routers.dashboard-local-insecure.rule: Host(`${LOCAL_DOMAIN}`)
|
||||
traefik.http.routers.dashboard-local-insecure.entrypoints: web
|
||||
traefik.http.routers.dashboard-local-insecure.service: dashboard
|
||||
traefik.http.routers.dashboard-local-insecure.middlewares: redirect-to-https
|
||||
# secure
|
||||
traefik.http.routers.dashboard-local.rule: Host(`${LOCAL_DOMAIN}`)
|
||||
traefik.http.routers.dashboard-local.entrypoints: websecure
|
||||
traefik.http.routers.dashboard-local.tls: true
|
||||
traefik.http.routers.dashboard-local.service: dashboard
|
||||
|
||||
networks:
|
||||
tipi_main_network:
|
||||
driver: bridge
|
||||
name: runtipi_tipi_main_network
|
||||
|
||||
volumes:
|
||||
pgdata:
|
||||
redisdata:
|
60
docker-compose.rc.yml
Normal file
60
docker-compose.rc.yml
Normal file
|
@ -0,0 +1,60 @@
|
|||
version: "3.7"
|
||||
|
||||
services:
|
||||
reverse-proxy:
|
||||
container_name: reverse-proxy
|
||||
image: traefik:v2.6
|
||||
restart: always
|
||||
ports:
|
||||
- ${NGINX_PORT}:80
|
||||
- ${PROXY_PORT}:8080
|
||||
command: --api.insecure=true --providers.docker
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- ${PWD}/traefik:/root/.config
|
||||
networks:
|
||||
- tipi_main_network
|
||||
|
||||
api:
|
||||
image: meienberger/tipi-api:rc-${TIPI_VERSION}
|
||||
container_name: api
|
||||
ports:
|
||||
- 3001:3001
|
||||
volumes:
|
||||
## Docker sock
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- ${PWD}:/tipi
|
||||
environment:
|
||||
- INTERNAL_IP=${INTERNAL_IP}
|
||||
- TIPI_VERSION=${TIPI_VERSION}
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- ROOT_FOLDER_HOST=${ROOT_FOLDER_HOST}
|
||||
networks:
|
||||
- tipi_main_network
|
||||
|
||||
dashboard:
|
||||
image: meienberger/tipi-dashboard:rc-${TIPI_VERSION}
|
||||
container_name: dashboard
|
||||
ports:
|
||||
- 3000:3000
|
||||
networks:
|
||||
- tipi_main_network
|
||||
environment:
|
||||
- INTERNAL_IP=${INTERNAL_IP}
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.routers.dashboard.rule: PathPrefix("/") # Host(`tipi.local`) &&
|
||||
traefik.http.routers.dashboard.entrypoints: webinsecure
|
||||
traefik.http.routers.dashboard.service: dashboard
|
||||
traefik.http.services.dashboard.loadbalancer.server.port: 3000
|
||||
|
||||
networks:
|
||||
tipi_main_network:
|
||||
driver: bridge
|
||||
driver_opts:
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
ipam:
|
||||
driver: default
|
||||
config:
|
||||
- subnet: 10.21.21.0/24
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue