| .forgejo/workflows | ||
| .vscode | ||
| config | ||
| docs | ||
| locales | ||
| public/-/assets | ||
| screenshots | ||
| spec | ||
| src | ||
| .ameba.yml | ||
| .editorconfig | ||
| .gitignore | ||
| .prettierrc | ||
| docker-compose.yml | ||
| Dockerfile | ||
| LICENSE | ||
| Makefile | ||
| patchy.service | ||
| README-es.md | ||
| README.md | ||
| renovate.json | ||
| shard.lock | ||
| shard.yml | ||
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 ;)
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
ffmpegto 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
Docs
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 upif using docker orpodman compose upif using Podman. If it works fine, then you can append the-dargument 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.ymlaccording 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/patchyfolder to the userpatchyusingsudo 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;
}

