diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..4a7103a --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +node_modules +.svelte-kit +build +.idea +.env diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..23ad782 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,43 @@ +FROM node:18-alpine as pre-production + +RUN mkdir -p /usr/src/app +WORKDIR /usr/src/app + +COPY . . + +#COPY package.json . +#COPY package-lock.json . + +RUN npm i + +RUN npm run build + +FROM --platform=linux/amd64 node:18-alpine as production + +RUN mkdir -p /usr/src/app +WORKDIR /usr/src/app + +ENV NODE_ENV=production + +COPY --from=pre-production /usr/src/app/build ./build + +COPY package.json . +COPY package-lock.json . + +RUN npm ci --omit dev + +CMD [ "PORT", "9494", "node", "build" ] + +FROM node:18 as development + +ENV NODE_ENV=development + +RUN mkdir -p /usr/src/app +WORKDIR /usr/src/app + +COPY package.json . +COPY package-lock.json . + +RUN npm i + +CMD [ "npm", "run", "dev" ] \ No newline at end of file diff --git a/README.md b/README.md index 4cb9ea2..6342d95 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,34 @@ Local Library & Playback For a list of planned features & known bugs, see [Reiverr Taskboard](https://github.com/users/aleksilassila/projects/5). -# Getting started +# Installation + +The easiest and the recommended way to insstall Reiverr is via docker-compose. Make sure to update the api keys and base URLs to match your setup. + +Radarr & Sonarr API keys can be found under Settings > General in their respective web UIs. Jellyfin API key is located under Administration > Dashboard > Advanced > API Keys in the Jellyfin Web UI. + +```yaml +version: '3.8' + +name: reiverr + +services: + reiverr-frontend: + container_name: reiverr + image: ghcr.io/aleksilassila/reiverr:latest + restart: unless-stopped + ports: + - 9494:9494 + environment: + PUBLIC_RADARR_API_KEY: yourapikeyhere + PUBLIC_RADARR_BASE_URL: http://127.0.0.1:7878 + PUBLIC_SONARR_API_KEY: yourapikeyhere + PUBLIC_SONARR_BASE_URL: http://127.0.0.1:8989 + PUBLIC_JELLYFIN_API_KEY: yourapikeyhere + PUBLIC_JELLYFIN_URL: http://127.0.0.1:8096 +``` + +### Reiverr will be accessible via port 9494 by default. # Contributing @@ -49,22 +76,24 @@ To get started with development: 3. Run `npm install` 4. Run `npm run dev` +Alternatively, you can run `docker-compose up`. + Example .env file: ```env -# The PUBLIC_ prefix is required for SvelteKit to expose the variable to the client. +# The PUBLIC_ prefix is required for SvelteKit to expose the variable to the web browser. # If you are exposing the server to the internet (not recommended), you should use HTTPS. # Fill in the blanks and change the base URLs to match your setup. PUBLIC_RADARR_API_KEY= -PUBLIC_RADARR_BASE_URL=http://192.168.0.129:7878 +PUBLIC_RADARR_BASE_URL=http://127.0.0.1:7878 PUBLIC_SONARR_API_KEY= -PUBLIC_SONARR_BASE_URL=http://192.168.0.129:8989 +PUBLIC_SONARR_BASE_URL=http://127.0.0.1:8989 PUBLIC_JELLYFIN_API_KEY= -PUBLIC_JELLYFIN_URL=http://192.168.0.129:8096 +PUBLIC_JELLYFIN_URL=http://127.0.0.1:8096 ``` # Additional Screenshots diff --git a/docker-compose.override.yml b/docker-compose.override.yml new file mode 100644 index 0000000..93804fe --- /dev/null +++ b/docker-compose.override.yml @@ -0,0 +1,14 @@ +version: '3.8' + +name: reiverr + +services: + reiverr-frontend: + volumes: + - ./:/usr/src/app/ + - /usr/src/app/node_modules + build: + context: . + target: development + ports: + - 5173:5173 diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..a7134ef --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,12 @@ +version: '3.8' + +name: reiverr-prod + +services: + reiverr-frontend: + container_name: reiverr-prod + build: + context: . + target: production + ports: + - 9494:3000 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..ac40c5d --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,9 @@ +version: '3.8' + +name: reiverr-dev + +services: + reiverr-frontend: + container_name: reiverr-dev + image: ghcr.io/aleksilassila/reiverr:latest + restart: unless-stopped diff --git a/images/reiverr-demo.gif b/images/reiverr-demo.gif index f133e80..1978fa9 100644 Binary files a/images/reiverr-demo.gif and b/images/reiverr-demo.gif differ diff --git a/package.json b/package.json index 6b493d8..f5e9e19 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "reiverr", "version": "0.0.1", "scripts": { - "dev": "vite dev", + "dev": "vite dev --host", "build": "vite build", "preview": "vite preview", "test": "playwright test", diff --git a/src/lib/apis/jellyfin/jellyfinApi.ts b/src/lib/apis/jellyfin/jellyfinApi.ts index 9b56871..cb40ed4 100644 --- a/src/lib/apis/jellyfin/jellyfinApi.ts +++ b/src/lib/apis/jellyfin/jellyfinApi.ts @@ -1,6 +1,6 @@ import createClient from 'openapi-fetch'; import type { components, paths } from '$lib/apis/jellyfin/jellyfin.generated'; -import { PUBLIC_JELLYFIN_API_KEY, PUBLIC_JELLYFIN_URL } from '$env/static/public'; +import { env } from '$env/dynamic/public'; import { request } from '$lib/utils'; import type { DeviceProfile } from '$lib/apis/jellyfin/playback-profiles'; import { settings } from '$lib/stores/settings.store'; @@ -11,9 +11,9 @@ export type JellyfinItem = components['schemas']['BaseItemDto']; export const JELLYFIN_DEVICE_ID = 'Reiverr Client'; export const JellyfinApi = createClient({ - baseUrl: PUBLIC_JELLYFIN_URL, + baseUrl: env.PUBLIC_JELLYFIN_URL, headers: { - Authorization: `MediaBrowser DeviceId="${JELLYFIN_DEVICE_ID}", Token="${PUBLIC_JELLYFIN_API_KEY}"` + Authorization: `MediaBrowser DeviceId="${JELLYFIN_DEVICE_ID}", Token="${env.PUBLIC_JELLYFIN_API_KEY}"` } }); diff --git a/src/lib/apis/radarr/radarrApi.ts b/src/lib/apis/radarr/radarrApi.ts index bb65444..fe313ad 100644 --- a/src/lib/apis/radarr/radarrApi.ts +++ b/src/lib/apis/radarr/radarrApi.ts @@ -3,7 +3,7 @@ import { log, request } from '$lib/utils'; import type { paths } from '$lib/apis/radarr/radarr.generated'; import type { components } from '$lib/apis/radarr/radarr.generated'; import { getTmdbMovie } from '$lib/apis/tmdb/tmdbApi'; -import { PUBLIC_RADARR_API_KEY, PUBLIC_RADARR_BASE_URL } from '$env/static/public'; +import { env } from '$env/dynamic/public'; import { settings } from '$lib/stores/settings.store'; import { get } from 'svelte/store'; @@ -27,9 +27,9 @@ export interface RadarrMovieOptions { } export const RadarrApi = createClient({ - baseUrl: PUBLIC_RADARR_BASE_URL, + baseUrl: env.PUBLIC_RADARR_BASE_URL, headers: { - 'X-Api-Key': PUBLIC_RADARR_API_KEY + 'X-Api-Key': env.PUBLIC_RADARR_API_KEY } }); diff --git a/src/lib/apis/sonarr/sonarrApi.ts b/src/lib/apis/sonarr/sonarrApi.ts index 37a3b65..f17ba2d 100644 --- a/src/lib/apis/sonarr/sonarrApi.ts +++ b/src/lib/apis/sonarr/sonarrApi.ts @@ -1,4 +1,4 @@ -import { PUBLIC_SONARR_API_KEY, PUBLIC_SONARR_BASE_URL } from '$env/static/public'; +import { env } from '$env/dynamic/public'; import type { components, paths } from '$lib/apis/sonarr/sonarr.generated'; import { log } from '$lib/utils'; import createClient from 'openapi-fetch'; @@ -40,9 +40,9 @@ export interface SonarrSeriesOptions { } export const SonarrApi = createClient({ - baseUrl: PUBLIC_SONARR_BASE_URL, + baseUrl: env.PUBLIC_SONARR_BASE_URL, headers: { - 'X-Api-Key': PUBLIC_SONARR_API_KEY + 'X-Api-Key': env.PUBLIC_SONARR_API_KEY } }); diff --git a/src/lib/components/SourceStats/RadarrStats.svelte b/src/lib/components/SourceStats/RadarrStats.svelte index ab13ab5..a253dbc 100644 --- a/src/lib/components/SourceStats/RadarrStats.svelte +++ b/src/lib/components/SourceStats/RadarrStats.svelte @@ -1,5 +1,5 @@