From d8c5b29610d8267046960176cc88e60c35658256 Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Mon, 25 Jul 2022 21:45:15 +0200 Subject: [PATCH 01/16] add: Portainer app --- Dockerfile.dev | 2 +- apps/portainer/config.json | 13 +++++++++++++ apps/portainer/docker-compose.yml | 16 ++++++++++++++++ apps/portainer/metadata/description.md | 6 ++++++ .../dashboard/public/logos/apps/portainer.jpg | Bin 0 -> 31676 bytes 5 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 apps/portainer/config.json create mode 100644 apps/portainer/docker-compose.yml create mode 100644 apps/portainer/metadata/description.md create mode 100644 packages/dashboard/public/logos/apps/portainer.jpg diff --git a/Dockerfile.dev b/Dockerfile.dev index bf6133ef..62e656be 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -3,7 +3,7 @@ FROM alpine:3.16.0 as app WORKDIR / # Install docker -RUN apk --no-cache add docker-compose nodejs npm bash +RUN apk --no-cache add docker-compose nodejs npm bash g++ make RUN npm install node-gyp -g diff --git a/apps/portainer/config.json b/apps/portainer/config.json new file mode 100644 index 00000000..02baff1a --- /dev/null +++ b/apps/portainer/config.json @@ -0,0 +1,13 @@ +{ + "name": "Portainer", + "port": 9443, + "available": true, + "id": "portainer", + "categories": ["utilities"], + "description": "", + "short_desc": "Making Docker and Kubernetes management easy. ", + "author": "portainer.io", + "source": "https://github.com/portainer/portainer", + "image": "/logos/apps/portainer.jpg", + "form_fields": [] +} diff --git a/apps/portainer/docker-compose.yml b/apps/portainer/docker-compose.yml new file mode 100644 index 00000000..f1b42b65 --- /dev/null +++ b/apps/portainer/docker-compose.yml @@ -0,0 +1,16 @@ +version: "3.9" + +services: + portainer: + image: portainer/portainer-ce:latest + container_name: portainer + restart: unless-stopped + ports: + - "${APP_PORT}:9443" + environment: + PHOTOPRISM_ADMIN_PASSWORD: ${PHOTOPRISM_ADMIN_PASSWORD} + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - "${APP_DATA_DIR}/data:/data" + networks: + - tipi_main_network \ No newline at end of file diff --git a/apps/portainer/metadata/description.md b/apps/portainer/metadata/description.md new file mode 100644 index 00000000..6567921c --- /dev/null +++ b/apps/portainer/metadata/description.md @@ -0,0 +1,6 @@ + +![Screenshot](https://github.com/portainer/portainer/blob/develop/app/assets/images/portainer-github-banner.png?raw=true) + +**Portainer Community Edition** is a lightweight service delivery platform for containerized applications that can be used to manage Docker, Swarm, Kubernetes and ACI environments. It is designed to be as simple to deploy as it is to use. The application allows you to manage all your orchestrator resources (containers, images, volumes, networks and more) through a β€˜smart’ GUI and/or an extensive API. + +Portainer consists of a single container that can run on any cluster. It can be deployed as a Linux container or a Windows native container. \ No newline at end of file diff --git a/packages/dashboard/public/logos/apps/portainer.jpg b/packages/dashboard/public/logos/apps/portainer.jpg new file mode 100644 index 0000000000000000000000000000000000000000..078e2bf3a69525ad13bd471ac95a1db1e080cc48 GIT binary patch literal 31676 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 H;QvhkmVj@( literal 0 HcmV?d00001 From de3efff6ea03c97477e3e461a6edec7f6fcbc9fd Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Mon, 25 Jul 2022 22:03:54 +0200 Subject: [PATCH 02/16] update: .gitignore --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index b0db5958..36154145 100644 --- a/.gitignore +++ b/.gitignore @@ -16,10 +16,13 @@ state/* media/data/movies/* media/data/tv/* -media/data/books/* +media/data/books/spoken/* +media/data/books/ebooks/* !media/data/movies/.gitkeep !media/data/tv/.gitkeep !media/data/books/metadata.db +!media/data/books/ebooks/.gitkeep +!media/data/books/spoken/.gitkeep media/torrents/complete/* !media/torrents/complete/.gitkeep From f716aa7256425f8403e9c97c48c19a9766206bb2 Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Mon, 25 Jul 2022 22:04:27 +0200 Subject: [PATCH 03/16] add: App Readarr --- apps/readarr/config.json | 13 +++++++++++ apps/readarr/docker-compose.yml | 20 ++++++++++++++++ apps/readarr/metadata/description.md | 22 ++++++++++++++++++ .../dashboard/public/logos/apps/readarr.jpg | Bin 0 -> 56564 bytes 4 files changed, 55 insertions(+) create mode 100644 apps/readarr/config.json create mode 100644 apps/readarr/docker-compose.yml create mode 100644 apps/readarr/metadata/description.md create mode 100644 packages/dashboard/public/logos/apps/readarr.jpg diff --git a/apps/readarr/config.json b/apps/readarr/config.json new file mode 100644 index 00000000..3ed11512 --- /dev/null +++ b/apps/readarr/config.json @@ -0,0 +1,13 @@ +{ + "name": "Readarr", + "available": true, + "port": 8112, + "id": "readarr", + "categories": ["books", "media"], + "description": "", + "short_desc": "Book Manager and Automation (Sonarr for Ebooks)", + "author": "readarr.com", + "source": "https://github.com/Readarr/Readarr", + "image": "/logos/apps/readarr.jpg", + "form_fields": [] +} diff --git a/apps/readarr/docker-compose.yml b/apps/readarr/docker-compose.yml new file mode 100644 index 00000000..f687e65f --- /dev/null +++ b/apps/readarr/docker-compose.yml @@ -0,0 +1,20 @@ +version: "3.9" +services: + readarr: + image: lscr.io/linuxserver/readarr:develop + container_name: readarr + environment: + - PUID=1000 + - PGID=1000 + - TZ=${TZ} + dns: + - ${DNS_IP} + volumes: + - /etc/localtime:/etc/localtime:ro + - ${APP_DATA_DIR}/data:/config + - ${ROOT_FOLDER_HOST}/media:/media + ports: + - ${APP_PORT}:8787 + restart: unless-stopped + networks: + - tipi_main_network diff --git a/apps/readarr/metadata/description.md b/apps/readarr/metadata/description.md new file mode 100644 index 00000000..b1652ea7 --- /dev/null +++ b/apps/readarr/metadata/description.md @@ -0,0 +1,22 @@ +Readarr is an ebook and audiobook collection manager for Usenet and BitTorrent users. It can monitor multiple RSS feeds for new books from your favorite authors and will grab, sort, and rename them. +Note that only one type of a given book is supported. If you want both an audiobook and ebook of a given book you will need multiple instances. + +## Major Features Include + +* Can watch for better quality of the ebooks and audiobooks you have and do an automatic upgrade. *e.g. from PDF to AZW3* +* Support for major platforms: Windows, Linux, macOS, Raspberry Pi, etc. +* Automatically detects new books +* Can scan your existing library and download any missing books +* Automatic failed download handling will try another release if one fails +* Manual search so you can pick any release or to see why a release was not downloaded automatically +* Advanced customization for profiles, such that Readarr will always download the copy you want +* Fully configurable book renaming +* SABnzbd, NZBGet, QBittorrent, Deluge, rTorrent, Transmission, uTorrent, and other download clients are supported and integrated +* Full integration with Calibre (add to library, conversion) (Requires Calibre Content Server) +* And a beautiful UI + +## Support + +[![Wiki](https://img.shields.io/badge/servarr-wiki-181717.svg?maxAge=60)](https://wiki.servarr.com/readarr) +[![Discord](https://img.shields.io/badge/discord-chat-7289DA.svg?maxAge=60)](https://readarr.com/discord) +[![Reddit](https://img.shields.io/badge/reddit-discussion-FF4500.svg?maxAge=60)](https://www.reddit.com/r/readarr) \ No newline at end of file diff --git a/packages/dashboard/public/logos/apps/readarr.jpg b/packages/dashboard/public/logos/apps/readarr.jpg new file mode 100644 index 0000000000000000000000000000000000000000..466e30f3cbaa878bd2987a14dc56d71c6900b4f2 GIT binary patch literal 56564 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 literal 0 HcmV?d00001 From d5d1f95bfe5f45fb53ebb706697848e93db4c881 Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Mon, 25 Jul 2022 22:44:19 +0200 Subject: [PATCH 04/16] wip: App Firefly-III [skip ci] --- apps/fireflyiii/config.json | 14 +++++++ apps/fireflyiii/docker-compose.yml | 66 ++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 apps/fireflyiii/config.json create mode 100644 apps/fireflyiii/docker-compose.yml diff --git a/apps/fireflyiii/config.json b/apps/fireflyiii/config.json new file mode 100644 index 00000000..3f08306d --- /dev/null +++ b/apps/fireflyiii/config.json @@ -0,0 +1,14 @@ +{ + "name": "File Browser", + "available": true, + "port": 8096, + "id": "filebrowser", + "categories": ["utilities"], + "description": "Reliable and Performant File Management Desktop Sync and File Sharing\n Default credentials: admin / admin", + "short_desc": "Access your homeserver files from your browser", + "author": "filebrowser.org", + "website": "https://filebrowser.org/", + "source": "https://github.com/filebrowser/filebrowser", + "image": "/logos/apps/filebrowser.jpg", + "form_fields": [] +} diff --git a/apps/fireflyiii/docker-compose.yml b/apps/fireflyiii/docker-compose.yml new file mode 100644 index 00000000..e11e85b4 --- /dev/null +++ b/apps/fireflyiii/docker-compose.yml @@ -0,0 +1,66 @@ +version: '3.9' + +services: + fireflyiii: + image: fireflyiii/core:latest + restart: unless-stopped + volumes: + - ${APP_DATA_DIR}/data/uplodad:/var/www/html/storage/upload + ports: + - ${APP_PORT}:8080 + depends_on: + - fireflyiii-db + environment: + - APP_ENV=local + - APP_DEBUG=false + - SITE_OWNER=${EMAIL} + - APP_KEY=${APP_KEY} + - TZ=${TZ} + - TRUSTED_PROXIES=** + + # Database + - DB_CONNECTION=mysql + - DB_HOST=fireflyiii-db + - DB_PORT=3306 + - DB_DATABASE=firefly + - DB_USERNAME=firefly + - DB_PASSWORD=${DB_PASSWORD} + + # Cookie settings + - COOKIE_PATH="/" + - COOKIE_DOMAIN= + - COOKIE_SECURE=false + - COOKIE_SAMESITE=lax + + # Firefly III can send you the following messages. + - SEND_REGISTRATION_MAIL=true + - SEND_ERROR_MESSAGE=true + - SEND_LOGIN_NEW_IP_WARNING=true + + - APP_NAME=FireflyIII + - BROADCAST_DRIVER=log + - QUEUE_DRIVER=sync + - CACHE_PREFIX=firefly + - PUSHER_KEY= + - IPINFO_TOKEN= + - PUSHER_SECRET= + - PUSHER_ID= + - IS_HEROKU=false + - FIREFLY_III_LAYOUT=v1 + - APP_URL=http://localhost:${APP_PORT} + networks: + - tipi_main_network + + fireflyiii-db: + image: mariadb + hostname: fireflyiii-db + restart: unless-stopped + environment: + - MYSQL_RANDOM_ROOT_PASSWORD=yes + - MYSQL_USER=firefly + - MYSQL_PASSWORD=firefly + - MYSQL_DATABASE=firefly + volumes: + - ${APP_DATA_DIR}/data/db:/var/lib/mysql + networks: + - tipi_main_network From 5c674e9f84aecd1c1560bfb09d1487249f6b09cc Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Tue, 26 Jul 2022 16:30:47 +0200 Subject: [PATCH 05/16] add: App Firefly III --- apps/firefly-iii/config.json | 28 ++++++++++++++++++ .../docker-compose.yml | 21 +++++-------- apps/firefly-iii/metadata/description.md | 26 ++++++++++++++++ apps/fireflyiii/config.json | 14 --------- .../public/logos/apps/firefly-iii.jpg | Bin 0 -> 33861 bytes packages/dashboard/src/core/constants.ts | 1 + packages/dashboard/src/generated/graphql.tsx | 1 + .../modules/AppStore/helpers/table.helpers.ts | 1 + .../modules/Apps/components/InstallForm.tsx | 5 +++- .../src/modules/apps/apps.helpers.ts | 14 ++++++++- .../system-api/src/modules/apps/apps.types.ts | 2 ++ packages/system-api/src/server.ts | 28 ++++++++++-------- 12 files changed, 99 insertions(+), 42 deletions(-) create mode 100644 apps/firefly-iii/config.json rename apps/{fireflyiii => firefly-iii}/docker-compose.yml (76%) create mode 100644 apps/firefly-iii/metadata/description.md delete mode 100644 apps/fireflyiii/config.json create mode 100644 packages/dashboard/public/logos/apps/firefly-iii.jpg diff --git a/apps/firefly-iii/config.json b/apps/firefly-iii/config.json new file mode 100644 index 00000000..a84db019 --- /dev/null +++ b/apps/firefly-iii/config.json @@ -0,0 +1,28 @@ +{ + "name": "Firefly III", + "available": true, + "port": 8115, + "id": "firefly-iii", + "categories": ["finance"], + "description": "", + "short_desc": "Firefly III: a personal finances manager ", + "author": "JC5", + "website": "https://www.firefly-iii.org/", + "source": "https://github.com/firefly-iii/firefly-iii", + "image": "/logos/apps/firefly-iii.jpg", + "form_fields": [ + { + "type": "email", + "label": "Your email", + "required": true, + "env_variable": "EMAIL" + }, + { + "type": "random", + "min": 32, + "max": 32, + "label": "Random key", + "env_variable": "APP_KEY" + } + ] +} diff --git a/apps/fireflyiii/docker-compose.yml b/apps/firefly-iii/docker-compose.yml similarity index 76% rename from apps/fireflyiii/docker-compose.yml rename to apps/firefly-iii/docker-compose.yml index e11e85b4..f48e980f 100644 --- a/apps/fireflyiii/docker-compose.yml +++ b/apps/firefly-iii/docker-compose.yml @@ -1,15 +1,16 @@ version: '3.9' services: - fireflyiii: + firefly-iii: image: fireflyiii/core:latest + container_name: firefly-iii restart: unless-stopped volumes: - ${APP_DATA_DIR}/data/uplodad:/var/www/html/storage/upload ports: - ${APP_PORT}:8080 depends_on: - - fireflyiii-db + - firefly-iii-db environment: - APP_ENV=local - APP_DEBUG=false @@ -20,11 +21,11 @@ services: # Database - DB_CONNECTION=mysql - - DB_HOST=fireflyiii-db + - DB_HOST=firefly-iii-db - DB_PORT=3306 - DB_DATABASE=firefly - DB_USERNAME=firefly - - DB_PASSWORD=${DB_PASSWORD} + - DB_PASSWORD=firefly # Cookie settings - COOKIE_PATH="/" @@ -32,26 +33,18 @@ services: - COOKIE_SECURE=false - COOKIE_SAMESITE=lax - # Firefly III can send you the following messages. - - SEND_REGISTRATION_MAIL=true - - SEND_ERROR_MESSAGE=true - - SEND_LOGIN_NEW_IP_WARNING=true - - APP_NAME=FireflyIII - BROADCAST_DRIVER=log - QUEUE_DRIVER=sync - CACHE_PREFIX=firefly - - PUSHER_KEY= - - IPINFO_TOKEN= - - PUSHER_SECRET= - - PUSHER_ID= - IS_HEROKU=false - FIREFLY_III_LAYOUT=v1 - APP_URL=http://localhost:${APP_PORT} networks: - tipi_main_network - fireflyiii-db: + firefly-iii-db: + container_name: firefly-iii-db image: mariadb hostname: fireflyiii-db restart: unless-stopped diff --git a/apps/firefly-iii/metadata/description.md b/apps/firefly-iii/metadata/description.md new file mode 100644 index 00000000..4f81d34f --- /dev/null +++ b/apps/firefly-iii/metadata/description.md @@ -0,0 +1,26 @@ +"Firefly III" is a (self-hosted) manager for your personal finances. It can help you keep track of your expenses and income, so you can spend less and save more. Firefly III supports the use of budgets, categories and tags. Using a bunch of external tools, you can import data. It also has many neat financial reports available. + +Firefly III should give you **insight** into and **control** over your finances. Money should be useful, not scary. You should be able to *see* where it is going, to *feel* your expenses and to... wow, I'm going overboard with this aren't I? + +But you get the idea: this is your money. These are your expenses. Stop them from controlling you. I built this tool because I started to dislike money. Having money, not having money, paying bills with money, you get the idea. But no more. I want to feel "safe", whatever my balance is. And I hope this tool can help you. I know it helps me. + +![Firefly III on iMac](https://raw.githubusercontent.com/firefly-iii/firefly-iii/develop/.github/assets/img/imac-complete.png) + +### Purpose + +Personal financial management is pretty difficult, and everybody has their own approach to it. Some people make budgets, other people limit their cashflow by throwing away their credit cards, others try to increase their current cashflow. There are tons of ways to save and earn money. Firefly III works on the principle that if you know where your money is going, you can stop it from going there. + +By keeping track of your expenses and your income you can budget accordingly and save money. Stop living from paycheck to paycheck but give yourself the financial wiggle room you need. + +You can read more about the purpose of Firefly III in the [documentation](https://docs.firefly-iii.org/). + +![Firefly III on iPad](https://raw.githubusercontent.com/firefly-iii/firefly-iii/develop/.github/assets/img/ipad-complete.png) + +## Need help? + +If you need support using Firefly III or the associated tools, come find us! + +- [GitHub Discussions for questions and support](https://github.com/firefly-iii/firefly-iii/discussions/) +- [Gitter.im for a good chat and a quick answer](https://gitter.im/firefly-iii/firefly-iii) +- [GitHub Issues for bugs and issues](https://github.com/firefly-iii/firefly-iii/issues) +- [Follow me around for news and updates on Twitter](https://twitter.com/Firefly_iii) \ No newline at end of file diff --git a/apps/fireflyiii/config.json b/apps/fireflyiii/config.json deleted file mode 100644 index 3f08306d..00000000 --- a/apps/fireflyiii/config.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "File Browser", - "available": true, - "port": 8096, - "id": "filebrowser", - "categories": ["utilities"], - "description": "Reliable and Performant File Management Desktop Sync and File Sharing\n Default credentials: admin / admin", - "short_desc": "Access your homeserver files from your browser", - "author": "filebrowser.org", - "website": "https://filebrowser.org/", - "source": "https://github.com/filebrowser/filebrowser", - "image": "/logos/apps/filebrowser.jpg", - "form_fields": [] -} diff --git a/packages/dashboard/public/logos/apps/firefly-iii.jpg b/packages/dashboard/public/logos/apps/firefly-iii.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e231f32d5588d13cb3eb66d0a440386e50afb57f GIT binary patch literal 33861 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

