diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index a7430779..27c6cbd8 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -17,10 +17,12 @@ Changed
=======
- Logged admin can see any project (#262)
+- Better install doc (#275)
Added
=====
+- ``ihatemoney generate-config`` to give working examples of config files (#275)
- Statistics tab (#257)
- Python3.6 support (#259)
- ALLOW_PUBLIC_PROJECT_CREATION setting (#262)
diff --git a/conf/apache-vhost.conf b/conf/apache-vhost.conf
deleted file mode 100644
index 1a84e7f7..00000000
--- a/conf/apache-vhost.conf
+++ /dev/null
@@ -1,18 +0,0 @@
-
- ServerAdmin admin@example.com
- ServerName ihatemoney.example.com
- # Uncomment the python-home option if you use a virtualenv
- WSGIDaemonProcess ihatemoney user=www-data group=www-data threads=5 python-path=/path/to/ihatemoney/ihatemoney # python-home=/path/to/your/venv
- WSGIScriptAlias / /path/to/ihatemoney/ihatemoney/wsgi.py
- ErrorLog /var/log/apache2/ihatemoney.example.com_error.log
- CustomLog /var/log/apache2/ihatemoney.example.com_access.log combined
-
- WSGIProcessGroup ihatemoney
- WSGIApplicationGroup %{GLOBAL}
- Order deny,allow
- Allow from all
-
-# Alias value may be some messy path, within python libs.
-# You may want to use "find $VIRTUAL_ENV -path */ihatemoney*/static" to find it.
-Alias /static/ /path/to/ihatemoney/ihatemoney/static/
-
diff --git a/conf/gunicorn.conf.py b/conf/gunicorn.conf.py
deleted file mode 100644
index 017a6709..00000000
--- a/conf/gunicorn.conf.py
+++ /dev/null
@@ -1,7 +0,0 @@
-backlog = 2048
-daemon = False
-debug = True
-workers = 3
-logfile = "/path/to/your/app/ihatemoney.gunicorn.log"
-loglevel = "info"
-bind = "unix:/path/to/your/app/ihatemoney.gunicorn.sock"
diff --git a/conf/supervisord.conf b/conf/supervisord.conf
deleted file mode 100644
index 8d3ac70e..00000000
--- a/conf/supervisord.conf
+++ /dev/null
@@ -1,6 +0,0 @@
-[program:ihatemoney]
-command=/path/to/your/app/venv/bin/gunicorn -c /etc/ihatemoney/gunicorn.conf.py ihatemoney.wsgi:application
-user=www
-autostart=true
-autorestart=true
-redirect_stderr=True
diff --git a/docs/installation.rst b/docs/installation.rst
index 3f2c6534..9fd96b77 100644
--- a/docs/installation.rst
+++ b/docs/installation.rst
@@ -18,6 +18,8 @@ it will work without if you prefer.
If wondering about the backend, SQLite is the simplest and will work fine for
most small to medium setups.
+.. note:: If curious, source config templates can be found in the `project git repository `_.
+
Prepare virtualenv (recommended)
================================
@@ -57,28 +59,56 @@ Now, if you want to deploy it on your own server, you have many options.
Two of them are documented at the moment.
*Of course, if you want to contribute another configuration, feel free to open a
-pull-request against this repository!*.
+pull-request against this repository!*
+
+
+Whatever your installation option is…
+--------------------------------------
+
+1. Initialize the ihatemoney directories::
+
+ mkdir /etc/ihatemoney /var/lib/ihatemoney
+
+2. Generate settings::
+
+ ihatemoney generate-config ihatemoney.cfg > /etc/ihatemoney/ihatemoney.cfg
+ chmod 740 /etc/ihatemoney/ihatemoney.cfg
+
+You probably want to adjust `/etc/ihatemoney/ihatemoney.cfg` contents, you may
+do it later, see `Configuration`_.
+
With Apache and mod_wsgi
------------------------
-1. Install Apache and mod_wsgi - libapache2-mod-wsgi(-py3) for Debian based and mod_wsgi for RedHat based distributions -
-2. Create an Apache virtual host based on the sample configuration file in `conf/apache-vhost.conf`
-3. Adapt it to your paths and specify your virtualenv path if you use one
+1. Fix permissions (considering `www-data` is the user running apache)::
+
+ chgrp www-data /etc/ihatemoney/ihatemoney.cfg
+ chown www-data /var/lib/ihatemoney
+
+2. Install Apache and mod_wsgi - libapache2-mod-wsgi(-py3) for Debian based and mod_wsgi for RedHat based distributions -
+3. Create an Apache virtual host, the command ``ihatemoney generate-config apache-vhost.conf`` will output a good starting point (read and adapt it)
4. Activate the virtual host if needed and restart Apache
With Nginx, Gunicorn and Supervisord
------------------------------------
-.. note:: For the 3 configuration files mentioned below, you will need to fix
- the paths to reflect yours.
+1. Create a dedicated unix user (here called `ihatemoney`), required dirs, and fix permissions::
-1. Copy *conf/gunicorn.conf.py* to */etc/ihatemoney/gunicorn.conf.py*
-2. Copy *conf/supervisord.conf* to */etc/supervisor/conf.d/ihatemoney.conf*
-3. Copy *conf/nginx.conf* with your nginx vhosts [#nginx-vhosts]_
-4. Reload both nginx and supervisord. It should be working ;)
+ useradd ihatemoney
+ chown ihatemoney /var/lib/ihatemoney/
+ chgrp ihatemoney /etc/ihatemoney/ihatemoney.cfg
-Don't forget to set the right permission for your files !
+2. Create gunicorn config file ::
+
+ ihatemoney generate-config gunicorn.conf.py > /etc/ihatemoney/gunicorn.conf.py
+
+3. Create supervisor config file ::
+
+ ihatemoney generate-config supervisord.conf > /etc/supervisor/conf.d/ihatemoney.conf
+
+4. Copy (and adapt) output of ``ihatemoney generate-config conf/nginx.conf`` with your nginx vhosts [#nginx-vhosts]_
+5. Reload both nginx and supervisord. It should be working ;)
.. [#nginx-vhosts] typically, */etc/nginx/conf.d/* or
*/etc/nginx/sites-available*, depending on your distribution.
@@ -90,48 +120,47 @@ ihatemoney relies on a configuration file. If you run the application for the
first time, you will need to take a few moments to configure the application
properly.
-.. warning:: You **must** customize the ``SECRET_KEY`` on a production installation.
+Defaults given here, are those for development mode. To know defaults on your
+deployed instance, simply look at your *ihatemoney.cfg*.
-+-------------------------------+---------------------------------+----------------------------------------------------------------------------------+
-| Setting name | Default | What does it do? |
-+===============================+=================================+==================================================================================+
-| SQLALCHEMY_DATABASE_URI | ``sqlite:///tmp/ihatemoney.db`` | Specifies the type of backend to use and its location. More information |
-| | | on the format used can be found on `the SQLAlchemy documentation |
-| | | `_. |
-+-------------------------------+---------------------------+----------------------------------------------------------------------------------------+
-| SECRET_KEY | ``tralala`` | The secret key used to encrypt the cookies. **This needs to be changed**. |
-+-------------------------------+---------------------------+----------------------------------------------------------------------------------------+
-| MAIL_DEFAULT_SENDER | ``("Budget manager", | A python tuple describing the name and email adress to use when sending |
-| | "budget@notmyidea.org")`` | emails. |
-+-------------------------------+---------------------------+----------------------------------------------------------------------------------------+
-| ACTIVATE_DEMO_PROJECT | ``True`` | If set to `True`, a demo project will be available on the frontpage. |
-+-------------------------------+---------------------------+----------------------------------------------------------------------------------------+
-| | | Hashed password to access protected endpoints. If left empty, all administrative |
-| ADMIN_PASSWORD | ``""`` | tasks are disabled. |
-| | | To generate the proper password HASH, use ``ihatemoney generate_password_hash`` |
-| | | and copy the output into the value of *ADMIN_PASSWORD*. |
-+-------------------------------+---------------------------+----------------------------------------------------------------------------------------+
-| ALLOW_PUBLIC_PROJECT_CREATION | ``True`` | If set to `True`, everyone can create a project without entering the admin password |
-| | | If set to `False`, the password needs to be entered (and as such, defined in the |
-| | | settings). |
-+-------------------------------+---------------------------+----------------------------------------------------------------------------------------+
-| ACTIVATE_ADMIN_DASHBOARD | ``False`` | If set to `True`, the dashboard will become accessible entering the admin password |
-| | | If set to `True`, a non empty ADMIN_PASSWORD needs to be set |
-+-------------------------------+---------------------------+----------------------------------------------------------------------------------------+
-| APPLICATION_ROOT | ``""`` | If empty, ihatemoney will be served at domain root (e.g: *http://domain.tld*), if set |
-| | | to ``"foo"``, it will be served from a "folder" (e.g: *http://domain.tld/foo*) |
-+-------------------------------+---------------------------+----------------------------------------------------------------------------------------+
-In a production environment
----------------------------
++-------------------------------+---------------------------------+----------------------------------------------------------------------------------------+
+| Setting name | Default | What does it do? |
++===============================+=================================+========================================================================================+
+| SQLALCHEMY_DATABASE_URI | ``sqlite:///tmp/ihatemoney.db`` | Specifies the type of backend to use and its location. More information on the |
+| | | format used can be found on `the SQLAlchemy documentation`_. |
++-------------------------------+---------------------------------+----------------------------------------------------------------------------------------+
+| SECRET_KEY | ``tralala`` | The secret key used to encrypt the cookies. `ihatemoney conf-example ihatemoney.cfg` |
+| | | sets it to something random, which is good. |
++-------------------------------+---------------------------------+----------------------------------------------------------------------------------------+
+| MAIL_DEFAULT_SENDER | ``("Budget manager", | A python tuple describing the name and email adress to use when sending |
+| | "budget@notmyidea.org")`` | emails. |
++-------------------------------+---------------------------------+----------------------------------------------------------------------------------------+
+| ACTIVATE_DEMO_PROJECT | ``True`` | If set to `True`, a demo project will be available on the frontpage. |
++-------------------------------+---------------------------------+----------------------------------------------------------------------------------------+
+| | | Hashed password to access protected endpoints. If left empty, all administrative |
+| ADMIN_PASSWORD | ``""`` | tasks are disabled. |
+| | | To generate the proper password HASH, use ``ihatemoney generate_password_hash`` |
+| | | and copy the output into the value of *ADMIN_PASSWORD*. |
++-------------------------------+---------------------------------+----------------------------------------------------------------------------------------+
+| ALLOW_PUBLIC_PROJECT_CREATION | ``True`` | If set to `True`, everyone can create a project without entering the admin password |
+| | | If set to `False`, the password needs to be entered (and as such, defined in the |
+| | | settings). |
++-------------------------------+---------------------------------+----------------------------------------------------------------------------------------+
+| ACTIVATE_ADMIN_DASHBOARD | ``False`` | If set to `True`, the dashboard will become accessible entering the admin password |
+| | | If set to `True`, a non empty ADMIN_PASSWORD needs to be set |
++-------------------------------+---------------------------------+----------------------------------------------------------------------------------------+
+| APPLICATION_ROOT | ``""`` | If empty, ihatemoney will be served at domain root (e.g: *http://domain.tld*), if set |
+| | | to ``"foo"``, it will be served from a "folder" (e.g: *http://domain.tld/foo*) |
++-------------------------------+---------------------------------+----------------------------------------------------------------------------------------+
-Make a copy of ``ihatemoney/default_settings.py`` and name it ``ihatemoney.cfg``.
-Then adjust the settings to your needs and move this file to
-``/etc/ihatemoney/ihatemoney.cfg``.
+.. _the SQLAlchemy documentation: http://docs.sqlalchemy.org/en/latest/core/engines.html#database-urls
-This is the default path of the settings but you can also place it
-elsewhere and pass the configuration file path to the application using
-the IHATEMONEY_SETTINGS_FILE_PATH environment variable.
+Using an alternate settings path
+--------------------------------
+
+You can put your settings file where you want, and pass its path to the
+application using the ``IHATEMONEY_SETTINGS_FILE_PATH`` environment variable.
e.g.::
diff --git a/ihatemoney/conf-templates/apache-vhost.conf.j2 b/ihatemoney/conf-templates/apache-vhost.conf.j2
new file mode 100644
index 00000000..cb0167f5
--- /dev/null
+++ b/ihatemoney/conf-templates/apache-vhost.conf.j2
@@ -0,0 +1,19 @@
+
+ ServerAdmin admin@example.com # CUSTOMIZE
+ ServerName ihatemoney.example.com # CUSTOMIZE
+
+ WSGIDaemonProcess ihatemoney user=www-data group=www-data threads=5 python-path={{ pkg_path }} {% if venv_path %}python-home={{ venv_path }}{% endif %}
+ WSGIScriptAlias / {{ pkg_path }}/wsgi.py
+
+ ErrorLog /var/log/apache2/ihatemoney.example.com_error.log
+ CustomLog /var/log/apache2/ihatemoney.example.com_access.log combined
+
+
+ WSGIProcessGroup ihatemoney
+ WSGIApplicationGroup %{GLOBAL}
+ Order deny,allow
+ Allow from all
+
+
+ Alias /static/ {{ pkg_path }}/static/
+
diff --git a/ihatemoney/conf-templates/gunicorn.conf.py.j2 b/ihatemoney/conf-templates/gunicorn.conf.py.j2
new file mode 100644
index 00000000..2c4492de
--- /dev/null
+++ b/ihatemoney/conf-templates/gunicorn.conf.py.j2
@@ -0,0 +1,8 @@
+backlog = 2048
+daemon = False
+debug = True
+workers = 3
+# log to stdout,
+logfile = "-" # Is the default setting for gunicorn>=20
+loglevel = "info"
+bind = "unix:/tmp/ihatemoney.gunicorn.sock"
diff --git a/ihatemoney/conf-templates/ihatemoney.cfg.j2 b/ihatemoney/conf-templates/ihatemoney.cfg.j2
new file mode 100644
index 00000000..5dfb9d47
--- /dev/null
+++ b/ihatemoney/conf-templates/ihatemoney.cfg.j2
@@ -0,0 +1,36 @@
+# You can find more information about what these settings mean in the
+# documentation, available online at
+# http://ihatemoney.readthedocs.io/en/latest/installation.html#configuration
+
+# Turn this on if you want to have more output on what's happening under the
+# hood. DO NOT TURN IT ON IN PRODUCTION.
+DEBUG = False
+
+# The database URI, reprensenting the type of database and how to connect to it.
+# Enter an absolute path here.
+SQLALCHEMY_DATABASE_URI = 'sqlite:///var/lib/ihatemoney/ihatemoney.sqlite'
+SQLACHEMY_ECHO = DEBUG
+
+# Will likely become the default value in flask-sqlalchemy >=3 ; could be removed
+# then:
+SQLALCHEMY_TRACK_MODIFICATIONS = False
+
+# This secret key is random and auto-generated, it protects cookies and user sessions
+SECRET_KEY = "{{ secret_key }}"
+
+# A python tuple describing the name and email adress of the sender of the mails.
+MAIL_DEFAULT_SENDER = ("Budget manager", "budget@notmyidea.org") # CUSTOMIZE
+
+# If set to True, a demonstration project will be activated.
+ACTIVATE_DEMO_PROJECT = True
+
+# If not empty, the specified password must be entered to create new projects.
+# DO NOT enter the password in cleartext. Generate a password hash with
+# "ihatemoney generate_password_hash" instead.
+ADMIN_PASSWORD = ""
+
+# If set to True (default value) anyone can create a new project.
+ALLOW_PUBLIC_PROJECT_CREATION = True
+
+# If set to True, an administration dashboard is available.
+ACTIVATE_ADMIN_DASHBOARD = False
diff --git a/conf/nginx.conf b/ihatemoney/conf-templates/nginx.conf.j2
similarity index 67%
rename from conf/nginx.conf
rename to ihatemoney/conf-templates/nginx.conf.j2
index 0fe26f02..42b45fc0 100644
--- a/conf/nginx.conf
+++ b/ihatemoney/conf-templates/nginx.conf.j2
@@ -1,11 +1,9 @@
server {
- server_name yourur;
+ server_name ihatemoney.example.com; # CUSTOMIZE
keepalive_timeout 5;
location /static/ {
- # Alias value may be some messy path, within python libs.
- # You may want to use "find $VIRTUAL_ENV -path */ihatemoney*/static" to find it.
- alias /path/to/app/ihatemoney/static/;
+ alias {{ pkg_path }}/static/;
}
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@@ -26,5 +24,5 @@ server {
}
upstream ihatemoney_backend {
- server unix:/path/to/app/ihatemoney.gunicorn.sock;
+ server unix:/tmp/ihatemoney.gunicorn.sock;
}
diff --git a/ihatemoney/conf-templates/supervisord.conf.j2 b/ihatemoney/conf-templates/supervisord.conf.j2
new file mode 100644
index 00000000..fa16c0cf
--- /dev/null
+++ b/ihatemoney/conf-templates/supervisord.conf.j2
@@ -0,0 +1,6 @@
+[program:ihatemoney]
+command={{ venv_path }}/bin/gunicorn -c /etc/ihatemoney/gunicorn.conf.py ihatemoney.wsgi:application
+user=ihatemoney
+autostart=true
+autorestart=true
+redirect_stderr=true
diff --git a/ihatemoney/default_settings.py b/ihatemoney/default_settings.py
index c7ce2973..6033d0ab 100644
--- a/ihatemoney/default_settings.py
+++ b/ihatemoney/default_settings.py
@@ -1,37 +1,10 @@
-# You can find more information about what these settings mean in the
-# documentation, available online at
-# http://ihatemoney.readthedocs.io/en/latest/installation.html#configuration
-
-# Turn this on if you want to have more output on what's happening under the
-# hood.
-DEBUG = False
-
-# The database URI, reprensenting the type of database and how to connect to it.
-# Enter an absolute path here.
+# Verbose and documented settings are in conf-templates/ihatemoney.cfg.j2
+DEBUG = SQLACHEMY_ECHO = False
SQLALCHEMY_DATABASE_URI = 'sqlite:////tmp/ihatemoney.db'
-SQLACHEMY_ECHO = DEBUG
-
-# Will likely become the default value in flask-sqlalchemy >=3 ; could be removed
-# then:
SQLALCHEMY_TRACK_MODIFICATIONS = False
-
-# You need to change this secret key, otherwise bad things might happen to your
-# users.
SECRET_KEY = "tralala"
-
-# A python tuple describing the name and email adress of the sender of the mails.
MAIL_DEFAULT_SENDER = ("Budget manager", "budget@notmyidea.org")
-
-# If set to True, a demonstration project will be activated.
ACTIVATE_DEMO_PROJECT = True
-
-# If not empty, the specified password must be entered to create new projects.
-# DO NOT enter the password in cleartext. Generate a password hash with
-# "ihatemoney generate_password_hash" instead.
ADMIN_PASSWORD = ""
-
-# If set to True (default value) anyone can create a new project.
ALLOW_PUBLIC_PROJECT_CREATION = True
-
-# If set to True, an administration dashboard is available.
ACTIVATE_ADMIN_DASHBOARD = False
diff --git a/ihatemoney/manage.py b/ihatemoney/manage.py
index 6f63a98c..c1821c59 100755
--- a/ihatemoney/manage.py
+++ b/ihatemoney/manage.py
@@ -1,8 +1,13 @@
#!/usr/bin/env python
+import os
+import pkgutil
+import random
from getpass import getpass
-from flask_script import Manager, Command
+
+from flask_script import Manager, Command, Option
from flask_migrate import Migrate, MigrateCommand
+from jinja2 import Template
from werkzeug.security import generate_password_hash
from ihatemoney.run import create_app
@@ -18,6 +23,38 @@ class GeneratePasswordHash(Command):
print(generate_password_hash(password))
+class ConfigTemplate(Command):
+ def get_options(self):
+ return [
+ Option('config_file', choices=[
+ 'ihatemoney.cfg',
+ 'apache-vhost.conf',
+ 'gunicorn.conf.py',
+ 'supervisord.conf',
+ 'nginx.conf',
+ ]),
+ ]
+
+ @staticmethod
+ def gen_secret_key():
+ return ''.join([
+ random.SystemRandom().choice(
+ 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)')
+ for i in range(50)])
+
+ def run(self, config_file):
+ template_content = pkgutil.get_data(
+ 'ihatemoney',
+ os.path.join('conf-templates/', config_file) + '.j2'
+ ).decode('utf-8')
+
+ print(Template(template_content).render(
+ pkg_path=os.path.abspath(os.path.dirname(__file__)),
+ venv_path=os.environ.get('VIRTUAL_ENV'),
+ secret_key=self.gen_secret_key(),
+ ))
+
+
def main():
app = create_app()
Migrate(app, db)
@@ -25,6 +62,7 @@ def main():
manager = Manager(app)
manager.add_command('db', MigrateCommand)
manager.add_command('generate_password_hash', GeneratePasswordHash)
+ manager.add_command('generate-config', ConfigTemplate)
manager.run()