diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..2649130 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,34 @@ +__pycache__ +*.pyc +*.pyo +*.pyd +.Python +*.so +*.egg +*.egg-info +dist +build +.git +.gitignore +.vscode +.idea +*.swp +*.swo +*~ +.DS_Store +db.sqlite3 +*.sqlite3 +.env +venv +env +ENV +.venv +staticfiles +media +*.log +.coverage +htmlcov +.pytest_cache +.mypy_cache +node_modules +postgres_data diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..3e74fdc --- /dev/null +++ b/Dockerfile @@ -0,0 +1,32 @@ +FROM python:3.11-slim + +ENV PYTHONUNBUFFERED=1 + +WORKDIR /app + +RUN apt-get update && apt-get install -y \ + postgresql-client \ + libpq-dev \ + gcc \ + libxml2-dev \ + libxslt1-dev \ + zlib1g-dev \ + git \ + netcat-openbsd \ + && rm -rf /var/lib/apt/lists/* + +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt +RUN pip install --no-cache-dir psycopg2-binary + +COPY . . + +RUN mkdir -p /app/static + +EXPOSE 8000 + +COPY docker-entrypoint.sh /docker-entrypoint.sh +RUN chmod +x /docker-entrypoint.sh + +ENTRYPOINT ["/docker-entrypoint.sh"] +CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] diff --git a/celerybeat-schedule b/celerybeat-schedule new file mode 100644 index 0000000..9e8fd74 Binary files /dev/null and b/celerybeat-schedule differ diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..becacdd --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,72 @@ +version: '3.8' + +services: + db: + image: postgres:15 + environment: + POSTGRES_DB: editgroups + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + volumes: + - postgres_data:/var/lib/postgresql/data + ports: + - "5432:5432" + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 5s + timeout: 5s + retries: 5 + + redis: + image: redis:7-alpine + ports: + - "6379:6379" + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 5s + timeout: 3s + retries: 5 + + web: + build: . + command: python manage.py runserver 0.0.0.0:8000 + volumes: + - .:/app + ports: + - "8000:8000" + environment: + - DJANGO_SETTINGS_MODULE=editgroups.settings.docker + - RUN_MIGRATIONS=true + depends_on: + db: + condition: service_healthy + redis: + condition: service_healthy + + celery: + build: . + command: celery -A editgroups worker -l info + volumes: + - .:/app + environment: + - DJANGO_SETTINGS_MODULE=editgroups.settings.docker + - C_FORCE_ROOT=true + depends_on: + - db + - redis + - web + + celery-beat: + build: . + command: celery -A editgroups beat -l info + volumes: + - .:/app + environment: + - DJANGO_SETTINGS_MODULE=editgroups.settings.docker + depends_on: + - db + - redis + - web + +volumes: + postgres_data: diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100755 index 0000000..ac512d0 --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +set -e + +echo "Waiting for PostgreSQL" +while ! nc -z db 5432; do + sleep 0.1 +done +echo "PostgreSQL started" + +if [ "$RUN_MIGRATIONS" = "true" ]; then + echo "Running migrations" + python manage.py migrate --noinput + + echo "Collecting static files" + python manage.py collectstatic --noinput + + echo "Creating superuser if it doesn't exist" + python manage.py shell -c " +from django.contrib.auth import get_user_model +User = get_user_model() +if not User.objects.filter(username='admin').exists(): + User.objects.create_superuser('admin', 'admin@example.com', 'admin') + print('Superuser created: admin/admin') +else: + print('Superuser already exists') +" || true +fi + +exec "$@" diff --git a/editgroups/settings/docker.py b/editgroups/settings/docker.py new file mode 100644 index 0000000..913c31a --- /dev/null +++ b/editgroups/settings/docker.py @@ -0,0 +1,34 @@ +import os +import sys +from types import ModuleType + +secret = ModuleType('editgroups.settings.secret') +secret.SECRET_KEY = '20oj&tj8uaruseitlrise,tries,uirsetur36746209etus7e' +secret.DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql_psycopg2', + 'NAME': 'editgroups', + 'USER': 'postgres', + 'PASSWORD': 'postgres', + 'HOST': 'db', + 'PORT': '5432', + 'DISABLE_SERVER_SIDE_CURSORS': False, + } +} +secret.SOCIAL_AUTH_MEDIAWIKI_KEY = 'your_mediawiki_key' +secret.SOCIAL_AUTH_MEDIAWIKI_SECRET = 'your_mediawiki_secret' +secret.SOCIAL_AUTH_MEDIAWIKI_URL = 'https://www.wikidata.org/w/index.php' +secret.SOCIAL_AUTH_MEDIAWIKI_CALLBACK = 'http://localhost:8000/oauth/complete/mediawiki/' +secret.REDIS_HOST = 'redis' +secret.REDIS_PORT = 6379 +secret.REDIS_DB = 0 +secret.REDIS_PASSWORD = '' +secret.REDIS_KEY_PREFIX = 'editgroups_' + +sys.modules['editgroups.settings.secret'] = secret + +from .common import * + +DEBUG = True +ALLOWED_HOSTS = ['*'] +BASE_DIR = os.path.dirname(os.path.dirname(__file__)) \ No newline at end of file diff --git a/editgroups/wsgi.py b/editgroups/wsgi.py index a709fb1..61d7e1a 120000 --- a/editgroups/wsgi.py +++ b/editgroups/wsgi.py @@ -1 +1,16 @@ -../app.py \ No newline at end of file +""" +WSGI config for editgroups project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "editgroups.settings") + +application = app = get_wsgi_application()