NtqyPNMTBQVij66#dSNQG_WOpk&$-zv$*TBU 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 F{|E0m`HcVo literal 0 HcmV?d00001 diff --git a/packages/dashboard/src/core/constants.ts b/packages/dashboard/src/core/constants.ts index a6b71f38..99c8fce2 100644 --- a/packages/dashboard/src/core/constants.ts +++ b/packages/dashboard/src/core/constants.ts @@ -13,4 +13,5 @@ export const APP_CATEGORIES = [ { name: 'Books', id: AppCategoriesEnum.Books, icon: 'FaBook' }, { name: 'Data', id: AppCategoriesEnum.Data, icon: 'FaDatabase' }, { name: 'Music', id: AppCategoriesEnum.Music, icon: 'FaMusic' }, + { name: 'Finance', id: AppCategoriesEnum.Finance, icon: 'FaMoneyBillAlt' }, ]; diff --git a/packages/dashboard/src/generated/graphql.tsx b/packages/dashboard/src/generated/graphql.tsx index 729fa07c..eca7bc95 100644 --- a/packages/dashboard/src/generated/graphql.tsx +++ b/packages/dashboard/src/generated/graphql.tsx @@ -37,6 +37,7 @@ export enum AppCategoriesEnum { Data = 'DATA', Development = 'DEVELOPMENT', Featured = 'FEATURED', + Finance = 'FINANCE', Media = 'MEDIA', Music = 'MUSIC', Network = 'NETWORK', diff --git a/packages/dashboard/src/modules/AppStore/helpers/table.helpers.ts b/packages/dashboard/src/modules/AppStore/helpers/table.helpers.ts index c15495b3..97b6ebcb 100644 --- a/packages/dashboard/src/modules/AppStore/helpers/table.helpers.ts +++ b/packages/dashboard/src/modules/AppStore/helpers/table.helpers.ts @@ -38,4 +38,5 @@ export const colorSchemeForCategory: Record = { [AppCategoriesEnum.Data]: 'red', [AppCategoriesEnum.Books]: 'blue', [AppCategoriesEnum.Music]: 'green', + [AppCategoriesEnum.Finance]: 'orange', }; diff --git a/packages/dashboard/src/modules/Apps/components/InstallForm.tsx b/packages/dashboard/src/modules/Apps/components/InstallForm.tsx index d3f12ca1..7265d376 100644 --- a/packages/dashboard/src/modules/Apps/components/InstallForm.tsx +++ b/packages/dashboard/src/modules/Apps/components/InstallForm.tsx @@ -11,6 +11,9 @@ interface IProps { initalValues?: Record; } +const hiddenTypes = ['random']; +const typeFilter = (field: FormField) => !hiddenTypes.includes(field.type); + const InstallForm: React.FC = ({ formFields, onSubmit, initalValues }) => { const renderField = (field: FormField) => { return ( @@ -30,7 +33,7 @@ const InstallForm: React.FC = ({ formFields, onSubmit, initalValues }) = validate={(values) => validateAppConfig(values, formFields)} render={({ handleSubmit, validating, submitting }) => (

