From 0484669888c6abe40faf74f9555f053770998fa8 Mon Sep 17 00:00:00 2001 From: ad-archer Date: Wed, 27 Aug 2025 00:43:15 -0400 Subject: [PATCH 1/2] Add Docker support and installation instructions to README, Dockerfile, and docker-compose.yml --- .dockerignore | 78 ++++++++++++++++++++++++++++++++++++++++++++++ Dockerfile | 71 +++++++++++++++++++++++++++++++++++++++++ README.md | 31 ++++++++++++++++++ docker-compose.yml | 24 ++++++++++++++ package.json | 8 ++++- 5 files changed, 211 insertions(+), 1 deletion(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..b92cf23 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,78 @@ +# Docker ignore file for Subarr +# Node modules +node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Build outputs +client/build/ +.env.local +.env.development.local +.env.test.local +.env.production.local + +# Database files (should be handled by volumes) +server/*.db +server/*.db-journal +*.db +*.db-journal + +# OS generated files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# IDE files +.vscode/ +.idea/ +*.swp +*.swo + +# Git +.git/ +.gitignore + +# Logs +logs/ +*.log + +# Runtime data +pids/ +*.pid +*.seed +*.pid.lock + +# Coverage directory used by tools like istanbul +coverage/ + +# Dependency directories +node_modules/ +jspm_packages/ + +# Optional npm cache directory +.npm + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + +# Docker files (to avoid recursion) +Dockerfile +docker-compose.yml +.dockerignore + +# Documentation +README.md diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5065e4d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,71 @@ +# Multi-stage Dockerfile for Subarr +FROM node:alpine3.22 AS base + +# Install system dependencies required for better-sqlite3 +RUN apk add --no-cache \ + python3 \ + make \ + g++ \ + sqlite-dev \ + linux-headers + +WORKDIR /app + +# Copy package files +COPY package*.json ./ +COPY client/package*.json ./client/ +COPY server/package*.json ./server/ + +# Install dependencies (including dev dependencies for building native modules) +RUN npm ci + +# Rebuild better-sqlite3 for the current architecture +RUN npm rebuild better-sqlite3 + +FROM base AS builder + +# Copy source code +COPY client/ ./client/ +COPY server/ ./server/ + +# Build the client +RUN npm --workspace client run build + +FROM node:alpine3.22 AS production + +# Install only runtime dependencies +RUN apk add --no-cache sqlite + +# Create non-root user for security +RUN addgroup -g 1001 -S subarr && \ + adduser -S subarr -u 1001 + +WORKDIR /app + +# Copy built application from builder stage +COPY --from=builder --chown=subarr:subarr /app/node_modules ./node_modules +COPY --from=builder --chown=subarr:subarr /app/client/build ./client/build +COPY --from=builder --chown=subarr:subarr /app/server ./server +COPY --from=builder --chown=subarr:subarr /app/package.json ./ + +# Rebuild native module for runtime architecture (avoids Exec format error) +RUN apk add --no-cache python3 make g++ sqlite-dev linux-headers \ + && npm rebuild better-sqlite3 --build-from-source \ + && apk del python3 make g++ sqlite-dev linux-headers \ + && rm -rf /root/.npm /root/.cache + +# Create data directory for database persistence +RUN mkdir -p /app/data && chown subarr:subarr /app/data + +# Switch to non-root user +USER subarr + +# Expose port +EXPOSE 3001 + +# Health check +HEALTHCHECK --interval=30s --timeout=3s --start-period=30s --retries=3 \ + CMD wget --no-verbose --tries=1 --spider http://localhost:3001/api/playlists || exit 1 + +# Start the server +CMD ["node", "server/index.js"] diff --git a/README.md b/README.md index c4526b9..bcf8710 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,37 @@ Subarr is NOT intended to do the following: ### Installation +#### Docker (Recommended) + +```bash +git clone https://github.com/derekantrican/subarr.git +cd subarr +docker-compose up -d +``` + +The app will be available at `http://localhost:3001` + +#### Helpful Docker Scripts + +From the project root you can use the following npm scripts (they just wrap common docker-compose commands): + +``` +npm run docker:run # Start (build if needed) in background +npm run docker:logs # Follow logs +npm run docker:stop # Stop and remove container +npm run docker:update # git pull then rebuild using latest base images and recreate +npm run docker:restart # Restart container (down + up -d) +``` + +Typical update workflow if you deployed via git clone: + +``` +cd subarr +npm run docker:update +``` + +#### Manual Installation + Make sure you have Node >= 18 installed, then run the following: ``` diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..bd47f74 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,24 @@ +# Please run `git pull` before running this compose +services: + subarr: + build: . + container_name: subarr + ports: + - "3001:3001" + volumes: + - subarr_data:/app/data + environment: + - NODE_ENV=production + - PORT=3001 + - DB_PATH=/app/data/subarr.db + restart: unless-stopped + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3001/"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + +volumes: + subarr_data: + driver: local diff --git a/package.json b/package.json index 9602d7c..7161d45 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,12 @@ "scripts": { "start-server": "npm --workspace client run build && NODE_ENV=production node server/index.js", "start-server-win": "npm --workspace client run build && SET NODE_ENV=production && node server/index.js", - "update": "git pull && npm install && npm run start-server" + "docker:run": "docker-compose up -d", + "update": "git pull && npm install", + "update:manual": "npm run update && npm run start-server", + "update:docker": "git pull && docker-compose build --pull && docker-compose up -d", + "docker:build": "docker build -t subarr .", + "docker:stop": "docker-compose down", + "docker:logs": "docker-compose logs -f" } } \ No newline at end of file From 442572d16a5561ee4cf650cf4bc5a2dd2fd2a9e0 Mon Sep 17 00:00:00 2001 From: ad-archer Date: Sat, 30 Aug 2025 00:40:08 -0400 Subject: [PATCH 2/2] Typo Fix: docker update script to update:docker --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bcf8710..fac3b7f 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ From the project root you can use the following npm scripts (they just wrap comm npm run docker:run # Start (build if needed) in background npm run docker:logs # Follow logs npm run docker:stop # Stop and remove container -npm run docker:update # git pull then rebuild using latest base images and recreate +npm run update:docker # git pull then rebuild using latest base images and recreate npm run docker:restart # Restart container (down + up -d) ``` @@ -107,7 +107,7 @@ Typical update workflow if you deployed via git clone: ``` cd subarr -npm run docker:update +npm run update:docker ``` #### Manual Installation