Thursday, 4 July 2013

Setting up a simple vibe.d application: environment

Time to get back to old article series and keep promises. This time I'll cover a very practical topic - how to set up vibe.d on linux within only home folder (using git sources and avoiding any help from a dub tool). Then will continue forward to using nginx as a reverse proxy in front of vibe.d and use it as a starting point for writing some web applications in next articles.

Installation

Sources

mkdir ~/vibed; cd ~/vibed;
# vibe.d itself
git clone https://github.com/rejectedsoftware/vibe.d.git; cd vibe.d;
git checkout v0.7.16 # released version tag
# Deimos bindings for used C libraries
cd ~/vibed
git clone https://github.com/D-Programming-Deimos/openssl.git
git clone https://github.com/D-Programming-Deimos/libevent.git
In theory vibe.d should support both livev and libevent, however, current support for a former is extremely lacking and I recommend to not event bother setting this right now.

Tools / libraries

Setting those is out of the scope of this article, but most likely you either want to use yout distro package manager or head to documentation of those projects about installing them manually.
  • dmd + phobos
  • rdmd
  • openssl
  • libevent
nginx is not required to run vibe.d applications but having some sort of reverse proxy in front with full HTTP support makes things much more safe and simple.

Configuring paths

Create a simple runner shel script which will incorporate all required flags. Those can also be added to DFLAGS if you are not going to run any other D projects for that user.
#!/bin/sh
# viberun.sh
rdmd -L-levent -L-lcrypto -L-lssl \
-J. -J./views/ \
-I~/vibed/vibe.d/source -I~/vibed/openssl -I~/vibed/libevent \
-release -O -inline -version=VibeLibeventDriver $@
Detailed explanation of flags:
  • Ones starting with -L are linker flags, those are simply forwarded to ld
  • -J defines paths where D compiler will look for a text files for compile-time manipulation. Vibe.d uses those to find Diet templates for processing - make sure that you have one of correct paths in this list if going to use them.
  • -I flags define import paths. If any additional third-party libraries are going to be used, they are like to go here.
  • Last line defines various optimization flags and sets event driver to work with - libevent.

Verifying minimal setup

app.d:
import vibe.d;

shared static this()
{
auto settings = new HTTPServerSettings;
settings.port = 8080;

listenHTTP(settings, (req, res) => res.writeBody("Hello!\n", "text/plain"));
}
console 1:
$ viberun app.d 
Listening for HTTP requests on :::8080
Failed to listen on 0.0.0.0:8080
console 2:
$ wget 127.0.0.1:8080
--2013-06-27 23:01:55-- http://127.0.0.1:8080/
Connecting to 127.0.0.1:8080... connected.
HTTP request sent, awaiting response... 200 OK
Length: 7 [text/plain]
Saving to: ‘index.html’
You can safely ignore message about second failed request - recent platform behavior change for binding ::: sockets has changed that makes vibe.d essentially to try to double-bind to 0.0.0.0. I expect this to be tweaked in one of nearby releases.

Hiding behind reverse proxy

nginx is often used to serve static content directly. Despite the fact that vibe.d can do it on its own with comparable performance, its support for various HTTP features is not as rich and has never been the priority. Using reverse proxy can also save from some exploits based on malformed requests.

Here is example of most basic nginx.conf I am using for this:

user http;           # this will be used to lower privileges.
# I also like to create home folder for such user and use it as a web root folder
worker_processes 2; # recommended count == number of processor cores

events
{
worker_connections 1024; # default in my distro package
}

http
{
# Set proper Content-Type for static files served
include mime.types;
default_type application/octet-stream;
# http://wiki.nginx.org/HttpCoreModule#sendfile
sendfile on;
# Will force closing keep-alive connections on server side after this period of inactivity
keepalive_timeout 65;
gzip on; # Use gzip archivation on served content

server
{
listen 80 default_server;
server_name example.com;

# All css files, images and other media, porbably static html files should go there
# Make sure that your main app uses proper URL for them (example.com/static/*)
# This is also often done via regexp location which checks extension for requested resource
location /static/
{
root /home/http/static/;
index index.html;
expires 1d;
}

# All other requests get simply passed to vibe.d process listening on some local
# socket. It is important to restore Host header, other wise it will be set to
# localhost (because technically it is HTTP request from nginx to backend)
location /
{
proxy_pass http://localhost:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
}
}
This is the setup I will keep in mind in next part, that will describe actually creating a trivial web application.

No comments:

Post a Comment