From ecfca080f015cc66b454d68a0a60c3716cc1bb29 Mon Sep 17 00:00:00 2001 From: stackia Date: Mon, 16 Mar 2020 21:45:13 +0800 Subject: [PATCH 1/2] =?UTF-8?q?build:=20=E5=B0=86=E8=AF=B8=E5=A4=9A?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E9=A1=B9=E5=8F=98=E4=B8=BA=E4=BB=8E=E7=8E=AF?= =?UTF-8?q?=E5=A2=83=E5=8F=98=E9=87=8F=E8=AF=BB=E5=8F=96=EF=BC=8C=E4=BE=BF?= =?UTF-8?q?=E4=BA=8E=E5=90=8E=E7=BB=AD=E6=94=AF=E6=8C=81=20Docker?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DJANGO_DEBUG DJANGO_SECRET_KEY DJANGO_MYSQL_DATABASE DJANGO_MYSQL_USER DJANGO_MYSQL_PASSWORD DJANGO_MYSQL_HOST DJANGO_MYSQL_PORT DJANGO_MEMCACHED_ENABLE DJANGO_MEMCACHED_LOCATION DJANGO_BAIDU_NOTIFY_URL DJANGO_EMAIL_TLS DJANGO_EMAIL_SSL DJANGO_EMAIL_HOST DJANGO_EMAIL_PORT DJANGO_EMAIL_USER DJANGO_EMAIL_PASSWORD DJANGO_ADMIN_EMAIL DJANGO_WXADMIN_PASSWORD DJANGO_WEROBOT_TOKEN --- .gitignore | 2 + DjangoBlog/settings.py | 48 +++++++++++++----------- docker-support/dev-environment-setup.yml | 21 +++++++++++ servermanager/robot.py | 2 +- 4 files changed, 50 insertions(+), 23 deletions(-) create mode 100644 docker-support/dev-environment-setup.yml diff --git a/.gitignore b/.gitignore index 9aa5e14..b507a4a 100644 --- a/.gitignore +++ b/.gitignore @@ -63,6 +63,8 @@ target/ .idea .iml +# virtualenv +venv/ migrations/ !migrations/__init__.py diff --git a/DjangoBlog/settings.py b/DjangoBlog/settings.py index 6d2decd..d8339bc 100644 --- a/DjangoBlog/settings.py +++ b/DjangoBlog/settings.py @@ -12,17 +12,23 @@ https://docs.djangoproject.com/en/1.10/ref/settings/ import sys import os + +def env_to_bool(env, default): + str_val = os.environ.get(env) + return default if str_val is None else str_val == 'True' + + # 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/1.10/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'n9ceqv38)#&mwuat@(mjb_p%em$e8$qyr#fw9ot!=ba6lijx-6' - +SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY') or 'n9ceqv38)#&mwuat@(mjb_p%em$e8$qyr#fw9ot!=ba6lijx-6' # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True +DEBUG = env_to_bool('DJANGO_DEBUG', True) # DEBUG = False TESTING = len(sys.argv) > 1 and sys.argv[1] == 'test' @@ -98,11 +104,11 @@ WSGI_APPLICATION = 'DjangoBlog.wsgi.application' DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', - 'NAME': 'djangoblog', - 'USER': os.environ.get('DJANGO_MYSQL_USER'), - 'PASSWORD': os.environ.get('DJANGO_MYSQL_PASSWORD'), - 'HOST': os.environ.get('DJANGO_MYSQL_HOST'), - 'PORT': 3306, + 'NAME': os.environ.get('DJANGO_MYSQL_DATABASE') or 'djangoblog', + 'USER': os.environ.get('DJANGO_MYSQL_USER') or 'root', + 'PASSWORD': os.environ.get('DJANGO_MYSQL_PASSWORD') or 'djangoblog_123', + 'HOST': os.environ.get('DJANGO_MYSQL_HOST') or '127.0.0.1', + 'PORT': int(os.environ.get('DJANGO_MYSQL_PORT') or 3306), 'OPTIONS': {'charset': 'utf8mb4'}, } } @@ -177,11 +183,10 @@ CACHE_CONTROL_MAX_AGE = 2592000 CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', - 'LOCATION': '127.0.0.1:11211', + 'LOCATION': os.environ.get('DJANGO_MEMCACHED_LOCATION') or '127.0.0.1:11211', 'KEY_PREFIX': 'django_test' if TESTING else 'djangoblog', 'TIMEOUT': 60 * 60 * 10 - }, - 'locmemcache': { + } if env_to_bool('DJANGO_MEMCACHED_ENABLE', True) else { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 'TIMEOUT': 10800, 'LOCATION': 'unique-snowflake', @@ -189,24 +194,23 @@ CACHES = { } SITE_ID = 1 -BAIDU_NOTIFY_URL = "http://data.zz.baidu.com/urls?site=https://www.lylinux.net&token=1uAOGrMsUm5syDGn" +BAIDU_NOTIFY_URL = os.environ.get('DJANGO_BAIDU_NOTIFY_URL') \ + or 'http://data.zz.baidu.com/urls?site=https://www.lylinux.net&token=1uAOGrMsUm5syDGn' -# Emial: +# Email: EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' - -# EMAIL_USE_TLS = True -EMAIL_USE_SSL = True - -EMAIL_HOST = 'smtp.mxhichina.com' -EMAIL_PORT = 465 +EMAIL_USE_TLS = env_to_bool('DJANGO_EMAIL_TLS', False) +EMAIL_USE_SSL = env_to_bool('DJANGO_EMAIL_SSL', True) +EMAIL_HOST = os.environ.get('DJANGO_EMAIL_HOST') or 'smtp.mxhichina.com' +EMAIL_PORT = int(os.environ.get('DJANGO_EMAIL_PORT') or 465) EMAIL_HOST_USER = os.environ.get('DJANGO_EMAIL_USER') EMAIL_HOST_PASSWORD = os.environ.get('DJANGO_EMAIL_PASSWORD') DEFAULT_FROM_EMAIL = EMAIL_HOST_USER -SERVER_EMAIL = os.environ.get('DJANGO_EMAIL_USER') +SERVER_EMAIL = EMAIL_HOST_USER # Setting debug=false did NOT handle except email notifications -ADMINS = [('admin', 'admin@admin.com')] +ADMINS = [('admin', os.environ.get('DJANGO_ADMIN_EMAIL') or 'admin@admin.com')] # WX ADMIN password(Two times md5) -WXADMIN = '995F03AC401D6CABABAEF756FC4D43C7' +WXADMIN = os.environ.get('DJANGO_WXADMIN_PASSWORD') or '995F03AC401D6CABABAEF756FC4D43C7' LOGGING = { 'version': 1, diff --git a/docker-support/dev-environment-setup.yml b/docker-support/dev-environment-setup.yml new file mode 100644 index 0000000..cd9028d --- /dev/null +++ b/docker-support/dev-environment-setup.yml @@ -0,0 +1,21 @@ +version: '3' +services: + mysql: + image: mysql:5.7 + restart: always + environment: + MYSQL_ROOT_PASSWORD: djangoblog_123 + MYSQL_DATABASE: djangoblog + volumes: + - mysql:/var/lib/mysql + ports: + - '3306:3306' + command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci + memcached: + image: memcached:1.6-alpine + restart: always + ports: + - '11211:11211' + command: memcached -m 64 +volumes: + mysql: ~ diff --git a/servermanager/robot.py b/servermanager/robot.py index 8834a42..fbee94c 100644 --- a/servermanager/robot.py +++ b/servermanager/robot.py @@ -26,7 +26,7 @@ from django.conf import settings import jsonpickle from servermanager.models import commands -robot = WeRoBot(token='lylinux', enable_session=True) +robot = WeRoBot(token=os.environ.get('DJANGO_WEROBOT_TOKEN') or 'lylinux', enable_session=True) memstorage = MemcacheStorage() if memstorage.is_available: robot.config['SESSION_STORAGE'] = memstorage From 4ac6dd8f26a427e7bd5d417286fb586e963dfda9 Mon Sep 17 00:00:00 2001 From: stackia Date: Tue, 17 Mar 2020 00:27:05 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=20Docker=20?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 使用 docker-compose 快速搭建开发环境 2. 构建成 Docker 镜像 --- .dockerignore | 81 ++++++++++++++++++++++++++++++++++++ docker-support/Dockerfile | 65 +++++++++++++++++++++++++++++ docker-support/README.md | 57 +++++++++++++++++++++++++ docker-support/entrypoint.sh | 17 ++++++++ docker-support/nginx.conf | 22 ++++++++++ 5 files changed, 242 insertions(+) create mode 100644 .dockerignore create mode 100644 docker-support/Dockerfile create mode 100644 docker-support/README.md create mode 100644 docker-support/entrypoint.sh create mode 100644 docker-support/nginx.conf diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..3f424f5 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,81 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + + +# PyCharm +# http://www.jetbrains.com/pycharm/webhelp/project.html +.idea +.iml + +# virtualenv +venv/ + +migrations/ +!migrations/__init__.py +collectedstatic/ +DjangoBlog/whoosh_index/ +google93fd32dbd906620a.html +baidu_verify_FlHL7cUyC9.html +BingSiteAuth.xml +cb9339dbe2ff86a5aa169d28dba5f615.txt +werobot_session +django.jpg +uploads/ +settings_production.py +werobot_session.db diff --git a/docker-support/Dockerfile b/docker-support/Dockerfile new file mode 100644 index 0000000..4eeb2fb --- /dev/null +++ b/docker-support/Dockerfile @@ -0,0 +1,65 @@ +FROM alpine:3.11 +WORKDIR /app + +COPY ./requirements.txt . + +RUN apk --update --no-cache add python3 py3-pip py-gunicorn nginx mariadb-connector-c \ + && apk --update --no-cache add --virtual .build-deps \ + tzdata \ + # mysqlclient dependencies + python3-dev \ + mariadb-connector-c-dev \ + gcc \ + musl-dev \ + # Pillow dependencies + jpeg-dev \ + zlib-dev \ + freetype-dev \ + lcms2-dev \ + openjpeg-dev \ + tiff-dev \ + tk-dev \ + tcl-dev \ + harfbuzz-dev \ + fribidi-dev \ + && pip3 install --upgrade pip setuptools gevent \ + && mkdir -p /run/nginx \ + && pip3 install -r requirements.txt \ + && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ + && echo "Asia/Shanghai" > /etc/timezone \ + && apk del .build-deps + +COPY . . +RUN python3 manage.py collectstatic --noinput \ + && python3 manage.py compress --force + +COPY ./docker-support/nginx.conf /etc/nginx/conf.d/default.conf + +ENV DJANGO_DEBUG False +ENV DJANGO_SECRET_KEY DJANGO_BLOG_CHANGE_ME + +ENV DJANGO_MYSQL_DATABASE djangoblog +ENV DJANGO_MYSQL_USER root +ENV DJANGO_MYSQL_PASSWORD djangoblog_123 +ENV DJANGO_MYSQL_HOST 127.0.0.1 +ENV DJANGO_MYSQL_PORT 3306 + +ENV DJANGO_MEMCACHED_ENABLE True +ENV DJANGO_MEMCACHED_LOCATION 127.0.0.1:11211 + +ENV DJANGO_BAIDU_NOTIFY_URL http://data.zz.baidu.com/urls?site=https://www.example.org&token=CHANGE_ME + +ENV DJANGO_EMAIL_TLS False +ENV DJANGO_EMAIL_SSL True +ENV DJANGO_EMAIL_HOST smtp.example.org +ENV DJANGO_EMAIL_PORT 465 +ENV DJANGO_EMAIL_USER SMTP_USER_CHANGE_ME +ENV DJANGO_EMAIL_PASSWORD SMTP_PASSWORD_CHANGE_ME + +ENV DJANGO_ADMIN_EMAIL admin@example.org + +ENV DJANGO_WXADMIN_PASSWORD DJANGO_BLOG_CHANGE_ME +ENV DJANGO_WEROBOT_TOKEN DJANGO_BLOG_CHANGE_ME + +EXPOSE 80 +ENTRYPOINT ["./docker-support/entrypoint.sh"] \ No newline at end of file diff --git a/docker-support/README.md b/docker-support/README.md new file mode 100644 index 0000000..b858e2a --- /dev/null +++ b/docker-support/README.md @@ -0,0 +1,57 @@ +# Docker 支持 + +## 使用 docker-compose 快速搭建开发环境(MySQL / Memcached) + +我们提供了 `dev-environment-setup.yml` 用于快速搭建开发环境。 + +```shell script +docker-compose -f ./docker-support/dev-environment-setup.yml up +``` + +运行这条命令后,可以快速搭建起以下环境: + +- MySQL 5.7 - 端口 `3306`,用户名 `root`,密码 `djangoblog_123`,自动以 UTF8MB4 编码创建 `djangoblog` 数据库 +- Memcached - 端口 `11211` + +## 构建镜像 + +```shell script +docker build -f .\docker-support\Dockerfile -t <你的 Docker Hub 用户名>/django_blog:latest . +``` + +## 运行自定义指令(例如数据库迁移) + +```shell script +docker run -it --rm <你的 Docker Hub 用户名>/django_blog:latest <指令> +``` + +例如: + +```shell script +docker run -it --rm -e DJANGO_MYSQL_HOST=192.168.231.50 django_blog/django_blog:latest makemigrations +docker run -it --rm -e DJANGO_MYSQL_HOST=192.168.231.50 django_blog/django_blog:latest migrate +docker run -it --rm -e DJANGO_MYSQL_HOST=192.168.231.50 django_blog/django_blog:latest createsuperuser +``` + +## 环境变量清单 + +| 环境变量名称 | 默认值 | 备注 | +|---------------------------|----------------------------------------------------------------------------|------------------------------------------------------------------------------------------------| +| DJANGO_DEBUG | False | | +| DJANGO_SECRET_KEY | DJANGO_BLOG_CHANGE_ME | 请务必修改,建议[随机生成](https://www.random.org/passwords/?num=5&len=24&format=html&rnd=new) | +| DJANGO_MYSQL_DATABASE | djangoblog | | +| DJANGO_MYSQL_USER | root | | +| DJANGO_MYSQL_PASSWORD | djangoblog_123 | | +| DJANGO_MYSQL_HOST | 127.0.0.1 | | +| DJANGO_MYSQL_PORT | 3306 | | +| DJANGO_MEMCACHED_ENABLE | True | | +| DJANGO_MEMCACHED_LOCATION | 127.0.0.1:11211 | | +| DJANGO_BAIDU_NOTIFY_URL | http://data.zz.baidu.com/urls?site=https://www.example.org&token=CHANGE_ME | 请在[百度站长平台](https://ziyuan.baidu.com/linksubmit/index)获取接口地址 | +| DJANGO_EMAIL_TLS | False | | +| DJANGO_EMAIL_SSL | True | | +| DJANGO_EMAIL_HOST | smtp.example.org | | +| DJANGO_EMAIL_PORT | 465 | | +| DJANGO_EMAIL_USER | SMTP_USER_CHANGE_ME | | +| DJANGO_EMAIL_PASSWORD | SMTP_PASSWORD_CHANGE_ME | | +| DJANGO_ADMIN_EMAIL | admin@example.org | | +| DJANGO_WEROBOT_TOKEN | DJANGO_BLOG_CHANGE_ME | 请使用自己的微信公众号通信令牌(Token) | \ No newline at end of file diff --git a/docker-support/entrypoint.sh b/docker-support/entrypoint.sh new file mode 100644 index 0000000..d2f64e0 --- /dev/null +++ b/docker-support/entrypoint.sh @@ -0,0 +1,17 @@ +#!/bin/sh +cd /app + +if [ $# -eq 0 ]; then + nginx + gunicorn DjangoBlog.wsgi:application \ + --name djangoblog \ + --user root \ + --group root \ + --bind 127.0.0.1:8000 \ + --log-level=debug \ + --log-file=- \ + --workers $(grep -c ^processor /proc/cpuinfo) \ + --worker-class gevent +else + python3 ./manage.py $1 +fi diff --git a/docker-support/nginx.conf b/docker-support/nginx.conf new file mode 100644 index 0000000..23e6673 --- /dev/null +++ b/docker-support/nginx.conf @@ -0,0 +1,22 @@ +server { + root /app/; + listen 80; + keepalive_timeout 70; + + location /static/ { + expires max; + alias /app/collectedstatic/; + } + + location / { + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; + proxy_set_header X-NginX-Proxy true; + proxy_redirect off; + if (!-f $request_filename) { + proxy_pass http://127.0.0.1:8000; + break; + } + } +}