Server Configuration¶
To know more about server configuration see requirements.
Apache¶
- To use Open Orchestra, you need to configure the different virtual hosts (Back Office and Front Office)
- in your Apache configuration.
Virtual Host¶
Back Office Virtual Host:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName admin.openorchestra.1-1.dev
DocumentRoot /path/to/your/open_orchestra/bo_installation/folder/web
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /path/to/your/open_orchestra/bo_installation/folder/web>
Options -Indexes +FollowSymLinks -MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
<IfModule mod_rewrite.c>
RewriteEngine On
</IfModule>
ErrorLog /var/log/apache2/admin.openorchestraError.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog /var/log/apache2/admin.openorchestraAccess.log combined
</VirtualHost>
Front Office Virtual Host:
<VirtualHost *:80>
ServerAdmin webmaster\@localhost
ServerName front.openorchestra.1-1.dev
DocumentRoot /path/to/your/open_orchestra/front_installation/folder/web
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /path/to/your/open_orchestra/front_installation/folder/web>
Options -Indexes +FollowSymLinks -MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
<IfModule mod_rewrite.c>
RewriteEngine On
</IfModule>
ErrorLog /var/log/apache2/front.openorchestraError.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog /var/log/apache2/front.openorchestraAccess.log combined
</VirtualHost>
Varnish vcl¶
With Open Orchestra, you can use Varnish
. It is particularly useful for ESI rendering for instance.
This vcl is a basic configuration example to use the esi render.
# This is a basic Open Orchestra VCL configuration file for varnish 4.
vcl 4.0;
import directors;
acl purgers {
"127.0.0.1";
}
acl invalidators {
"127.0.0.1";
}
backend f1 {
.host = "127.0.1.1";
.port = "80";
}
backend g1 {
.host = "127.0.1.1";
.port = "80";
}
sub vcl_init {
new back = directors.round_robin();
back.add_backend(g1);
new front = directors.round_robin();
front.add_backend(f1);
}
sub vcl_recv {
set req.backend_hint = front.backend();
if (req.http.Cache-Control ~ "no-cache" && client.ip ~ invalidators) {
set req.hash_always_miss = true;
}
#=== Pass when request for admin ===#
if(req.http.host ~ "(admin.openorchestra.1-2.dev)") {
set req.backend_hint = back.backend();
return (pass);
}
#=== Pass when request for preview ===#
if (req.url ~ "^/preview") {
return (pass);
}
#=== Add X-Forwarded-Port ===#
if (req.http.X-Forwarded-Proto == "https" ) {
set req.http.X-Forwarded-Port = "443";
} else {
set req.http.X-Forwarded-Port = "6081";
}
#=== Add Surrogate-Capability ===#
set req.http.Surrogate-Capability = "varnish=ESI/1.0";
#=== BAN request ===#
if (req.method == "BAN") {
if (!client.ip ~ invalidators) {
return (synth(405, "Ban not allowed"));
}
if (req.http.X-Cache-Tags) {
ban("obj.http.X-Host ~ " + req.http.X-Host
+ " && obj.http.X-Url ~ " + req.http.X-Url
+ " && obj.http.content-type ~ " + req.http.X-Content-Type
+ " && obj.http.X-Cache-Tags ~ " + req.http.X-Cache-Tags
);
} else {
ban("obj.http.X-Host ~ " + req.http.X-Host
+ " && obj.http.X-Url ~ " + req.http.X-Url
+ " && obj.http.content-type ~ " + req.http.X-Content-Type
);
}
return (synth(200, "Ban added"));
}
#=== PURGE request ===#
if (req.method == "PURGE") {
if (!client.ip ~ purgers) {
return (synth(405, "Purge not allowed"));
}
return(purge);
}
#=== Normalize Accept-Encoding header ===#
if (req.http.Accept-Encoding) {
if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
unset req.http.Accept-Encoding;
} elsif (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} elsif (req.http.Accept-Encoding ~ "deflate") {
set req.http.Accept-Encoding = "deflate";
} else {
unset req.http.Accept-Encoding;
}
}
#=== Pass when method different from GET and HEAD ===#
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}
#=== Pass when private block ===#
if (req.url ~ ".*[?&]cache=private.*") {
return (pass);
}
#=== Remove all cookies ===#
unset req.http.Cookie;
#=== If you want to keep the session #ID ===#
#=== Comment the previous line ===#
#=== And uncomment the following block ===#
#if (req.http.Cookie) {
# set req.http.Cookie = ";" + req.http.Cookie;
# set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
# set req.http.Cookie = regsuball(req.http.Cookie, ";(PHPSESSID)=", "; \1=");
# set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
# set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
#
# if (req.http.Cookie == "") {
# unset req.http.Cookie;
# }
#}
return (hash);
}
sub vcl_pipe {
# By default Connection: close is set on all piped requests, to stop
# connection reuse from sending future requests directly to the
# (potentially) wrong backend. If you do want this to happen, you can undo
# it here.
# unset bereq.http.connection;
return (pipe);
}
sub vcl_pass {
return (fetch);
}
sub vcl_hash {
hash_data(req.url);
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}
if (req.http.X-UA-Device) {
hash_data(req.http.X-UA-Device);
}
return (lookup);
}
sub vcl_purge {
return (synth(200, "Purged"));
}
sub vcl_hit {
if (obj.ttl >= 0s) {
// A pure unadultered hit, deliver it
return (deliver);
}
if (obj.ttl + obj.grace > 0s) {
// Object is in grace, deliver it
// Automatically triggers a background fetch
return (deliver);
}
// fetch & deliver once we get the result
return (fetch);
}
sub vcl_miss {
return (fetch);
}
sub vcl_deliver {
# Keep ban-lurker headers only if debugging is enabled
if (!resp.http.X-Cache-Debug) {
# Remove ban-lurker friendly custom headers when delivering to client
unset resp.http.X-Url;
unset resp.http.X-Host;
unset resp.http.X-Cache-Tags;
}
return (deliver);
}
/*
* We can come here "invisibly" with the following errors: 413, 417 & 503
*/
sub vcl_synth {
set resp.http.Content-Type = "text/html; charset=utf-8";
set resp.http.Retry-After = "5";
synthetic( {"<!DOCTYPE html>
<html>
<head>
<title>"} + resp.status + " " + resp.reason + {"</title>
</head>
<body>
<h1>Error "} + resp.status + " " + resp.reason + {"</h1>
<p>"} + resp.reason + {"</p>
<h3>Guru Meditation:</h3>
<p>XID: "} + req.xid + {"</p>
<hr>
<p>Varnish cache server</p>
</body>
</html>
"} );
return (deliver);
}
#######################################################################
# Backend Fetch
sub vcl_backend_fetch {
return (fetch);
}
sub vcl_backend_response {
# Set ban-lurker friendly custom headers
set beresp.http.X-Url = bereq.url;
set beresp.http.X-Host = bereq.http.host;
if (beresp.status == 404 || beresp.status == 500 || beresp.status == 503) {
set beresp.ttl = 30s;
}
if (beresp.ttl <= 0s ||
beresp.http.Surrogate-control ~ "no-store" ||
(!beresp.http.Surrogate-Control &&
beresp.http.Cache-Control ~ "no-cache|no-store|private") ||
beresp.http.Vary == "*") {
/*
* Mark as "Hit-For-Pass" for the next 2 minutes
*/
set beresp.ttl = 120s;
set beresp.uncacheable = true;
}
if (beresp.http.Surrogate-Control ~ "ESI/1.0") {
unset beresp.http.Surrogate-Control;
set beresp.do_esi = true;
}
if (beresp.ttl>0s && !beresp.uncacheable) {
unset beresp.http.Set-Cookie;
}
return (deliver);
}
sub vcl_backend_error {
set beresp.http.Content-Type = "text/html; charset=utf-8";
set beresp.http.Retry-After = "5";
synthetic( {"<!DOCTYPE html>
<html>
<head>
<title>"} + beresp.status + " " + beresp.reason + {"</title>
</head>
<body>
<h1>Error "} + beresp.status + " " + beresp.reason + {"</h1>
<p>"} + beresp.reason + {"</p>
<h3>Guru Meditation:</h3>
<p>XID: "} + bereq.xid + {"</p>
<hr>
<p>Varnish cache server</p>
</body>
</html>
"} );
return (deliver);
}
#######################################################################
# Housekeeping
sub vcl_fini {
return (ok);
}
Cron jobs¶
Cron jobs are used for tasks (commands or shell scripts) to run periodically at fixed times, dates, or intervals. Cron jobs typically automate system maintenance.
Cron jobs on Open Orchestra¶
Open Orchestra has 6 cron jobs created with the provisioning:
Site maps¶
Generate sitemap files for every sites, more information available in the sitemap documentation
0 2 * * * php /var/www/front-open-orchestra/current/app/console -e=prod orchestra:sitemaps:generate 2>> /tmp/cron.error.message
Robots.txt¶
Generate the robots.txt files for every sites, further information about robots
0 2 * * * php /var/www/front-open-orchestra/current/app/console -e=prod orchestra:robots:generate 2>> /tmp/cron.error.message
Error pages¶
Generate the special error pages files for every sites (eg 404 & 503 status), for more information about the 404 and 503 special pages see the documentation customizing error pages
0 2 * * * php /var/www/front-open-orchestra/current/app/console -e=prod orchestra:errorpages:generate 2>> /tmp/cron.error.message
Nodes auto publish cron¶
This cron publish nodes based on contributed publishing dates and status.
0 2 * * * php /var/www/open-orchestra/current/app/console -e=prod orchestra:publish:node 2>> /tmp/cron.error.message
Nodes auto unpublish cron¶
This cron unpublish nodes based on contributed unpublishing dates.
30 2 * * * php /var/www/open-orchestra/current/app/console -e=prod orchestra:unpublish:node 2>> /tmp/cron.error.message
Error cron¶
This cron sends an email if any of above cron didn’t correctly.
59 0-23 * * * if [ -s '/tmp/cron.error.message' ]; then cat /tmp/cron.error.message | mailx -s "cron error" contact@open-orchestra.com; fi; rm /tmp/cron.error.message;
Ansible¶
If you don’t want set the different configurations (Virtual Host, Varnish, Cron) manually, you can use the provisioning.