add init command to ensure settings post migration

This commit is contained in:
Your Name 2023-08-20 04:27:23 +00:00 committed by Henri Dickson
parent 6de5335528
commit 4702b4feb3
14 changed files with 138 additions and 54 deletions

View file

@ -4,9 +4,17 @@
.vscode
.github
.git
.gitignore
.pre-commit-config.yaml
__pycache__
/Dockerfile
/doc
/docker-compose.yml
/media
/static
/docker-compose.yml
/Dockerfile
/test_data
/neodb
/neodb-takahe/doc
/neodb-takahe/docker
/neodb-takahe/static-collected
/neodb-takahe/takahe/local_settings.py

View file

@ -27,6 +27,7 @@ RUN --mount=type=cache,sharing=locked,target=/var/cache/apt-run apt-get update \
&& apt-get install -y --no-install-recommends libpq-dev \
busybox \
nginx \
gettext-base \
opencc
RUN busybox --install
@ -42,12 +43,12 @@ COPY --from=build /takahe/.venv .venv
RUN pwd && ls
RUN TAKAHE_DATABASE_SERVER="postgres://x@y/z" TAKAHE_SECRET_KEY="t" TAKAHE_MAIN_DOMAIN="x.y" .venv/bin/python3 manage.py collectstatic --noinput
COPY misc/nginx.conf.d/* /etc/nginx/conf.d/
WORKDIR /neodb
COPY misc/bin/* /bin/
RUN mkdir -p /www
RUN useradd -U app
RUN rm -rf /var/lib/apt/lists/*
WORKDIR /neodb
USER app:app
# invoke check by default

View file

@ -201,6 +201,10 @@ if os.getenv("NEODB_SSL", "") != "":
STATIC_URL = "/s/"
STATIC_ROOT = os.environ.get("NEODB_STATIC_ROOT", os.path.join(BASE_DIR, "static/"))
if DEBUG:
# django-sass-processor will generate neodb.css on-the-fly when DEBUG
# NEODB_STATIC_ROOT is readonly in docker mode, so we give it a writable place
SASS_PROCESSOR_ROOT = "/tmp"
STATICFILES_STORAGE = "django.contrib.staticfiles.storage.ManifestStaticFilesStorage"
STATICFILES_FINDERS = [
@ -338,42 +342,13 @@ REDIS_PORT = int(os.environ.get("NEODB_REDIS_PORT", 6379))
REDIS_DB = int(os.environ.get("NEODB_REDIS_DB", 0))
RQ_QUEUES = {
"mastodon": {
q: {
"HOST": REDIS_HOST,
"PORT": REDIS_PORT,
"DB": REDIS_DB,
"DEFAULT_TIMEOUT": -1,
},
"export": {
"HOST": REDIS_HOST,
"PORT": REDIS_PORT,
"DB": REDIS_DB,
"DEFAULT_TIMEOUT": -1,
},
"import": {
"HOST": REDIS_HOST,
"PORT": REDIS_PORT,
"DB": REDIS_DB,
"DEFAULT_TIMEOUT": -1,
},
"fetch": {
"HOST": REDIS_HOST,
"PORT": REDIS_PORT,
"DB": REDIS_DB,
"DEFAULT_TIMEOUT": -1,
},
"crawl": {
"HOST": REDIS_HOST,
"PORT": REDIS_PORT,
"DB": REDIS_DB,
"DEFAULT_TIMEOUT": -1,
},
"doufen": {
"HOST": REDIS_HOST,
"PORT": REDIS_PORT,
"DB": REDIS_DB,
"DEFAULT_TIMEOUT": -1,
},
}
for q in ["mastodon", "export", "import", "fetch", "crawl", "ap"]
}
RQ_SHOW_ADMIN_LINK = True

View file

@ -2,12 +2,14 @@ import logging
import types
from datetime import timedelta
from pprint import pprint
from time import sleep
import django_rq
import typesense
from django.conf import settings
from django.db.models.signals import post_delete, post_save
from django_redis import get_redis_connection
from loguru import logger
from rq.job import Job
from typesense.collection import Collection
from typesense.exceptions import ObjectNotFound
@ -51,9 +53,6 @@ SORTING_ATTRIBUTE = None
SEARCH_PAGE_SIZE = 20
logger = logging.getLogger(__name__)
_PENDING_INDEX_KEY = "pending_index_ids"
_PENDING_INDEX_QUEUE = "import"
_PENDING_INDEX_JOB_ID = "pending_index_flush"
@ -184,10 +183,30 @@ class Indexer:
@classmethod
def init(cls):
idx = typesense.Client(settings.TYPESENSE_CONNECTION).collections
try:
client = typesense.Client(settings.TYPESENSE_CONNECTION)
wait = 5
while not client.operations.is_healthy() and wait:
logger.warning("Typesense: server not healthy")
sleep(1)
wait -= 1
idx = client.collections[settings.TYPESENSE_INDEX_NAME]
if idx:
# idx.delete()
idx.create(cls.config())
try:
i = idx.retrieve()
logger.debug(
f"Typesense: index {settings.TYPESENSE_INDEX_NAME} has {i['num_documents']} documents"
)
return
except:
client.collections.create(cls.config())
logger.info(
f"Typesense: index {settings.TYPESENSE_INDEX_NAME} created"
)
return
logger.error("Typesense: server unknown error")
except Exception as e:
logger.error(f"Typesense: server error {e}")
@classmethod
def delete_index(cls):
@ -309,7 +328,7 @@ class Indexer:
try:
cls.instance().documents[pk].delete()
except Exception as e:
logger.warn(f"delete item error: \n{e}")
logger.warning(f"delete item error: \n{e}")
@classmethod
def search(cls, q, page=1, categories=None, tag=None, sort=None):

View file

@ -0,0 +1,19 @@
from django.core.management.base import BaseCommand
from catalog.search.typesense import Indexer
class Command(BaseCommand):
help = "Post-Migration Setup"
def handle(self, *args, **options):
# Update site name if changed
# Create/update admin user if configured in env
# Create basic emoji if not exists
# Create search index if not exists
Indexer.init()
# Register cron jobs if not yet

View file

@ -7,5 +7,6 @@ urlpatterns = [
path("", home),
path("home/", home, name="home"),
path("me/", me, name="me"),
path("nodeinfo/2.0/", nodeinfo2),
re_path("^~neodb~(?P<uri>.+)", ap_redirect),
]

View file

@ -1,8 +1,13 @@
from django.conf import settings
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.db import connection
from django.http import JsonResponse
from django.shortcuts import redirect, render
from django.urls import reverse
from users.models import User
@login_required
def me(request):
@ -26,6 +31,41 @@ def ap_redirect(request, uri):
return redirect(uri)
def nodeinfo2(request):
usage = {"users": {"total": User.objects.count()}}
# return estimated number of marks as posts, since count the whole table is slow
# TODO filter local with SQL function in https://wiki.postgresql.org/wiki/Count_estimate
with connection.cursor() as cursor:
cursor.execute(
"SELECT n_live_tup FROM pg_stat_all_tables WHERE relname = 'journal_shelfmember';"
)
row = cursor.fetchone()
if row:
usage["localPosts"] = row[0]
with connection.cursor() as cursor:
cursor.execute(
"SELECT n_live_tup FROM pg_stat_all_tables WHERE relname = 'journal_comment';"
)
row = cursor.fetchone()
if row:
usage["localComments"] = row[0]
return JsonResponse(
{
"version": "2.1",
"software": {
"name": "neodb",
"version": settings.NEODB_VERSION,
"repository": "https://github.com/neodb-social/neodb",
"homepage": "https://neodb.net/",
},
"protocols": ["activitypub", "neodb"],
"services": {"outbound": [], "inbound": []},
"usage": usage,
"metadata": {"nodeName": settings.SITE_INFO["site_name"]},
}
)
def error_400(request, exception=None):
return render(
request,

View file

@ -15,6 +15,10 @@ x-shared:
build: .
image: neodb/neodb:${TAG:-latest}
environment:
- NEODB_SITE_NAME
- NEODB_SITE_DOMAIN
- NEODB_DEBUG
- NEODB_SECRET_KEY
- NEODB_DB_NAME=neodb
- NEODB_DB_USER=neodb
- NEODB_DB_PASSWORD=aubergine
@ -29,6 +33,7 @@ x-shared:
- NEODB_TYPESENSE_KEY=eggplant
- NEODB_FROM_EMAIL=no-reply@${NEODB_SITE_DOMAIN}
- NEODB_MEDIA_ROOT=/www/m/
- NEODB_WEB_SERVER=neodb-web:8000
- TAKAHE_DB_NAME=takahe
- TAKAHE_DB_USER=takahe
- TAKAHE_DB_PASSWORD=aubergine
@ -46,6 +51,7 @@ x-shared:
- TAKAHE_STATOR_CONCURRENCY=4
- TAKAHE_STATOR_CONCURRENCY_PER_MODEL=2
- TAKAHE_DEBUG=${NEODB_DEBUG:-False}
- TAKAHE_WEB_SERVER=takahe-web:8000
restart: "on-failure"
volumes:
- ${NEODB_DATA:-../data}/neodb-media:/www/m
@ -110,7 +116,7 @@ services:
migration:
<<: *neodb-service
restart: "no"
command: "sh -c '/takahe/.venv/bin/python /takahe/manage.py migrate && /neodb/.venv/bin/python /neodb/manage.py migrate'"
command: /bin/neodb-init
depends_on:
neodb-db:
condition: service_healthy
@ -127,21 +133,21 @@ services:
# - "18000:8000"
command: /neodb/.venv/bin/gunicorn boofilsic.wsgi -w ${NEODB_WEB_WORKER_NUM:-8} --preload -b 0.0.0.0:8000
healthcheck:
test: ['CMD', 'wget', '-qO/tmp/test', 'http://127.0.0.1:8000/discover/']
test: ['CMD', 'wget', '-qO/tmp/test', 'http://127.0.0.1:8000/nodeinfo/2.0/']
depends_on:
migration:
condition: service_completed_successfully
neodb-worker:
<<: *neodb-service
command: /neodb/.venv/bin/python /neodb/manage.py rqworker --with-scheduler import export mastodon fetch crawl
command: /neodb/.venv/bin/python /neodb/manage.py rqworker --with-scheduler import export mastodon fetch crawl ap
depends_on:
migration:
condition: service_completed_successfully
neodb-worker-extra:
<<: *neodb-service
command: /neodb/.venv/bin/python /neodb/manage.py rqworker --with-scheduler fetch crawl
command: /neodb/.venv/bin/python /neodb/manage.py rqworker --with-scheduler fetch crawl ap
depends_on:
migration:
condition: service_completed_successfully
@ -167,7 +173,7 @@ services:
nginx:
<<: *neodb-service
user: "root:root"
command: nginx -g 'daemon off;'
command: nginx-start
depends_on:
takahe-web:
condition: service_started

View file

@ -3,7 +3,6 @@ from django.core.exceptions import BadRequest, ObjectDoesNotExist, PermissionDen
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from httpx import request
from catalog.models import *
from common.utils import (

10
misc/bin/neodb-init Executable file
View file

@ -0,0 +1,10 @@
#!/bin/sh
echo '\033[0;35m====== NeoDB ======\033[0m'
echo Initializing ${NEODB_SITE_NAME} on ${NEODB_SITE_DOMAIN}
[[ -z "${NEODB_DEBUG}" ]] || echo DEBUG is ON
[[ -z "${NEODB_DEBUG}" ]] || set
/takahe/.venv/bin/python /takahe/manage.py migrate || exit $?
/neodb/.venv/bin/python /neodb/manage.py migrate || exit $?
/neodb/.venv/bin/python /neodb/manage.py setup || exit $?

3
misc/bin/nginx-start Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
envsubst '${NEODB_WEB_SERVER} ${TAKAHE_WEB_SERVER}' < /neodb/misc/nginx.conf.d/neodb.conf > /etc/nginx/conf.d/neodb.conf
nginx -g 'daemon off;'

View file

@ -1,11 +1,11 @@
proxy_cache_path /www/cache levels=1:2 keys_zone=takahe:20m inactive=14d max_size=1g;
upstream neodb {
server neodb-web:8000;
server ${NEODB_WEB_SERVER};
}
upstream takahe {
server takahe-web:8000;
server ${TAKAHE_WEB_SERVER};
}
server {
@ -98,7 +98,7 @@ server {
proxy_cache_valid any 72h;
add_header X-Cache $upstream_cache_status;
}
location ~* ^/(@|\.well-known|actor|inbox|nodeinfo|api/v1|api/v2|auth|oauth|tags|settings|media|proxy|admin|djadmin) {
location ~* ^/(@|\.well-known|actor|inbox|api/v1|api/v2|auth|oauth|tags|settings|media|proxy|admin|djadmin) {
proxy_pass http://takahe;
}
location / {

@ -1 +1 @@
Subproject commit 4bf7dd6b6e6594fdfe2df4e9b3b5383d5aea7063
Subproject commit af8880f1b61556ae83e1f9970ba3ee6bbfa84292

View file

@ -21,3 +21,6 @@ NEODB_SITE_DOMAIN=example.site
# Turn on DEBUG mode, either set this to True or don't set it at all
# NEODB_DEBUG=True
# pull NeoDB Docker image from another tag/branch
# TAG=latest