docs: comprehensive README with TypeScript and Unraid deployment
This commit is contained in:
203
README.md
203
README.md
@@ -1,69 +1,208 @@
|
|||||||
# PNGer - Modern PNG Editor & Resizer
|
# PNGer - Modern PNG Editor & Resizer
|
||||||
|
|
||||||
A simple, reactive, modern PNG editor and resizer with direct upload and download features. Deployed as a single Docker container on Unraid.
|
A simple, reactive, modern PNG editor and resizer with direct upload and download features. Built with TypeScript and deployed as a single Docker container on Unraid.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- **Drag & Drop Upload**: Intuitive file upload interface
|
- **Drag & Drop Upload**: Intuitive file upload interface
|
||||||
- **Real-time Preview**: See changes as you adjust settings
|
|
||||||
- **Resize Operations**: Width, height, and aspect ratio controls
|
- **Resize Operations**: Width, height, and aspect ratio controls
|
||||||
- **Compression**: Optimize PNG file sizes
|
- **Crop to Fit**: Smart cropping with position control (center, top, bottom, etc.)
|
||||||
|
- **Format Conversion**: PNG, WebP, and JPEG output
|
||||||
|
- **Quality Control**: Adjustable compression settings
|
||||||
- **Direct Download**: No server-side storage, immediate download
|
- **Direct Download**: No server-side storage, immediate download
|
||||||
- **Modern UI**: Sleek, responsive design
|
- **Modern UI**: Sleek, responsive TypeScript/Svelte design
|
||||||
|
|
||||||
## Tech Stack
|
## Tech Stack
|
||||||
|
|
||||||
- **Frontend**: Svelte + Vite
|
- **Frontend**: Svelte 4 + Vite + TypeScript
|
||||||
- **Backend**: Node.js + Express
|
- **Backend**: Node.js + Express + TypeScript
|
||||||
- **Image Processing**: Sharp
|
- **Image Processing**: Sharp (high-performance image library)
|
||||||
- **Container**: Docker (Alpine-based)
|
- **Container**: Docker (Alpine-based, multi-stage build)
|
||||||
- **Deployment**: Unraid via Docker Compose
|
- **Deployment**: Unraid via Docker Compose
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
### Local Development
|
### Unraid Deployment (Recommended)
|
||||||
|
|
||||||
```bash
|
1. **Clone or pull this repository to your Unraid server:**
|
||||||
# Install dependencies
|
```bash
|
||||||
npm install
|
cd /mnt/user/appdata
|
||||||
|
git clone https://git.alwisp.com/jason/pnger.git
|
||||||
|
cd pnger
|
||||||
|
```
|
||||||
|
|
||||||
# Run in development mode
|
2. **Build the Docker image:**
|
||||||
npm run dev
|
```bash
|
||||||
|
docker build -t pnger:latest .
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Run via docker-compose:**
|
||||||
|
```bash
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Access the application:**
|
||||||
|
- Navigate to `http://[unraid-ip]:8080`
|
||||||
|
|
||||||
|
### Unraid Environment Variables (Configurable via UI)
|
||||||
|
|
||||||
|
When setting up in Unraid Docker UI, you can configure:
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `HOST_PORT` | `8080` | External port to access the app |
|
||||||
|
| `MAX_FILE_SIZE` | `10485760` | Max upload size in bytes (10MB default) |
|
||||||
|
| `MEM_LIMIT` | `512m` | Memory limit for container |
|
||||||
|
| `CPU_LIMIT` | `1.0` | CPU limit (1.0 = 1 full core) |
|
||||||
|
| `NODE_ENV` | `production` | Node environment |
|
||||||
|
|
||||||
|
### Unraid Docker Template Example
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<Container version="2">
|
||||||
|
<Name>pnger</Name>
|
||||||
|
<Repository>pnger:latest</Repository>
|
||||||
|
<Network>bridge</Network>
|
||||||
|
<Privileged>false</Privileged>
|
||||||
|
<WebUI>http://[IP]:[PORT:8080]</WebUI>
|
||||||
|
<Config Name="WebUI Port" Target="3000" Default="8080" Mode="tcp" Description="Port for web interface" Type="Port" Display="always" Required="true" Mask="false">8080</Config>
|
||||||
|
<Config Name="Max File Size" Target="MAX_FILE_SIZE" Default="10485760" Mode="" Description="Maximum upload file size in bytes" Type="Variable" Display="advanced" Required="false" Mask="false">10485760</Config>
|
||||||
|
<Config Name="Memory Limit" Target="" Default="512m" Mode="" Description="Container memory limit" Type="Variable" Display="advanced" Required="false" Mask="false">512m</Config>
|
||||||
|
</Container>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Docker Deployment
|
## Local Development
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
- Node.js 20+
|
||||||
|
- npm or yarn
|
||||||
|
|
||||||
|
### Setup
|
||||||
|
|
||||||
|
1. **Install backend dependencies:**
|
||||||
|
```bash
|
||||||
|
cd backend
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Install frontend dependencies:**
|
||||||
|
```bash
|
||||||
|
cd frontend
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Run development servers:**
|
||||||
|
|
||||||
|
Terminal 1 (Backend):
|
||||||
|
```bash
|
||||||
|
cd backend
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Terminal 2 (Frontend):
|
||||||
|
```bash
|
||||||
|
cd frontend
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Access dev server:**
|
||||||
|
- Frontend: `http://localhost:5173`
|
||||||
|
- Backend API: `http://localhost:3000/api`
|
||||||
|
|
||||||
|
### Building for Production
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Build the image
|
# Backend TypeScript compilation
|
||||||
|
cd backend
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# Frontend build
|
||||||
|
cd frontend
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
## Docker Deployment (Manual)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build the image (all dependencies and builds are handled internally)
|
||||||
docker build -t pnger:latest .
|
docker build -t pnger:latest .
|
||||||
|
|
||||||
# Run the container
|
# Run the container
|
||||||
docker run -p 8080:3000 pnger:latest
|
docker run -d \
|
||||||
|
--name pnger \
|
||||||
|
-p 8080:3000 \
|
||||||
|
-e MAX_FILE_SIZE=10485760 \
|
||||||
|
--restart unless-stopped \
|
||||||
|
pnger:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
### Unraid Deployment
|
|
||||||
|
|
||||||
1. Clone this repository to your Unraid server
|
|
||||||
2. Use the provided `docker-compose.yml`
|
|
||||||
3. Access via http://[unraid-ip]:8080
|
|
||||||
|
|
||||||
## Project Structure
|
## Project Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
pnger/
|
pnger/
|
||||||
├── frontend/ # Svelte application
|
├── frontend/ # Svelte + TypeScript application
|
||||||
├── backend/ # Express API server
|
│ ├── src/
|
||||||
├── Dockerfile # Multi-stage build
|
│ │ ├── App.svelte # Main UI component
|
||||||
├── docker-compose.yml # Unraid deployment config
|
│ │ ├── main.ts # Entry point
|
||||||
└── INSTRUCTIONS.md # Development guide
|
│ │ └── lib/
|
||||||
|
│ │ └── api.ts # API client
|
||||||
|
│ ├── package.json
|
||||||
|
│ ├── tsconfig.json
|
||||||
|
│ └── vite.config.ts
|
||||||
|
├── backend/ # Express + TypeScript API server
|
||||||
|
│ ├── src/
|
||||||
|
│ │ ├── index.ts # Express server
|
||||||
|
│ │ ├── routes/
|
||||||
|
│ │ │ └── image.ts # Image transform endpoint
|
||||||
|
│ │ └── types/
|
||||||
|
│ │ └── image.ts # TypeScript types
|
||||||
|
│ ├── package.json
|
||||||
|
│ └── tsconfig.json
|
||||||
|
├── Dockerfile # Multi-stage build (frontend + backend)
|
||||||
|
├── docker-compose.yml # Unraid deployment config
|
||||||
|
└── INSTRUCTIONS.md # Development guide
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
1. User uploads an image via the web interface
|
||||||
|
2. Frontend sends image + transform parameters to backend API
|
||||||
|
3. Backend processes image using Sharp (resize, crop, compress, convert format)
|
||||||
|
4. Processed image is returned directly to browser
|
||||||
|
5. Browser triggers automatic download
|
||||||
|
6. No files stored on server (stateless operation)
|
||||||
|
|
||||||
|
## API Endpoints
|
||||||
|
|
||||||
|
### POST /api/transform
|
||||||
|
|
||||||
|
Transform an image with resize, crop, and format conversion.
|
||||||
|
|
||||||
|
**Request:**
|
||||||
|
- Method: `POST`
|
||||||
|
- Content-Type: `multipart/form-data`
|
||||||
|
- Body:
|
||||||
|
- `file`: Image file (PNG/JPEG/WebP)
|
||||||
|
- `width`: Target width (optional)
|
||||||
|
- `height`: Target height (optional)
|
||||||
|
- `quality`: Quality 10-100 (optional, default: 80)
|
||||||
|
- `format`: Output format `png|webp|jpeg` (optional, default: `png`)
|
||||||
|
- `fit`: Resize mode `inside|cover` (optional, default: `inside`)
|
||||||
|
- `position`: Crop position when `fit=cover` (optional, default: `center`)
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
- Content-Type: `image/[format]`
|
||||||
|
- Body: Transformed image binary
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
Environment variables (optional):
|
All configuration is handled via environment variables passed through Docker/Unraid:
|
||||||
- `PORT`: Server port (default: 3000)
|
|
||||||
- `MAX_FILE_SIZE`: Maximum upload size in MB (default: 10)
|
- `PORT`: Server port (default: `3000`, internal)
|
||||||
- `NODE_ENV`: production or development
|
- `MAX_FILE_SIZE`: Maximum upload size in bytes (default: `10485760` = 10MB)
|
||||||
|
- `TEMP_DIR`: Temporary directory for uploads (default: `/app/temp`)
|
||||||
|
- `NODE_ENV`: Node environment (default: `production`)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user