mirror of https://github.com/openspug/spug
feat: add new docker-compose solution
parent
fdea7a6e4e
commit
af2d92d030
|
@ -1 +1,2 @@
|
||||||
/.idea/
|
.idea
|
||||||
|
.env
|
|
@ -0,0 +1,17 @@
|
||||||
|
VERSION=2.3.16
|
||||||
|
|
||||||
|
CONFIG_DIR=./config
|
||||||
|
VOLUME_DIR=./data
|
||||||
|
|
||||||
|
SECRET_KEY=CHANGE_SECRET_KEY
|
||||||
|
|
||||||
|
DB_HOST=mysql
|
||||||
|
DB_PORT=3306
|
||||||
|
DB_USER=spug
|
||||||
|
DB_PASSWORD=CHANGE_DB_PASSWORD
|
||||||
|
DB_NAME=spug
|
||||||
|
DB_ROOT_PASSWORD_USER=CHANGE_DB_ROOT_PASSWORD
|
||||||
|
|
||||||
|
REDIS_HOST=redis
|
||||||
|
REDIS_PORT=6379
|
||||||
|
REDIS_PASSWORD=CHANGE_REDIS_PASSWORD
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2021 Eason
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
|
@ -0,0 +1,25 @@
|
||||||
|
# [Spug Docker Compose](https://github.com/whatwewant/spug-docker-compose)
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
### Getting Started
|
||||||
|
* Solution 1: Automatically Startup
|
||||||
|
* Run `./start.sh`
|
||||||
|
* Solution 2: Manual Startup (RECOMMEND)
|
||||||
|
* Step 1
|
||||||
|
* Copy `.env.example` to `.env`, then update environments
|
||||||
|
* Step 2
|
||||||
|
* Run `docker-compose up`
|
||||||
|
|
||||||
|
### Version Histories
|
||||||
|
* v2.3.16
|
||||||
|
|
||||||
|
### FAQ
|
||||||
|
* How to build fast
|
||||||
|
* Use Docker Image instead of building in `docker-compose.yml`
|
||||||
|
* How to connect exist existing mysql/redis ?
|
||||||
|
* Just update your `.env`
|
||||||
|
|
||||||
|
### License
|
||||||
|
[MIT](./LICENSE)
|
|
@ -0,0 +1,80 @@
|
||||||
|
# Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug
|
||||||
|
# Copyright: (c) <spug.dev@gmail.com>
|
||||||
|
# Released under the AGPL-3.0 License.
|
||||||
|
|
||||||
|
# Git
|
||||||
|
FROM alpine/git:v2.30.1 as git
|
||||||
|
|
||||||
|
ARG VERSION=v2.3.16
|
||||||
|
|
||||||
|
WORKDIR /
|
||||||
|
|
||||||
|
RUN git clone https://github.com/openspug/spug.git --depth 1 -b ${VERSION} spug
|
||||||
|
|
||||||
|
|
||||||
|
# Build Front
|
||||||
|
FROM node:14-alpine as builder-front
|
||||||
|
|
||||||
|
COPY --from=git /spug /spug
|
||||||
|
|
||||||
|
WORKDIR /spug/spug_web/
|
||||||
|
|
||||||
|
RUN yarn
|
||||||
|
|
||||||
|
RUN yarn run build
|
||||||
|
|
||||||
|
|
||||||
|
# Build Backend
|
||||||
|
FROM python:3.9.4-alpine3.13 as builder
|
||||||
|
|
||||||
|
RUN echo -e "http://mirrors.aliyun.com/alpine/v3.13/main\nhttp://mirrors.aliyun.com/alpine/v3.13/community" > /etc/apk/repositories \
|
||||||
|
&& apk update
|
||||||
|
|
||||||
|
RUN pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/
|
||||||
|
|
||||||
|
RUN apk add --no-cache \
|
||||||
|
bash \
|
||||||
|
git \
|
||||||
|
nginx \
|
||||||
|
supervisor \
|
||||||
|
openssh-client \
|
||||||
|
openldap-dev \
|
||||||
|
mariadb-dev # mysql_config for python mysqlclient
|
||||||
|
|
||||||
|
RUN apk add --no-cache --virtual .build-deps \
|
||||||
|
gcc \
|
||||||
|
make \
|
||||||
|
musl-dev \
|
||||||
|
libressl-dev \
|
||||||
|
libffi-dev \
|
||||||
|
rust \
|
||||||
|
cargo # python cryptography
|
||||||
|
|
||||||
|
ADD spug.ini /etc/supervisor.d/spug.ini
|
||||||
|
ADD default.conf /etc/nginx/conf.d/default.conf
|
||||||
|
ADD entrypoint.sh /entrypoint.sh
|
||||||
|
ADD create_admin /usr/bin/create_admin
|
||||||
|
ADD delete_admin /usr/bin/delete_admin
|
||||||
|
ADD generate_secret_key /usr/bin/generate_secret_key
|
||||||
|
|
||||||
|
COPY --from=git /spug /spug
|
||||||
|
COPY --from=builder-front /spug/spug_web/build /var/www/build
|
||||||
|
|
||||||
|
WORKDIR /spug/spug_api/
|
||||||
|
|
||||||
|
RUN pip install -r requirements.txt
|
||||||
|
RUN pip install gunicorn mysqlclient
|
||||||
|
|
||||||
|
# Clean
|
||||||
|
# 1. Build Dependencies
|
||||||
|
RUN apk del .build-deps
|
||||||
|
# 2. Cargo
|
||||||
|
RUN rm -rf /root/.cargo
|
||||||
|
|
||||||
|
# PATCH
|
||||||
|
COPY patches/overrides.py /spug/spug_api/spug/overrides.py
|
||||||
|
COPY patches/user.py /spug/spug_api/apps/account/management/commands/user.py
|
||||||
|
# COPY patches/settings.py /spug/spug_api/spug/settings.py
|
||||||
|
|
||||||
|
|
||||||
|
ENTRYPOINT ["sh", "/entrypoint.sh"]
|
|
@ -0,0 +1,31 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
CMD="create_admin" #$0
|
||||||
|
USERNAME=$1
|
||||||
|
PASSWORD=$2
|
||||||
|
NICKNAME=${3:-ADMIN}
|
||||||
|
|
||||||
|
help() {
|
||||||
|
echo "How to:"
|
||||||
|
echo " $CMD YOUR_USERNAME YOUR_PASSWORD [YOUR_NICKNAME]"
|
||||||
|
echo ""
|
||||||
|
echo "Example:"
|
||||||
|
echo " $CMD admin spug.dev"
|
||||||
|
echo " $CMD admin spug.dev Zero"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "$1" = "" ] || [ "$2" = "" ]; then
|
||||||
|
echo "ERROR: username and password are required."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
help
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# @DEPRIATED `useradd` instead of `user add`
|
||||||
|
# python manage.py useradd -u admin -p spug.dev -s -n 管理员
|
||||||
|
#
|
||||||
|
#
|
||||||
|
python manage.py user add -u $USERNAME -p ${PASSWORD} -s -n ${NICKNAME}
|
|
@ -0,0 +1,28 @@
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name _; # 修改为自定义的访问域名
|
||||||
|
root /var/www/build/;
|
||||||
|
|
||||||
|
location ^~ /api/ {
|
||||||
|
rewrite ^/api(.*) $1 break;
|
||||||
|
|
||||||
|
proxy_pass http://127.0.0.1:9001;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /api/ws/ {
|
||||||
|
rewrite ^/api(.*) $1 break;
|
||||||
|
|
||||||
|
proxy_pass http://127.0.0.1:9002;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "Upgrade";
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
error_page 404 /index.html;
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
CMD="delete_admin" #$0
|
||||||
|
USERNAME=$1
|
||||||
|
|
||||||
|
help() {
|
||||||
|
echo "How to:"
|
||||||
|
echo " $CMD ADMIN_USERNAME"
|
||||||
|
echo ""
|
||||||
|
echo "Example:"
|
||||||
|
echo " $CMD admin"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "$1" = "" ]; then
|
||||||
|
echo "ERROR: username are required."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
help
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# @DEPRIATED `useradd` instead of `user add`
|
||||||
|
# python manage.py useradd -u admin -p spug.dev -s -n 管理员
|
||||||
|
#
|
||||||
|
#
|
||||||
|
python manage.py user del -u $USERNAME
|
|
@ -0,0 +1,25 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug
|
||||||
|
# Copyright: (c) <spug.dev@gmail.com>
|
||||||
|
# Released under the AGPL-3.0 License.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# init nginx
|
||||||
|
if [ ! -d /run/nginx ]; then
|
||||||
|
mkdir -p /run/nginx
|
||||||
|
chown -R nginx.nginx /run/nginx
|
||||||
|
fi
|
||||||
|
|
||||||
|
# @TODO BUG, this will run every startup,
|
||||||
|
# because /spug/spug_api/db.sqlite3 has never been generated.
|
||||||
|
# init spug
|
||||||
|
if [ ! -f /spug/spug_api/db.sqlite3 ]; then
|
||||||
|
cd /spug/spug_api
|
||||||
|
python manage.py initdb
|
||||||
|
# python manage.py useradd -u admin -p spug.dev -s -n 管理员
|
||||||
|
create_admin admin spug.dev
|
||||||
|
fi
|
||||||
|
|
||||||
|
nginx
|
||||||
|
supervisord -c /etc/supervisord.conf
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
openssl rand -base64 36
|
|
@ -0,0 +1,64 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
# Environment
|
||||||
|
MYSQL_CONFIG = {
|
||||||
|
"HOST": os.getenv('DB_HOST', '127.0.0.1'),
|
||||||
|
"PORT": os.getenv('DB_PORT', '3306'),
|
||||||
|
"USER": os.getenv('DB_USER', 'spug'),
|
||||||
|
"PASSWORD": os.getenv('DB_PASSWORD', 'spug.dev'),
|
||||||
|
"DATABASE": os.getenv('DB_DATABASE', 'spug'),
|
||||||
|
}
|
||||||
|
|
||||||
|
REDIS_CONFIG = {
|
||||||
|
"HOST": os.getenv('REDIS_HOST', '127.0.0.1'),
|
||||||
|
"PORT": os.getenv('REDIS_PORT', '6379'),
|
||||||
|
"PASSWORD": os.getenv('REDIS_PASSWORD', ''),
|
||||||
|
"DB0": os.getenv('REDIS_DATABASE_0', '0'),
|
||||||
|
"DB1": os.getenv('REDIS_DATABASE_1', '1'),
|
||||||
|
}
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
DEBUG = False
|
||||||
|
|
||||||
|
ALLOWED_HOSTS = ['127.0.0.1']
|
||||||
|
|
||||||
|
SECRET_KEY = os.getenv('SECRET_KEY', 'SHOULD_BE_OVERRODE')
|
||||||
|
|
||||||
|
DATABASES = {
|
||||||
|
'default': {
|
||||||
|
'ATOMIC_REQUESTS': True,
|
||||||
|
'ENGINE': 'django.db.backends.mysql',
|
||||||
|
'NAME': MYSQL_CONFIG['DATABASE'],
|
||||||
|
'USER': MYSQL_CONFIG['USER'],
|
||||||
|
'PASSWORD': MYSQL_CONFIG['PASSWORD'],
|
||||||
|
'HOST': MYSQL_CONFIG['HOST'],
|
||||||
|
'PORT': MYSQL_CONFIG['PORT'],
|
||||||
|
'OPTIONS': {
|
||||||
|
# 'unix_socket': '/var/lib/mysql/mysql.sock',
|
||||||
|
'charset': 'utf8mb4',
|
||||||
|
'sql_mode': 'STRICT_TRANS_TABLES',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CACHES = {
|
||||||
|
"default": {
|
||||||
|
"BACKEND": "django_redis.cache.RedisCache",
|
||||||
|
"LOCATION": "redis://" + REDIS_CONFIG['HOST'] + ":" + REDIS_CONFIG['PORT'] + "/" + REDIS_CONFIG['DB1'],
|
||||||
|
"OPTIONS": {
|
||||||
|
"CLIENT_CLASS": "django_redis.client.DefaultClient",
|
||||||
|
"PASSWORD": REDIS_CONFIG['PASSWORD'],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CHANNEL_LAYERS = {
|
||||||
|
"default": {
|
||||||
|
"BACKEND": "channels_redis.core.RedisChannelLayer",
|
||||||
|
"CONFIG": {
|
||||||
|
"hosts": [("redis://:" + REDIS_CONFIG['PASSWORD'] + "@" + REDIS_CONFIG['HOST'] + ":" + REDIS_CONFIG['PORT'] + "/" + REDIS_CONFIG['DB0'])],
|
||||||
|
"capacity": 1000,
|
||||||
|
"expiry": 120,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
|
@ -0,0 +1,141 @@
|
||||||
|
"""
|
||||||
|
# Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug
|
||||||
|
# Copyright: (c) <spug.dev@gmail.com>
|
||||||
|
# Released under the AGPL-3.0 License.
|
||||||
|
|
||||||
|
Django settings for spug project.
|
||||||
|
|
||||||
|
Generated by 'django-admin startproject' using Django 2.2.7.
|
||||||
|
|
||||||
|
For more information on this file, see
|
||||||
|
https://docs.djangoproject.com/en/2.2/topics/settings/
|
||||||
|
|
||||||
|
For the full list of settings and their values, see
|
||||||
|
https://docs.djangoproject.com/en/2.2/ref/settings/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||||
|
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
|
# Quick-start development settings - unsuitable for production
|
||||||
|
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
|
||||||
|
|
||||||
|
# SECURITY WARNING: keep the secret key used in production secret!
|
||||||
|
SECRET_KEY = 'vk0do47)egwzz!uk49%(y3s(fpx4+ha@ugt-hcv&%&d@hwr&p7'
|
||||||
|
|
||||||
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
|
DEBUG = True
|
||||||
|
|
||||||
|
ALLOWED_HOSTS = ['127.0.0.1']
|
||||||
|
|
||||||
|
# Application definition
|
||||||
|
|
||||||
|
INSTALLED_APPS = [
|
||||||
|
'channels',
|
||||||
|
'apps.account',
|
||||||
|
'apps.host',
|
||||||
|
'apps.setting',
|
||||||
|
'apps.exec',
|
||||||
|
'apps.schedule',
|
||||||
|
'apps.monitor',
|
||||||
|
'apps.alarm',
|
||||||
|
'apps.config',
|
||||||
|
'apps.app',
|
||||||
|
'apps.deploy',
|
||||||
|
'apps.notify',
|
||||||
|
]
|
||||||
|
|
||||||
|
MIDDLEWARE = [
|
||||||
|
'django.middleware.security.SecurityMiddleware',
|
||||||
|
'django.middleware.common.CommonMiddleware',
|
||||||
|
'libs.middleware.AuthenticationMiddleware',
|
||||||
|
'libs.middleware.HandleExceptionMiddleware',
|
||||||
|
]
|
||||||
|
|
||||||
|
ROOT_URLCONF = 'spug.urls'
|
||||||
|
|
||||||
|
WSGI_APPLICATION = 'spug.wsgi.application'
|
||||||
|
ASGI_APPLICATION = 'spug.routing.application'
|
||||||
|
|
||||||
|
# Database
|
||||||
|
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
|
||||||
|
|
||||||
|
DATABASES = {
|
||||||
|
'default': {
|
||||||
|
'ATOMIC_REQUESTS': True,
|
||||||
|
'ENGINE': 'django.db.backends.sqlite3',
|
||||||
|
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
REDIS_CONFIG = {
|
||||||
|
"HOST": os.getenv('REDIS_HOST') or '127.0.0.1',
|
||||||
|
"PORT": os.getenv('REDIS_PORT') or '6379',
|
||||||
|
"PASSWORD": os.getenv('REDIS_PASSWORD') or '',
|
||||||
|
"DB0": os.getenv('REDIS_DATABASE_0') or '0',
|
||||||
|
"DB1": os.getenv('REDIS_DATABASE_1') or '1',
|
||||||
|
}
|
||||||
|
|
||||||
|
CACHES = {
|
||||||
|
"default": {
|
||||||
|
"BACKEND": "django_redis.cache.RedisCache",
|
||||||
|
"LOCATION": "redis://" + REDIS_CONFIG['HOST'] + ":" + REDIS_CONFIG['PORT'] + "/" + REDIS_CONFIG['DB1'],
|
||||||
|
"OPTIONS": {
|
||||||
|
"CLIENT_CLASS": "django_redis.client.DefaultClient",
|
||||||
|
"PASSWORD": REDIS_CONFIG['PASSWORD'],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CHANNEL_LAYERS = {
|
||||||
|
"default": {
|
||||||
|
"BACKEND": "channels_redis.core.RedisChannelLayer",
|
||||||
|
"CONFIG": {
|
||||||
|
"hosts": [("redis://:" + REDIS_CONFIG['PASSWORD'] + "@" + REDIS_CONFIG['HOST'] + ":" + REDIS_CONFIG['PORT'] + "/" + REDIS_CONFIG['DB0'])],
|
||||||
|
"capacity": 1000,
|
||||||
|
"expiry": 120,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
TEMPLATES = [
|
||||||
|
{
|
||||||
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
|
'DIRS': [],
|
||||||
|
'APP_DIRS': False,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
SCHEDULE_KEY = 'spug:schedule'
|
||||||
|
MONITOR_KEY = 'spug:monitor'
|
||||||
|
REQUEST_KEY = 'spug:request'
|
||||||
|
REPOS_DIR = os.path.join(BASE_DIR, 'repos')
|
||||||
|
|
||||||
|
# Internationalization
|
||||||
|
# https://docs.djangoproject.com/en/2.2/topics/i18n/
|
||||||
|
|
||||||
|
LANGUAGE_CODE = 'en-us'
|
||||||
|
|
||||||
|
TIME_ZONE = 'Asia/Shanghai'
|
||||||
|
|
||||||
|
USE_I18N = True
|
||||||
|
|
||||||
|
USE_L10N = True
|
||||||
|
|
||||||
|
USE_TZ = True
|
||||||
|
|
||||||
|
AUTHENTICATION_EXCLUDES = (
|
||||||
|
'/account/login/',
|
||||||
|
re.compile('/apis/.*'),
|
||||||
|
)
|
||||||
|
|
||||||
|
SPUG_VERSION = 'v2.3.16'
|
||||||
|
|
||||||
|
# override default config
|
||||||
|
try:
|
||||||
|
from spug.overrides import *
|
||||||
|
except ImportError:
|
||||||
|
pass
|
|
@ -0,0 +1,100 @@
|
||||||
|
# Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug
|
||||||
|
# Copyright: (c) <spug.dev@gmail.com>
|
||||||
|
# Released under the AGPL-3.0 License.
|
||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
from django.core.cache import cache
|
||||||
|
from apps.account.models import User
|
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = '账户管理'
|
||||||
|
|
||||||
|
def add_arguments(self, parser):
|
||||||
|
parser.add_argument('action', type=str, help='执行动作')
|
||||||
|
parser.add_argument('-u', required=False, help='账户名称')
|
||||||
|
parser.add_argument('-p', required=False, help='账户密码')
|
||||||
|
parser.add_argument('-n', required=False, help='账户昵称')
|
||||||
|
parser.add_argument('-s', default=False, action='store_true', help='是否是超级用户(默认否)')
|
||||||
|
|
||||||
|
def echo_success(self, msg):
|
||||||
|
self.stdout.write(self.style.SUCCESS(msg))
|
||||||
|
|
||||||
|
def echo_error(self, msg):
|
||||||
|
self.stderr.write(self.style.ERROR(msg))
|
||||||
|
|
||||||
|
def print_help(self, *args):
|
||||||
|
message = '''
|
||||||
|
账户管理命令用法:
|
||||||
|
user add 创建账户,例如:user add -u admin -p 123 -n 管理员 -s
|
||||||
|
user del 删除账户,例如:user del -u admin
|
||||||
|
user reset 重置账户密码,例如:user reset -u admin -p 123
|
||||||
|
user enable 启用被禁用的账户,例如:user enable -u admin
|
||||||
|
user disable 禁用的账户,例如:user disable -u admin
|
||||||
|
'''
|
||||||
|
self.stdout.write(message)
|
||||||
|
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
action = options['action']
|
||||||
|
if action == 'add':
|
||||||
|
if not all((options['u'], options['p'], options['n'])):
|
||||||
|
self.echo_error('缺少参数')
|
||||||
|
self.print_help()
|
||||||
|
elif User.objects.filter(username=options['u'], deleted_by_id__isnull=True).exists():
|
||||||
|
self.echo_error(f'已存在登录名为【{options["u"]}】的用户')
|
||||||
|
else:
|
||||||
|
User.objects.create(
|
||||||
|
username=options['u'],
|
||||||
|
nickname=options['n'],
|
||||||
|
password_hash=User.make_password(options['p']),
|
||||||
|
is_supper=options['s'],
|
||||||
|
)
|
||||||
|
self.echo_success('创建用户成功')
|
||||||
|
elif action == 'del':
|
||||||
|
if not options['u']:
|
||||||
|
self.echo_error('缺少参数')
|
||||||
|
self.print_help()
|
||||||
|
|
||||||
|
user = User.objects.filter(username=options['u'], deleted_by_id__isnull=True).first()
|
||||||
|
if not user:
|
||||||
|
return self.echo_error(f'未找到登录名为【{options["u"]}】的账户')
|
||||||
|
|
||||||
|
user.delete()
|
||||||
|
cache.delete(user.username)
|
||||||
|
self.echo_success('账户已删除')
|
||||||
|
elif action == 'enable':
|
||||||
|
if not options['u']:
|
||||||
|
self.echo_error('缺少参数')
|
||||||
|
self.print_help()
|
||||||
|
user = User.objects.filter(username=options['u'], deleted_by_id__isnull=True).first()
|
||||||
|
if not user:
|
||||||
|
return self.echo_error(f'未找到登录名为【{options["u"]}】的账户')
|
||||||
|
user.is_active = True
|
||||||
|
user.save()
|
||||||
|
cache.delete(user.username)
|
||||||
|
self.echo_success('账户已启用')
|
||||||
|
elif action == 'disable':
|
||||||
|
if not options['u']:
|
||||||
|
self.echo_error('缺少参数')
|
||||||
|
self.print_help()
|
||||||
|
|
||||||
|
user = User.objects.filter(username=options['u'], deleted_by_id__isnull=True).first()
|
||||||
|
if not user:
|
||||||
|
return self.echo_error(f'未找到登录名为【{options["u"]}】的账户')
|
||||||
|
|
||||||
|
user.is_active = False
|
||||||
|
user.save()
|
||||||
|
cache.delete(user.username)
|
||||||
|
self.echo_success('账户已禁用')
|
||||||
|
elif action == 'reset':
|
||||||
|
if not all((options['u'], options['p'])):
|
||||||
|
self.echo_error('缺少参数')
|
||||||
|
self.print_help()
|
||||||
|
user = User.objects.filter(username=options['u'], deleted_by_id__isnull=True).first()
|
||||||
|
if not user:
|
||||||
|
return self.echo_error(f'未找到登录名为【{options["u"]}】的账户')
|
||||||
|
user.password_hash = User.make_password(options['p'])
|
||||||
|
user.save()
|
||||||
|
self.echo_success('账户密码已重置')
|
||||||
|
else:
|
||||||
|
self.echo_error('未识别的操作')
|
||||||
|
self.print_help()
|
|
@ -0,0 +1,40 @@
|
||||||
|
; # Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug
|
||||||
|
; # Copyright: (c) <spug.dev@gmail.com>
|
||||||
|
; # Released under the AGPL-3.0 License.
|
||||||
|
|
||||||
|
[supervisord]
|
||||||
|
nodaemon=true
|
||||||
|
|
||||||
|
; [program:redis]
|
||||||
|
; command = bash -c 'redis-server'
|
||||||
|
; autostart = true
|
||||||
|
|
||||||
|
[program:spug-api]
|
||||||
|
command = bash /spug/spug_api/tools/start-api.sh
|
||||||
|
autostart = true
|
||||||
|
stdout_logfile = /spug/spug_api/logs/api.log
|
||||||
|
redirect_stderr = true
|
||||||
|
|
||||||
|
[program:spug-ws]
|
||||||
|
command = bash /spug/spug_api/tools/start-ws.sh
|
||||||
|
autostart = true
|
||||||
|
stdout_logfile = /spug/spug_api/logs/ws.log
|
||||||
|
redirect_stderr = true
|
||||||
|
|
||||||
|
[program:spug-worker]
|
||||||
|
command = bash /spug/spug_api/tools/start-worker.sh
|
||||||
|
autostart = true
|
||||||
|
stdout_logfile = /spug/spug_api/logs/worker.log
|
||||||
|
redirect_stderr = true
|
||||||
|
|
||||||
|
[program:spug-monitor]
|
||||||
|
command = bash /spug/spug_api/tools/start-monitor.sh
|
||||||
|
autostart = true
|
||||||
|
stdout_logfile = /spug/spug_api/logs/monitor.log
|
||||||
|
redirect_stderr = true
|
||||||
|
|
||||||
|
[program:spug-scheduler]
|
||||||
|
command = bash /spug/spug_api/tools/start-scheduler.sh
|
||||||
|
autostart = true
|
||||||
|
stdout_logfile = /spug/spug_api/logs/scheduler.log
|
||||||
|
redirect_stderr = true
|
|
@ -0,0 +1,105 @@
|
||||||
|
[mysqld]
|
||||||
|
basedir = /usr/
|
||||||
|
datadir = /var/lib/mysql
|
||||||
|
pid-file = /var/run/mysqld/mysqld.pid
|
||||||
|
socket = /var/run/mysqld/mysqld.sock
|
||||||
|
port = 3306
|
||||||
|
user = mysql
|
||||||
|
|
||||||
|
log_error = /var/lib/mysql/mysql-error.log
|
||||||
|
slow-query-log-file = /var/lib/mysql/mysql-slow.log
|
||||||
|
log_bin = /var/lib/mysql/mysql-bin.log
|
||||||
|
relay-log = /var/lib/mysql/mysql-relay-bin
|
||||||
|
|
||||||
|
server-id = 1
|
||||||
|
#read_only = 1
|
||||||
|
innodb_buffer_pool_size = 1024M
|
||||||
|
innodb_log_buffer_size = 16M
|
||||||
|
#key_buffer_size = 64M
|
||||||
|
key_buffer_size = 128M
|
||||||
|
query_cache_size = 256M
|
||||||
|
tmp_table_size = 128M
|
||||||
|
|
||||||
|
#lower_case_table_names = 1
|
||||||
|
binlog_format = mixed
|
||||||
|
#binlog_format = statement
|
||||||
|
skip-external-locking
|
||||||
|
skip-name-resolve
|
||||||
|
character-set-server = utf8
|
||||||
|
collation-server = utf8_bin
|
||||||
|
#collation-server = utf8_general_ci
|
||||||
|
max_allowed_packet = 16M
|
||||||
|
thread_cache_size = 256
|
||||||
|
table_open_cache = 4096
|
||||||
|
back_log = 1024
|
||||||
|
max_connect_errors = 100000
|
||||||
|
#wait_timeout = 864000
|
||||||
|
|
||||||
|
interactive_timeout = 1800
|
||||||
|
wait_timeout = 1800
|
||||||
|
|
||||||
|
max_connections = 2048
|
||||||
|
sort_buffer_size = 16M
|
||||||
|
join_buffer_size = 4M
|
||||||
|
read_buffer_size = 4M
|
||||||
|
#read_rnd_buffer_size = 8M
|
||||||
|
read_rnd_buffer_size = 16M
|
||||||
|
binlog_cache_size = 2M
|
||||||
|
thread_stack = 192K
|
||||||
|
|
||||||
|
max_heap_table_size = 128M
|
||||||
|
myisam_sort_buffer_size = 128M
|
||||||
|
bulk_insert_buffer_size = 256M
|
||||||
|
open_files_limit = 65535
|
||||||
|
query_cache_limit = 2M
|
||||||
|
slow-query-log
|
||||||
|
long_query_time = 2
|
||||||
|
|
||||||
|
expire_logs_days = 3
|
||||||
|
max_binlog_size = 1000M
|
||||||
|
slave_parallel_workers = 4
|
||||||
|
log-slave-updates
|
||||||
|
#slave-skip-errors =1062,1053,1146,1032
|
||||||
|
|
||||||
|
binlog_ignore_db = mysql
|
||||||
|
replicate_wild_ignore_table = mysql.%
|
||||||
|
sync_binlog = 1
|
||||||
|
|
||||||
|
innodb_file_per_table = 1
|
||||||
|
innodb_flush_method = O_DIRECT
|
||||||
|
innodb_buffer_pool_instances = 4
|
||||||
|
innodb_log_file_size = 512M
|
||||||
|
innodb_log_files_in_group = 3
|
||||||
|
innodb_open_files = 4000
|
||||||
|
innodb_read_io_threads = 8
|
||||||
|
innodb_write_io_threads = 8
|
||||||
|
innodb_thread_concurrency = 8
|
||||||
|
innodb_io_capacity = 2000
|
||||||
|
innodb_io_capacity_max = 6000
|
||||||
|
innodb_lru_scan_depth = 2000
|
||||||
|
innodb_max_dirty_pages_pct = 85
|
||||||
|
innodb_flush_log_at_trx_commit = 2
|
||||||
|
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
|
||||||
|
|
||||||
|
|
||||||
|
[mysqldump]
|
||||||
|
quick
|
||||||
|
quote-names
|
||||||
|
max_allowed_packet = 16M
|
||||||
|
|
||||||
|
[client]
|
||||||
|
default-character-set = utf8
|
||||||
|
[mysql]
|
||||||
|
default-character-set = utf8
|
||||||
|
|
||||||
|
[isamchk]
|
||||||
|
key_buffer = 128M
|
||||||
|
sort_buffer_size = 4M
|
||||||
|
read_buffer = 2M
|
||||||
|
write_buffer = 2M
|
||||||
|
|
||||||
|
[myisamchk]
|
||||||
|
key_buffer = 128M
|
||||||
|
sort_buffer_size = 4M
|
||||||
|
read_buffer = 2M
|
||||||
|
write_buffer = 2M
|
|
@ -0,0 +1,65 @@
|
||||||
|
###
|
||||||
|
# 初始化: docker-compose exec spug create_admin
|
||||||
|
#
|
||||||
|
# ADMIN 用户名/密码:admin/spug.dev
|
||||||
|
#
|
||||||
|
# 注意: 从 v2.3.15 开始,默认创建 ADMIN 用户
|
||||||
|
# 关于管理员:
|
||||||
|
# 你可以使用自己创建或删除其他超级管理员用户
|
||||||
|
# 创建:docker-compose exec spug create_admin USERNAME PASSWORD
|
||||||
|
# 删除: docker-compose exec spug delete_admin USERNAME
|
||||||
|
#
|
||||||
|
# 关于 SECRET_KEY:
|
||||||
|
# 生成:docker-compose exec spug generate_secret_key
|
||||||
|
###
|
||||||
|
version: '3.4'
|
||||||
|
|
||||||
|
services:
|
||||||
|
spug:
|
||||||
|
restart: always
|
||||||
|
build:
|
||||||
|
context: ./build
|
||||||
|
# image: whatwewant/spug:${VERSION}
|
||||||
|
ports:
|
||||||
|
- 8080:80
|
||||||
|
environment:
|
||||||
|
SECRET_KEY: $SECRET_KEY
|
||||||
|
DB_HOST: $DB_HOST
|
||||||
|
DB_PORT: $DB_PORT
|
||||||
|
DB_USER: $DB_USER
|
||||||
|
DB_PASSWORD: $DB_PASSWORD
|
||||||
|
DB_NAME: $DB_NAME
|
||||||
|
REDIS_HOST: $REDIS_HOST
|
||||||
|
REDIS_PORT: $REDIS_PORT
|
||||||
|
REDIS_PASSWORD: $REDIS_PASSWORD
|
||||||
|
depends_on:
|
||||||
|
- mysql
|
||||||
|
- redis
|
||||||
|
networks:
|
||||||
|
- spug
|
||||||
|
|
||||||
|
mysql:
|
||||||
|
restart: always
|
||||||
|
image: mysql:5.7
|
||||||
|
environment:
|
||||||
|
# MYSQL_ROOT_HOST: '0.0.0.0'
|
||||||
|
MYSQL_ROOT_PASSWORD: $DB_ROOT_PASSWORD_USER
|
||||||
|
MYSQL_USER: $DB_USER
|
||||||
|
MYSQL_PASSWORD: $DB_PASSWORD
|
||||||
|
MYSQL_DATABASE: $DB_NAME
|
||||||
|
volumes:
|
||||||
|
- ${CONFIG_DIR}/mysql/my.cnf:/etc/mysql/my.cnf
|
||||||
|
- ${VOLUME_DIR}/mysql/lib:/var/lib/mysql
|
||||||
|
networks:
|
||||||
|
- spug
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:5-alpine
|
||||||
|
command: redis-server --requirepass ${REDIS_PASSWORD}
|
||||||
|
volumes:
|
||||||
|
- ${VOLUME_DIR}/redis:/data
|
||||||
|
networks:
|
||||||
|
- spug
|
||||||
|
|
||||||
|
networks:
|
||||||
|
spug:
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
cp .env.example .env
|
||||||
|
|
||||||
|
docker-compose up
|
Loading…
Reference in New Issue