From 027c6c165c691fa3d80724a95c2eca1874d25e49 Mon Sep 17 00:00:00 2001 From: Georgiy Sitnikov Date: Fri, 2 Jan 2026 16:01:42 +0100 Subject: [PATCH 1/3] - Add configuration via Environment Variables support - Compose files update: - Add Environments with comments - Removed Default values from the arguments example - Readme minor update, markdown syntax and typos. --- Cargo.toml | 2 +- README.md | 58 +++++++++++++++++++++++++++++++++------------- docker-compose.yml | 39 ++++++++++++++++++++++++------- src/main.rs | 48 ++++++++++++++++++++++++++++++++------ 4 files changed, 115 insertions(+), 32 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b0886e8..79f403a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pastebin" -version = "0.1.3" +version = "0.1.4" authors = ["Kaczanowski Mateusz "] edition = "2018" diff --git a/README.md b/README.md index fe6fc53..a93a8f6 100644 --- a/README.md +++ b/README.md @@ -13,14 +13,17 @@ [github-workflow]: https://github.com/mkaczanowski/pastebin/workflows/Test%20and%20Build/badge.svg # Pastebin + Simple, fast, standalone pastebin service. ## Why? + Whenever you need to share a code snippet, diff, logs, or a secret with another human being, the Pastebin service is invaluable. However, using public services such as [pastebin.com](https://pastebin.com), [privnote.com](https://privnote.com), etc. should be avoided when you're sharing data that should be available only for a selected audience (i.e., your company, private network). Instead of trusting external providers, you could host your own Pastebin service and take ownership of all your data! **There are numerous [Pastebin implementations](https://github.com/awesome-selfhosted/awesome-selfhosted#pastebins) out there, why would you implement another one?** While the other implementations are great, I couldn't find one that would satisfy my requirements: + * no dependencies - one binary is all I want, no python libs, ruby runtime magic, no javascript or external databases to setup * storage - fast, lightweight, self-hosted key-value storage able to hold a lot of data. * speed - it must be fast. Once deployed in a mid-sized company you can expect high(er) traffic with low latency expectations from users @@ -28,15 +31,17 @@ While the other implementations are great, I couldn't find one that would satisf * cheap - low-cost service that would not steal too much CPU time, thus adding up to your bill * CLI + GUI - it must be easy to interface from both ends (but still, no deps!) * other features: - * on-demand encryption - * syntax highlighting - * destroy after reading - * destroy after expiration date + * on-demand encryption + * syntax highlighting + * destroy after reading + * destroy after expiration date This Pastebin implementation satisfies all of the above requirements! ## Implementation + This is a rust version of Pastebin service with [rocksdb](https://rocksdb.org/) database as storage. In addition to previously mentioned features it's worth to mention: + * all-in-one binary - all the data, including css/javascript files are compiled into the binary. This way you don't need to worry about external dependencies, it's all within. (see: [std::include_bytes](https://doc.rust-lang.org/std/macro.include_bytes.html)) * [REST endpoint](https://rocket.rs/) - you can add/delete pastes via standard HTTP client (ie. curl) * [RocksDB compaction filter](https://github.com/facebook/rocksdb/wiki/Compaction-Filter) - the expired pastes will be automatically removed by custom compaction filter @@ -45,46 +50,57 @@ This is a rust version of Pastebin service with [rocksdb](https://rocksdb.org/) * Encryption - password-protected pastes are AES encrypted/decprypted in the browser via [CryptoJS](https://code.google.com/archive/p/crypto-js/) ### Plugins + The default configuration enables only one plugin, this is syntax highlighting through `prism.js`. This should be enough for p90 of the users but if you need extra features you might want to use the plugin system (`src/plugins`). To enable additional plugins, pass: -``` + +```shell --plugins prism ``` Currently supported: + * [prism.js](https://prismjs.com/) * [mermaid.js](https://github.com/mermaid-js/mermaid) - ## Usage + Pastebin builds only with `rust-nightly` version and requires `llvm` compiler (rocksdb deps). To skip the build process, you can use the docker image. ### Cargo -``` + +```shell cargo build --release cargo run ``` + ### Docker + x86 image: -``` + +```shell docker pull mkaczanowski/pastebin:latest docker run --init --network host mkaczanowski/pastebin --address localhost --port 8000 ``` ARM images: -``` + +```shell docker pull mkaczanowski/pastebin:armv7 docker pull mkaczanowski/pastebin:armv8 ``` Compose setup: -``` + +```shell URI="http://localhost" docker-compose up curl -L "http://localhost" ``` + ### Client -``` + +```shell alias pastebin="curl -w '\n' -q -L --data-binary @- -o - http://localhost:8000/" echo "hello World" | pastebin @@ -92,8 +108,10 @@ http://localhost:8000/T9kGrI5aNkI4Z-PelmQ5U ``` ## Nginx (optional) + The Pastebin service serves `/static` files from memory. To lower down the load on the service you might want to consider setting up nginx with caching and compression enabled, as shown here: -``` + +```nginx map $sent_http_content_type $expires { default off; text/css 30d; @@ -119,17 +137,21 @@ server { ``` ## REST API + See [REST API doc](https://github.com/mkaczanowski/pastebin/blob/master/API.md) ## Benchmark -I used [k6.io](https://k6.io/) for benchmarking the read-by-id HTTP endoint. Details: + +I used [k6.io](https://k6.io/) for benchmarking the read-by-id HTTP endpoint. Details: + * CPU: Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz (4 CPUs, 8 threads = 16 rocket workers) * Mem: 24 GiB * Storage: NVMe SSD Controller SM981/PM981/PM983 * both client (k6) and server (pastebin) running on the same machine ### Setup -``` + +```shell $ cargo run --release $ echo "Hello world" | curl -q -L -d @- -o - http://localhost:8000/ @@ -147,7 +169,8 @@ $ docker pull loadimpact/k6 ``` ### Test 1: 5 concurrent clients, duration: 15s -``` + +```shell $ docker run --network=host -i loadimpact/k6 run --vus 5 -d 15s - , #[structopt( long = "tls-key", + env = "PASTEBIN_TLS_KEY", help = "Path to private key for tls-certs in PEM format" )] tls_key: Option, - #[structopt(long = "uri", help = "Override default URI")] + #[structopt( + long = "uri", + env = "PASTEBIN_URI", + help = "Override default URI" + )] uri: Option, #[structopt( long = "uri-prefix", + env = "PASTEBIN_URI_PREFIX", help = "Prefix appended to the URI (ie. '/pastebin')", default_value = "" )] @@ -272,26 +294,38 @@ struct PastebinConfig { #[structopt( long = "slug-charset", + env = "PASTEBIN_SLUG_CHARSET", help = "Character set (expressed as rust compatible regex) to use for generating the URL slug", default_value = "[A-Za-z0-9_-]" )] slug_charset: String, - #[structopt(long = "slug-len", help = "Length of URL slug", default_value = "21")] + #[structopt( + long = "slug-len", + env = "PASTEBIN_SLUG_LENGTH", + help = "Length of URL slug", + default_value = "21")] slug_len: usize, #[structopt( long = "ui-expiry-times", - help = "List of paste expiry times redered in the UI dropdown selector", + env = "PASTEBIN_UI_EXPIRY_TIMES", + help = "List of paste expiry times rendered in the UI dropdown selector", default_value = "5 minutes, 10 minutes, 1 hour, 1 day, 1 week, 1 month, 1 year, Never" )] ui_expiry_times: Vec, - #[structopt(long = "ui-line-numbers", help = "Display line numbers")] + #[structopt( + long = "ui-line-numbers", + env = "PASTEBIN_UI_LINE_NUMBERS", + help = "Display line numbers" + default_value = "true" + )] ui_line_numbers: bool, #[structopt( long = "plugins", + env = "PASTEBIN_PLUGINS", help = "Enable additional functionalities (ie. prism, mermaid)", default_value = "prism" )] From dfba7f73910c1e48f4a3d997b9981aa449155568 Mon Sep 17 00:00:00 2001 From: Georgiy Sitnikov Date: Fri, 2 Jan 2026 16:23:14 +0100 Subject: [PATCH 2/3] Add solution for #48 --- static/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/index.html b/static/index.html index 8a57071..c8a6d58 100644 --- a/static/index.html +++ b/static/index.html @@ -8,7 +8,7 @@ Pastebin - + {{#each css_imports as |url|}} From 6b461fd3b63af280d0765a9e5e15dd9190041a62 Mon Sep 17 00:00:00 2001 From: Georgiy Sitnikov Date: Fri, 2 Jan 2026 19:32:44 +0100 Subject: [PATCH 3/3] Correction --- src/main.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index fe5dd5e..050058b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -319,7 +319,6 @@ struct PastebinConfig { long = "ui-line-numbers", env = "PASTEBIN_UI_LINE_NUMBERS", help = "Display line numbers" - default_value = "true" )] ui_line_numbers: bool,