feat(docker): add Docker support for containerized deployment

- Add multi-stage Dockerfile with Node.js 20 Alpine
- Add docker-compose.yml for easy deployment
- Add .dockerignore to optimize build context
- Enable standalone output in next.config.ts
- Add Docker deployment documentation to README
- Move Docker support from planned to completed in roadmap

The Dockerfile uses a three-stage build process:
1. deps: Install production dependencies
2. builder: Build Next.js application
3. runner: Minimal production runtime with non-root user

Includes health checks, restart policy, and security best practices.
This commit is contained in:
retrozenith
2025-12-28 12:52:23 +02:00
parent afd0102d0d
commit 57a4aca128
5 changed files with 174 additions and 2 deletions

54
.dockerignore Normal file
View File

@@ -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

58
Dockerfile Normal file
View File

@@ -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"]

View File

@@ -81,6 +81,45 @@ npm start
</details>
<details>
<summary><h2>🐳 Docker Deployment</h2></summary>
### 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
```
</details>
## 🛠️ 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)

21
docker-compose.yml Normal file
View File

@@ -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

View File

@@ -1,7 +1,7 @@
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
/* config options here */
output: 'standalone',
};
export default nextConfig;