Skip to content

Framadate Install Guide

Schedule meetings or create opinion polls quickly and easily with this open source software.

Warning

The Framadate project is now in maintenance mode, see issue #545.

Prerequisites

Assumptions

  • General understanding of using a Linux terminal (command-line interface)
  • Steps prefixed with a "$" (dollar sign) represents the CLI prompt; The text after the "$" is to be entered at the CLI
  • Steps prefixed with a "#" (number sign) represents the CLI prompt with elevated user permissions (e.g. root); The text after the "#" is to be entered at the CLI

Environment

The instructions are tested using the following.

  • Arch Linux
  • PHP v8.1.12
  • Nginx v1.22.1

Preparation

Choose one of the following database systems.

MySQL/MariaDB/Percona

  1. Connect to database system.

    $ mysql -u root -p
    

  2. Create database.

    CREATE DATABASE IF NOT EXISTS `framadate` DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
    

  3. Create database user for Framadate.

    CREATE USER 'framadate'@'localhost' IDENTIFIED BY 'useastrongpassword';
    GRANT ALL PRIVILEGES ON `framadate`.* TO 'framadate'@'localhost';
    

    Tip

    If database is on another server replace the hostname, "localhost" with applicable value.

PostgreSQL

  1. Connect to database system.

    $ psql -U root
    

  2. Create database.

    CREATE DATABASE framadate;
    

  3. Create database user for Framadate.

    CREATE USER 'framadate'@'localhost' WITH PASSWORD 'useastrongpassword';
    

  4. Grant user privileges.

    GRANT ALL PRIVILEGES ON DATABASE framadate to 'framadate'@'localhost';
    

    Tip

    If database is on another server replace the hostname, "localhost" with applicable value.

