diff --git a/.gitignore b/.gitignore index fc6eb78d0..07f4c0882 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ htmlcov/ __pycache__/ _static/ .idea +.secret diff --git a/deployment/docker/standalone/Dockerfile b/deployment/docker/standalone/Dockerfile index 9f708d343..9afd78432 100644 --- a/deployment/docker/standalone/Dockerfile +++ b/deployment/docker/standalone/Dockerfile @@ -2,7 +2,7 @@ FROM debian:jessie RUN apt-get update && apt-get install -y supervisor python3 git python3-pip \ libxml2-dev libxslt1-dev python-dev python-virtualenv locales libffi-dev \ - build-essential python3-dev zlib1g-dev libssl-dev npm gettext \ + build-essential python3-dev zlib1g-dev libssl-dev npm gettext git \ --no-install-recommends WORKDIR / @@ -20,16 +20,18 @@ RUN apt-get clean && rm -rf /var/lib/apt/lists/* ADD supervisord.conf /etc/supervisor/conf.d/supervisord.conf ADD gunicorn_starter.bash /gunicorn_starter.bash -ADD src /src -WORKDIR /src +RUN git clone --recursive --depth 1 https://github.com/pretix/pretix.git /pretix +WORKDIR /pretix/src RUN pip3 install -r requirements.txt RUN pip3 install gunicorn -ADD local_settings.py /src/pretix/local_settings.py - RUN make production +RUN mkdir /etc/pretix +RUN mkdir /data +VOLUME /etc/pretix + EXPOSE 80 CMD ["/usr/bin/supervisord"] diff --git a/deployment/docker/standalone/Makefile b/deployment/docker/standalone/Makefile index 9444b355e..372b7fdbd 100644 --- a/deployment/docker/standalone/Makefile +++ b/deployment/docker/standalone/Makefile @@ -1,2 +1,3 @@ main: - tar ch --exclude=_static --exclude=htmlcov --exclude=db.sqlite3 . | docker build -t test - + #tar ch --exclude=_static --exclude=htmlcov --exclude=db.sqlite3 . | + docker build -t raphaelm/pretix-standalone . diff --git a/deployment/docker/standalone/gunicorn_starter.bash b/deployment/docker/standalone/gunicorn_starter.bash index d4aff98c3..3366dd68f 100644 --- a/deployment/docker/standalone/gunicorn_starter.bash +++ b/deployment/docker/standalone/gunicorn_starter.bash @@ -1,6 +1,7 @@ #!/bin/bash -cd /src +cd /pretix/src export DJANGO_SETTINGS_MODULE=pretix.settings +export MEDIA_ROOT=/data/ gunicorn \ -b '0.0.0.0:80' \ -w 3 --max-requests 1000 --max-requests-jitter 50 \ diff --git a/deployment/docker/standalone/local_settings.py b/deployment/docker/standalone/local_settings.py deleted file mode 100644 index f517bed92..000000000 --- a/deployment/docker/standalone/local_settings.py +++ /dev/null @@ -1,5 +0,0 @@ -COMPRESS_OFFLINE = True -COMPRESS_ENABLED = True -#DEBUG = False -#TEMPLATE_DEBUG = False - diff --git a/deployment/docker/standalone/src b/deployment/docker/standalone/src deleted file mode 120000 index dabb0e15a..000000000 --- a/deployment/docker/standalone/src +++ /dev/null @@ -1 +0,0 @@ -../../../src \ No newline at end of file diff --git a/doc/admin/config.rst b/doc/admin/config.rst new file mode 100644 index 000000000..73b6ab054 --- /dev/null +++ b/doc/admin/config.rst @@ -0,0 +1,153 @@ +.. highlight:: ini + +Configuration file +================== + +Pretix reads its configuration from a configuration file. It tries to find this file +at the following locations. It will try to read the file from the specified paths in +the following order. The file that is found *last* will override the settings from +the files found before. + +1. ``/etc/pretix/pretix.cfg`` +2. ``~/.pretix.cfg`` +3. ``pretix.cfg`` in the current working directory + +The file is expected to be in the INI format as specified in the `Python documentation`_. + +The config file may contain the following sections (all settings are optional and have default values). + +pretix settings +--------------- + +Example:: + + [pretix] + instance_name=pretix.de + global_registration=off + site_url=http://localhost + currency=EUR + +``instance_name`` + The name of this installation. Default: ``pretix.de`` + +``global_registration`` + Whether or not this installation supports global user accounts (in addition to + event-bound accounts). Defaults to ``True``. + +``site_url`` + The installation's full URL, without a trailing slash. + +``currency`` + The default currency as a three-letter code. Defaults to ``EUR``. + +Locale settings +--------------- + +Example:: + + [locale] + default=de + timezone=Europe/Berlin + +``default`` + The system's default locale. Default: ``en`` + +``timezone`` + The system's default timezone as a ``pytz`` name. Default: ``UTC`` + +Database settings +----------------- + +Example:: + + [database] + backend=mysql + name=pretix + user=pretix + password=abcd + host=localhost + port=3306 + +``backend`` + One of ``mysql``, ``sqlite3``, ``oracle`` and ``postgresql_psycopg2``. + Default: ``sqlite3``. + +``name`` + The database's name. Default: ``db.sqlite3``. + +``user``, ``password``, ``host``, ``port`` + Connection details for the database connection. Empty by default. + +Uploaded files +-------------- + +Example:: + + [media] + url=/media/ + root=media + +``root`` + The filesystem location to store user-uploaded content at. By default, this takes + the value of the environment variable ``MEDIA_ROOT``, if present, or ``media`` if not. + +``url`` + The URL to be used to serve user-uploaded content. You should not need to modify + this. Default: ``/media/`` + +Email +----- + +Example:: + + [mail] + from=hello@localhost + +``from`` + The email address to set as ``From`` header in outgoing emails by the system. + Default: ``pretix@localhost`` + +Django settings +--------------- + +Example:: + + [django] + hosts=localhost + secret=j1kjps5a5&4ilpn912s7a1!e2h!duz^i3&idu@_907s$wrz@x- + debug=off + +``hosts`` + Comma-seperated list of allowed host names for this installation. + Default: ``localhost`` + +``secret`` + The secret to be used by Django for signing and verification purposes. If this + setting is not provided, pretix will generate a random secret on the first start + and store it in the filesystem for later usage. + +``debug`` + Whether or not to run in debug mode. Default is ``False``. + + .. WARNING:: Never set this to ``True`` in production! + +Static files +------------ + +You should *not* need to modify these settings as logn as you don't want to use a +custom delivery method for static files such as an external CDN. + +Example:: + + [static] + url=/static/ + root=_static + +``url`` + The URL to be used to serve static files. Default: ``/static/``. + +``root`` + The filesystem path to be used for static file storage. Default: ``_static`` + + +.. _Python documentation: https://docs.python.org/3/library/configparser.html?highlight=configparser#supported-ini-file-structure \ No newline at end of file diff --git a/doc/admin/index.rst b/doc/admin/index.rst new file mode 100644 index 000000000..570fb7084 --- /dev/null +++ b/doc/admin/index.rst @@ -0,0 +1,11 @@ +Administrator documentation +=========================== + +This documentation is for everyone who wants to install pretix on a server. + +Contents: + +.. toctree:: + :maxdepth: 2 + + config diff --git a/doc/index.rst b/doc/index.rst index 387b86ee8..eadea83f7 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -11,5 +11,6 @@ Contents: .. toctree:: :maxdepth: 2 + admin/index development/index diff --git a/src/pretix/settings.py b/src/pretix/settings.py index 2b950625f..054265e88 100644 --- a/src/pretix/settings.py +++ b/src/pretix/settings.py @@ -1,32 +1,57 @@ -""" -Django settings for pretix project. - -For more information on this file, see -https://docs.djangoproject.com/en/dev/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/dev/ref/settings/ -""" - +import configparser import os +from django.utils.crypto import get_random_string + +config = configparser.ConfigParser() +config.read(['/etc/pretix/pretix.cfg', os.path.expanduser('~/.pretix.cfg'), 'pretix.cfg'], + encoding='utf-8') -# Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(__file__)) +if config.has_option('django', 'secret'): + SECRET_KEY = config.get('django', 'secret') +else: + SECRET_FILE = os.path.join(BASE_DIR, '.secret') + if os.path.exists(SECRET_FILE): + with open(SECRET_FILE, 'r') as f: + SECRET_KEY = f.read().strip() + else: + chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)' + SECRET_KEY = get_random_string(50, chars) + with open(SECRET_FILE, 'w') as f: + f.write(SECRET_KEY) -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/dev/howto/deployment/checklist/ +DEBUG = TEMPLATE_DEBUG = config.getboolean('django', 'debug', fallback=False) -# SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = '0ro^46+8k#dv3ej=oen-2ww)i30#$$^&x&eajyj&_&h)$nc6@5' +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.' + config.get('database', 'backend', fallback='sqlite3'), + 'NAME': config.get('database', 'name', fallback=os.path.join(BASE_DIR, 'db.sqlite3')), + 'USER': config.get('database', 'user', fallback=''), + 'PASSWORD': config.get('database', 'user', fallback=''), + 'HOST': config.get('database', 'host', fallback=''), + 'PORT': config.get('database', 'port', fallback='') + } +} -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True +STATIC_URL = config.get('static', 'url', fallback='/static/') +STATIC_ROOT = config.get('static', 'root', fallback='_static') -TEMPLATE_DEBUG = True +MEDIA_URL = config.get('media', 'url', fallback=os.environ.get('MEDIA_ROOT', '/media/')) +MEDIA_ROOT = config.get('media', 'root', fallback='media') -ALLOWED_HOSTS = [] +PRETIX_INSTANCE_NAME = config.get('pretix', 'instance_name', fallback='pretix.de') +PRETIX_GLOBAL_REGISTRATION = config.getboolean('pretix', 'global_registration', fallback=True) +MAIL_FROM = config.get('mail', 'from', fallback='pretix@localhost') +SITE_URL = config.get('pretix', 'url', fallback='http://localhost') + +DEFAULT_CURRENCY = config.get('pretix', 'currency', fallback='EUR') + +ALLOWED_HOSTS = config.get('django', 'hosts', fallback='localhost').split(',') + +LANGUAGE_CODE = config.get('locale', 'default', fallback='en') +TIME_ZONE = config.get('locale', 'timezone', fallback='UTC') # Application definition @@ -84,27 +109,8 @@ ROOT_URLCONF = 'pretix.urls' WSGI_APPLICATION = 'pretix.wsgi.application' -# Database -# https://docs.djangoproject.com/en/dev/ref/settings/#databases - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), - } -} - -# Internationalization -# https://docs.djangoproject.com/en/dev/topics/i18n/ - -LANGUAGE_CODE = 'en' - -TIME_ZONE = 'UTC' - USE_I18N = True - USE_L10N = True - USE_TZ = True LOCALE_PATHS = ( @@ -127,10 +133,6 @@ LOGIN_URL_CONTROL = '/control/login' # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/dev/howto/static-files/ -STATIC_URL = '/static/' -STATIC_ROOT = '_static' -MEDIA_ROOT = 'media' -MEDIA_URL = '/media/' STATICFILES_FINDERS = ( 'django.contrib.staticfiles.finders.FileSystemFinder', @@ -142,7 +144,7 @@ COMPRESS_PRECOMPILERS = ( ('text/less', 'pretix.helpers.lessabsolutefilter.LessFilter'), ) -COMPRESS_OFFLINE = not DEBUG +COMPRESS_ENABLED = COMPRESS_OFFLINE = not DEBUG COMPRESS_CSS_FILTERS = ( 'compressor.filters.css_default.CssAbsoluteFilter', @@ -157,10 +159,6 @@ DEBUG_TOOLBAR_CONFIG = { # Pretix specific settings -PRETIX_INSTANCE_NAME = 'pretix.de' -PRETIX_GLOBAL_REGISTRATION = True - -DEFAULT_CURRENCY = 'EUR' INTERNAL_IPS = ('127.0.0.1', '::1') @@ -197,9 +195,6 @@ LOGGING = { }, } -MAIL_FROM = 'pretix@localhost' -SITE_URL = 'http://localhost' - try: from .local_settings import * # NOQA except ImportError: