diff --git a/Dockerfile b/Dockerfile index ee548c1..5fa2601 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,6 @@ # pull official base image -FROM python:3.8-slim-buster +FROM python:3.8.14-slim +#FROM python:3.8-slim-buster # set environment variables ENV PYTHONDONTWRITEBYTECODE 1 @@ -50,7 +51,8 @@ RUN apt-get autoremove -y && \ RUN ln -s /home/data/www/db /db && \ ln -s /home/data/www/logs /logs && \ - ln -s /home/data/www/backups /backups + ln -s /home/data/www/backups /backups && \ + ln -s /home/data/www/conf /conf EXPOSE 80 diff --git a/README.md b/README.md index 58a63f5..c964844 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ docker pull xingsu1021/pthelper 仓库地址: https://hub.docker.com/repository/docker/xingsu1021/pthelper ``` -本地部署需要Python3.9+ +本地部署需要Python3.9+(如果cpu不支持avx则使用3.8) ```shell pip install --no-cache-dir -r requirements.txt -i https://pypi.mirrors.ustc.edu.cn/simple/ @@ -108,19 +108,48 @@ v2.0 签到截图 # docker-compose.yml +默认sqlite ```dockerfile version: '3.7' services: - flexget: - image: pthelper:v1.0 + pthelper: + image: pthelper:latest container_name: pthelper restart: always volumes: - - /home/data/docker-compose/pthelper/db:/db - - /home/data/docker-compose/pthelper/logs:/logs - - /home/data/docker-compose/pthelper/backups:/backups + - 你的目录:/db + - 你的目录:/logs + - 你的目录:/backups ports: - - "58000:80" + - "你的端口:80" +``` +Mysql需要修改config/env.prod中的mysql信息 +```dockerfile +version: '3.7' +services: + pthelper: + image: pthelper:latest + container_name: pthelper + restart: always + environment: + APP_ENV: prod + volumes: + - 你的目录:/db + - 你的目录:/logs + - 你的目录:/backups + - 你的目录:/conf + ports: + - "你的端口:80" +``` +```shell +APP_ENV: prod 指定使用env.prod配置文件 + +DATABASE_URL=mysql://root:123456@127.0.0.1:3306/pthelper?charset=utf8mb4&use_unicode=true&ssl_disabled=true +root 数据库用户名 +123456 数据库密码 +127.0.0.1 数据库地址 +3306 数据库端口 +pthelper 数据库名称 ``` ## 感谢 @@ -138,7 +167,7 @@ PTPP增强版:白大版PTPP@菩提蛋(没找到仓库:() # 本地启动测试命令 -python manage.py runserver --settings=pthelper.local_settings +APP_ENV=prod python manage.py runserver 0.0.0.0:80 # 编译镜像 diff --git a/conf/env.dev b/conf/env.dev new file mode 100644 index 0000000..6d89e15 --- /dev/null +++ b/conf/env.dev @@ -0,0 +1 @@ +DEBUG=True \ No newline at end of file diff --git a/conf/env.prod b/conf/env.prod new file mode 100644 index 0000000..b21c54d --- /dev/null +++ b/conf/env.prod @@ -0,0 +1,2 @@ +DEBUG=True +DATABASE_URL=mysql://root:123456@127.0.0.1:3306/pthelper?charset=utf8mb4&use_unicode=true&ssl_disabled=true \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 2c7ce5e..c89feeb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,12 +1,13 @@ version: '3.7' services: flexget: - image: pthelper:v1.0 + image: xingsu1021/pthelper:latest container_name: pthelper restart: always volumes: - 本地目录/db:/db - 本地目录/logs:/logs - 本地目录/backups:/backups + - 本地目录/conf:/conf ports: - - "58000:80" + - "本地端口:80" diff --git a/pthelper/local_settings.py b/pthelper/local_settings.py deleted file mode 100644 index 9654733..0000000 --- a/pthelper/local_settings.py +++ /dev/null @@ -1,266 +0,0 @@ -""" -Django settings for pthelper project. - -Generated by 'django-admin startproject' using Django 4.0.2. - -For more information on this file, see -https://docs.djangoproject.com/en/4.0/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/4.0/ref/settings/ -""" - -from pathlib import Path -import os -import sys -#使用pymysql代替mysqlclient -import pymysql -pymysql.install_as_MySQLdb() - -# Build paths inside the project like this: BASE_DIR / 'subdir'. -BASE_DIR = Path(__file__).resolve().parent.parent - - -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/ - -# SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'django-insecure-j2in)-m(_2f7#o059j-of8ao^s6j07d1w9rx1#cxeh#f2&)b_3' - -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True - -ALLOWED_HOSTS = ['*'] - -#自定义app目录的时候需要添加,以下两种方法都可以 -sys.path.insert(0,os.path.join(BASE_DIR, "apps")) -#sys.path.append(os.path.join(BASE_DIR, 'apps')) - -# Application definition - -INSTALLED_APPS = [ - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'rest_framework', - 'rest_framework.authtoken', - #'rest_framework_swagger', - 'django_filters', - 'django_apscheduler',#定时执行任务 - 'common', - 'login', - 'mymenu', - 'myauth', - 'index', - 'dashboard', - 'sites', - 'cron', #计划任务 - 'notify', #消息通知 - 'initdata', #数据初始化 -] - -AUTH_USER_MODEL = 'myauth.User' -#请求登录地址,默认/accounts/login/ -LOGIN_URL = '/login/' -#/accounts/profile/ -#LOGIN_REDIRECT_URL = '/myauth/user' - -MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - #'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', -] - -REST_FRAMEWORK = { - 'DEFAULT_AUTHENTICATION_CLASSES': ( - 'rest_framework.authentication.SessionAuthentication', - 'rest_framework.authentication.TokenAuthentication', - ), - 'DEFAULT_FILTER_BACKENDS': ( - 'django_filters.rest_framework.DjangoFilterBackend', - ) -} - -ROOT_URLCONF = 'pthelper.urls' - -TEMPLATES = [ - { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [os.path.join(BASE_DIR, 'templates'),], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', - #引入全局settings变量,方便模板直接引用 - 'apps.global_settings.get_global_settings', - ], - }, - }, -] - -WSGI_APPLICATION = 'pthelper.wsgi.application' - - -# Database -# https://docs.djangoproject.com/en/4.0/ref/settings/#databases - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.mysql', - #'ENGINE': 'mysql.connector.django', #使用mysql官方连接模块https://dev.mysql.com/downloads/connector/python/ - 'NAME': 'pthelper', - 'USER': 'root', - 'PASSWORD': '123456', - 'HOST': '127.0.0.1', - 'PORT': '3306', - 'CHARSET': 'utf8mb4', - 'COLLATION': 'utf8mb4_unicode_ci', - 'OPTIONS': {'sql_mode': 'TRADITIONAL', 'use_unicode': True, 'charset': 'utf8mb4'}, - #mysqlclient使用8.0(docker) - #'OPTIONS': {'sql_mode': 'TRADITIONAL', 'use_unicode': True, 'charset': 'utf8mb4', 'ssl_mode': 'DISABLED'}, - } -} - -# Password validation -# https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators - -AUTH_PASSWORD_VALIDATORS = [ - { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', - 'OPTIONS': { - 'min_length': 6, - } - }, - { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', - }, -] - - -# Internationalization -# https://docs.djangoproject.com/en/4.0/topics/i18n/ - -LANGUAGE_CODE = 'zh-hans' - -TIME_ZONE = 'Asia/Shanghai' - -USE_I18N = True - -USE_L10N = True - -USE_TZ = False - - -# Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/4.0/howto/static-files/ - -STATIC_URL = 'static/' - -STATICFILES_DIRS = ( - os.path.join(BASE_DIR, "static"), -) - -# Default primary key field type -# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field - -DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' - -#模板使用变量 -SITE_NAME = 'PT助手' -SITE_URL = 'https://www.baidu.com' -SITE_VERSION = 'Version 1.0.0' -SITE_COPYRIGHT = 'copyright © 2022' - -#https://docs.djangoproject.com/en/dev/ref/templates/builtins/#std:templatefilter-date -APSCHEDULER_DATETIME_FORMAT = "Y-m-d H:i:s" -APSCHEDULER_RUN_NOW_TIMEOUT = 25 # Seconds - -#临时目录 -TMP_LOG_DIR = os.path.join(BASE_DIR, "tmp") -if not os.path.exists(TMP_LOG_DIR): os.mkdir(TMP_LOG_DIR) - -BACKUP_DIR = os.path.join(BASE_DIR, 'backups') -if not os.path.exists(BACKUP_DIR): os.mkdir(BACKUP_DIR) - -#日志 -BASE_LOG_DIR = os.path.join(BASE_DIR, "logs") -if not os.path.exists(BASE_LOG_DIR): os.mkdir(BASE_LOG_DIR) -LOGGING = { - 'version': 1, # 保留字 - 'disable_existing_loggers': False, # 禁用已经存在的logger实例 - # 日志文件的格式 - 'formatters': { - # 详细的日志格式 - 'standard': { - 'format': '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d][%(levelname)s][%(message)s]' - }, - # 简单的日志格式 - 'simple': { - 'format': '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s' - }, - # 定义一个特殊的日志格式 - 'collect': { - 'format': '%(message)s' - } - }, - # 过滤器 - 'filters': { - 'require_debug_true': { - '()': 'django.utils.log.RequireDebugTrue', - }, - }, - # 处理器 - 'handlers': { - # 在终端打印 - 'console': { - 'level': 'DEBUG', - #'filters': ['require_debug_true'], # 只有在Django debug为True时才在屏幕打印日志 - 'class': 'logging.StreamHandler', # - 'formatter': 'simple' - }, - # 默认的 - 'default': { - 'level': 'INFO', - 'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,自动切 - 'filename': os.path.join(BASE_LOG_DIR, "info.log"), # 日志文件 - 'maxBytes': 1024 * 1024 * 50, # 日志大小 50M - 'backupCount': 3, # 最多备份几个 - 'formatter': 'standard', - 'encoding': 'utf-8', - }, - # 专门用来记错误日志 - 'error': { - 'level': 'ERROR', - 'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,自动切 - 'filename': os.path.join(BASE_LOG_DIR, "error.log"), # 日志文件 - 'maxBytes': 1024 * 1024 * 50, # 日志大小 50M - 'backupCount': 5, - 'formatter': 'standard', - 'encoding': 'utf-8', - }, - }, - 'loggers': { - # 默认的logger应用如下配置 - 'default': { - 'handlers': ['default', 'console', 'error'], # 上线之后可以把'console'移除 - 'level': 'DEBUG', - 'propagate': True, # 向不向更高级别的logger传递 - }, - }, -} \ No newline at end of file diff --git a/pthelper/settings.py b/pthelper/settings.py index c110001..27ea12f 100644 --- a/pthelper/settings.py +++ b/pthelper/settings.py @@ -13,19 +13,30 @@ https://docs.djangoproject.com/en/4.0/ref/settings/ from pathlib import Path import os import sys +# 引入environ +import environ +#使用pymysql代替mysqlclient +import pymysql +pymysql.install_as_MySQLdb() # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent +#BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +#读取环境变量 +env = environ.Env() +APP_ENV = env.str('APP_ENV', 'dev') -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/ +# 读取相对应的env文件 +env_file = 'env.%s' % APP_ENV +env = environ.Env() +env.read_env(env_file=os.path.join(BASE_DIR, 'conf', env_file)) # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'django-insecure-j2in)-m(_2f7#o059j-of8ao^s6j07d1w9rx1#cxeh#f2&)b_3' # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True +DEBUG = env.bool('DEBUG', True) ALLOWED_HOSTS = ['*'] @@ -118,11 +129,42 @@ WSGI_APPLICATION = 'pthelper.wsgi.application' # Database # https://docs.djangoproject.com/en/4.0/ref/settings/#databases +#数据库目录 +# DB_DIR = os.path.join(BASE_DIR, "db") +# if not os.path.exists(DB_DIR): os.mkdir(DB_DIR) +# DATABASES = { +# 'default': { +# 'ENGINE': 'django.db.backends.sqlite3', +# 'NAME': os.path.join(BASE_DIR,'db','pthelper.sqlite3'), +# } +# } +#mysql +#DATABASES = { + #'default': { + #'ENGINE': 'django.db.backends.mysql', + ##'ENGINE': 'mysql.connector.django', #使用mysql官方连接模块https://dev.mysql.com/downloads/connector/python/ + #'NAME': 'pthelper', + #'USER': 'root', + #'PASSWORD': '123456', + #'HOST': '127.0.0.1', + #'PORT': '3306', + #'CHARSET': 'utf8mb4', + #'COLLATION': 'utf8mb4_unicode_ci', + #'OPTIONS': {'sql_mode': 'TRADITIONAL', 'use_unicode': True, 'charset': 'utf8mb4'}, + ##mysqlclient使用8.0(docker) + ##'OPTIONS': {'sql_mode': 'TRADITIONAL', 'use_unicode': True, 'charset': 'utf8mb4', 'ssl_mode': 'DISABLED'}, + #} +#} +#使用环境变量模式,默认使用sqlite DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR,'db','pthelper.sqlite3'), - } + + # 默认读取os.environ['DATABASE_URL'],不存在则使用sqlite + 'default': env.db('DATABASE_URL', default="sqlite:///" + os.path.join(BASE_DIR,'db','pthelper.sqlite3')), + #'default': env.db(), + + # read os.environ['SQLITE_URL'] + #'extra': env.db('SQLITE_URL', default="sqlite:///" + os.path.join(BASE_DIR,'db','pthelper.sqlite3')) + } @@ -284,7 +326,7 @@ LOGGING = { 'propagate': True, # 向不向更高级别的logger传递 }, 'user': { #记录站点用户日志 - 'handlers': ['user'], + 'handlers': ['user', 'error'], 'level': 'INFO', 'propagate': True, # 向不向更高级别的logger传递 }, diff --git a/requirements.txt b/requirements.txt index 9923c24..33926ea 100644 --- a/requirements.txt +++ b/requirements.txt @@ -20,8 +20,8 @@ paddleocr transmission-rpc qbittorrent-api feedparser -#本地测试使用 -#PyMySQL >= 1.0.2 +PyMySQL >= 1.0.2 +django-environ #使用后台运行 #gunicorn diff --git a/start.sh b/start.sh index 713f23f..0ad8387 100644 --- a/start.sh +++ b/start.sh @@ -4,4 +4,8 @@ python3 manage.py migrate python3 manage.py runserver 0.0.0.0:80 -#/usr/sbin/unitd --no-daemon --control 0.0.0.0:60081 --user root --group root \ No newline at end of file +#/usr/sbin/unitd --no-daemon --control 0.0.0.0:60081 --user root --group root +#windows +#set APP_ENV=prod +#python3 manage.py migrate +#python3 manage.py runserver 0.0.0.0:80 \ No newline at end of file