--- title: "Pasty: Selfhosted pastebin сервис" date: 2022-09-15T11:01:12+03:00 draft: true tags: [tutorial] --- ## Введение pasty - это Pastebin сервис. > Pastebin или nopaste — веб-приложение, которое позволяет загружать отрывки текста, > обычно фрагменты исходного кода, для возможности просмотра окружающими. (c) [Wikipedia](https://ru.wikipedia.org/wiki/Pastebin) Адрес сервиса: [pasty.lus.pm](https://pasty.lus.pm/). Преимущества этого проекта (как и почти всех остальных) это открытый исходный код, что позволяет развернуть сервис на своём сервере. ## Selfhosting ### Сборка Исходный код досупен на [GitHub](https://github.com/lus/pasty), а также на моём [зеркале](https://git.a2s.su/mirror/pasty) Gitea. В первую очередь `pasty` необходимо собрать из исходного кода, потому что автор не размещает бинарные сборки. Проекты на [Go](https://go.dev/) собираются без каких-либо проблем. ```sh git clone https://github.com/lus/pasty cd pasty/ go build -o pasty ./cmd/pasty/main.go ``` После завершения операции, в текущей директории появится файл исполняемый `pasty`. ### Настройка Pasty конфигурируется через файл `.env`, размещённый в тойже директории, где расположен исполняемый файл. Pasty поддерживает несколько типов хранения данных, который определяется параметром `PASTY_STORAGE_TYPE`. **Список поддерживаемых типов хранения данных:** * [file](https://github.com/lus/pasty#file-file) * [postgres](https://github.com/lus/pasty#postgresql-postgres) * [mongodb](https://github.com/lus/pasty#mongodb-mongodb) * [s3](https://github.com/lus/pasty#s3-s3) Для каждого из типа хранения присутсуют свои особеннные настройки, которые можно посмотреть перейдя по ссылке из списка типов выше. Я буду использовать тип `file`, для чего мне необходимо добавить второй параметр в настройки `PASTY_STORAGE_FILE_PATH`. Значение по умолчанию `./data`. **Если ты запускаешь исполняемый файл из сторонней директории, необходимо ещё скопировать каталог `web` из исходников.** Я допустим создал отдельную директорию `$HOME/Sites/Pasty/`, настроил в `.env` запуск по адресу **localhost:3004** (`PASTY_WEB_ADDRESS=localhost:3004`), а в [Nginx]() настроил `location` с `proxy_pass`. ```nginx location /pastebin/ { proxy_pass http://localhost:3004; } ``` ### Глубокая настройка ... заключается в изменении всех остальных параметров, список которых можно посмотреть в файле README.md или на странице проекта на GitHub [pasty#general-environment-variables](https://github.com/lus/pasty#general-environment-variables). ## Использование pasty не на отдельном домене Если захочется использовать pasty не на отдельном домене/поддомене, например **pastebin.example.com**, а например как я, по пути **iiiypuk.me/pastebin/**, ничего работать не будет. Получим ошибку ```text Failed loading API information: 404 Not Found ``` В первую очередь, необходимо исправить константу `API_BASE_URL` в файле `/web/assets/js/modules/api.js`. Это первая строка. ```javascript const API_BASE_URL = location.protocol + "//" + location.host + "/api/v2"; ``` ```javascript const API_BASE_URL = location.protocol + "//" + location.host + "/pastebin" + "/api/v2"; ``` Однако опять ничего не заработает, будет ошибка ```text Could not load paste: paste not found ``` А всё потому, что часть `/pastebin/` в адресе сервис распознаёт, как ID. ```text api.js:8 GET https://iiiypuk.me/pastebin/api/v2/pastes/pastebin 404 (Not Found) ``` Вот код, в котором якобы происходит ошибка. ```javascript export async function getPaste(pasteID) { return fetch(API_BASE_URL + "/pastes/" + pasteID); } ``` Следующий файл, который необходимо исправить `/web/assets/js/modules/state.js`. В этом куске кода изменяем первую строку: ```javascript if (location.pathname !== "/") { // Extract the paste data (ID and language) const split = location.pathname.replace("/", "").split("."); const pasteID = split[0]; const language = split[1]; ``` На это: ```javascript if (location.pathname !== "/pastebin/") { ``` Всё, теперь с главной страницы не редиректит. Но при сохранении, в редирект не подставляется `/pastebin/`. Эта часть кода овечает, за редирект на главную, если pasteID отсутсвует в базе. ```javascript // Try to retrieve the paste data from the API const response = await API.getPaste(pasteID); if (!response.ok) { Notifications.error("Could not load paste: " + await response.text() + ""); setTimeout(() => location.replace(location.protocol + "//" + location.host), 3000); return; } ``` Исправляем пятую строку на: ```javascript setTimeout(() => location.replace(location.protocol + "//" + location.host + "/pastebin/"), 3000); ``` По сути во все куски кода с `location.protocol + "//" + location.host` необходимо добавить `/pastebin/`. ```javascript // Redirect the user to his newly created paste location.replace(location.protocol + "//" + location.host + "/" + data.id + (key ? "#" + key : "")); ``` ```javascript // Redirect the user to his newly created paste location.replace(location.protocol + "//" + location.host + "/pastebin/" + data.id + (key ? "#" + key : "")); ``` ## Мой инстанс Мой pasty доступен по адресу `TODO: add links`