- {formFields.map(renderField)} + {formFields.filter(typeFilter).map(renderField)} diff --git a/packages/system-api/src/modules/apps/apps.helpers.ts b/packages/system-api/src/modules/apps/apps.helpers.ts index 03589908..e2a95e89 100644 --- a/packages/system-api/src/modules/apps/apps.helpers.ts +++ b/packages/system-api/src/modules/apps/apps.helpers.ts @@ -1,6 +1,7 @@ import portUsed from 'tcp-port-used'; import { fileExists, readdirSync, readFile, readJsonFile, runScript, writeFile } from '../fs/fs.helpers'; import InternalIp from 'internal-ip'; +import crypto from 'crypto'; import config from '../../config'; import { AppInfo } from './apps.types'; @@ -84,6 +85,12 @@ export const ensureAppState = (appName: string, installed: boolean) => { writeFile('/state/apps.json', JSON.stringify(state)); }; +const getEntropy = (name: string, length: number) => { + const hash = crypto.createHash('sha256'); + hash.update(name); + return hash.digest('hex').substring(0, length); +}; + export const generateEnvFile = (appName: string, form: Record) => { const configFile: AppInfo = readJsonFile(`/apps/${appName}/config.json`); const baseEnvFile = readFile('/.env').toString(); @@ -91,10 +98,15 @@ export const generateEnvFile = (appName: string, form: Record) = configFile.form_fields?.forEach((field) => { const formValue = form[field.env_variable]; + const envVar = field.env_variable; if (formValue) { - const envVar = field.env_variable; envFile += `${envVar}=${formValue}\n`; + } else if (field.type === 'random') { + const length = field.min || 32; + const randomString = getEntropy(field.env_variable, length); + + envFile += `${envVar}=${randomString}\n`; } else if (field.required) { throw new Error(`Variable ${field.env_variable} is required`); } diff --git a/packages/system-api/src/modules/apps/apps.types.ts b/packages/system-api/src/modules/apps/apps.types.ts index b46c5085..705061a3 100644 --- a/packages/system-api/src/modules/apps/apps.types.ts +++ b/packages/system-api/src/modules/apps/apps.types.ts @@ -14,6 +14,7 @@ export enum AppCategoriesEnum { BOOKS = 'books', DATA = 'data', MUSIC = 'music', + FINANCE = 'finance', } export enum FieldTypes { @@ -25,6 +26,7 @@ export enum FieldTypes { ip = 'ip', fqdnip = 'fqdnip', url = 'url', + random = 'random', } export enum AppStatusEnum { diff --git a/packages/system-api/src/server.ts b/packages/system-api/src/server.ts index dee47e86..c9af25aa 100644 --- a/packages/system-api/src/server.ts +++ b/packages/system-api/src/server.ts @@ -15,20 +15,24 @@ import datasource from './config/datasource'; import appsService from './modules/apps/apps.service'; import { runUpdates } from './core/updates/run'; -const corsOptions = { - credentials: true, - origin: function (origin: any, callback: any) { - // disallow requests with no origin - if (!origin) return callback(new Error('Not allowed by CORS'), false); +let corsOptions = {}; - if (config.CLIENT_URLS.includes(origin)) { - return callback(null, true); - } +if (__prod__) { + corsOptions = { + credentials: true, + origin: function (origin: any, callback: any) { + // disallow requests with no origin + if (!origin) return callback(new Error('Not allowed by CORS'), false); - const message = "The CORS policy for this origin doesn't allow access from the particular origin."; - return callback(new Error(message), false); - }, -}; + if (config.CLIENT_URLS.includes(origin)) { + return callback(null, true); + } + + const message = "The CORS policy for this origin doesn't allow access from the particular origin."; + return callback(new Error(message), false); + }, + }; +} const main = async () => { try { From 4048d98d0d8678ded965cae9de7170cc5e2c3d7b Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Tue, 26 Jul 2022 19:25:54 +0200 Subject: [PATCH 06/16] add: app overseerr --- apps/overseerr/config.json | 13 +++++++++++++ apps/overseerr/docker-compose.yml | 14 ++++++++++++++ apps/overseerr/metadata/description.md | 14 ++++++++++++++ .../dashboard/public/logos/apps/overseerr.jpg | Bin 0 -> 35095 bytes 4 files changed, 41 insertions(+) create mode 100644 apps/overseerr/config.json create mode 100644 apps/overseerr/docker-compose.yml create mode 100644 apps/overseerr/metadata/description.md create mode 100644 packages/dashboard/public/logos/apps/overseerr.jpg diff --git a/apps/overseerr/config.json b/apps/overseerr/config.json new file mode 100644 index 00000000..e894933a --- /dev/null +++ b/apps/overseerr/config.json @@ -0,0 +1,13 @@ +{ + "name": "Overseerr", + "available": true, + "port": 8118, + "id": "overseerr", + "categories": ["media", "utilities"], + "description": "Overseerr is a free and open source software application for managing requests for your media library. It integrates with your existing services, such as Sonarr, Radarr, and Plex!", + "short_desc": "Request management and media discovery tool for the Plex ecosystem", + "author": "sct", + "source": "https://github.com/sct/overseerr", + "image": "/logos/apps/overseerr.jpg", + "form_fields": [] +} \ No newline at end of file diff --git a/apps/overseerr/docker-compose.yml b/apps/overseerr/docker-compose.yml new file mode 100644 index 00000000..1684c653 --- /dev/null +++ b/apps/overseerr/docker-compose.yml @@ -0,0 +1,14 @@ +version: "3" +services: + overseerr: + container_name: overseerr + image: sctx/overseerr:latest + environment: + - TZ=${TZ} + volumes: + - ${APP_DATA_DIR}/data/config:/app/config + ports: + - ${APP_PORT}:5055 + restart: unless-stopped + networks: + - tipi_main_network \ No newline at end of file diff --git a/apps/overseerr/metadata/description.md b/apps/overseerr/metadata/description.md new file mode 100644 index 00000000..ef83a357 --- /dev/null +++ b/apps/overseerr/metadata/description.md @@ -0,0 +1,14 @@ +**Overseerr** is a free and open source software application for managing requests for your media library. It integrates with your existing services, such as **[Sonarr](https://sonarr.tv/)**, **[Radarr](https://radarr.video/)**, and **[Plex](https://www.plex.tv/)**! + +## Current Features + +- Full Plex integration. Authenticate and manage user access with Plex! +- Easy integration with your existing services. Currently, Overseerr supports Sonarr and Radarr. More to come! +- Plex library scan, to keep track of the titles which are already available. +- Customizable request system, which allows users to request individual seasons or movies in a friendly, easy-to-use interface. +- Incredibly simple request management UI. Don't dig through the app to simply approve recent requests! +- Granular permission system. +- Support for various notification agents. +- Mobile-friendly design, for when you need to approve requests on the go! + +With more features on the way! Check out our [issue tracker](https://github.com/sct/overseerr/issues) to see the features which have already been requested. \ No newline at end of file diff --git a/packages/dashboard/public/logos/apps/overseerr.jpg b/packages/dashboard/public/logos/apps/overseerr.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7f64d53a3bc716752198ff974c3d16e7eb50f67e GIT binary patch literal 35095 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 literal 0 HcmV?d00001 From 4c148a58e0eed9b2c1e7e6761b95279c3c705cee Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Tue, 26 Jul 2022 20:20:31 +0200 Subject: [PATCH 07/16] Update README --- README.md | 1 + apps/firefly-iii/config.json | 7 +++++++ apps/firefly-iii/docker-compose.yml | 4 ++-- packages/system-api/src/modules/apps/apps.helpers.ts | 11 ++++++++--- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 0be83a6e..8dfe2591 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ Check our demo instance : **95.179.210.152** / username: **user@runtipi.com** / - [Calibre-Web](https://github.com/janeczku/calibre-web) - Web Ebook Reader - [Code-Server](https://github.com/coder/code-server) - Web VS Code - [Filebrowser](https://github.com/filebrowser/filebrowser) - Web File Browser +- [Firefly III](https://github.com/firefly-iii/firefly-iii) - A personal finances manager - [Freshrss](https://github.com/FreshRSS/FreshRSS) - A free, self-hostable RSS aggregator - [Gitea](https://github.com/go-gitea/gitea) - Gitea - A painless self-hosted Git service - [Homarr](https://github.com/ajnart/homarr) - A homepage for your server diff --git a/apps/firefly-iii/config.json b/apps/firefly-iii/config.json index a84db019..8f0d8539 100644 --- a/apps/firefly-iii/config.json +++ b/apps/firefly-iii/config.json @@ -23,6 +23,13 @@ "max": 32, "label": "Random key", "env_variable": "APP_KEY" + }, + { + "type": "random", + "min": 32, + "max": 32, + "label": "Database password", + "env_variable": "MYSQL_PASSWORD" } ] } diff --git a/apps/firefly-iii/docker-compose.yml b/apps/firefly-iii/docker-compose.yml index f48e980f..58159244 100644 --- a/apps/firefly-iii/docker-compose.yml +++ b/apps/firefly-iii/docker-compose.yml @@ -25,7 +25,7 @@ services: - DB_PORT=3306 - DB_DATABASE=firefly - DB_USERNAME=firefly - - DB_PASSWORD=firefly + - DB_PASSWORD=${MYSQL_PASSWORD} # Cookie settings - COOKIE_PATH="/" @@ -51,7 +51,7 @@ services: environment: - MYSQL_RANDOM_ROOT_PASSWORD=yes - MYSQL_USER=firefly - - MYSQL_PASSWORD=firefly + - MYSQL_PASSWORD=${MYSQL_PASSWORD} - MYSQL_DATABASE=firefly volumes: - ${APP_DATA_DIR}/data/db:/var/lib/mysql diff --git a/packages/system-api/src/modules/apps/apps.helpers.ts b/packages/system-api/src/modules/apps/apps.helpers.ts index e2a95e89..ec86b407 100644 --- a/packages/system-api/src/modules/apps/apps.helpers.ts +++ b/packages/system-api/src/modules/apps/apps.helpers.ts @@ -95,6 +95,7 @@ export const generateEnvFile = (appName: string, form: Record) = const configFile: AppInfo = readJsonFile(`/apps/${appName}/config.json`); const baseEnvFile = readFile('/.env').toString(); let envFile = `${baseEnvFile}\nAPP_PORT=${configFile.port}\n`; + const envMap = getEnvMap(appName); configFile.form_fields?.forEach((field) => { const formValue = form[field.env_variable]; @@ -103,10 +104,14 @@ export const generateEnvFile = (appName: string, form: Record) = if (formValue) { envFile += `${envVar}=${formValue}\n`; } else if (field.type === 'random') { - const length = field.min || 32; - const randomString = getEntropy(field.env_variable, length); + if (envMap.has(envVar)) { + envFile += `${envVar}=${envMap.get(envVar)}\n`; + } else { + const length = field.min || 32; + const randomString = getEntropy(field.env_variable, length); - envFile += `${envVar}=${randomString}\n`; + envFile += `${envVar}=${randomString}\n`; + } } else if (field.required) { throw new Error(`Variable ${field.env_variable} is required`); } From 59556f81a68798c85434ce646ecf697cf9b27afa Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Tue, 26 Jul 2022 20:24:18 +0200 Subject: [PATCH 08/16] Update README [skip ci] --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0be83a6e..0a96a965 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ Check our demo instance : **95.179.210.152** / username: **user@runtipi.com** / - [Nextcloud](https://github.com/nextcloud/server) - A safe home for all your data - [Nitter](https://github.com/zedeus/nitter) - Alternative Twitter front-end - [Node-RED](https://github.com/node-red/node-red) - Low-code programming for event-driven applications +- [Overseerr](https://github.com/sct/overseerr) - Request management and media discovery tool for the Plex ecosystem - [Photoprism](https://github.com/photoprism/photoprism) - AI-Powered Photos App for the Decentralized Web. We are on a mission to protect your freedom and privacy. - [Pihole](https://github.com/pi-hole/pi-hole) - A black hole for Internet advertisements - [Plex](https://github.com/plexinc/pms-docker) - Stream Movies & TV Shows From 4f3e5289dc93be440d8394f29aeae09201cdd962 Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Tue, 26 Jul 2022 20:28:05 +0200 Subject: [PATCH 09/16] Update README [skip ci] --- .gitignore | 3 +-- README.md | 1 + media/data/books/ebooks/.gitkeep | 0 media/data/books/spoken/.gitkeep | 0 4 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 media/data/books/ebooks/.gitkeep create mode 100644 media/data/books/spoken/.gitkeep diff --git a/.gitignore b/.gitignore index 36154145..781ea4c4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,9 @@ .pnpm-debug.log .env* -data/ github.secrets node_modules/ app-data/* -data/ +data/postgres traefik/ssl/* !traefik/ssl/.gitkeep !app-data/.gitkeep diff --git a/README.md b/README.md index 0be83a6e..7147aac4 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ Check our demo instance : **95.179.210.152** / username: **user@runtipi.com** / - [Plex](https://github.com/plexinc/pms-docker) - Stream Movies & TV Shows - [Prowlarr](https://github.com/Prowlarr/Prowlarr/) - A torrent/usenet indexer manager/proxy - [Radarr](https://github.com/Radarr/Radarr) - Movie collection manager for Usenet and BitTorrent users +- [Readarr](https://github.com/Readarr/Readarr) - Book Manager and Automation (Sonarr for Ebooks) - [Resilio Sync](https://github.com/bt-sync) - Fast, reliable, and simple file sync and share solution - [Sonarr](https://github.com/Sonarr/Sonarr) - TV show manager for Usenet and BitTorrent - [Syncthing](https://github.com/syncthing/syncthing) - Continuous File Synchronization diff --git a/media/data/books/ebooks/.gitkeep b/media/data/books/ebooks/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/media/data/books/spoken/.gitkeep b/media/data/books/spoken/.gitkeep new file mode 100644 index 00000000..e69de29b From 41b399a931cd93c47af662205ebd5c8a815fe913 Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Tue, 26 Jul 2022 20:29:50 +0200 Subject: [PATCH 10/16] Update README [skip ci] --- README.md | 1 + apps/portainer/config.json | 2 +- apps/portainer/docker-compose.yml | 2 -- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0be83a6e..27bfeb68 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ Check our demo instance : **95.179.210.152** / username: **user@runtipi.com** / - [Photoprism](https://github.com/photoprism/photoprism) - AI-Powered Photos App for the Decentralized Web. We are on a mission to protect your freedom and privacy. - [Pihole](https://github.com/pi-hole/pi-hole) - A black hole for Internet advertisements - [Plex](https://github.com/plexinc/pms-docker) - Stream Movies & TV Shows +- [Portainer](https://github.com/portainer/portainer) - Making Docker and Kubernetes management easy. - [Prowlarr](https://github.com/Prowlarr/Prowlarr/) - A torrent/usenet indexer manager/proxy - [Radarr](https://github.com/Radarr/Radarr) - Movie collection manager for Usenet and BitTorrent users - [Resilio Sync](https://github.com/bt-sync) - Fast, reliable, and simple file sync and share solution diff --git a/apps/portainer/config.json b/apps/portainer/config.json index 02baff1a..f5c6ad22 100644 --- a/apps/portainer/config.json +++ b/apps/portainer/config.json @@ -5,7 +5,7 @@ "id": "portainer", "categories": ["utilities"], "description": "", - "short_desc": "Making Docker and Kubernetes management easy. ", + "short_desc": "Making Docker and Kubernetes management easy.", "author": "portainer.io", "source": "https://github.com/portainer/portainer", "image": "/logos/apps/portainer.jpg", diff --git a/apps/portainer/docker-compose.yml b/apps/portainer/docker-compose.yml index f1b42b65..2d95f435 100644 --- a/apps/portainer/docker-compose.yml +++ b/apps/portainer/docker-compose.yml @@ -7,8 +7,6 @@ services: restart: unless-stopped ports: - "${APP_PORT}:9443" - environment: - PHOTOPRISM_ADMIN_PASSWORD: ${PHOTOPRISM_ADMIN_PASSWORD} volumes: - /var/run/docker.sock:/var/run/docker.sock - "${APP_DATA_DIR}/data:/data" From 71c27cd6abc3a54ddf2bd1467a826e3f1f9dcd15 Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Tue, 26 Jul 2022 20:34:06 +0200 Subject: [PATCH 11/16] Bump version --- apps/overseerr/config.json | 6 +++--- package.json | 2 +- packages/dashboard/package.json | 2 +- packages/system-api/package.json | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/overseerr/config.json b/apps/overseerr/config.json index e894933a..464dafad 100644 --- a/apps/overseerr/config.json +++ b/apps/overseerr/config.json @@ -1,13 +1,13 @@ { "name": "Overseerr", "available": true, - "port": 8118, + "port": 8116, "id": "overseerr", - "categories": ["media", "utilities"], + "categories": ["media", "utilities"], "description": "Overseerr is a free and open source software application for managing requests for your media library. It integrates with your existing services, such as Sonarr, Radarr, and Plex!", "short_desc": "Request management and media discovery tool for the Plex ecosystem", "author": "sct", "source": "https://github.com/sct/overseerr", "image": "/logos/apps/overseerr.jpg", "form_fields": [] -} \ No newline at end of file +} diff --git a/package.json b/package.json index 463c9e0f..3fb05d72 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "runtipi", - "version": "0.4.1", + "version": "0.4.2", "description": "A homeserver for everyone", "scripts": { "test": "jest", diff --git a/packages/dashboard/package.json b/packages/dashboard/package.json index 886119a8..a2de2b36 100644 --- a/packages/dashboard/package.json +++ b/packages/dashboard/package.json @@ -1,6 +1,6 @@ { "name": "dashboard", - "version": "0.4.1", + "version": "0.4.2", "private": true, "scripts": { "test": "jest --colors", diff --git a/packages/system-api/package.json b/packages/system-api/package.json index 6741eed5..2c90079c 100644 --- a/packages/system-api/package.json +++ b/packages/system-api/package.json @@ -1,6 +1,6 @@ { "name": "system-api", - "version": "0.4.1", + "version": "0.4.2", "description": "", "exports": "./dist/server.js", "type": "module", From 19dd59505bdf82b3ae9f5b8feb9d95166c0f6f9e Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Tue, 26 Jul 2022 19:51:22 +0000 Subject: [PATCH 12/16] fix: Add DNS setting to overseerr [skip ci] --- apps/overseerr/docker-compose.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/overseerr/docker-compose.yml b/apps/overseerr/docker-compose.yml index 1684c653..77f33a6f 100644 --- a/apps/overseerr/docker-compose.yml +++ b/apps/overseerr/docker-compose.yml @@ -10,5 +10,7 @@ services: ports: - ${APP_PORT}:5055 restart: unless-stopped + dns: + - ${DNS_IP} networks: - - tipi_main_network \ No newline at end of file + - tipi_main_network From bdbb4213779a5c308baa2005e3c9a73782e327cd Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Tue, 26 Jul 2022 20:12:44 +0000 Subject: [PATCH 13/16] fix: log production status at startup --- packages/system-api/src/config/config.ts | 2 ++ packages/system-api/src/server.ts | 32 +++++++++++------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/system-api/src/config/config.ts b/packages/system-api/src/config/config.ts index 0af6a43b..269c3f76 100644 --- a/packages/system-api/src/config/config.ts +++ b/packages/system-api/src/config/config.ts @@ -20,6 +20,8 @@ if (process.env.NODE_ENV !== 'production') { dotenv.config({ path: '.env' }); } +console.log('Production => ', process.env.NODE_ENV === 'production'); + const { LOGS_FOLDER = 'logs', LOGS_APP = 'app.log', diff --git a/packages/system-api/src/server.ts b/packages/system-api/src/server.ts index c9af25aa..15028b04 100644 --- a/packages/system-api/src/server.ts +++ b/packages/system-api/src/server.ts @@ -15,24 +15,22 @@ import datasource from './config/datasource'; import appsService from './modules/apps/apps.service'; import { runUpdates } from './core/updates/run'; -let corsOptions = {}; +let corsOptions = __prod__ + ? { + credentials: true, + origin: function (origin: any, callback: any) { + // disallow requests with no origin + if (!origin) return callback(new Error('Not allowed by CORS'), false); -if (__prod__) { - corsOptions = { - credentials: true, - origin: function (origin: any, callback: any) { - // disallow requests with no origin - if (!origin) return callback(new Error('Not allowed by CORS'), false); + if (config.CLIENT_URLS.includes(origin)) { + return callback(null, true); + } - if (config.CLIENT_URLS.includes(origin)) { - return callback(null, true); - } - - const message = "The CORS policy for this origin doesn't allow access from the particular origin."; - return callback(new Error(message), false); - }, - }; -} + const message = "The CORS policy for this origin doesn't allow access from the particular origin."; + return callback(new Error(message), false); + }, + } + : {}; const main = async () => { try { @@ -71,7 +69,7 @@ const main = async () => { httpServer.listen(port, () => { // Start apps appsService.startAllApps(); - logger.info(`Server running on port ${port}`); + logger.info(`Server running on port ${port} πŸš€ Production => ${__prod__}`); }); } catch (error) { console.log(error); From cb985ca38465cb1e7304dbb75b0a2004f57427f7 Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Tue, 26 Jul 2022 20:46:45 +0000 Subject: [PATCH 14/16] Recovery plan for failed migrations --- docker-compose.rc.yml | 6 ++- docker-compose.yml | 6 ++- .../src/core/updates/recover-migrations.ts | 38 +++++++++++++++++++ packages/system-api/src/server.ts | 16 +++++--- 4 files changed, 57 insertions(+), 9 deletions(-) create mode 100644 packages/system-api/src/core/updates/recover-migrations.ts diff --git a/docker-compose.rc.yml b/docker-compose.rc.yml index 7dd982c1..ac063a30 100644 --- a/docker-compose.rc.yml +++ b/docker-compose.rc.yml @@ -29,7 +29,7 @@ services: POSTGRES_USER: tipi POSTGRES_DB: tipi healthcheck: - test: [ "CMD-SHELL", "pg_isready -d tipi -U tipi" ] + test: ["CMD-SHELL", "pg_isready -d tipi -U tipi"] interval: 5s timeout: 10s retries: 120 @@ -59,6 +59,7 @@ services: POSTGRES_USERNAME: tipi POSTGRES_DBNAME: tipi POSTGRES_HOST: tipi-db + NODE_ENV: production networks: - tipi_main_network @@ -71,7 +72,8 @@ services: networks: - tipi_main_network environment: - - INTERNAL_IP=${INTERNAL_IP} + INTERNAL_IP: ${INTERNAL_IP} + NODE_ENV: production labels: traefik.enable: true traefik.http.routers.dashboard.rule: PathPrefix("/") # Host(`tipi.local`) && diff --git a/docker-compose.yml b/docker-compose.yml index 5b8bb195..981cbdc9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -29,7 +29,7 @@ services: POSTGRES_USER: tipi POSTGRES_DB: tipi healthcheck: - test: [ "CMD-SHELL", "pg_isready -d tipi -U tipi" ] + test: ["CMD-SHELL", "pg_isready -d tipi -U tipi"] interval: 5s timeout: 10s retries: 120 @@ -60,6 +60,7 @@ services: POSTGRES_USERNAME: tipi POSTGRES_DBNAME: tipi POSTGRES_HOST: tipi-db + NODE_ENV: production networks: - tipi_main_network @@ -73,7 +74,8 @@ services: networks: - tipi_main_network environment: - - INTERNAL_IP=${INTERNAL_IP} + INTERNAL_IP: ${INTERNAL_IP} + NODE_ENV: production labels: traefik.enable: true traefik.http.routers.dashboard.rule: PathPrefix("/") # Host(`tipi.local`) && diff --git a/packages/system-api/src/core/updates/recover-migrations.ts b/packages/system-api/src/core/updates/recover-migrations.ts new file mode 100644 index 00000000..275a13ba --- /dev/null +++ b/packages/system-api/src/core/updates/recover-migrations.ts @@ -0,0 +1,38 @@ +import datasource from '../../config/datasource'; +import App from '../../modules/apps/app.entity'; +import User from '../../modules/auth/user.entity'; +import Update from '../../modules/system/update.entity'; + +const recover = async () => { + console.log('Recovering broken database'); + const apps = await App.find(); + const users = await User.find(); + const updated = await Update.find(); + + // drop database + await datasource.dropDatabase(); + + console.log('running migrations'); + await datasource.runMigrations(); + + // create users + for (const user of users) { + await User.create(user).save(); + } + + // create apps + for (const app of apps) { + await App.create(app).save(); + } + + // create updates + for (const update of updated) { + await Update.create(update).save(); + } + + console.log('Users recovered', users.length); + console.log('Apps recovered', apps.length); + console.log('Database recovered'); +}; + +export default recover; diff --git a/packages/system-api/src/server.ts b/packages/system-api/src/server.ts index 15028b04..4474e91e 100644 --- a/packages/system-api/src/server.ts +++ b/packages/system-api/src/server.ts @@ -14,6 +14,7 @@ import cors from 'cors'; import datasource from './config/datasource'; import appsService from './modules/apps/apps.service'; import { runUpdates } from './core/updates/run'; +import recover from './core/updates/recover-migrations'; let corsOptions = __prod__ ? { @@ -42,10 +43,6 @@ const main = async () => { await datasource.initialize(); - if (__prod__) { - await datasource.runMigrations(); - } - const schema = await createSchema(); const httpServer = createServer(app); const plugins = [ApolloLogs]; @@ -63,13 +60,22 @@ const main = async () => { await apolloServer.start(); apolloServer.applyMiddleware({ app, cors: corsOptions }); + if (__prod__) { + try { + await datasource.runMigrations(); + } catch (e) { + logger.error(e); + await recover(); + } + } + // Run migrations await runUpdates(); httpServer.listen(port, () => { // Start apps appsService.startAllApps(); - logger.info(`Server running on port ${port} πŸš€ Production => ${__prod__}`); + console.info(`Server running on port ${port} πŸš€ Production => ${__prod__}`); }); } catch (error) { console.log(error); From b23eb749c4691aef0147105018492200f5c21b8a Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Tue, 26 Jul 2022 21:13:42 +0000 Subject: [PATCH 15/16] Add DNS settings to main api --- docker-compose.rc.yml | 2 ++ docker-compose.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/docker-compose.rc.yml b/docker-compose.rc.yml index ac063a30..5aff87c0 100644 --- a/docker-compose.rc.yml +++ b/docker-compose.rc.yml @@ -60,6 +60,8 @@ services: POSTGRES_DBNAME: tipi POSTGRES_HOST: tipi-db NODE_ENV: production + dns: + - ${DNS_IP} networks: - tipi_main_network diff --git a/docker-compose.yml b/docker-compose.yml index 981cbdc9..b0cab1ad 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -61,6 +61,8 @@ services: POSTGRES_DBNAME: tipi POSTGRES_HOST: tipi-db NODE_ENV: production + dns: + - ${DNS_IP} networks: - tipi_main_network From 35db4a00d908638397ced27c63930f6265e47474 Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Tue, 26 Jul 2022 21:19:39 +0000 Subject: [PATCH 16/16] upd: delete db when cleaning [skip ci] --- scripts/unsafe-cleanup.sh | 1 + 1 file changed, 1 insertion(+) mode change 100644 => 100755 scripts/unsafe-cleanup.sh diff --git a/scripts/unsafe-cleanup.sh b/scripts/unsafe-cleanup.sh old mode 100644 new mode 100755 index 0636d229..542629d3 --- a/scripts/unsafe-cleanup.sh +++ b/scripts/unsafe-cleanup.sh @@ -22,6 +22,7 @@ echo y | docker image prune -a # Remove everything in app-data folder rm -rf "${ROOT_FOLDER}/app-data" +rm -rf "${ROOT_FOLDER}/data/postgres" mkdir -p "${ROOT_FOLDER}/app-data" # Put {"installed":""} in state/apps.json