no-pain web development
Part I make your web app 
90's
easy but static
cgi-scripts....
netscape index.html
90's
easy but static
cgi-scripts....
netscape index.html
mozilla http://localhost/my-app
PHP
apache server required
easy deployment
+ database
2000's
The rise of web frameworks
… and databases
extra configuration
the deployment requires daemonization
and more configuration
2010's
Single-page applications
real app in the browser
framework required: Backone, Angular, Ember...…
JS files require organization and assembling
HTML templates?…
Coffeescript? Livescript?… …
css pre-processors
your CSS files need a build
before coding any feature I need to...
chose two frameworks
before coding any feature I need to...
chose two frameworks
chose a database
before coding any feature I need to...
chose two frameworks
chose a database
configure my app
before coding any feature I need to...
chose two frameworks
chose a database
configure my app
handle deployment
before coding any feature I need to...
chose two frameworks
chose a database
configure my app
handle deployment
assemble my front-end files
before coding any feature I need to...
chose two frameworks
chose a database
configure my app
handle deployment
assemble my front-end files
build my stylesheets
NEED HELP?…
Part II Templates
chose your frameworks and your
database
sorry there is no golden rule for this
how to organize my files and my
configuration ? 
people already use your framework and know
the good practices
they provide application templates
your templates are like your dotfiles
clone a template, modify it then keep it for your next apps( )
rails new blog -m http://example.com/template.rb
or
# Clone repository
git pull https://github.com/gaarf/express-boilerplate
mv express-boilerplate your-app
cd your-app
# Link to your repository
git remote rm origin
git remote add origin git@github.com:you/your-app.git
git add .
git push -u origin master
Part III Deployment
isolate with containers
One for each module
Easier to manage
More secured
that's true for dev environment too
Vagrant, a simple hypervisor
for developers, can help
(cleaner that it looks like)
http://vagrantup.com
useful for
keeping your local machine clean
simulating the production environment
init vagrant
gem install vagrant
# add a box to your base box list
vagrant box add ubuntu http://files.vagrantup.com/precise64.box
create and start your vm
vagrant init ubuntu # init config
vagrant up # start the vm
vagrant ssh # connect through ssh...
... # and install your stuff!
port forwarding to access to your module like if they were
running on localhost
# modify Vagrantfile
config.vm.forward_port 9101, 9101
act as a devop
automate your deployment
straighforward
but hard to maintain
remote shell scripting with
python
still require some work
recipes
Idempotent
great but
a little bit
overkill
?
Fabtools
Fabtools
=
Fabric + helpers + idempotence
http://fabtools.readthedocs.org/
Fabric
from fabric.api import env, run
def prod():
env.hosts = ['www.yourapp.com']
env.user = 'root'
def install_db():
run('apt-get install postgres')
run('psql -c "CREATE USER you')
run('sudo -u postgres createdb ydb --owner you')
$ fab prod install_db
Fabtools
from fabtools import require
def prod():
env.hosts = ['www.yourapp.com']
env.user = 'root'
def require_db():
require.postgres.server()
require.postgres.user('you', 's3cr3')
require.postgres.database('yourdb', 'you')
$ fab prod require_db
Part IV Front-end assembler
makefile for frontend
quickstart
compile
assemble
minify
http://brunch.io
install brunch as a global package
npm install brunch -g
create project
cd yourproject
brunch new client # create a client template
cd client
npm install # dependencies required by brunch
brunch build
Automatic build when changes occur
brunch watch
Directory structure
|-app
|---assets
|-----images
|---controllers
|---lib
|---models
|---views
|-----styles
|-----templates
|-vendor
|---scripts
|---styles
paths:
public: 'public'
files:
javascripts:
defaultExtension: 'coffee'
joinTo:
'javascripts/app.js': /^app/
'javascripts/vendor.js': /^vendor/
stylesheets:
defaultExtension: 'styl'
joinTo:
'stylesheets/app.css': /^app/
'stylesheets/vendor.css': /^vendor/
templates:
defaultExtension: 'jade'
joinTo: 'javascripts/app.js'
framework: 'backbone'
paths:
public: 'public'
files:
javascripts:
defaultExtension: 'coffee'
joinTo:
'javascripts/app.js': /^app/
'javascripts/vendor.js': /^vendor/
stylesheets:
defaultExtension: 'styl'
joinTo:
'stylesheets/app.css': /^app/
'stylesheets/vendor.css': /^vendor/
templates:
defaultExtension: 'jade'
joinTo: 'javascripts/app.js'
framework: 'backbone'
paths:
public: 'public'
files:
javascripts:
defaultExtension: 'coffee'
joinTo:
'javascripts/app.js': /^app/
'javascripts/vendor.js': /^vendor/
stylesheets:
defaultExtension: 'styl'
joinTo:
'stylesheets/app.css': /^app/
'stylesheets/vendor.css': /^vendor/
templates:
defaultExtension: 'jade'
joinTo: 'javascripts/app.js'
framework: 'backbone'
paths:
public: 'public'
files:
javascripts:
defaultExtension: 'coffee'
joinTo:
'javascripts/app.js': /^app/
'javascripts/vendor.js': /^vendor/
stylesheets:
defaultExtension: 'styl'
joinTo:
'stylesheets/app.css': /^app/
'stylesheets/vendor.css': /^vendor/
templates:
defaultExtension: 'jade'
joinTo: 'javascripts/app.js'
framework: 'backbone'
alternative
Yeoman (Grunt)
Live reload
Codekit
Part V Features
hello world
yeah I got my hello world with my new devops
stuff!
basic features
What about authentication?…
registration?…
Taking advantage of user data?…
NEED
HELP?…
http://cozy.io
an open personal cloud with
auth and registration included
apps that share their data
real-time notifications for all data changes
https://demo.cozycloud.cc/
+
a choice for two frameworks
a choice for a database
a node.js template
easy deployment
an already configured assembler
a packaged vm for your dev environment
default stack
front-end:…
backbone
assembler:…
brunch
back-end:…
compound (node.js)
data:
storage:…
couchdb
events:
redis
indexes:…
whoosh
am I stuck with cozy ? 
change database adapter
=> then you have a classic web app.
cozy is a good way to...
quickstart
learn node.js and spa
prototype
make personal tools
Appendix Code
the bookmark tutorial
let's write an app that allows you to store
your favorite links
Get prepared
npm install compound brunch cozy scaffolt -g
Setup the dev environment (based on Vagrant)
cozy dev:init
cozy dev:start
Create your project
$ cozy new yourproject --github your-account
Github password:
Your cozy url: https://yourcozy.cozycloud.cc/
Project created!
we are coding
a full client in the browser
that takes its data from a REST API
Generate front end code
cd client/
scaffolt module bookmark
info: create app/models/bookmark.coffee
info: create app/collections/bookmarks.coffee
info: create app/views/bookmarks.coffee
info: create app/views/bookmark.coffee
info: create app/views/templates/bookmark.jade
info: create app/views/styles/_bookmark.styl
brunch w # build on changes
Then code what is missing!
Templates
# views/templates/bookmark.jade
.title #{model.title}
.url
a(href="#{model.url}") #{model.url}
button.delete-button delete
# views/templates/home.jade
h1 My bookmarks
#create-bookmark-form
input#title-field(placeholder="title")
input#url-field(placeholder="url")
button.btn#create-button create
#bookmarks
Home View
# views/home.coffee
View = require '../lib/view'
BookmarksView = require './bookmarks'
Bookmark = require '../models/bookmark'
module.exports = class AppView extends View
el: 'body'
events:
'click #create-button': 'onCreateClicked'
template: -> require './templates/home'
afterRender: ->
@bookmarksView = new BookmarksView()
@bookmarksView.collection.fetch()
onCreateClicked: =>
title = @$('#title-field').val()
url = @$('#url-field').val()
bookmark = new Bookmark title: title, url: url
@bookmarksView.collection.create bookmark,
success: => alert 'bookmark added'
error: => alert 'Server error occured'
Bookmark view
# views/bookmark.jade
View = require '../lib/view'
module.exports = class BookmarkView extends View
template: require './templates/bookmark'
className: 'bookmark'
events:
'click .delete-button': 'onDeleteClicked'
onDeleteClicked: ->
@model.destroy
success: => @destroy()
error: => alert 'Server error occured'
Styles
# views/styles/application.styl
body
padding: 20px
# views/styles/_bookmark.styl
.bookmark
padding: 10px 0
backend
urls to retrieve, create and delete bookmarks
Generate backend files
compound g model bookmark title url
exists app/
exists app/models/
create app/models/bookmark.coffee
patch db/schema.coffee
Routes
# config/routes.coffee
exports.routes = (map) ->
map.get 'bookmarks', 'bookmarks#all'
map.post 'bookmarks', 'bookmarks#create'
map.del 'bookmarks/:id', 'bookmarks#destroy'
Controllers
# apps/controllers/bookmarks_controller.coffee
action 'all', ->
Bookmark.all (err, bookmarks) ->
if err then send 500
else send bookmarks
action 'create', ->
Bookmark.create req.body, (err, bookmark) =>
if err then send 500
else send bookmark
action 'destroy', ->
Bookmark.find req.params.id, (err, bookmark) =>
if err then send 500
else if not bookmark
send error: 'not found', 404
else
bookmark.destroy (err) ->
if err then send 500
else send success: true, 204
Define requests (couchdb)
# config/initializers/requests.coffee
module.exports = (compound) ->
Bookmark = compound.models.Bookmark
all = (doc) -> emit doc.title, doc
Bookmark.defineRequest 'all', all, (err) ->
console.log 'request all created' unless err
Test
coffee server.coffee
firefox http://localhost:9250
Then deploy!
$ cozy deploy
Bookmarks successfully deployed on
https://yourcozy.cozycloud.cc/ !
And share your repo url with...
Biscuit man
who is now
happy again !!…
contact@cozycloud.cc
https://blog.cozycloud.cc
https://twitter.com/mycozycloud
Crédits photos Flickr: Ben Garney, CG94 photos, twicepix, flickrsven,
Virginia Guard Public Affairs, henskechristine, NASA Goddard Photo
and Video, World of Oddy
License Creative Commons by-3.0
a talk by...

20130528 solution linux_frousseau_nopain_webdev