Instructions

  1. Download the latest release archive, Framadate project.
  2. Decompress the downloaded archive.

    $ unzip framadate-1.1.19.zip
    

  3. Change directory.

    $ cd framadate-1.1.19/
    

  4. Install dependencies.

    $ composer install -a
    

  5. Create log file.

    $ touch admin/stdout.log
    

  6. Generate authentication file for admin.

    $ htpasswd -c admin/.htpasswd username
    New password:
    Re-type new password:
    

  7. Move directory.

    # mv ~/Downloads/framadate-1.1.19 /srv/http/framadate
    

  8. Set user/group ownership.

    # chown -r http:http /srv/http/framadate/
    

  9. Set permissions.

    $ chmod 600 /srv/http/framadate/admin/stdout.log
    

  10. Create Nginx site configuration.

    # nano /etc/nginx/sites-available/framadate.conf
    
    server {
        listen 80;
        listen [::]:80;
        server_name date.example.org;
        return 301 https://$host$request_uri;
    }
    
    server {
            listen 443 ssl http2;
            listen [::]:443 ssl http2; # For ipv6 only
            server_name date.example.org;
    
        # This must be adapted if you use cdn or stats scripts.
        add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; object-src 'none'; style-src 'self' 'unsafe-inline'; font-src 'self'; img-src 'self'";
        add_header Referrer-Policy "strict-origin";
    
        # Those ssl certificates is generated by letsencrypt, to create an certificates
        # through letsencrypt information are available here https://certbot.eff.org/lets-encrypt/debianstretch-nginx
        # For secure ssl configuration, look also at https://mozilla.github.io/server-side-tls/ssl-config-generator/
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_certificate /etc/letsencrypt/live/date.example.org/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/date.example.org/privkey.pem;
    
    
            access_log /var/log/nginx/date.example.org.access.log;
            error_log /var/log/nginx/date.example.org.error.log;
    
            root /path/to/your/framadate;
    
            index index.php;
    
        location ~^/(\.git)/{
            deny all;
        }
        location ~ /\. {
            deny all;
        }
    
        location ~ ^/composer\.json.*$|^/composer\.lock.*$|^/php\.ini.*$|^/.*\.sh {
            deny all;
        }
    
            location /admin/ {
            auth_basic "Restricted access";
            auth_basic_user_file /path/to/framadate/admin/.htpasswd;
    
            location ~ \.php$ {
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include /etc/nginx/fastcgi_params;
                fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
            }
            try_files $uri $uri/ =401;
        }
    
            location / {
            rewrite "^/admin$" "/admin/" permanent;
    
                # Clean URL
            rewrite "^/([a-zA-Z0-9-]+)$" "/studs.php?poll=$1" last;
            rewrite "^/([a-zA-Z0-9-]+)/action/([a-zA-Z_-]+)/(.+)$" "/studs.php?poll=$1&$2=$3" last;
            rewrite "^/([a-zA-Z0-9-]+)/vote/([a-zA-Z0-9]{16})$" "/studs.php?poll=$1&vote=$2" last;
            rewrite "^/([a-zA-Z0-9]{24})/admin$" "/adminstuds.php?poll=$1" last;
            rewrite "^/([a-zA-Z0-9]{24})/admin/vote/([a-zA-Z0-9]{16})$" "/adminstuds.php?poll=$1&vote=$2" last;
            rewrite "^/([a-zA-Z0-9]{24})/admin/action/([a-zA-Z_-]+)(/([A-Za-z0-9]+))?$" "/adminstuds.php?poll=$1&$2=$4" last;
                    try_files $uri /index.php;
            }
    
    
    
    
            location ~ \.php$ {
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_index index.php;
                include /etc/nginx/fastcgi_params;
                fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
            }
    }
    

  11. Following on screen instructions.

    Browse to the configured server address (e.g. https://date.example.org) and then follow on scree instructions.

  12. Set SMTP configuration.

    # nano /srv/http/framadate/app/inc/config.php
    
    'smtp_options' => [
        'host' => 'localhost',              // SMTP server (you could add many servers (main and backup for example) : use ";" like sepa>
        'auth' => false,                    // Enable SMTP authentication
        'username' => '',                   // SMTP username
        'password' => '',                   // SMTP password
        'secure' => '',                     // Enable encryption (false, tls or ssl)
        'port' => 25,                       // TCP port to connect to
    ],
    

Config Example

The following is a working configuration file, "app/inc/config.php".

<?php
/**
 * This software is governed by the CeCILL-B license. If a copy of this license
 * is not distributed with this file, you can obtain one at
 * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt
 *
 * Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ
 * Authors of Framadate/OpenSondage: Framasoft (https://github.com/framasoft)
 *
 * =============================
 *
 * Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence
 * ne se trouve pas avec ce fichier vous pouvez l'obtenir sur
 * http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt
 *
 * Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
 * Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
 */

// Fully qualified domain name of your webserver.
// If this is unset or empty, the servername is determined automatically.
// You *have to set this* if you are running Framadate behind a reverse proxy.
// const APP_URL = '<www.mydomain.fr>';

// Application name
const NOMAPPLICATION = 'Framadate';

// Database administrator email
const ADRESSEMAILADMIN = 'webmaster@example.com';

// Email for automatic responses (you should set it to "no-reply")
const ADRESSEMAILREPONSEAUTO = '';

// Database server name, leave empty to use a socket
const DB_CONNECTION_STRING = 'mysql:host=localhost;dbname=framadate;port=3306';

// Database user
const DB_USER= 'framadate';

// Database password
const DB_PASSWORD = 'framadate';

// Table name prefix
const TABLENAME_PREFIX = '';

// Name of the table that stores migration script already executed
const MIGRATION_TABLE = 'framadate_migration';

// Default Language
const DEFAULT_LANGUAGE = 'en';

// List of supported languages, fake constant as arrays can be used as constants only in PHP >=5.6
$ALLOWED_LANGUAGES = [
    'fr' => 'Français',
    'en' => 'English',
    'oc' => 'Occitan',
    'es' => 'Español',
    'de' => 'Deutsch',
    'nl' => 'Dutch',
    'it' => 'Italiano',
    'br' => 'Brezhoneg',
    'ca' => 'Català',
];

// Path to image file with the title
const IMAGE_TITRE = 'images/logo-framadate.png';

// Clean URLs, boolean
const URL_PROPRE = true;

// Use REMOTE_USER data provided by web server
const USE_REMOTE_USER =  true;

// Path to the log file
const LOG_FILE = 'admin/stdout.log';

// Days (after expiration date) before purging a poll
const PURGE_DELAY = 60;

// Max slots per poll
const MAX_SLOTS_PER_POLL = 366;

// Number of seconds before we allow to resend an "Remember Edit Link" email.
const TIME_EDIT_LINK_EMAIL = 60;

// Config
$config = [
    /* general config */
    'use_smtp' => true,                      // use email for polls creation/modification/responses notification
    'smtp_options' => [
        'host' => 'smtp.example.com',        // SMTP server (you could add many servers (main and backup for example) : use ";" like separator
        'auth' => true,                      // Enable SMTP authentication
        'username' => 'noreply@example.com', // SMTP username
        'password' => '',                    // SMTP password
        'secure' => 'ssl',                   // Enable encryption (false, tls or ssl)
        'port' => 465,                       // TCP port to connect to
    ],
    /* home */
    'show_what_is_that' => true,            // display "how to use" section
    'show_the_software' => true,            // display technical information about the software
    'show_cultivate_your_garden' => true,   // display "development and administration" information
    /* create_classic_poll.php / create_date_poll.php */
    'default_poll_duration' => 180,         // default values for the new poll duration (number of days).
    /* create_classic_poll.php */
    'user_can_add_img_or_link' => true,     // user can add link or URL when creating his poll.
    'markdown_editor_by_default' => true,   // The markdown editor for the description is enabled by default
    'provide_fork_awesome' => true,         // Whether the build-in fork-awesome should be provided
];