Skip to content
botusunPublic

About

A self-hosted image hosting web app — a Java 21 / Spring Boot. Upload, browse, and delete pictures from a private dashboard with automatic thumbnail generation.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

17 Commits

Folders and files

Repository files navigation

picjava

A self-hosted image hosting web app — a Java 21 / Spring Boot. Upload, browse, and delete pictures from a private dashboard with automatic thumbnail generation.

Features

  • Single-admin login with rate-limited brute-force protection (5 attempts, 15-minute lockout)
  • Upload JPEG, PNG, GIF, and WebP images up to 32 MB
  • Automatic thumbnail generation with EXIF orientation correction
  • Paginated dashboard (20 images per page)
  • SQLite-backed metadata store (WAL mode)
  • CSRF protection on all mutating actions
  • 1-year cache headers on served images
  • Structured request logging
  • Virtual threads (Project Loom) for request handling and thumbnail generation

Running locally

./mvnw spring-boot:run

The server starts on port 8080. Visit http://localhost:8080 and log in with the default credentials (admin / password123).

Data is stored under ./data/ — uploaded files in data/uploads/, thumbnails in data/uploads/thumbs/, and the SQLite database at data/picgo.db. The database schema and file layout are identical to picgo, so pointing DATA_DIR at an existing picgo data directory works as a drop-in migration.

To run the tests:

./mvnw test

Configuration

All configuration is via environment variables:

Variable Default Description
PORT 8080 HTTP port to listen on
DATA_DIR data Directory for the database and uploaded files
ADMIN_USERNAME admin Admin login username
ADMIN_PASSWORD password123 Admin login password — change this
SECURE_COOKIES false Set to true to mark session cookies as Secure (required behind HTTPS)
TRUSTED_PROXY (unset) CIDR of a reverse proxy whose forwarded-IP headers should be trusted

Docker

Build and run with Docker:

docker build -t picjava .
docker run -p 8080:8080 -v $(pwd)/data:/app/data \
  -e ADMIN_PASSWORD=yourpassword \
  picjava

Or with Docker Compose:

services:
  picjava:
    image: ghcr.io/your-org/picjava:latest
    ports:
      - "8080:8080"
    volumes:
      - ./data:/app/data
    environment:
      ADMIN_PASSWORD: yourpassword
      SECURE_COOKIES: "true"
    restart: unless-stopped

CI / CD

GitHub Actions runs on every push and pull request to main:

  1. Build — ./mvnw -B verify (compiles and runs the test suite)
  2. Docker — builds and pushes the image to GHCR (ghcr.io/<owner>/<repo>:latest and :<sha>) on pushes to main
  3. Deploy — SSHes into a VPS, pulls the new image, and restarts via docker compose

Required repository secrets for deployment: VPS_HOST, VPS_USER, VPS_SSH_KEY, VPS_PORT, VPS_COMPOSE_DIR, GHCR_TOKEN, GHCR_USER.

Routes

Method Path Description
GET / Redirects to dashboard or login
GET /login Login page
POST /login Authenticate
POST /logout Invalidate session
GET /dashboard Image management dashboard
POST /upload Upload an image
POST /delete/{id} Delete an image
GET /pics/{filename} Serve the original image
GET /thumb/{filename} Serve the 400×400 JPEG thumbnail

Tech stack

Authentication is deliberately hand-rolled (DB-backed session tokens, per-session CSRF tokens, per-IP login rate limiting) to mirror picgo's behavior exactly, rather than pulling in Spring Security.

About

A self-hosted image hosting web app — a Java 21 / Spring Boot. Upload, browse, and delete pictures from a private dashboard with automatic thumbnail generation.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages