diff --git a/.vscode/launch.json b/.vscode/launch.json index dc96e081..3cad0bf0 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -20,7 +20,8 @@ "mode": "auto", "cwd":"${workspaceFolder}", "program": "${workspaceFolder}/cmd/gochan-migration/", - "showGlobalVariables": true + "showGlobalVariables": true, + "args": ["-updatedb"] } ] } \ No newline at end of file diff --git a/docker/Dockerfile b/docker/Dockerfile index 99709754..fdc48971 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.20-alpine3.19 +FROM golang:1.24-alpine WORKDIR /opt/gochan @@ -13,6 +13,9 @@ ENV DBHOST=${GOCHAN_DBHOST} COPY docker/build-image.sh . +RUN apk update && apk add --no-cache python3 nodejs npm +RUN npm --prefix frontend/ install +RUN ["python3", "build.py", "js"] RUN ["./build-image.sh"] CMD ["/opt/gochan/docker/startup.sh"] diff --git a/docker/gochan-docker.json b/docker/gochan-docker.json index 969f8cbc..718e06d2 100644 --- a/docker/gochan-docker.json +++ b/docker/gochan-docker.json @@ -98,18 +98,18 @@ } ], "MaxLineLength": 150, - "ReservedTrips": [ - "thischangesto##this", - "andthischangesto##this" - ], + "ReservedTrips": { + "thischangesto": "this", + "andthischangesto": "this" + }, "RepliesOnBoardPage": 3, "StickyRepliesOnBoardPage": 1, "NewThreadsRequireUpload": false, "CyclicalThreadNumPosts": 500, - "BanColors": [ - "admin:#0000A0", - "somemod:blue" - ], + "BanColors": { + "admin": "#0000A0", + "somemod": "blue" + }, "BanMessage": "USER WAS BANNED FOR THIS POST", "EmbedWidth": 200, "EmbedHeight": 164, diff --git a/go.mod b/go.mod index 237e624d..10295d41 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,7 @@ module github.com/gochan-org/gochan -go 1.22.2 +go 1.23.0 + toolchain go1.24.1 require ( diff --git a/note b/note new file mode 100644 index 00000000..3ae72767 --- /dev/null +++ b/note @@ -0,0 +1,366 @@ +USER gochanuser WITH PASSWORD 'TestDWPassord' + + +Теперь ты можешь использовать эту локальную копию Gochan для тестирования, изучения кода или разработки. + +Чтобы остановить контейнеры, вернись в терминал, где запущен docker compose up, и нажми Ctrl+C. + +Чтобы запустить снова (без пересборки, так как код теперь исправлен), используй команду: + +sudo docker compose -f docker/docker-compose-postgres.yml up +Use code with caution. +Bash +Если хочешь, чтобы контейнеры работали в фоновом режиме, используй: + +sudo docker compose -f docker/docker-compose-postgres.yml up -d +Use code with caution. +Bash +А для остановки фоновых контейнеров: + +sudo docker compose -f docker/docker-compose-postgres.yml down + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +ленных проблем и необходимых шагов (помимо стандартной установки Docker):** + +Проблема с файлом go.mod и старой версией Go в Dockerfile: + +Ошибка: Сборка Docker-образа падала с ошибками invalid go version '1.23.0' и unknown directive: toolchain. + +Причина: Dockerfile использовал старый образ golang:1.20-alpine, который несовместим с синтаксисом go.mod проекта. + +Исправление: В файле docker/Dockerfile заменили строку FROM golang:1.20-alpine3.19 на FROM golang:1.24-alpine. + +Проблема с отсутствием python3 для сборки фронтенда: + +Ошибка: При выполнении RUN ["python3", "build.py", "js"] в Dockerfile возникала ошибка "python3": executable file not found. + +Причина: В базовом образе golang:1.24-alpine нет Python 3 по умолчанию. + +Исправление: В docker/Dockerfile перед запуском build.py добавили установку Python: RUN apk update && apk add --no-cache python3 nodejs npm (добавили сразу и nodejs/npm). + +Проблема с отсутствием npm для сборки фронтенда: + +Ошибка: При выполнении RUN ["python3", "build.py", "js"] скрипт падал с ошибкой FileNotFoundError: [Errno 2] No such file or directory: 'npm'. + +Причина: Пакет nodejs в Alpine не всегда включает npm, или npm не попадал в PATH. + +Исправление: Явно добавили npm в команду установки: RUN apk update && apk add --no-cache python3 nodejs npm. + +Проблема с отсутствием зависимостей Node.js (webpack): + +Ошибка: При выполнении RUN ["python3", "build.py", "js"] скрипт падал с ошибкой sh: webpack: not found. + +Причина: Не были установлены зависимости Node.js, определенные в frontend/package.json. + +Исправление: В docker/Dockerfile перед запуском build.py js добавили команду установки зависимостей: RUN npm --prefix frontend/ install. + +Проблема с неправильным форматом полей в конфиге (docker/gochan-docker.json): + +Ошибка: Gochan падал при запуске с ошибкой invalid field type BoardConfig.PostConfig.ReservedTrips ... expected map[string]string, found array (и аналогично для BanColors). + +Причина: В файле docker/gochan-docker.json поля ReservedTrips и BanColors были в формате массива [], а код ожидал формат карты {}. + +Исправление: В файле docker/gochan-docker.json изменили формат этих полей: + +// Было: "ReservedTrips": ["key1:val1", "key2:val2"] +// Стало: +"ReservedTrips": { "key1": "val1", "key2": "val2" }, + +// Было: "BanColors": ["key1:val1", "key2:val2"] +// Стало: +"BanColors": { "key1": "val1", "key2": "val2" }, + + +(Ты исправил конкретные значения thischangesto и admin/somemod). + +Проблема с неправильными настройками БД в конфиге (docker/gochan-docker.json): + +Ошибка: Gochan пытался подключиться к sqlite3 или mysql/mariadb и падал с ошибкой аутентификации (Missing '_auth_user'). + +Причина: В файле docker/gochan-docker.json по умолчанию были прописаны DBtype: mysql и DBhost: gochan-mariadb:3306, а не настройки для PostgreSQL, используемые в docker-compose-postgres.yml. + +Исправление: В файле docker/gochan-docker.json в секции Database прописали корректные данные для PostgreSQL: + +"Database": { + "DBType": "postgres", + "DBHostname": "gochan-postgres", // Имя сервиса postgres из docker-compose + "DBPort": 5432, + "Username": "gochan", // Из environment postgres в docker-compose + "Password": "gochan", // Из environment postgres в docker-compose + "DatabaseName": "gochan", // Из environment postgres в docker-compose + "DBPrefix": "" +}, +IGNORE_WHEN_COPYING_START +content_copy +download +Use code with caution. +Json +IGNORE_WHEN_COPYING_END + +Проблема с некорректным SQL для PostgreSQL (сравнение boolean с integer): + +Ошибка: Gochan падал при запуске с ошибкой pq: operator does not exist: boolean = integer при попытке выполнить CREATE VIEW v_posts_cyclical_check. + +Причина: SQL-код для создания этого view сравнивал булевы поля (is_deleted, is_top_post, cyclical) с числами 0 и 1, что недопустимо в PostgreSQL. + +Исправление: В файле sql/reset_views.sql в определении CREATE VIEW DBPREFIXv_posts_cyclical_check заменили p.is_deleted = 0, d.is_top_post = 0, t.cyclical = 1 на p.is_deleted = FALSE, d.is_top_post = FALSE, t.cyclical = TRUE. + +Проблема с неправильным порядком DROP VIEW: + +Ошибка: Gochan падал при перезапуске с ошибкой pq: cannot drop view v_posts_to_delete because other objects depend on it. + +Причина: В файле sql/reset_views.sql команда DROP VIEW ... v_posts_to_delete выполнялась раньше, чем DROP VIEW ... v_posts_cyclical_check, который от нее зависит. + +Исправление: В файле sql/reset_views.sql поменяли местами эти две строки DROP VIEW. + +План развертывания на Droplet: + +Подготовь Droplet: Установи Docker и Docker Compose (как ты делал локально, см. Шаг 1 из инструкции по Docker). Добавь пользователя в группу docker. + +Скопируй проект: Перенеси всю папку gochan со всеми твоими исправлениями (docker/Dockerfile, docker/gochan-docker.json, sql/reset_views.sql) на Droplet (например, с помощью scp или git clone + применение твоих изменений). + +Создай папки для томов: На Droplet внутри папки проекта gochan создай папки, указанные в docker-compose-postgres.yml: + +mkdir -p ./volumes/gochan/log +mkdir -p ./volumes/gochan/www +mkdir -p ./volumes/postgres/data +# Установи правильные права, если Docker будет ругаться (редко нужно, но возможно) +# sudo chown -R : ./volumes # Может понадобиться, если Docker не может писать в папки +IGNORE_WHEN_COPYING_START +content_copy +download +Use code with caution. +Bash +IGNORE_WHEN_COPYING_END + +Запусти Docker Compose: Перейди в папку gochan на Droplet и выполни: + +sudo docker compose -f docker/docker-compose-postgres.yml up --build -d +IGNORE_WHEN_COPYING_START +content_copy +download +Use code with caution. +Bash +IGNORE_WHEN_COPYING_END + +(Флаг --build нужен для первой сборки на сервере, -d для запуска в фоне). + +Проверь логи: Убедись, что контейнеры запустились без ошибок: + +sudo docker compose -f docker/docker-compose-postgres.yml logs -f +IGNORE_WHEN_COPYING_START +content_copy +download +Use code with caution. +Bash +IGNORE_WHEN_COPYING_END + +(Нажми Ctrl+C, чтобы выйти из логов). + +Проверь доступность: Открой в браузере IP-адрес твоего Droplet (порт 80 должен быть открыт по умолчанию или в фаерволе). + +Выполни первоначальную настройку (admin/password и т.д.). + +Сообщение разработчикам (GitHub Issues): + +Стоит создать несколько отдельных Issues на GitHub проекта gochan-org/gochan для каждой группы проблем: + +Issue 1: Docker build fails due to outdated Go version and missing dependencies. + +Описать ошибки с go.mod, python3, npm, webpack. + +Предложить исправление: обновить версию Go в Dockerfile (до 1.24 или новее), добавить установку python3, nodejs, npm через apk, добавить шаг npm install перед build.py js. + +Issue 2: Default Docker configuration (gochan-docker.json) is incorrect. + +Указать, что дефолтный DBtype и DBhost не соответствуют docker-compose-postgres.yml. + +Указать, что формат ReservedTrips и BanColors использует устаревший синтаксис массива вместо карты (map). + +Предложить обновить gochan-docker.json до корректных значений и формата. + +Issue 3: SQL error in reset_views.sql for PostgreSQL. + +Указать на ошибку operator does not exist: boolean = integer при создании v_posts_cyclical_check. + +Предложить заменить 0/1 на FALSE/TRUE в WHERE условии. + +Указать на ошибку cannot drop view v_posts_to_delete because other objects depend on it при перезапуске. + +Предложить исправить порядок DROP VIEW для v_posts_cyclical_check и v_posts_to_delete. + +К каждому Issue приложи логи ошибок, которые ты получал, и код исправлений. Это очень поможет разработчикам! + +С этим списком ты готов и к развертыванию, и к созданию полезных баг-репортов! + + + + + + + + + + + + + + + + + + + + + + + + + +Ты абсолютно прав! Задокументировать все исправления — ключ к успешному развертыванию на Droplet и к тому, чтобы помочь разработчикам улучшить проект. + +Давай систематизируем все, что мы сделали, разбив на две части: + +**Часть 1: Инструкция по запуску Gochan на новом сервере (Droplet) с использованием Docker (с учетом наших исправлений)** + +1. **Подготовка сервера (Droplet):** + * Установи Docker: `sudo apt update && sudo apt install docker.io` + * Установи Docker Compose: `sudo apt install docker-compose-v2` (или `docker-compose-plugin`) + * Добавь своего пользователя в группу `docker`, чтобы не писать `sudo` (выйди и войди снова после этого): `sudo usermod -aG docker $USER` + * Установи Git: `sudo apt install git` + +2. **Клонирование репозитория:** + ```bash + git clone https://github.com/gochan-org/gochan.git + cd gochan + ``` + +3. **Применение исправлений к файлам (ВАЖНО: сделай это *перед* первым запуском `docker compose up --build`):** + + * **Исправь `docker/Dockerfile`:** + * Открой `docker/Dockerfile` для редактирования. + * Замени `FROM golang:1.20-alpine3.19` на `FROM golang:1.24-alpine`. + * Перед строкой `RUN ["./build-image.sh"]` добавь три новые строки: + ```dockerfile + # Устанавливаем Python 3, Node.js и npm + RUN apk update && apk add --no-cache python3 nodejs npm + + # Устанавливаем зависимости Node.js для фронтенда + RUN npm --prefix frontend/ install + + # Собираем фронтенд JS + RUN ["python3", "build.py", "js"] + ``` + * Сохрани файл. + + * **Исправь `docker/gochan-docker.json`:** + * Открой `docker/gochan-docker.json`. + * Найди секцию `"Database"` и приведи ее к виду (для PostgreSQL): + ```json + "Database": { + "DBType": "postgres", + "DBHostname": "gochan-postgres", + "DBPort": 5432, + "Username": "gochan", + "Password": "gochan", + "DatabaseName": "gochan", + "DBPrefix": "" + }, + ``` + * Найди поле `"ReservedTrips"` и замени его на: + ```json + "ReservedTrips": { + "thischangesto": "this", + "andthischangesto": "this" + }, + ``` + * Найди поле `"BanColors"` и замени его на: + ```json + "BanColors": { + "admin": "#0000A0", + "somemod": "blue" + }, + ``` + * Сохрани файл. + + * **Исправь `sql/reset_views.sql`:** + * Открой `sql/reset_views.sql`. + * Найди строку `WHERE p.is_deleted = 0 AND d.is_top_post = 0 and t.cyclical = 1;` внутри `CREATE VIEW DBPREFIXv_posts_cyclical_check` и замени `0` на `FALSE` и `1` на `TRUE`: + ```sql + WHERE p.is_deleted = FALSE AND d.is_top_post = FALSE and t.cyclical = TRUE; + ``` + * Найди строки `DROP VIEW` в начале файла и поменяй местами две строки, чтобы `DBPREFIXv_posts_cyclical_check` удалялась *перед* `DBPREFIXv_posts_to_delete`: + ```sql + -- Было: + -- DROP VIEW IF EXISTS DBPREFIXv_posts_to_delete; + -- DROP VIEW IF EXISTS DBPREFIXv_posts_cyclical_check; + + -- Стало: + DROP VIEW IF EXISTS DBPREFIXv_posts_cyclical_check; + DROP VIEW IF EXISTS DBPREFIXv_posts_to_delete; + ``` + * Сохрани файл. + +4. **Первый запуск и сборка:** + * Выполни из корневой папки проекта (`~/gochan`): + ```bash + docker compose -f docker/docker-compose-postgres.yml up --build + ``` + * Дождись завершения сборки и запуска контейнеров. Проверь, что в логах нет ошибок (последняя строка должна быть `SQL views reset`). + +5. **Проверка и настройка:** + * Открой браузер и перейди на IP-адрес твоего Droplet. + * Зайди в `/manage/staff` (admin/password), создай нового админа, удали старого. + +6. **Запуск в фоновом режиме (для постоянной работы):** + * Останови текущий запуск `Ctrl+C`. + * Запусти в фоновом режиме: + ```bash + docker compose -f docker/docker-compose-postgres.yml up -d + ``` + +7. **Данные:** Помни, что данные PostgreSQL будут храниться в папке `./volumes/postgres/data` на твоем Droplet, а загруженные файлы — в `./volumes/gochan/www`. Убедись, что у тебя есть бэкапы этих папок! + + + \ No newline at end of file diff --git a/sql/reset_views.sql b/sql/reset_views.sql index 31db9922..b9da4b79 100644 --- a/sql/reset_views.sql +++ b/sql/reset_views.sql @@ -7,8 +7,8 @@ DROP VIEW IF EXISTS DBPREFIXv_upload_info; DROP VIEW IF EXISTS DBPREFIXv_front_page_posts_with_file; DROP VIEW IF EXISTS DBPREFIXv_front_page_posts; DROP VIEW IF EXISTS DBPREFIXv_posts_to_delete_file_only; -DROP VIEW IF EXISTS DBPREFIXv_posts_to_delete; DROP VIEW IF EXISTS DBPREFIXv_posts_cyclical_check; +DROP VIEW IF EXISTS DBPREFIXv_posts_to_delete; DROP VIEW IF EXISTS DBPREFIXv_recent_posts; DROP VIEW IF EXISTS DBPREFIXv_building_posts; DROP VIEW IF EXISTS DBPREFIXv_top_post_thread_ids; @@ -61,7 +61,7 @@ SELECT post_id, d.thread_id, op_id, d.is_top_post, filename, dir FROM DBPREFIXv_posts_to_delete d INNER JOIN DBPREFIXposts p ON p.id = post_id INNER JOIN DBPREFIXthreads t ON d.thread_id = t.id -WHERE p.is_deleted = 0 AND d.is_top_post = 0 and t.cyclical = 1; +WHERE p.is_deleted = FALSE AND d.is_top_post = FALSE and t.cyclical = TRUE; CREATE VIEW DBPREFIXv_front_page_posts AS SELECT DBPREFIXposts.id, DBPREFIXposts.message_raw,