From af2d92d030bc486e93db57e65b97b19e85969506 Mon Sep 17 00:00:00 2001 From: Zero Date: Sat, 15 May 2021 21:27:14 +0800 Subject: [PATCH] feat: add new docker-compose solution --- .gitignore | 3 +- docker/.env.example | 17 ++++ docker/LICENSE | 21 +++++ docker/README.md | 25 ++++++ docker/build/Dockerfile | 80 +++++++++++++++++ docker/build/create_admin | 31 +++++++ docker/build/default.conf | 28 ++++++ docker/build/delete_admin | 28 ++++++ docker/build/entrypoint.sh | 25 ++++++ docker/build/generate_secret_key | 3 + docker/build/patches/overrides.py | 64 ++++++++++++++ docker/build/patches/settings.py | 141 ++++++++++++++++++++++++++++++ docker/build/patches/user.py | 100 +++++++++++++++++++++ docker/build/spug.ini | 40 +++++++++ docker/config/mysql/my.cnf | 105 ++++++++++++++++++++++ docker/docker-compose.yml | 65 ++++++++++++++ docker/start.sh | 5 ++ 17 files changed, 780 insertions(+), 1 deletion(-) create mode 100644 docker/.env.example create mode 100644 docker/LICENSE create mode 100644 docker/README.md create mode 100644 docker/build/Dockerfile create mode 100755 docker/build/create_admin create mode 100644 docker/build/default.conf create mode 100755 docker/build/delete_admin create mode 100644 docker/build/entrypoint.sh create mode 100644 docker/build/generate_secret_key create mode 100644 docker/build/patches/overrides.py create mode 100644 docker/build/patches/settings.py create mode 100644 docker/build/patches/user.py create mode 100644 docker/build/spug.ini create mode 100644 docker/config/mysql/my.cnf create mode 100644 docker/docker-compose.yml create mode 100755 docker/start.sh diff --git a/.gitignore b/.gitignore index 85e7c1d..3bf780b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -/.idea/ +.idea +.env \ No newline at end of file diff --git a/docker/.env.example b/docker/.env.example new file mode 100644 index 0000000..4848cbd --- /dev/null +++ b/docker/.env.example @@ -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 \ No newline at end of file diff --git a/docker/LICENSE b/docker/LICENSE new file mode 100644 index 0000000..808cb0a --- /dev/null +++ b/docker/LICENSE @@ -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. diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 0000000..2ea7d3a --- /dev/null +++ b/docker/README.md @@ -0,0 +1,25 @@ +# [Spug Docker Compose](https://github.com/whatwewant/spug-docker-compose) + +![https://hub.docker.com/repository/docker/whatwewant/spug](https://img.shields.io/docker/v/whatwewant/spug) +![](https://img.shields.io/badge/docker%20build-automated-066da5) + +### 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) \ No newline at end of file diff --git a/docker/build/Dockerfile b/docker/build/Dockerfile new file mode 100644 index 0000000..fa3f38a --- /dev/null +++ b/docker/build/Dockerfile @@ -0,0 +1,80 @@ +# Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug +# Copyright: (c) +# 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"] \ No newline at end of file diff --git a/docker/build/create_admin b/docker/build/create_admin new file mode 100755 index 0000000..a4c5ef0 --- /dev/null +++ b/docker/build/create_admin @@ -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} \ No newline at end of file diff --git a/docker/build/default.conf b/docker/build/default.conf new file mode 100644 index 0000000..1e336f3 --- /dev/null +++ b/docker/build/default.conf @@ -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; +} \ No newline at end of file diff --git a/docker/build/delete_admin b/docker/build/delete_admin new file mode 100755 index 0000000..1cb363e --- /dev/null +++ b/docker/build/delete_admin @@ -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 \ No newline at end of file diff --git a/docker/build/entrypoint.sh b/docker/build/entrypoint.sh new file mode 100644 index 0000000..ab47cf8 --- /dev/null +++ b/docker/build/entrypoint.sh @@ -0,0 +1,25 @@ +#!/bin/sh +# Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug +# Copyright: (c) +# 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 \ No newline at end of file diff --git a/docker/build/generate_secret_key b/docker/build/generate_secret_key new file mode 100644 index 0000000..4f68d25 --- /dev/null +++ b/docker/build/generate_secret_key @@ -0,0 +1,3 @@ +#!/bin/sh + +openssl rand -base64 36 \ No newline at end of file diff --git a/docker/build/patches/overrides.py b/docker/build/patches/overrides.py new file mode 100644 index 0000000..f279fd8 --- /dev/null +++ b/docker/build/patches/overrides.py @@ -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, + }, + }, +} diff --git a/docker/build/patches/settings.py b/docker/build/patches/settings.py new file mode 100644 index 0000000..f58c86f --- /dev/null +++ b/docker/build/patches/settings.py @@ -0,0 +1,141 @@ +""" +# Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug +# Copyright: (c) +# 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 \ No newline at end of file diff --git a/docker/build/patches/user.py b/docker/build/patches/user.py new file mode 100644 index 0000000..d4e2d72 --- /dev/null +++ b/docker/build/patches/user.py @@ -0,0 +1,100 @@ +# Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug +# Copyright: (c) +# 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() \ No newline at end of file diff --git a/docker/build/spug.ini b/docker/build/spug.ini new file mode 100644 index 0000000..bcefbc5 --- /dev/null +++ b/docker/build/spug.ini @@ -0,0 +1,40 @@ +; # Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug +; # Copyright: (c) +; # 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 \ No newline at end of file diff --git a/docker/config/mysql/my.cnf b/docker/config/mysql/my.cnf new file mode 100644 index 0000000..fcd3b5f --- /dev/null +++ b/docker/config/mysql/my.cnf @@ -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 diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..ab67782 --- /dev/null +++ b/docker/docker-compose.yml @@ -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: \ No newline at end of file diff --git a/docker/start.sh b/docker/start.sh new file mode 100755 index 0000000..aa5211e --- /dev/null +++ b/docker/start.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +cp .env.example .env + +docker-compose up