Commit a6d61cb6 authored by Alexandre Friquet's avatar Alexandre Friquet
Browse files

Use docker for development

parent 2c271704
#
# OLIGAA - Stands for "Outil en Ligne d'Information et de Gestion des Activités
# des Associations" which is an online tool for associations to manage news,
# actors and activities.
# Copyright (C) 2010-2019 Comité Départemental du Sport Adapté de la Gironde (CDSA
# 33) <contact@cdsa33.org>
#
# This file is part of OLIGAA.
#
# OLIGAA is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# OLIGAA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with OLIGAA. If not, see <http://www.gnu.org/licenses/>.
#
# Used for cookies store name : identifies your app
APP_ID=OLIGAA
# Used for pdf file names and other stuff
APP_NAME="OLIGAA Test"
# Secret token to verify identity of the provided cookies
# at least 30 chars : try `rake secret`
APP_SECRET_TOKEN='cookies_secret'
# Secret used to prevent cross-site scripting attacks
# with URL store for breadcrumb
GRETEL_TRAILS_SECRET='gretel_secret'
# Google service account Oauth 2.0 client ID for Google
# Calendar synchronization
# GOOGLE_CLIENT_ID=''
# Mainly used for ContactUs mails (usefull for SPF and DKIM)
DEFAULT_MAIL_FROM=www@test.tld
......@@ -5,8 +5,13 @@ log/*.log
tmp/
public/system
.DS_Store
vendor/bundle*
coverage
.env
.byebug_history
# vim
*.swp
# docker
core
log/.bash_history
FROM ruby:2.3.6-slim-stretch
# Base for Rails
RUN apt-get update -qq \
&& DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends \
build-essential \
gnupg2 \
curl \
less \
git \
vim \
xvfb xauth \
nodejs \
tmux \
&& apt-get clean \
&& rm -rf /var/cache/apt/archives/* \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
&& truncate -s 0 /var/log/*log
# DB
RUN apt-get update -qq \
&& DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends \
libmariadb-dev \
&& apt-get clean \
&& rm -rf /var/cache/apt/archives/* \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
&& truncate -s 0 /var/log/*log
# Specific to app
RUN apt-get update -qq \
&& DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends \
imagemagick \
g++ qt5-default libqt5webkit5-dev gstreamer1.0-plugins-base gstreamer1.0-tools gstreamer1.0-x \
&& apt-get clean \
&& rm -rf /var/cache/apt/archives/* \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
&& truncate -s 0 /var/log/*log
ENV LANG=C.UTF-8 \
BUNDLER_VERSION=2.0.2 \
BUNDLE_JOBS=4 \
BUNDLE_RETRY=3 \
TZ='/usr/share/zoneinfo/Europe/Paris'
RUN gem update --system && \
gem install bundler:$BUNDLER_VERSION && \
rm -rf $GEM_HOME/cache/*
RUN mkdir -p /app
WORKDIR /app
......@@ -59,9 +59,9 @@ gem 'font-awesome-rails'
gem 'jquery-minicolors-rails'
gem 'prettyphoto-rails'
gem 'validates_timeliness', '~> 5.0.0.alpha3'
gem 'mysql2'
group :development, :test do
gem "sqlite3"
gem 'rspec-rails'
gem 'byebug'
gem 'listen'
......@@ -77,7 +77,6 @@ group :test do
gem 'factory_girl_rails'
gem 'shoulda-matchers', git: 'https://github.com/thoughtbot/shoulda-matchers.git', branch: 'rails-5'
gem 'test-unit', '~> 3.0' # For shoulda-matchers with ruby 2.3+
gem 'database_cleaner'
# see https://github.com/thoughtbot/capybara-webkit/issues/1065
gem 'capybara-webkit', github: 'thoughtbot/capybara-webkit', branch: 'master'
gem 'fuubar'
......
......@@ -95,7 +95,7 @@ GEM
bindex (0.5.0)
bluecloth (2.2.0)
brakeman (3.7.2)
builder (3.2.3)
builder (3.2.4)
byebug (9.1.0)
capybara (3.7.1)
addressable
......@@ -132,24 +132,23 @@ GEM
compass (~> 1.0.0)
sass-rails (< 5.1)
sprockets (< 4.0)
concurrent-ruby (1.1.5)
concurrent-ruby (1.1.8)
crack (0.4.3)
safe_yaml (~> 1.0.0)
crass (1.0.4)
crass (1.0.6)
daemons (1.2.4)
database_cleaner (1.6.1)
delayed_job (4.1.3)
activesupport (>= 3.0, < 5.2)
delayed_job_active_record (4.1.2)
activerecord (>= 3.0, < 5.2)
delayed_job (>= 3.0, < 5)
diff-lcs (1.3)
diff-lcs (1.4.4)
docile (1.1.5)
dotenv (2.2.1)
dotenv-rails (2.2.1)
dotenv (= 2.2.1)
railties (>= 3.2, < 5.2)
erubi (1.8.0)
erubi (1.10.0)
execjs (2.7.0)
extlib (0.9.16)
factory_girl (4.8.0)
......@@ -223,27 +222,28 @@ GEM
logging (2.2.2)
little-plugger (~> 1.1)
multi_json (~> 1.10)
loofah (2.2.3)
loofah (2.9.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.7.1)
mini_mime (>= 0.1.1)
memoist (0.16.0)
method_source (0.9.2)
method_source (1.0.0)
mime-types (3.2.2)
mime-types-data (~> 3.2015)
mime-types-data (3.2018.0812)
mimemagic (0.3.2)
mini_mime (1.0.2)
mini_portile2 (2.4.0)
minitest (5.11.3)
minitest (5.14.3)
momentjs-rails (2.17.1)
railties (>= 3.1)
multi_json (1.12.2)
multipart-post (2.0.0)
mysql2 (0.5.3)
nested_form (0.3.2)
nio4r (2.4.0)
nokogiri (1.10.4)
nokogiri (1.10.10)
mini_portile2 (~> 2.4.0)
os (0.9.6)
paperclip (5.1.0)
......@@ -261,7 +261,7 @@ GEM
uglifier
public_suffix (3.0.3)
puma (3.10.0)
rack (2.0.7)
rack (2.2.3)
rack-test (1.1.0)
rack (>= 1.0, < 3)
rails (5.1.7)
......@@ -279,37 +279,37 @@ GEM
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.2.0)
loofah (~> 2.2, >= 2.2.2)
rails-html-sanitizer (1.3.0)
loofah (~> 2.3)
railties (5.1.7)
actionpack (= 5.1.7)
activesupport (= 5.1.7)
method_source
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
rake (12.3.3)
rake (13.0.3)
rb-fsevent (0.10.2)
rb-inotify (0.9.10)
ffi (>= 0.5.0, < 2)
rdoc (5.1.0)
retriable (1.4.1)
rspec-core (3.6.0)
rspec-support (~> 3.6.0)
rspec-expectations (3.6.0)
rspec-core (3.10.1)
rspec-support (~> 3.10.0)
rspec-expectations (3.10.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.6.0)
rspec-mocks (3.6.0)
rspec-support (~> 3.10.0)
rspec-mocks (3.10.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.6.0)
rspec-rails (3.6.1)
actionpack (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
rspec-core (~> 3.6.0)
rspec-expectations (~> 3.6.0)
rspec-mocks (~> 3.6.0)
rspec-support (~> 3.6.0)
rspec-support (3.6.0)
rspec-support (~> 3.10.0)
rspec-rails (4.0.2)
actionpack (>= 4.2)
activesupport (>= 4.2)
railties (>= 4.2)
rspec-core (~> 3.10)
rspec-expectations (~> 3.10)
rspec-mocks (~> 3.10)
rspec-support (~> 3.10)
rspec-support (3.10.2)
ruby-progressbar (1.8.3)
ruby_dep (1.5.0)
safe_yaml (1.0.4)
......@@ -340,18 +340,17 @@ GEM
actionpack (>= 4.0)
activesupport (>= 4.0)
sprockets (>= 3.0.0)
sqlite3 (1.3.13)
susy (2.2.12)
sass (>= 3.3.0, < 3.5)
test-unit (3.2.5)
power_assert
thor (0.20.3)
thor (1.1.0)
thread_safe (0.3.6)
tilt (2.0.8)
timecop (0.8.1)
timeliness (0.3.8)
truncate_html (0.9.3)
tzinfo (1.2.5)
tzinfo (1.2.9)
thread_safe (~> 0.1)
uglifier (3.2.0)
execjs (>= 0.3.0, < 3)
......@@ -386,7 +385,6 @@ DEPENDENCIES
coffee-rails
compass-rails
daemons
database_cleaner
delayed_job
delayed_job_active_record
dotenv-rails
......@@ -409,6 +407,7 @@ DEPENDENCIES
leaflet-rails
listen
momentjs-rails
mysql2
nested_form
paperclip
pdfkit
......@@ -422,7 +421,6 @@ DEPENDENCIES
shoulda-matchers!
simple_form
simplecov (>= 0.4.0)
sqlite3
susy
test-unit (~> 3.0)
timecop (~> 0.8.0)
......
......@@ -35,21 +35,31 @@ Si ce que vous venez de lire ne vous parle pas, nous vous invitons à vous rappr
### Poste de développement
Avant de démarrer l'application pour la première fois, vous devez, dans le répertoire du projet :
0. Installer les dépendances : `bundle install` ;
0. Configurer votre environnement
0. Copier le fichier `.env.example` vers `.env` ;
0. Modifier les informations dans ce nouveau fichier.
0. Initialiser la base de données : `bundle exec rake db:setup` ;
0. Créer le compte administrateur : `bundle exec rake oligaa:create_admin`
Pour simplifier la mise en place d'un environnement de développement le choix a été fait d'utiliser [Docker](https://www.docker.com/), mais il est tout à fait possible d'installer l'application de manière conventionnelle, modulo quelques adaptations (*mysql*, *mailcatcher*, *overmind*).
Pour Docker :
1. installer [Docker](https://docs.docker.com/engine/install/)
1. installer [docker-compose](https://docs.docker.com/compose/install/)
1. construire l'image : `docker-compose build`
1. récupérer les images et lancer les conteneurs : `docker-compose up`
1. lister des conteneurs actifs : `docker-compose ps`
1. accéder au terminal du conteneur de l'application : `docker-compose exec app bash`
1. arrêter les conteneurs : `docker-compose down`
Avant de démarrer l'application pour la première fois, vous devez :
1. Accéder au terminal du conteneur si vous utilisez Docker ;
1. Installer les dépendances : `bundle install` ;
1. Configurer votre environnement
1. Copier le fichier `.env.example` vers `.env` ;
1. Modifier les informations dans ce nouveau fichier.
1. Initialiser la base de données : `bundle exec rake db:setup` ;
1. Créer le compte administrateur : `bundle exec rake oligaa:create_admin`
* N'oubliez pas de noter le mot de passe affiché dans votre terminal.
Vous pouvez alors :
0. Lancer le serveur : `bundle exec rails s Puma` ;
0. Vous connecter avec l'identifiant `admin` et le mot de passe noté plus tôt.
Vous pouvez alors vous connecter avec l'identifiant `admin` et le mot de passe noté plus tôt.
#### Éxécution des tests
#### Exécution des tests
Tout nouveau développement doit être accompagné de son jeu de tests, qui garantira qu'aucune régression ne pourra se glisser dans le futur. Pour leur écriture, nous utilisons la bibliothèque [RSpec](http://rspec.info/) pour tous les types de test. Pour vous assurer que tout fonctionne comme attendu, vous pouvez lancer la suite de tests complète et vérifier que tout se déroule sans erreur, grâce à la commande habituelle :
```
......@@ -58,11 +68,15 @@ $ bundle exec rake
XXX examples, 0 failures
```
Avec Docker :
1. se connecter au conteneur de l'application : `docker-compose exec app bash`
1. lancer les tests : `xvfb-run bundle exec rake`
### Déploiement sur serveur
OLIGAA se déploie comme nombre d'applications Rails, sur hébergement dédié ou mutualisé. Les solutions habituelles telles que [Phusion Passenger](https://www.phusionpassenger.com/) ou _Nginx/Apache + Puma/Unicorn/Thin…_ fonctionnent sans problème. À titre d'exemple, le CDSA33 utilise un hébergement mutualisé chez [AlwaysData](https://www.alwaysdata.com/pricing/#shared), servi par _Apache + Passenger_.
OLIGAA se déploie comme nombre d'applications Rails, sur hébergement dédié ou mutualisé. Les solutions habituelles telles que [Phusion Passenger](https://www.phusionpassenger.com/) ou _Nginx/Apache + Puma/Unicorn/Thin…_ fonctionnent sans problème. À titre d'exemple, le CDSA33 utilise un serveur dédié servi par _Apache + Passenger_.
Vous devez également avoir à disposition une base de données relationnelle (MySQL par exemple), les bases SQLite utilisées en environnement de développement et test n'étant pas adaptées à un environnement de production.
Vous devez également avoir à disposition une base de données relationnelle : MariaDB est recommandée car c'est celle qui est utilisée en production et pour les tests, mais PostgreSQL devrait faire l'affaire sans problème.
**NB :** OLIGAA n'a pas été testé sur les plateformes de _cloud PaaS_ telles que Heroku.
......
......@@ -34,7 +34,8 @@ class ContactUsController < ApplicationController
Mailer.contact_us(@mail).deliver_now
flash[:notice] = "Votre email a été envoyé avec succès."
redirect_to root_path
rescue
rescue => exception
Rails.logger.error exception
flash.now[:error] = "Nous n'avons pu envoyer votre email pour une raison quelconque. Merci d'essayer un peu plus tard. Si le problème persiste, merci de nous contacter par téléphone."
render :new
end
......
......@@ -20,14 +20,17 @@
# You should have received a copy of the GNU Affero General Public License
# along with OLIGAA. If not, see <http://www.gnu.org/licenses/>.
#
common: &common
adapter: mysql2
host: db
username: root
password: passw0rd
development:
adapter: sqlite3
database: db/development.sqlite3
pool: 5
timeout: 5000
<<: *common
database: oligaa
test:
adapter: sqlite3
database: db/test.sqlite3
pool: 5
timeout: 5000
\ No newline at end of file
<<: *common
database: oligaa-test
......@@ -51,7 +51,7 @@ Rails.application.configure do
config.action_mailer.raise_delivery_errors = true
config.action_mailer.perform_caching = false
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = { address: "localhost", port: 1025 }
config.action_mailer.smtp_settings = { address: "mailcatcher", port: 1025 }
# Print deprecation notices to the Rails logger.
config.active_support.deprecation = :log
......
# See https://stackoverflow.com/a/21912537
require 'paperclip/media_type_spoof_detector'
module Paperclip
class MediaTypeSpoofDetector
def spoofed?
false
end
end
end
class DatetimePrecisionMigration < ActiveRecord::Migration[5.1]
def change
reversible do |change|
# Migrate Up
change.up do
table_columns do |table, column|
# MySQL supports time precision down to microseconds -- DATETIME(6)
change_column table, column, :datetime, limit: 6
end
end
# Migrate Down
change.down do
table_columns do |table, column|
change_column table, column, :datetime
end
end
# NOTE: only MySQL 5.6.4 and above supports DATETIME's with more precision
# than a second. See https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-4.html#mysqld-5-6-4-fractional-seconds
end
end
private
def table_columns
# Iterate through all tables in this environment's database
ActiveRecord::Base.connection.tables.each do |table|
# Iterate through all columns in table
ActiveRecord::Base.connection.columns(table).each do |column|
yield table, column.name if column.type == :datetime && block_given?
end
end
end
end
This diff is collapsed.
version: '2.4'
services:
app:
build:
context: .
dockerfile: Dockerfile
image: oligaa:1.0
stdin_open: true
tty: true
volumes:
- .:/app
- bundle:/usr/local/bundle
- rails_cache:/app/tmp/cache
environment:
- RAILS_ENV=${RAILS_ENV:-development}
- HISTFILE=/app/log/.bash_history
- EDITOR=vim
entrypoint: docker/entrypoint_app.sh
ports:
- '3000:3000'
jobs:
image: oligaa:1.0
stdin_open: true
tty: true
volumes:
- .:/app
- bundle:/usr/local/bundle
- rails_cache:/app/tmp/cache
environment:
- RAILS_ENV=${RAILS_ENV:-development}
- HISTFILE=/app/log/.bash_history
- EDITOR=vim
command: bundle exec rake jobs:work
depends_on:
- app
mailcatcher:
image: rordi/docker-mailcatcher
container_name: mailcatcher
ports:
- 1080:1080
db:
image: mariadb:10.3
environment:
MYSQL_ROOT_PASSWORD: passw0rd
volumes:
- mysql-data:/var/lib/mysql
volumes:
mysql-data:
bundle:
rails_cache:
#!/bin/bash
# Cleanup
rm -f tmp/pids/server.pid
# Start
bundle exec rails s -b 0.0.0.0 -p 3000
......@@ -22,6 +22,6 @@
#
FactoryGirl.define do
factory :contact_type do
title {"Type de contact #{Faker::Lorem.unique.word}"}
sequence(:title) { |n| "Type de contact #{n}"}
end
end
......@@ -22,7 +22,7 @@
#
FactoryGirl.define do
factory :member do
login { "member-login-#{Faker::Lorem.unique.word}" }
sequence(:login) { |n| "member-login-#{n}" }
name { "Membre #{Faker::Lorem.unique.word}" }
description "Member description"
address "Member address"
......
......@@ -22,6 +22,6 @@
#
FactoryGirl.define do
factory :menu do
title {"Menu-#{Faker::Lorem.unique.word}"}
sequence(:title) { |n| "Menu-#{n}"}
end
end
......@@ -43,7 +43,7 @@ feature "Manage Member Groups" do
click_create_button
end
expect(current_path).to eq(member_group_path(Member.first))
expect(current_path).to eq(member_group_path(MemberGroup.last))
within "section#content" do
expect(page).to have_content "Le groupe de membres a été créé avec succès."
expect(page).to have_selector("h1", text: mg.title)
......
......@@ -110,7 +110,7 @@ feature "Manage Settings" do
expect(current_path).to eq(edit_settings_path)
expect(page).to have_content "Les paramètres ont bien été mis à jour"
within "header h1" do
expect(page.find('img.logo')['src']).to have_content '/system/site_logos/1/standard/sample_image.png'
expect(page.find('img.logo')['src']).to have_content "sample_image.png"
end
end
......@@ -120,7 +120,7 @@ feature "Manage Settings" do
visit root_path
within "header h1" do
expect(page.find('img.logo')['src']).to have_content '/system/site_logos/1/standard/sample_image.png'
expect(page.find('img.logo')['src']).to have_content "sample_image.png"
end
visit edit_settings_path
......@@ -154,7 +154,7 @@ feature "Manage Settings" do
expect(page).to have_content "Les paramètres ont bien été mis à jour"
within "header h2" do
expect(page).to have_content @settings.motto
expect(page.find('img.motto_logo')['src']).to have_content '/system/motto_logos/1/standard/sample_image.png'
expect(page.find('img.motto_logo')['src']).to have_content "sample_image.png"
end
end
......@@ -165,7 +165,7 @@ feature "Manage Settings" do
visit root_path
within "header h2" do
expect(page).to have_content @settings.motto
expect(page.find('img.motto_logo')['src']).to have_content '/system/motto_logos/1/standard/sample_image.png'
expect(page.find('img.motto_logo')['src']).to have_content "sample_image.png"
end
visit edit_settings_path
......
......@@ -59,4 +59,4 @@ describe Newsletter do
expect(Newsletter.ordered).to eq([n3, n2, n1])
end
end
end
\ No newline at end of file
end
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment