commit a8af8d1b649f0e8d2e18cb74462efc8c8c341407 Author: gqt <3217233537@qq.com> Date: Sun Feb 8 12:40:31 2026 +0800 init: django project with CI pipeline diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml new file mode 100644 index 0000000..7862016 --- /dev/null +++ b/.gitea/workflows/ci.yml @@ -0,0 +1,28 @@ +name: Build and Push Docker Image + +on: + push: + branches: [main] + +jobs: + build: + runs-on: ubuntu-latest + container: + image: catthehacker/ubuntu:act-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Login to Gitea Registry + uses: docker/login-action@v3 + with: + registry: gitea.chatgqt.top + username: ${{ gitea.actor }} + password: ${{ secrets.REGISTRY_TOKEN }} + + - name: Build and Push + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: gitea.chatgqt.top/gqt/test-ci:latest diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d48e072 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +__pycache__/ +*.py[cod] +*.egg-info/ +db.sqlite3 +staticfiles/ +.env diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..b06099a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM python:3.11-slim + +WORKDIR /app + +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +COPY . . +RUN python manage.py collectstatic --noinput 2>/dev/null || true + +EXPOSE 8000 + +CMD ["gunicorn", "app.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "2"] diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/settings.py b/app/settings.py new file mode 100644 index 0000000..d6c5ba7 --- /dev/null +++ b/app/settings.py @@ -0,0 +1,25 @@ +import os +from pathlib import Path + +BASE_DIR = Path(__file__).resolve().parent.parent +SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY', 'dev-secret-key-change-in-production') +DEBUG = os.environ.get('DJANGO_DEBUG', 'False').lower() == 'true' +ALLOWED_HOSTS = os.environ.get('DJANGO_ALLOWED_HOSTS', '*').split(',') + +INSTALLED_APPS = [ + 'django.contrib.contenttypes', + 'django.contrib.staticfiles', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.middleware.common.CommonMiddleware', +] + +ROOT_URLCONF = 'app.urls' +WSGI_APPLICATION = 'app.wsgi.application' +LANGUAGE_CODE = 'zh-hans' +TIME_ZONE = 'Asia/Shanghai' +STATIC_URL = '/static/' +STATIC_ROOT = BASE_DIR / 'staticfiles' +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' diff --git a/app/urls.py b/app/urls.py new file mode 100644 index 0000000..f8b162c --- /dev/null +++ b/app/urls.py @@ -0,0 +1,13 @@ +from django.http import JsonResponse + +def health(request): + return JsonResponse({'status': 'ok'}) + +urlpatterns = [] + +# 使用简单的路由,避免引入 django.contrib.admin +from django.urls import path +urlpatterns = [ + path('', health), + path('health/', health), +] diff --git a/app/wsgi.py b/app/wsgi.py new file mode 100644 index 0000000..feb9165 --- /dev/null +++ b/app/wsgi.py @@ -0,0 +1,5 @@ +import os +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'app.settings') +application = get_wsgi_application() diff --git a/manage.py b/manage.py new file mode 100644 index 0000000..e5c5bc7 --- /dev/null +++ b/manage.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python +import os +import sys + +def main(): + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'app.settings') + from django.core.management import execute_from_command_line + execute_from_command_line(sys.argv) + +if __name__ == '__main__': + main() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..7568f40 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +django>=4.2,<5.0 +gunicorn>=21.2