├── Dockerfile ├── README.md ├── etc ├── supervisor │ └── conf.d │ │ ├── celery.conf │ │ ├── redis.conf │ │ └── tenma.conf └── supervisord.conf └── tenma ├── init.sh └── tenma └── settings.py /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.6 2 | 3 | MAINTAINER Harley Hicks "harley@hicks.house" 4 | # TODO: 5 | # - Install and configure NGNIX and Gunicorn 6 | 7 | ENV DEBIAN_FRONTEND noninteractive 8 | ENV PYTHONUNBUFFERED 1 9 | ENV C_FORCE_ROOT true 10 | ENV PATH /usr/local/bin:$PATH 11 | ENV LIBRARY_PATH=/lib:/usr/lib 12 | ENV TENMA_INSTALL_DIR=/tenma 13 | ENV TENMA_MEDIA_DIR=/tenma/files 14 | ENV TENMA_CONFIG_DIR=/tenma/media 15 | ENV TENMA_UNRAR_PATH=/usr/bin/unrar 16 | 17 | RUN \ 18 | # Install alpine packages 19 | apk add --no-cache python3-dev curl unzip jpeg-dev zlib-dev gcc make g++ redis supervisor unrar bash && \ 20 | 21 | # Download and unpack Tenma 22 | mkdir $TENMA_INSTALL_DIR && \ 23 | curl -o $TENMA_INSTALL_DIR/tenma.zip "https://codeload.github.com/hmhrex/Tenma/zip/v0.1.11-alpha" && \ 24 | unzip $TENMA_INSTALL_DIR/tenma.zip -d /tenma && \ 25 | mv $TENMA_INSTALL_DIR/Tenma-0.1.11-alpha/* /tenma/ && \ 26 | rm -f $TENMA_INSTALL_DIR/tenma.zip && \ 27 | rm -rf $TENMA_INSTALL_DIR/Tenma-0.1.11-alpha && \ 28 | 29 | # Upgrade pip and install setuptools 30 | pip3 install --upgrade pip setuptools && \ 31 | if [ ! -e /usr/bin/pip ]; then ln -s pip3 /usr/bin/pip ; fi && \ 32 | rm -r /root/.cache && \ 33 | 34 | # Install Tenma requirements 35 | pip3 install -r $TENMA_INSTALL_DIR/requirements.txt && \ 36 | pip3 install redis && \ 37 | 38 | # Fix ownership 39 | set -x ; addgroup -g 82 -S www-data ; \ 40 | adduser -u 82 -D -S -G www-data www-data && exit 0 ; exit 1 && \ 41 | chown -R www-data:www-data $TENMA_INSTALL_DIR && \ 42 | 43 | # Remove default configurations 44 | rm /tenma/tenma/settings.py && \ 45 | rm /etc/supervisord.conf 46 | 47 | COPY /tenma/tenma/settings.py /tenma/tenma 48 | COPY /etc/supervisord.conf /etc/ 49 | COPY /etc/supervisor/conf.d/redis.conf /etc/supervisor/conf.d/ 50 | COPY /etc/supervisor/conf.d/celery.conf /etc/supervisor/conf.d/ 51 | COPY /etc/supervisor/conf.d/tenma.conf /etc/supervisor/conf.d/ 52 | 53 | COPY /tenma/init.sh / 54 | RUN chmod +x /init.sh 55 | 56 | VOLUME $TENMA_MEDIA_DIR 57 | VOLUME $TENMA_CONFIG_DIR 58 | WORKDIR $TENMA_INSTALL_DIR 59 | EXPOSE 8000 60 | 61 | CMD ["bash", "/init.sh"] 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tenma Dockerized 2 | 3 | [Tenma](https://github.com/hmhrex/tenma) is a digital comic book server. Use this Docker image to get up and running quickly. 4 | 5 | ## Usage 6 | 7 | `docker create --name=tenma -v :/tenma/files -v :/tenma/media -p 8000:8000 hmhrex/tenma` 8 | 9 | ## Parameters 10 | 11 | * `-v :/tenma/files` - Tenma's library directory. 12 | * `-v :/tenma/media` - Tenma's configuration directory. 13 | * `-p :8000` - This is the mapped port for http access. 8000 is recommended, although anything works here. (i.e. `localhost:8000`) 14 | 15 | ## Getting set up 16 | 17 | 1. Once you've set up your container, go to `localhost:8000`. 18 | 2. Log in with the default username and password. (_**It is recommended to change this once you are logged in.**_) 19 | * Username: `admin` 20 | * Password: `Pegasus!` 21 | 3. To import your comics, follow the instructions on the [wiki](https://github.com/hmhrex/Tenma/wiki/Importing-your-comics) 22 | 23 | ## Details 24 | 25 | * To change your password, visit `localhost:8000/admin/auth/user/1/change/` 26 | * Using a ComicVine API key isn't required to use Tenma, but it will vastly improve your experience. 27 | 28 | ## Changelog 29 | 30 | #### 08.22.17 31 | * Updated to use [v0.1.11-alpha](https://github.com/Tenma-Server/Tenma/releases/tag/v0.1.11-alpha). 32 | 33 | #### 08.16.17 34 | * Updated to use [v0.1.10-alpha](https://github.com/Tenma-Server/Tenma/releases/tag/v0.1.10-alpha). 35 | 36 | #### 08.16.17 37 | * Updated to use [v0.1.9-alpha](https://github.com/Tenma-Server/Tenma/releases/tag/v0.1.9-alpha). 38 | 39 | #### 08.11.17 40 | * Updated to use [v0.1.8-alpha](https://github.com/Tenma-Server/Tenma/releases/tag/v0.1.8-alpha). 41 | 42 | #### 08.11.17 43 | * Updated to use [v0.1.7-alpha](https://github.com/Tenma-Server/Tenma/releases/tag/v0.1.7-alpha). 44 | * Persistent media now stored in `/tenma/media/`. 45 | * Persistent database now stored in `/tenma/media/db.sqlite3`. 46 | * Fix for occasional database timeout on import. 47 | 48 | #### 08.07.17 49 | * Updated to use [v0.1.6-alpha](https://github.com/Tenma-Server/Tenma/releases/tag/v0.1.6-alpha). 50 | * Now generates random SECRET_KEY for security. 51 | * Persistent database now stored in `/files/db.sqlite3`. 52 | 53 | #### 08.03.17 54 | * Updated to use [v0.1.5-alpha](https://github.com/Tenma-Server/Tenma/releases/tag/v0.1.5-alpha). 55 | 56 | #### 08.02.17 57 | * Updated to use [v0.1.4-alpha](https://github.com/Tenma-Server/Tenma/releases/tag/v0.1.4-alpha). 58 | * Added unrar for CBR support. 59 | 60 | #### 08.02.17 61 | * Updated to use [v0.1.3-alpha](https://github.com/Tenma-Server/Tenma/releases/tag/v0.1.3-alpha). 62 | 63 | #### 07.31.17 64 | * Updated to use [v0.1.2-alpha](https://github.com/Tenma-Server/Tenma/releases/tag/v0.1.2-alpha). 65 | 66 | #### 07.27.17 67 | * Updated to use [v0.1.1-alpha](https://github.com/Tenma-Server/Tenma/releases/tag/v0.1.1-alpha). 68 | 69 | #### 07.26.17 70 | * First version. Runs Tenma v0.1-alpha. 71 | -------------------------------------------------------------------------------- /etc/supervisor/conf.d/celery.conf: -------------------------------------------------------------------------------- 1 | [program:celery] 2 | autorestart = false 3 | autostart = true 4 | command = celery -A tenma worker --loglevel=info 5 | directory = /tenma/ 6 | stderr_logfile = /var/log/celery.err.log 7 | stdout_logfile = /var/log/celery.out.log 8 | -------------------------------------------------------------------------------- /etc/supervisor/conf.d/redis.conf: -------------------------------------------------------------------------------- 1 | [program:redis] 2 | autorestart = false 3 | autostart = true 4 | command = redis-server 5 | stderr_logfile = /var/log/redis.err.log 6 | stdout_logfile = /var/log/redis.out.log 7 | -------------------------------------------------------------------------------- /etc/supervisor/conf.d/tenma.conf: -------------------------------------------------------------------------------- 1 | [program:tenma] 2 | autorestart = false 3 | autostart = true 4 | command = python3 manage.py runserver 0.0.0.0:8000 5 | directory = /tenma/ 6 | stderr_logfile = /var/log/tenma.err.log 7 | stdout_logfile = /var/log/tenma.out.log 8 | -------------------------------------------------------------------------------- /etc/supervisord.conf: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | ;priority=999 ; the relative start priority (default 999) 3 | 4 | ; The [include] section can just contain the "files" setting. This 5 | ; setting can list multiple files (separated by whitespace or 6 | ; newlines). It can also contain wildcards. The filenames are 7 | ; interpreted as relative to this file. Included files *cannot* 8 | ; include files themselves. 9 | 10 | [include] 11 | files = /etc/supervisor/conf.d/*.conf 12 | -------------------------------------------------------------------------------- /tenma/init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | python3 manage.py generatesecretkey 3 | if [ ! -d $TENMA_CONFIG_DIR/CACHE/ ] 4 | then 5 | mkdir $TENMA_CONFIG_DIR/CACHE 6 | fi 7 | if [ ! -d $TENMA_CONFIG_DIR/images/ ] 8 | then 9 | mkdir $TENMA_CONFIG_DIR/images 10 | fi 11 | if [ ! -d $TENMA_CONFIG_DIR/temp/ ] 12 | then 13 | mkdir $TENMA_CONFIG_DIR/temp 14 | fi 15 | if [ -e $TENMA_CONFIG_DIR/db.sqlite3 ] 16 | then 17 | python3 manage.py migrate 18 | else 19 | python3 manage.py migrate 20 | echo "from django.contrib.auth.models import User; User.objects.filter(email='admin@example.com').delete(); User.objects.create_superuser('admin', 'admin@example.com', 'Pegasus!')" | python3 ./manage.py shell 21 | fi 22 | supervisord --nodaemon --configuration /etc/supervisord.conf 23 | -------------------------------------------------------------------------------- /tenma/tenma/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for tenma project. 3 | Generated by 'django-admin startproject' using Django 1.9.8. 4 | For more information on this file, see 5 | https://docs.djangoproject.com/en/1.9/topics/settings/ 6 | For the full list of settings and their values, see 7 | https://docs.djangoproject.com/en/1.9/ref/settings/ 8 | """ 9 | 10 | import os 11 | 12 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 13 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 14 | 15 | # Quick-start development settings - unsuitable for production 16 | # See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/ 17 | 18 | # SECURITY WARNING: keep the secret key used in production secret! 19 | SECRET_KEY = '' 20 | 21 | # SECURITY WARNING: don't run with debug turned on in production! 22 | DEBUG = True 23 | ALLOWED_HOSTS = [] 24 | 25 | 26 | # LOGGING 27 | LOGGING = { 28 | 'version': 1, 29 | 'disable_existing_loggers': False, 30 | 'formatters': { 31 | 'verbose': { 32 | 'format': '%(levelname)s | %(asctime)s | %(module)s | %(message)s', 33 | 'datefmt': '%m/%d/%Y %I:%M:%S %p', 34 | }, 35 | 'simple': { 36 | 'format': '%(levelname)s %(message)s' 37 | }, 38 | }, 39 | 'filters': { 40 | 'require_debug_false': { 41 | '()': 'django.utils.log.RequireDebugFalse', 42 | }, 43 | }, 44 | 'handlers': { 45 | 'file': { 46 | 'level':'DEBUG', 47 | 'class':'logging.handlers.RotatingFileHandler', 48 | 'formatter': 'verbose', 49 | 'filename': os.path.join(BASE_DIR, 'logs', 'tenma.log'), 50 | 'maxBytes': 1024*1024*15, # 15MB 51 | 'backupCount': 5, 52 | }, 53 | }, 54 | 'loggers': { 55 | 'django.server': { 56 | 'handlers': ['file'], 57 | 'level': 'DEBUG', 58 | 'propagate': True, 59 | }, 60 | 'tenma': { 61 | 'handlers': ['file'], 62 | 'level': 'DEBUG', 63 | 'propagate': True, 64 | }, 65 | } 66 | } 67 | 68 | # Application definition 69 | 70 | INSTALLED_APPS = [ 71 | 'widget_tweaks', 72 | 'kombu.transport.django', 73 | 'solo.apps.SoloAppConfig', 74 | 'comics.apps.ComicsConfig', 75 | 'django.contrib.admin', 76 | 'django.contrib.auth', 77 | 'django.contrib.contenttypes', 78 | 'django.contrib.sessions', 79 | 'django.contrib.messages', 80 | 'django.contrib.staticfiles', 81 | ] 82 | 83 | MIDDLEWARE_CLASSES = [ 84 | 'django.middleware.security.SecurityMiddleware', 85 | 'django.contrib.sessions.middleware.SessionMiddleware', 86 | 'django.middleware.common.CommonMiddleware', 87 | 'django.middleware.csrf.CsrfViewMiddleware', 88 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 89 | 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 90 | 'django.contrib.messages.middleware.MessageMiddleware', 91 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 92 | 'comics.middleware.LoginRequiredMiddleware', 93 | ] 94 | 95 | ROOT_URLCONF = 'tenma.urls' 96 | 97 | TEMPLATES = [ 98 | { 99 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 100 | 'DIRS': [os.path.join(BASE_DIR, 'templates')], 101 | 'APP_DIRS': True, 102 | 'OPTIONS': { 103 | 'context_processors': [ 104 | 'django.template.context_processors.debug', 105 | 'django.template.context_processors.request', 106 | 'django.contrib.auth.context_processors.auth', 107 | 'django.contrib.messages.context_processors.messages', 108 | ], 109 | }, 110 | }, 111 | ] 112 | 113 | WSGI_APPLICATION = 'tenma.wsgi.application' 114 | 115 | # Database 116 | # https://docs.djangoproject.com/en/1.9/ref/settings/#databases 117 | DATABASES = { 118 | 'default': { 119 | 'ENGINE': 'django.db.backends.sqlite3', 120 | 'NAME': os.path.join(BASE_DIR, 'media', 'db.sqlite3'), 121 | 'OPTIONS': { 122 | 'timeout': 20, 123 | }, 124 | } 125 | } 126 | 127 | BROKER_URL = 'redis://127.0.0.1:6379/0' 128 | CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/0' 129 | 130 | # Password validation 131 | # https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators 132 | AUTH_PASSWORD_VALIDATORS = [ 133 | { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, 134 | { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, 135 | { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, 136 | { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, 137 | ] 138 | 139 | # Internationalization 140 | # https://docs.djangoproject.com/en/1.9/topics/i18n/ 141 | LANGUAGE_CODE = 'en-us' 142 | TIME_ZONE = 'EST' 143 | USE_I18N = True 144 | USE_L10N = True 145 | USE_TZ = True 146 | 147 | # Static files (CSS, JavaScript, Images) 148 | # https://docs.djangoproject.com/en/1.9/howto/static-files/ 149 | STATIC_URL = '/static/' 150 | MEDIA_ROOT = os.path.join(BASE_DIR, 'media') 151 | MEDIA_URL = '/media/' 152 | LOGIN_URL = '/admin/login/' 153 | --------------------------------------------------------------------------------