Temporary file uploader.
  • Crystal 86.2%
  • JavaScript 5%
  • HTML 4.5%
  • CSS 1.9%
  • Nix 1.5%
  • Other 0.9%
Find a file
Fijxu 17aebdf659
All checks were successful
patchy CI / build (push) Successful in 2m10s
feat: show cover of audio file when showing file
2026-05-18 13:38:17 -04:00
.forgejo/workflows Revert "feat: check crystal formatting before compiling" 2026-04-17 02:32:54 -04:00
.vscode Update .vscode/settings.json and .editorconfig 2026-03-02 17:33:53 -03:00
config fix: increase libmagic buffer size to 131072 2026-05-18 13:24:28 -04:00
dist/nix chore: update wrong strings in module.nix file 2026-03-26 12:30:00 -03:00
docs feat: use libmagic to detect mime types and encoding 2026-04-08 18:08:30 -04:00
locales feat: add information for some video formats that may not play on certain browsers, depending of the codec used 2026-04-23 17:49:11 -04:00
public/-/assets feat: show cover of audio file when showing file 2026-05-18 13:38:17 -04:00
screenshots update readme screenshot images 2025-09-30 17:32:30 -03:00
spec spec: update spec 2025-08-07 02:50:38 -04:00
src feat: show cover of audio file when showing file 2026-05-18 13:38:17 -04:00
.ameba.yml add ameba 2025-05-27 17:57:11 -04:00
.editorconfig Update .vscode/settings.json and .editorconfig 2026-03-02 17:33:53 -03:00
.envrc add .envrc 2026-03-03 00:32:29 -03:00
.gitignore feat: minify js files at build time 2026-04-17 02:04:47 -04:00
.prettierrc.json chore: update prettierrc 2026-04-01 09:58:00 -03:00
biome.json Integrate biomejs for Javascript formatting and linting 2026-03-02 17:23:08 -03:00
docker-compose.yml compose: add config.yml volume for configuration 2025-08-27 19:13:40 -04:00
Dockerfile chore(deps): update crystallang/crystal docker tag to v1.20.2 (#282) 2026-05-15 12:21:34 -04:00
flake.lock chore: update flake.nix and nix inputs 2026-03-27 14:43:54 -03:00
flake.nix feat: minify js files at build time 2026-04-17 02:04:47 -04:00
LICENSE 0.2.0 2024-07-31 18:25:30 -04:00
Makefile feat: minify js files at build time 2026-04-17 02:04:47 -04:00
patchy.service rename whole project to patchy 2025-05-26 01:07:37 -04:00
README-es.md update readme.md 2025-05-26 00:46:22 -04:00
README.md Update README.md 2026-03-02 17:16:11 -03:00
renovate.json chore: Configure Renovate (#20) 2025-05-24 19:04:24 -04:00
shard.lock chore: update crystal-lru dependency 2026-04-06 16:57:29 -04:00
shard.yml feat: use libmagic to detect mime types and encoding 2026-04-08 18:08:30 -04:00
shards.nix Add Nix flake! [skip ci] 2026-02-24 02:40:22 -03:00

Patchy

A temporary file uploader easy to host that I did to replace Uguu, which is not easy to host due to PHP.

Uses a low amount of memory, it works without JS, it can be used on other software like Chatterino2 and ShareX and it has other features that are listed bellow

There is an instance of this software running at patchy.moe

Why is called Patchy?

At first I wanted to call it "Patchouli", from Patchouli Knowledge, but there was already some projects that already used that name, probably because of the same reason as me (they like Touhou). So I went with Patchy, which is how Remi calls Patchouli.

So, why is called Patchy and how it's related to a file uploader service? Think about it, Patchy is a librarian, take the books as files, and Patchy as the software that manages them ;)

https://safebooru.org/index.php?page=post&s=view&id=905633

Screenshots

Javascript enabled

Javascript disabled

Features

  • Temporary file uploads like Uguu
  • File deletion link (not available on the noJS until I find a way)
  • Chatterino and ShareX support
  • Thumbnails for OpenGraph User-Agents (Requires ffmpeg to be installed, disabled by default)
  • File upload rate limits (based on the IP address)
  • Small Admin API that allows you to delete files, gather file information, see cached files on RAM and more (Needs to be enabled in the configuration)
  • Unix socket support if you don't want to deal with all the TCP overhead
  • Automatic protocol detection (HTTPS or HTTP)
  • Cache files on memory to reduce stress on the drive using LRU, more information on config.example.yml
  • Low memory usage: Between 6MB at idle and 40MB if a file is being uploaded or retrieved. It will depend of your traffic, if cache is enabled and if checksumming is enabled.
  • Experimental S3 bucket support (OpenGraph thumbnails are not available, tested using Minio)
  • Localization support (Only English and Spanish supported for now)
  • VPN blocking (Not really necessary, but still, it's a good addition) (In progress)

TODO

https://codeberg.org/Fijxu/patchy/issues/9

Docs

./docs

Repository mirrors

Patchy source code is currently hosted at:

How to host Patchy

Containers

Docker Compose / Podman Compose

  • Create a folder with the name you want
  • Download the docker-compose.yml file into the folder you created
  • If you are using docker, create the data folder using mkdir ./data && sudo chown -R 10000:10000 ./data
  • Run it using docker compose up if using docker or podman compose up if using Podman. If it works fine, then you can append the -d argument next to leave the container running on the background

Kubernetes

TODO

Native (Compiling it yourself)

  • Create a user for the uploader: sudo useradd -u 10000 patchy (you can replace the username with whatever you want)
  • Clone this repository on something like /opt/patchy
  • Install Crystal and compile the uploader using shards build --release
  • Change the settings file ./config/config.yml according to what you need.
  • Setup a systemd service to keep the uploader running. Copy patchy.service into /etc/systemd/system/patchy.service
  • Give permissions to the /opt/patchy folder to the user patchy using sudo chown -R 10000:10000 /opt/patchy
  • Start the uploader using sudo systemctl start patchy

Warning

This was not tested, if you have any issues with it, please open an issue!

NGINX Server block

Assuming you are already using NGINX and you know how to use it, you can use this example server block.

server {
  # You can keep the domain prefixed with `~.` if you want
  # to allow users to use any domain to upload and retrieve
  # files. Like xdxd.example.com or lolol.example.com
  # This will only work if you have a wildcard domain and certificate.
  server_name ~.example.com example.com;

  location / {
    proxy_pass http://127.0.0.1:8080;
    # This if you want to use a UNIX socket instead
    # proxy_pass http://unix:/tmp/patchy.sock;
    proxy_set_header X-Real-IP   $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Host  $host;
    proxy_pass_request_headers      on;
  }

  # This should be the size_limit value (from config.yml)
  client_max_body_size 512M;

  listen 443 ssl;
  http2 on;
}