diff --git a/templates/pinepods/assets/logo.png b/templates/pinepods/assets/logo.png new file mode 100644 index 000000000..e218d0922 Binary files /dev/null and b/templates/pinepods/assets/logo.png differ diff --git a/templates/pinepods/assets/screenshot.png b/templates/pinepods/assets/screenshot.png new file mode 100644 index 000000000..39797a138 Binary files /dev/null and b/templates/pinepods/assets/screenshot.png differ diff --git a/templates/pinepods/index.ts b/templates/pinepods/index.ts new file mode 100644 index 000000000..c12d83921 --- /dev/null +++ b/templates/pinepods/index.ts @@ -0,0 +1,78 @@ +import { Output, randomPassword, Services } from "~templates-utils"; +import { Input } from "./meta"; + +export function generate(input: Input): Output { + const services: Services = []; + const dbServiceName = `${input.appServiceName}-db`; + const valkeyServiceName = `${input.appServiceName}-valkey`; + const dbPassword = randomPassword(); + const valkeyPassword = randomPassword(); + const timezone = input.timezone || "Etc/UTC"; + + services.push({ + type: "app", + data: { + serviceName: input.appServiceName, + source: { + type: "image", + image: input.appServiceImage, + }, + env: [ + `SEARCH_API_URL=https://search.pinepods.online/api/search`, + `PEOPLE_API_URL=https://people.pinepods.online`, + `HOSTNAME=https://$(PRIMARY_DOMAIN)`, + `DB_TYPE=postgresql`, + `DB_HOST=$(PROJECT_NAME)_${dbServiceName}`, + `DB_PORT=5432`, + `DB_USER=postgres`, + `DB_PASSWORD=${dbPassword}`, + `DB_NAME=$(PROJECT_NAME)`, + `VALKEY_HOST=$(PROJECT_NAME)-${valkeyServiceName}`, + `VALKEY_PORT=6379`, + `VALKEY_PASSWORD=${valkeyPassword}`, + `DEBUG_MODE=false`, + `PUID=911`, + `PGID=911`, + `TZ=${timezone}`, + ].join("\n"), + domains: [ + { + host: "$(EASYPANEL_DOMAIN)", + port: 8040, + }, + ], + mounts: [ + { + type: "volume", + name: "downloads", + mountPath: "/opt/pinepods/downloads", + }, + { + type: "volume", + name: "backups", + mountPath: "/opt/pinepods/backups", + }, + ], + }, + }); + + services.push({ + type: "postgres", + data: { + serviceName: dbServiceName, + password: dbPassword, + }, + }); + + services.push({ + type: "redis", + data: { + serviceName: valkeyServiceName, + image: "valkey/valkey:8-alpine", + password: valkeyPassword, + command: `valkey-server --requirepass ${valkeyPassword}`, + }, + }); + + return { services }; +} diff --git a/templates/pinepods/meta.yaml b/templates/pinepods/meta.yaml new file mode 100644 index 000000000..f42481e0b --- /dev/null +++ b/templates/pinepods/meta.yaml @@ -0,0 +1,72 @@ +name: PinePods +description: + PinePods is a complete podcast management system that lets you play, download, + and keep track of the podcasts you enjoy, all self-hosted on your own server. + It syncs across devices and works as an installable Progressive Web App on + desktop and mobile. +instructions: >- + Open the app and you'll be prompted to create the first admin account. + Downloaded episodes and backups are stored on persistent volumes, and Postgres + data persists across restarts. +changeLog: + - date: 2026-08-17 + description: first release +links: + - label: Website + url: https://www.pinepods.online + - label: GitHub Repo + url: https://github.com/madeofpendletonwool/PinePods + - label: Documentation + url: https://www.pinepods.online/docs/intro +contributors: + - name: Ahson Shaikh + url: https://github.com/Ahson-Shaikh +schema: + type: object + required: + - appServiceName + - appServiceImage + properties: + appServiceName: + type: string + title: App Service Name + default: pinepods + appServiceImage: + type: string + title: App Service Image + default: madeofpendletonwool/pinepods:0.9.0 + timezone: + type: string + title: Timezone + description: "Example: America/New_York" + default: Etc/UTC +benefits: + - title: Play, Download, and Track + description: + Stream or download episodes and keep listening progress synced across + every device you use + - title: Installable PWA + description: + Works as a Progressive Web App so you can install it on desktop and mobile + for a native-like experience + - title: Fully Self-Hosted + description: + Your subscriptions, downloads, and listening history stay entirely on your + own server +features: + - title: Cross-Device Sync + description: + Keeps playback position and subscriptions in sync no matter which device + you're listening from + - title: Podcast Search + description: + Search and subscribe to new shows directly from the app using the built-in + search API + - title: Automatic Downloads + description: + Automatically downloads new episodes from your subscriptions so they're + ready to play offline +tags: + - Media + - Podcasts + - Self-Hosting