diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..2414015 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,54 @@ +# Dependencies +node_modules +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Build outputs +.next +out +dist +build + +# Git +.git +.gitignore +.gitattributes + +# Environment files +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# IDE and editors +.vscode +.idea +*.swp +*.swo +*~ +.DS_Store + +# Documentation +README.md +CONTRIBUTING.md +CODE_OF_CONDUCT.md +LICENSE + +# Screenshots and media +src/screenshots +*.png +*.jpg +*.jpeg +*.gif +*.svg +TUXMATE.png + +# Testing +coverage +.nyc_output + +# Misc +*.log +.cache diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0b025fd --- /dev/null +++ b/Dockerfile @@ -0,0 +1,58 @@ +# Stage 1: Install dependencies +FROM node:20-alpine AS deps +WORKDIR /app + +# Copy package files +COPY package.json package-lock.json ./ + +# Install dependencies +RUN npm ci --only=production && \ + npm cache clean --force + +# Stage 2: Build the application +FROM node:20-alpine AS builder +WORKDIR /app + +# Copy package files +COPY package.json package-lock.json ./ + +# Install all dependencies (including devDependencies) +RUN npm ci + +# Copy source code +COPY . . + +# Build Next.js application +RUN npm run build + +# Stage 3: Production runtime +FROM node:20-alpine AS runner +WORKDIR /app + +# Set environment to production +ENV NODE_ENV=production + +# Create non-root user for security +RUN addgroup --system --gid 1001 nodejs && \ + adduser --system --uid 1001 nextjs + +# Copy necessary files from builder +COPY --from=builder /app/public ./public +COPY --from=builder /app/.next/standalone ./ +COPY --from=builder /app/.next/static ./.next/static + +# Set correct permissions +RUN chown -R nextjs:nodejs /app + +# Switch to non-root user +USER nextjs + +# Expose port +EXPOSE 3000 + +# Set environment variable for port +ENV PORT=3000 +ENV HOSTNAME="0.0.0.0" + +# Start the application +CMD ["node", "server.js"] diff --git a/README.md b/README.md index 2edca5a..b3720cd 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,45 @@ npm start +
+

🐳 Docker Deployment

+ +### Quick Start with Docker + +```bash +# Build the Docker image +docker build -t tuxmate:latest . + +# Run the container +docker run -p 3000:3000 tuxmate:latest +``` + +### Using Docker Compose (Recommended) + +```bash +# Start the application +docker-compose up -d + +# View logs +docker-compose logs -f + +# Stop the application +docker-compose down +``` + +Open [http://localhost:3000](http://localhost:3000) + +### Configuration + +The Docker container exposes port 3000 by default. You can customize the port mapping: + +```bash +docker run -p 8080:3000 tuxmate:latest +``` + +
+ + ## 🛠️ Tech Stack - Next.js 16 @@ -117,13 +156,13 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines. - [x] Copy command & Download script - [x] Package availability indicators - [x] Custom domain +- [x] Docker support for containerized deployment ### Planned - [ ] Search & filter applications - [ ] Winget support (Windows) - [ ] Homebrew support (macOS) -- [ ] Dockerfile for containerized deployment - [ ] Save custom presets / profiles - [ ] Share configurations via URL - [ ] More distros (Gentoo, Void, Alpine) diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..e3ea7a2 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,21 @@ +version: '3.8' + +services: + tuxmate: + build: + context: . + dockerfile: Dockerfile + image: tuxmate:latest + container_name: tuxmate + ports: + - "3000:3000" + environment: + - NODE_ENV=production + - PORT=3000 + restart: unless-stopped + healthcheck: + test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3000"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s diff --git a/next.config.ts b/next.config.ts index e9ffa30..225e495 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,7 +1,7 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { - /* config options here */ + output: 'standalone', }; export default nextConfig;