Temporary file uploader.
  • Crystal 86.1%
  • JavaScript 5.3%
  • HTML 4.8%
  • CSS 2%
  • Nix 1.5%
  • Other 0.3%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Fijxu 45b0ac583d
All checks were successful
Run Ameba Linter and Crystal Formatter against Patchy source code / ameba-lint (push) Successful in 7s
Run Ameba Linter and Crystal Formatter against Patchy source code / test build - crystal: 1.18.2, stable: true (push) Successful in 1m31s
Run Ameba Linter and Crystal Formatter against Patchy source code / crystal-format (push) Successful in 18s
Build Patchy Contianer / build (push) Successful in 3m7s
Run Ameba Linter and Crystal Formatter against Patchy source code / test build - crystal: 1.19.2, stable: true (push) Successful in 1m3s
Run Ameba Linter and Crystal Formatter against Patchy source code / test build - crystal: 1.20.3, stable: true (push) Successful in 1m3s
Run Ameba Linter and Crystal Formatter against Patchy source code / test build - crystal: 1.21.1, stable: true (push) Successful in 56s
Run Ameba Linter and Crystal Formatter against Patchy source code / test build - crystal: nightly, stable: false (push) Successful in 1m6s
CI: add Github PAT for install-crystal action for build tests
2026-10-04 23:47:02 -03:00
.forgejo/workflows CI: add Github PAT for install-crystal action for build tests 2026-10-04 23:47:02 -03:00
.vscode Update .vscode/settings.json and .editorconfig 2026-03-02 17:33:53 -03:00
config feat: add user setting to get the file directly on upload 2026-09-27 20:00:57 -03:00
dist chore(deps): update crystallang/crystal docker tag to v1.21.1 (#296) 2026-09-27 18:44:03 -03:00
docs feat: use libmagic to detect mime types and encoding 2026-04-08 18:08:30 -04:00
locales feat: add user setting to get the file directly on upload 2026-09-27 20:00:57 -03:00
public/-/assets feat: Free the JavaScript used on Patchy #33 (#38) 2026-09-25 19:35:56 +02:00
screenshots update readme screenshot images 2025-09-30 17:32:30 -03:00
spec chore: remove unused spec file test.cr 2026-09-27 17:57:31 -03:00
src feat: add user setting to get the file directly on upload 2026-09-27 20:00:57 -03:00
.ameba.yml chore: Adhere to Ameba Linter Style conventions 2026-09-27 17:33:33 -03: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 git: update .gitignore adding .direnv directory 2026-07-14 02:05:43 -04:00
.pre-commit-config.yaml chore: improve pre-commit config 2026-09-27 18:02:18 -03: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 CI: also push to quay.io 2026-10-04 20:57:39 -03:00
flake.lock chore: update flakes 2026-09-25 14:36:38 -03:00
flake.nix chore+CI: add lint.yml file and configure Makefile with forgejo-runner to test the lint workflow 2026-09-27 18:27:08 -03:00
LICENSE 0.2.0 2024-07-31 18:25:30 -04:00
Makefile chore+CI: add lint.yml file and configure Makefile with forgejo-runner to test the lint workflow 2026-09-27 18:27:08 -03: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-ru.md Add Russian translation (#34) 2026-07-14 02:19:12 -04:00
README.md CI: also push to quay.io 2026-10-04 20:57:39 -03:00
renovate.json chore: Configure Renovate (#20) 2025-05-24 19:04:24 -04:00
shard.lock chore(deps): update all deps 2026-09-25 17:36:29 -03:00
shard.yml CI: Test Patchy against multiple crystal verisons 2026-10-04 23:44:46 -03: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

Patchy pushes to two containers registries, git.nadeko.net (this one of course) and quay.io. You can use whatever image registry you want to use.

  • git.nadeko.net/fijxu/patchy:latest
  • quay.io/fijxu/patchy:latest

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;
}