WIP: Deployment #3

Manually merged
MassiveAtoms merged 8 commits from development into master 2020-08-02 14:56:54 +00:00
10 changed files with 108 additions and 28 deletions
Showing only changes of commit 43e5d71cec - Show all commits

View File

@ -12,10 +12,13 @@ https://docs.djangoproject.com/en/3.0/ref/settings/
import os import os
import json import json
import logging
logger = logging.getLogger(__name__)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
with open( BASE_DIR + "/settings.json", "r") as userfile: with open(BASE_DIR + "/settings.json", "r") as userfile:
usersettings = json.load(userfile) usersettings = json.load(userfile)
CALIBRE_DIR = os.path.abspath(usersettings["CALIBRE_DIR"]) CALIBRE_DIR = os.path.abspath(usersettings["CALIBRE_DIR"])
SECRET_KEY = usersettings["SECRET_KEY"] SECRET_KEY = usersettings["SECRET_KEY"]
@ -24,23 +27,21 @@ with open( BASE_DIR + "/settings.json", "r") as userfile:
DEBUG = usersettings["DEBUG"] DEBUG = usersettings["DEBUG"]
# Build paths inside the project like this: os.path.join(BASE_DIR, ...) # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
# optimisation stuff ###############################################3 # optimisation stuff ###############################################3
# # # #
CONN_MAX_AGE = 60 * 5 CONN_MAX_AGE = 60 * 5
CACHES = { CACHES = {
'default': { 'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-snowflake', 'LOCATION': 'unique-snowflake',
"TIMEOUT" : 60 * 5, "TIMEOUT": 60 * 5,
} }
} }
@ -59,6 +60,42 @@ STATICFILES_DIRS = [
STATIC_URL = '/static/' STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR + "/static/" STATIC_ROOT = BASE_DIR + "/static/"
## ##
#########################################################################
# LOGGING
logfile = usersettings["LOGFILE"]
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"root": {"level": "INFO", "handlers": ["file"]},
"handlers": {
"file": {
"level": "INFO",
"class": "logging.FileHandler",
"filename": usersettings["LOGFILE"],
"formatter": "app",
},
},
"loggers": {
"django": {
"handlers": ["file"],
"level": "INFO",
"propagate": True
},
},
"formatters": {
"app": {
"format": (
u"%(asctime)s [%(levelname)-8s] "
"(%(module)s.%(funcName)s) %(message)s"
),
"datefmt": "%Y-%m-%d %H:%M:%S",
},
},
}
## ## ## ##
######################################################################## ########################################################################
@ -109,7 +146,7 @@ INSTALLED_APPS = [
MIDDLEWARE = [ MIDDLEWARE = [
# 'silk.middleware.SilkyMiddleware', # DEBUG/profiling purposes # 'silk.middleware.SilkyMiddleware', # DEBUG/profiling purposes
# 'debug_toolbar.middleware.DebugToolbarMiddleware', # DEBUG purposes # 'debug_toolbar.middleware.DebugToolbarMiddleware', # DEBUG purposes
'django.middleware.cache.UpdateCacheMiddleware', # cache 'django.middleware.cache.UpdateCacheMiddleware', # cache
'django.middleware.security.SecurityMiddleware', 'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware', 'django.middleware.common.CommonMiddleware',
@ -117,7 +154,7 @@ MIDDLEWARE = [
'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware', # cache 'django.middleware.cache.FetchFromCacheMiddleware', # cache
] ]
## ## ## ##
######################################################################## ########################################################################
@ -163,7 +200,7 @@ DATABASES = {
} }
DATABASE_ROUTERS = [ "db_routers.CalibreRouter", "db_routers.DjangoRouter"] DATABASE_ROUTERS = ["db_routers.CalibreRouter", "db_routers.DjangoRouter"]
# Password validation # Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators # https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators

View File

@ -6,9 +6,11 @@ preload_app = True # By preloading an application you can save some RAM resource
keepalive = 5 keepalive = 5
# daemon = True # Detaches the server from the controlling terminal and enters the background. disabled for now # daemon = True # Detaches the server from the controlling terminal and enters the background. disabled for now
# logging # logging
errorlog = "/home/massiveatoms/Desktop/logs/gunicorn.log"
loglevel = "warning"
errorlog = "/home/massiveatoms/Desktop/logs/gunicorn_error.log"
loglevel = "warning"
accesslog = "/home/massiveatoms/Desktop/logs/gunicorn_access.log"
# capture_output = True
# debug settings which need to be commented out in prod # debug settings which need to be commented out in prod
# reload=True # reload=True

View File

@ -1,10 +1,12 @@
{ {
"CALIBRE_DIR": "PATH\\TO\\your\\calibre\library", "CALIBRE_DIR": "PATH\\TO\\your\\calibre\library",
"SECRET_KEY": "u(8^+rb%rz5hsx4v^^y(ul7g(4n7a8!db@s*9(m5cs*2_ppy8+", "SECRET_KEY": "u(8^+rb%rz5hsx4v^^y(ul7g(4n7a8!db@s*9(m5cs*2_ppy8+",
"ALLOWED_HOSTS": [ "ALLOWED_HOSTS": [
"127.0.0.1" "127.0.0.1"
], ],
"INTERNAL_IPS": [ "INTERNAL_IPS": [
"127.0.0.1" "127.0.0.1"
] ],
"DEBUG" : false,
"LOGFILE" : "/home/massiveatoms/Desktop/logs/django.log"
} }

View File

@ -1,9 +1,44 @@
# What is CalibreWebAlternative?
This is a web server to the popular book management application Calibre. We found that the builtin webserver was kinda shit, so we're building our own. (make this friendlier later)
# Features
- navbar with tags, series, authors, etc
- Search by author, identifier, title
- authentication
# Some screenshots
Here's how the various lists look like
![booklist](./screenshots/booklist.png)
Book detail
![bookdetail](./screenshots/bookdetail.png)
navbar
![nav](./screenshots/navbar.png)
Adanced search
![booklist](./screenshots/search.png)
# requirements # requirements
Django 3.0 Django 3.0
Calibre 4.13 (I have not tested it with anything else atm, will be resolved later)
# how to use: # how to use:
EDIT `./CalibreWebCompanion/settings.json.bak` 1. clone repo
Remove the `.bak` from `db.sqlite3.bak` and `settings.json.bak` 2. Remove the `.bak` from `./CalibreWebCompanion/settings.json.bak` and `db.sqlite3.bak`
3. Edit `./CalibreWebCompanion/settings.json`. Definitely change the secret key
4. Not sure if the db needs to be regenerated, but we'll see later __!!!!!!!!!!__
5. pip install -r requirements.txt
6. install gunicorn and nginx
7. move this nginx.conf to /etc/nginx
8. make whatever user nginx runs as (in this case, massiveatoms) the owner of calibredir
9. give execute permissions to parent of calibredir
10. cd to repo, run `gunicorn CalibreWebCompanion.wsgi`
11. start nginx `sudo systemctl restart nginx`
`./CalibreWebCompanion` `./CalibreWebCompanion`
run `./manage.py runserver` run `./manage.py runserver`
@ -22,24 +57,24 @@ headless = true
in `locust.conf`, and then run `./bench.py` in `locust.conf`, and then run `./bench.py`
You can then go to [http://localhost:8089/](http://localhost:8089/) to see live graphs, tweak the number of users and more. You can then go to [http://localhost:8089/](http://localhost:8089/) to see live graphs, tweak the number of users and more.
this is in development mode. don't actually use it or release it like this. The debug info it shows is spicy.
# Features # Finished Features
- [x] Books - [x] Books
- [x] navbar with tags, series, authors, etc - [x] navbar with tags, series, authors, etc
- [x] Search - [x] Search
- [x] authentication - [x] authentication
- [x] Cache - [x] Cache
- [x] Profiling with logging - [x] logging
- [x] deploy instructions
# TODO ROADMAP
# TODO
- [ ] cache with vary headers - [ ] cache with vary headers
- [ ] localisation - [ ] localisation
- [ ] Beautifying template - [ ] Beautifying template (only works well on 720p, no other viewports)
- [ ] Setup email functionality - [ ] Setup email functionality
- [ ] deploy

View File

@ -5,7 +5,7 @@
4. move this nginx.conf to /etc/nginx 4. move this nginx.conf to /etc/nginx
5. make whatever user nginx runs as (in this case, massiveatoms) the owner of calibredir 5. make whatever user nginx runs as (in this case, massiveatoms) the owner of calibredir
6. give execute permissions to parent of calibredir 6. give execute permissions to parent of calibredir
7. cd to repo, run `gunicorn -w <2x n cores/threads> CalibreWebCompanion.wsgi` 7. cd to repo, run `gunicorn CalibreWebCompanion.wsgi`
8. start nginx `sudo systemctl restart nginx` 8. start nginx `sudo systemctl restart nginx`
Slight issues with this atm: Slight issues with this atm:

View File

@ -1,7 +1,7 @@
worker_processes 1; worker_processes 1;
# user nobody nogroup; # user nobody nogroup;
user massiveatoms; # MASSIVEATOMS user massiveatoms;
# user nobody nobody; # for systems with 'nobody' as a group instead # user nobody nobody; # for systems with 'nobody' as a group instead
error_log /home/massiveatoms/Desktop/logs/nginx.log warn; error_log /home/massiveatoms/Desktop/logs/nginx.log warn;
# pid /var/run/nginx.pid; # pid /var/run/nginx.pid;
@ -38,13 +38,13 @@ http {
} }
server { server {
listen 80 deferred; # for Linux MASSIVEATOMS listen 80 deferred; # for Linux massiveatoms
# use 'listen 80 accept_filter=httpready;' for FreeBSD # use 'listen 80 accept_filter=httpready;' for FreeBSD
# listen 80; # listen 80;
client_max_body_size 4G; client_max_body_size 4G;
# set the correct host(s) for your site # set the correct host(s) for your site
server_name localhost www.localhost 192.168.1.4; # set this to the server url? or ip? we'll see MASSIVEATOMS server_name localhost 192.168.1.4; # set this to the server url? or ip? we'll see MASSIVEATOMS
keepalive_timeout 5; keepalive_timeout 5;
@ -62,13 +62,17 @@ http {
location / { location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host; # proxy_set_header Host $http_host;
# we don't want nginx trying to do something clever with # we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already. # redirects, we set the Host: header above already.
proxy_redirect off; proxy_redirect off;
proxy_pass http://127.0.0.1:8000; proxy_pass http://127.0.0.1:8000;
} }
error_page 500 502 503 504 /500.html; error_page 500 502 503 504 /500.html;
location = /500.html { location = /500.html {
root /path/to/app/current/public; root /path/to/app/current/public;

BIN
screenshots/bookdetail.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

BIN
screenshots/booklist.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

BIN
screenshots/navbar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

BIN
screenshots/search.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB