Initial commit

This commit is contained in:
Sander van der Burg 2020-01-28 00:11:29 +01:00 committed by Sander van der Burg
commit 9c6b781308
36 changed files with 1305 additions and 0 deletions

View File

@ -0,0 +1,34 @@
{createManagedProcess, apacheHttpd}:
{instanceSuffix ? "", configFile, initialize ? ""}:
let
instanceName = "httpd${instanceSuffix}";
user = instanceName;
group = instanceName;
in
createManagedProcess {
name = instanceName;
inherit instanceName initialize;
process = "${apacheHttpd}/bin/httpd";
args = [ "-f" configFile ];
foregroundProcessExtraArgs = [ "-DFOREGROUND" ];
credentials = {
groups = {
"${group}" = {};
};
users = {
"${user}" = {
inherit group;
description = "Apache HTTP daemon user";
};
};
};
overrides = {
sysvinit = {
runlevels = [ 3 4 5 ];
};
};
}

View File

@ -0,0 +1,49 @@
{ pkgs
, stateDir
, logDir
, runtimeDir
, tmpDir
, forceDisableUserChange
, processManager
}:
let
createManagedProcess = import ../../nixproc/create-managed-process/agnostic/create-managed-process-universal.nix {
inherit pkgs runtimeDir tmpDir forceDisableUserChange processManager;
};
in
{
apache = import ./apache.nix {
inherit createManagedProcess;
inherit (pkgs) apacheHttpd;
};
static-webapp-apache = import ./static-webapp-apache.nix {
inherit createManagedProcess logDir runtimeDir forceDisableUserChange;
inherit (pkgs) stdenv apacheHttpd writeTextFile;
};
mysql = import ./mysql.nix {
inherit createManagedProcess stateDir runtimeDir forceDisableUserChange;
inherit (pkgs) stdenv mysql;
};
postgresql = import ./postgresql.nix {
inherit createManagedProcess stateDir runtimeDir forceDisableUserChange;
inherit (pkgs) stdenv postgresql;
};
tomcat = import ./tomcat.nix {
inherit createManagedProcess stateDir runtimeDir tmpDir forceDisableUserChange;
inherit (pkgs) stdenv;
jre = pkgs.jre8;
tomcat = pkgs.tomcat9;
};
simple-appserving-tomcat = import ./simple-appserving-tomcat.nix {
inherit createManagedProcess stateDir runtimeDir tmpDir forceDisableUserChange;
inherit (pkgs) stdenv;
jre = pkgs.jre8;
tomcat = pkgs.tomcat9;
};
}

View File

@ -0,0 +1,49 @@
{createManagedProcess, stdenv, mysql, stateDir, runtimeDir, forceDisableUserChange}:
{port ? 3306, instanceSuffix ? ""}:
let
instanceName = "mysqld${instanceSuffix}";
dataDir = "${stateDir}/db/${instanceName}";
user = instanceName;
group = instanceName;
in
createManagedProcess {
name = instanceName;
inherit instanceName user;
initialize = ''
mkdir -m0700 -p ${dataDir}
mkdir -m0700 -p ${runtimeDir}
${stdenv.lib.optionalString (!forceDisableUserChange) ''
chown ${user}:${group} ${dataDir}
''}
if [ ! -e "${dataDir}/mysql" ]
then
${mysql}/bin/mysql_install_db --basedir=${mysql} --datadir=${dataDir} ${if forceDisableUserChange then "" else "--user=${user}"}
fi
'';
foregroundProcess = "${mysql}/bin/mysqld";
foregroundProcessArgs = [ "--basedir" mysql "--datadir" dataDir "--port" port "--socket" "${runtimeDir}/${instanceName}.sock" ]
++ stdenv.lib.optionals (!forceDisableUserChange) [ "--user" user ];
credentials = {
groups = {
"${group}" = {};
};
users = {
"${user}" = {
inherit group;
description = "MySQL user";
};
};
};
overrides = {
sysvinit = {
runlevels = [ 3 4 5 ];
};
};
}

View File

@ -0,0 +1,57 @@
{createManagedProcess, stdenv, postgresql, stateDir, runtimeDir, forceDisableUserChange}:
{port ? 5432, instanceSuffix ? ""}:
let
instanceName = "postgresql${instanceSuffix}";
dataDir = "${stateDir}/db/${instanceName}/data";
socketDir = "${runtimeDir}/${instanceName}";
user = instanceName;
group = instanceName;
in
createManagedProcess rec {
name = instanceName;
inherit instanceName user;
initialize = ''
mkdir -m0700 -p ${socketDir}
mkdir -m0700 -p ${dataDir}
${stdenv.lib.optionalString (!forceDisableUserChange) ''
chown ${user}:${group} ${socketDir}
chown ${user}:${group} ${dataDir}
''}
if [ ! -e "${dataDir}/PG_VERSION" ]
then
${postgresql}/bin/initdb -D ${dataDir} --no-locale
fi
'';
process = "${postgresql}/bin/postgres";
args = [ "-D" dataDir "-p" port "-k" socketDir ];
credentials = {
groups = {
"${group}" = {};
};
users = {
"${user}" = {
inherit group;
description = "PostgreSQL user";
};
};
};
overrides = {
sysvinit = {
runlevels = [ 3 4 5 ];
instructions.start = {
activity = "Starting";
instruction = ''
${initialize}
${postgresql}/bin/pg_ctl -D ${dataDir} -o "-p ${toString port} -k ${socketDir}" start
'';
};
};
};
}

View File

@ -0,0 +1,48 @@
{ pkgs ? import <nixpkgs> { inherit system; }
, system ? builtins.currentSystem
, stateDir ? "/var"
, runtimeDir ? "${stateDir}/run"
, logDir ? "${stateDir}/log"
, tmpDir ? (if stateDir == "/var" then "/tmp" else "${stateDir}/tmp")
, forceDisableUserChange ? false
, processManager ? "sysvinit"
}:
let
constructors = import ./constructors.nix {
inherit pkgs stateDir runtimeDir logDir tmpDir forceDisableUserChange processManager;
};
in
rec {
static-webapp-apache = rec {
port = 8080;
pkg = constructors.static-webapp-apache {
inherit port;
};
};
mysql = rec {
port = 3307;
pkg = constructors.mysql {
inherit port;
};
};
postgresql = rec {
port = 6432;
pkg = constructors.postgresql {
inherit port;
};
};
simple-appserving-tomcat = rec {
httpPort = 8081;
pkg = constructors.simple-appserving-tomcat {
inherit httpPort;
};
};
}

View File

@ -0,0 +1,29 @@
{createManagedProcess, stdenv, tomcat, jre, stateDir, runtimeDir, tmpDir, forceDisableUserChange}:
{instanceSuffix ? "", serverPort ? 8005, httpPort ? 8080, httpsPort ? 8443, ajpPort ? 8009}:
let
tomcatConfigFiles = stdenv.mkDerivation {
name = "tomcat-config-files";
buildCommand = ''
mkdir -p $out
cd $out
mkdir conf
cp ${tomcat}/conf/* conf
sed -i \
-e 's|<Server port="8005" shutdown="SHUTDOWN">|<Server port="${toString serverPort}" shutdown="SHUTDOWN">|' \
-e 's|<Connector port="8080" protocol="HTTP/1.1"|<Connector port="${toString httpPort}" protocol="HTTP/1.1"|' \
-e 's|redirectPort="8443"|redirectPort="${toString httpsPort}"|' \
-e 's|<Connector port="8009" protocol="AJP/1.3"|<Connector port="${toString ajpPort}" protocol="AJP/1.3"|' \
conf/server.xml
mkdir webapps
cp -av ${tomcat.webapps}/webapps/* webapps
'';
};
in
import ./tomcat.nix {
inherit createManagedProcess stdenv tomcat jre stateDir runtimeDir tmpDir forceDisableUserChange;
} {
inherit tomcatConfigFiles instanceSuffix;
}

View File

@ -0,0 +1,73 @@
{createManagedProcess, stdenv, apacheHttpd, writeTextFile, logDir, runtimeDir, forceDisableUserChange}:
{instanceSuffix ? "", port ? 80}:
let
instanceName = "httpd${instanceSuffix}";
user = instanceName;
group = instanceName;
modules = [
"mpm_prefork"
"authn_file"
"authn_core"
"authz_host"
"authz_groupfile"
"authz_user"
"authz_core"
"access_compat"
"auth_basic"
"reqtimeout"
"filter"
"mime"
"log_config"
"env"
"headers"
"setenvif"
"version"
"unixd"
"status"
"autoindex"
"alias"
"dir"
];
apacheLogDir = "${logDir}/${instanceName}";
in
import ./apache.nix {
inherit createManagedProcess apacheHttpd;
} {
inherit instanceSuffix;
initialize = ''
mkdir -m0700 -p ${apacheLogDir}
${stdenv.lib.optionalString (!forceDisableUserChange) ''
chown ${user}:${group} ${apacheLogDir}
''}
'';
configFile = writeTextFile {
name = "httpd.conf";
text = ''
ErrorLog "${apacheLogDir}/error_log"
PidFile "${runtimeDir}/${instanceName}.pid"
${stdenv.lib.optionalString (!forceDisableUserChange) ''
User ${user}
Group ${group}
''}
ServerName localhost
ServerRoot ${apacheHttpd}
Listen ${toString port}
${stdenv.lib.concatMapStrings (module: ''
LoadModule ${module}_module ${apacheHttpd}/modules/mod_${module}.so
'') modules}
ServerAdmin root@localhost
DocumentRoot "${./webapp}"
'';
};
}

View File

@ -0,0 +1,61 @@
{createManagedProcess, stdenv, tomcat, jre, stateDir, runtimeDir, tmpDir, forceDisableUserChange}:
{instanceSuffix ? "", tomcatConfigFiles}:
let
instanceName = "tomcat${instanceSuffix}";
baseDir = "${stateDir}/${instanceName}";
user = instanceName;
group = instanceName;
pidFile = "${runtimeDir}/${instanceName}.pid";
in
createManagedProcess rec {
name = "tomcat";
inherit instanceName user pidFile;
process = "${tomcat}/bin/catalina.sh";
args = [ "run" ];
environment = {
JRE_HOME = jre;
CATALINA_TMPDIR = tmpDir;
CATALINA_BASE = baseDir;
CATALINA_PID = pidFile;
};
initialize = ''
if [ ! -d "${baseDir}" ]
then
mkdir -p ${baseDir}/logs
cd ${baseDir}
cp -av ${tomcatConfigFiles}/* .
chmod -R u+w .
${stdenv.lib.optionalString (!forceDisableUserChange) ''
chown -R ${user}:${group} ${baseDir}
''}
fi
'';
credentials = {
groups = {
"${group}" = {};
};
users = {
"${user}" = {
inherit group;
description = "Tomcat user";
};
};
};
overrides = {
sysvinit = {
instructions.start = {
activity = "Starting";
instruction = ''
${initialize}
${tomcat}/bin/startup.sh
'';
};
runlevels = [ 3 4 5 ];
};
};
}

View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title>Hello world!</title>
</head>
<body>
<h1>Hello world!</h1>
</body>
</html>

View File

@ -0,0 +1,29 @@
{ pkgs
, stateDir
, logDir
, runtimeDir
, tmpDir
, forceDisableUserChange
, processManager
, webappMode # set to 'foreground' to make them all foreground process, 'daemon' to make them all daemons. null is to pick best option for the selected processManager
}:
let
createManagedProcess = import ../../nixproc/create-managed-process/agnostic/create-managed-process-universal.nix {
inherit pkgs runtimeDir tmpDir forceDisableUserChange processManager;
};
webappExpr = if webappMode == "foreground" then ./webapp-fg.nix
else if webappMode == "daemon" then ./webapp-daemon.nix
else ./webapp.nix;
in
{
webapp = import webappExpr {
inherit createManagedProcess runtimeDir;
};
nginxReverseProxy = import ./nginx-reverse-proxy.nix {
inherit createManagedProcess stateDir logDir runtimeDir forceDisableUserChange;
inherit (pkgs) stdenv writeTextFile nginx;
};
}

View File

@ -0,0 +1,5 @@
{infrastructure}:
{
}

View File

@ -0,0 +1,6 @@
{infrastructure}:
{
webapp = [ infrastructure.test1 ];
nginxReverseProxy = [ infrastructure.test2 ];
}

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<title>Disnix VirtualHosts example</title>
</head>
<body>
This web application is unavailable at the moment!
</body>
</html>

View File

@ -0,0 +1,4 @@
{
test1.properties.hostname = "test1";
test2.properties.hostname = "test2";
}

View File

@ -0,0 +1,41 @@
let
nixproc-generate-config = (import ../../tools {}).generate-config;
in
{
test1 = {pkgs, ...}:
{
dysnomia = {
extraContainerProperties = {
managed-process = {
processManager = "systemd";
NIX_PATH = "/root/.nix-defexpr/channels:nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos:nixos-config=/etc/nixos/configuration.nix:/nix/var/nix/profiles/per-user/root/channels";
};
};
};
services.disnix.enable = true;
services.openssh.enable = true;
networking.firewall.enable = false;
environment.systemPackages = [ pkgs.pythonPackages.supervisor nixproc-generate-config ];
};
test2 = {pkgs, ...}:
{
dysnomia = {
extraContainerProperties = {
managed-process = {
processManager = "sysvinit";
NIX_PATH = "/root/.nix-defexpr/channels:nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos:nixos-config=/etc/nixos/configuration.nix:/nix/var/nix/profiles/per-user/root/channels";
};
};
};
services.disnix.enable = true;
services.openssh.enable = true;
networking.firewall.enable = false;
environment.systemPackages = [ pkgs.pythonPackages.supervisor nixproc-generate-config ];
};
}

View File

@ -0,0 +1,14 @@
{
test1 = {pkgs, ...}:
{
deployment.targetEnv = "virtualbox";
deployment.virtualbox.memorySize = 4096; # megabytes
};
test2 = {pkgs, ...}:
{
deployment.targetEnv = "virtualbox";
deployment.virtualbox.memorySize = 4096; # megabytes
};
}

View File

@ -0,0 +1,84 @@
{createManagedProcess, stdenv, writeTextFile, nginx, runtimeDir, stateDir, logDir, forceDisableUserChange}:
{port ? 80, webapps ? [], instanceSuffix ? ""}:
interDeps:
let
instanceName = "nginx${instanceSuffix}";
user = instanceName;
group = instanceName;
nginxStateDir = "${stateDir}/${instanceName}";
dependencies = webapps ++ (builtins.attrValues interDeps);
generateNginxConf = daemon:
writeTextFile {
name = "nginx.conf";
text = ''
error_log ${nginxStateDir}/logs/error.log;
${stdenv.lib.optionalString (!forceDisableUserChange) ''
user ${user} ${group};
''}
${if daemon then ''
pid ${runtimeDir}/${instanceName}.pid;
'' else ''
daemon off;
''}
events {
worker_connections 190000;
}
http {
${stdenv.lib.concatMapStrings (dependency: ''
upstream webapp${toString dependency.port} {
server localhost:${toString dependency.port};
}
'') webapps}
${stdenv.lib.concatMapStrings (dependencyName:
let
dependency = builtins.getAttr dependencyName interDeps;
in
''
upstream webapp${toString dependency.port} {
server ${dependency.target.properties.hostname}:${toString dependency.port};
}
'') (builtins.attrNames interDeps)}
# Fallback virtual host displaying an error page. This is what users see
# if they connect to a non-deployed web application.
# Without it, nginx redirects to the first available virtual host, giving
# unpredictable results. This could happen while an upgrade is in progress.
server {
listen ${toString port};
server_name aaaa;
root ${./errorpage};
}
${stdenv.lib.concatMapStrings (dependency: ''
server {
listen ${toString port};
server_name ${dependency.dnsName};
location / {
proxy_pass http://webapp${toString dependency.port};
}
}
'') dependencies}
}
'';
};
in
import ./nginx.nix {
inherit createManagedProcess stdenv nginx stateDir forceDisableUserChange;
} {
inherit instanceSuffix;
dependencies = map (webapp: webapp.pkg) dependencies;
daemonConfigFile = generateNginxConf true;
foregroundConfigFile = generateNginxConf false;
}

View File

@ -0,0 +1,43 @@
{createManagedProcess, stdenv, nginx, stateDir, forceDisableUserChange}:
{daemonConfigFile, foregroundConfigFile, dependencies ? [], instanceSuffix ? ""}:
let
instanceName = "nginx${instanceSuffix}";
user = instanceName;
group = instanceName;
nginxLogDir = "${stateDir}/${instanceName}/logs";
in
createManagedProcess {
name = instanceName;
description = "Nginx";
initialize = ''
mkdir -p ${nginxLogDir}
${stdenv.lib.optionalString (!forceDisableUserChange) ''
chown ${user}:${group} ${nginxLogDir}
''}
'';
process = "${nginx}/bin/nginx";
args = [ "-p" "${stateDir}/${instanceName}" ];
foregroundProcessExtraArgs = [ "-c" foregroundConfigFile ];
daemonExtraArgs = [ "-c" daemonConfigFile ];
inherit dependencies instanceName;
credentials = {
groups = {
"${group}" = {};
};
users = {
"${user}" = {
inherit group;
description = "Nginx user";
};
};
};
overrides = {
sysvinit = {
runlevels = [ 3 4 5 ];
};
};
}

View File

@ -0,0 +1,96 @@
{ pkgs ? import <nixpkgs> { inherit system; }
, system ? builtins.currentSystem
, stateDir ? "/var"
, runtimeDir ? "${stateDir}/run"
, logDir ? "${stateDir}/log"
, tmpDir ? (if stateDir == "/var" then "/tmp" else "${stateDir}/tmp")
, forceDisableUserChange ? false
, processManager ? "sysvinit"
, webappMode ? null
}:
let
constructors = import ./constructors.nix {
inherit pkgs stateDir runtimeDir logDir tmpDir forceDisableUserChange processManager webappMode;
};
in
rec {
webapp1 = rec {
port = 5000;
dnsName = "webapp1.local";
pkg = constructors.webapp {
inherit port;
instanceSuffix = "1";
};
};
webapp2 = rec {
port = 5001;
dnsName = "webapp2.local";
pkg = constructors.webapp {
inherit port;
instanceSuffix = "2";
};
};
webapp3 = rec {
port = 5002;
dnsName = "webapp3.local";
pkg = constructors.webapp {
inherit port;
instanceSuffix = "3";
};
};
webapp4 = rec {
port = 5003;
dnsName = "webapp4.local";
pkg = constructors.webapp {
inherit port;
instanceSuffix = "4";
};
};
nginxReverseProxy = rec {
port = 8080;
pkg = constructors.nginxReverseProxy {
webapps = [ webapp1 webapp2 webapp3 webapp4 ];
inherit port;
} {};
};
webapp5 = rec {
port = 6002;
dnsName = "webapp5.local";
pkg = constructors.webapp {
inherit port;
instanceSuffix = "5";
};
};
webapp6 = rec {
port = 6003;
dnsName = "webapp6.local";
pkg = constructors.webapp {
inherit port;
instanceSuffix = "6";
};
};
nginxReverseProxy2 = rec {
port = 8081;
pkg = constructors.nginxReverseProxy {
webapps = [ webapp5 webapp6 ];
inherit port;
instanceSuffix = "2";
} {};
};
}

View File

@ -0,0 +1,35 @@
{ pkgs ? import <nixpkgs> { inherit system; }
, system ? builtins.currentSystem
, stateDir ? "/var"
, runtimeDir ? "${stateDir}/run"
, logDir ? "${stateDir}/log"
, tmpDir ? (if stateDir == "/var" then "/tmp" else "${stateDir}/tmp")
, forceDisableUserChange ? false
, processManager
, webappMode ? null
}:
let
constructors = import ./constructors.nix {
inherit pkgs stateDir runtimeDir logDir tmpDir forceDisableUserChange processManager webappMode;
};
in
rec {
webapp = rec {
port = 5000;
dnsName = "webapp.local";
pkg = constructors.webapp {
inherit port;
};
};
nginxReverseProxy = rec {
port = 8080;
pkg = constructors.nginxReverseProxy {
webapps = [ webapp ];
inherit port;
} {};
};
}

View File

@ -0,0 +1,45 @@
{ pkgs, distribution, invDistribution, system
, stateDir ? "/var"
, runtimeDir ? "${stateDir}/run"
, logDir ? "${stateDir}/log"
, tmpDir ? (if stateDir == "/var" then "/tmp" else "${stateDir}/tmp")
, forceDisableUserChange ? false
, processManager ? null # "sysvinit"
}:
let
constructors = import ./constructors.nix {
inherit pkgs stateDir runtimeDir logDir tmpDir forceDisableUserChange processManager;
webappMode = null;
};
processType =
if processManager == null then "managed-process"
else if processManager == "sysvinit" then "sysvinit-script"
else if processManager == "systemd" then "systemd-unit"
else if processManager == "supervisord" then "supervisord-program"
else throw "Unknown process manager: ${processManager}";
in
rec {
webapp = rec {
name = "webapp";
port = 5000;
dnsName = "webapp.local";
pkg = constructors.webapp {
inherit port;
};
type = processType;
};
nginxReverseProxy = rec {
name = "nginxReverseProxy";
port = 8080;
pkg = constructors.nginxReverseProxy {
inherit port;
};
dependsOn = {
inherit webapp;
};
type = processType;
};
}

View File

@ -0,0 +1,39 @@
{createManagedProcess, runtimeDir}:
{port, instanceSuffix ? ""}:
let
webapp = import ../webapp;
instanceName = "webapp${instanceSuffix}";
in
createManagedProcess {
name = instanceName;
description = "Simple web application";
inherit instanceName;
# This expression only specifies how to run webapp in daemon mode
daemon = "${webapp}/bin/webapp";
daemonArgs = [ "-D" ];
environment = {
PORT = port;
PID_FILE = "${runtimeDir}/${instanceName}.pid";
};
user = instanceName;
credentials = {
groups = {
"${instanceName}" = {};
};
users = {
"${instanceName}" = {
group = instanceName;
description = "Webapp";
};
};
};
overrides = {
sysvinit = {
runlevels = [ 3 4 5 ];
};
};
}

View File

@ -0,0 +1,37 @@
{createManagedProcess, runtimeDir}:
{port, instanceSuffix ? ""}:
let
webapp = import ../webapp;
instanceName = "webapp${instanceSuffix}";
in
createManagedProcess {
name = instanceName;
description = "Simple web application";
inherit instanceName;
# This expression only specifies how to run the webapp in foreground mode
foregroundProcess = "${webapp}/bin/webapp";
environment = {
PORT = port;
};
user = instanceName;
credentials = {
groups = {
"${instanceName}" = {};
};
users = {
"${instanceName}" = {
group = instanceName;
description = "Webapp";
};
};
};
overrides = {
sysvinit = {
runlevels = [ 3 4 5 ];
};
};
}

View File

@ -0,0 +1,40 @@
{createManagedProcess, runtimeDir}:
{port, instanceSuffix ? ""}:
let
webapp = import ../../webapp;
instanceName = "webapp${instanceSuffix}";
in
createManagedProcess {
name = instanceName;
description = "Simple web application";
inherit instanceName;
# This expression can both run in foreground or daemon mode.
# The process manager can pick which mode it prefers.
process = "${webapp}/bin/webapp";
daemonArgs = [ "-D" ];
environment = {
PORT = port;
PID_FILE = "${runtimeDir}/${instanceName}.pid";
};
user = instanceName;
credentials = {
groups = {
"${instanceName}" = {};
};
users = {
"${instanceName}" = {
group = instanceName;
description = "Webapp";
};
};
};
overrides = {
sysvinit = {
runlevels = [ 3 4 5 ];
};
};
}

View File

@ -0,0 +1,34 @@
{ pkgs
, stateDir
, logDir
, runtimeDir
, tmpDir
, forceDisableUserChange
}:
let
createSystemVInitScript = import ../../nixproc/create-managed-process/sysvinit/create-sysvinit-script.nix {
inherit (pkgs) stdenv writeTextFile daemon;
inherit runtimeDir tmpDir forceDisableUserChange;
createCredentials = import ../../nixproc/create-credentials {
inherit (pkgs) stdenv;
};
initFunctions = import ../../nixproc/create-managed-process/sysvinit/init-functions.nix {
basePackages = [ pkgs.coreutils pkgs.gnused pkgs.inetutils pkgs.gnugrep pkgs.sysvinit ];
inherit (pkgs) stdenv fetchurl;
inherit runtimeDir;
};
};
in
{
webapp = import ./webapp.nix {
inherit createSystemVInitScript runtimeDir;
};
nginxReverseProxy = import ./nginx-reverse-proxy.nix {
inherit createSystemVInitScript stateDir logDir runtimeDir;
inherit (pkgs) stdenv writeTextFile nginx;
};
}

View File

@ -0,0 +1,5 @@
{infrastructure}:
{
}

View File

@ -0,0 +1,6 @@
{infrastructure}:
{
webapp = [ infrastructure.test1 ];
nginxReverseProxy = [ infrastructure.test2 ];
}

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<title>Disnix VirtualHosts example</title>
</head>
<body>
This web application is unavailable at the moment!
</body>
</html>

View File

@ -0,0 +1,17 @@
{
test1 = {pkgs, ...}:
{
services.disnix.enable = true;
services.openssh.enable = true;
networking.firewall.enable = false;
};
test2 = {pkgs, ...}:
{
services.disnix.enable = true;
services.openssh.enable = true;
networking.firewall.enable = false;
};
}

View File

@ -0,0 +1,14 @@
{
test1 = {pkgs, ...}:
{
deployment.targetEnv = "virtualbox";
deployment.virtualbox.memorySize = 4096; # megabytes
};
test2 = {pkgs, ...}:
{
deployment.targetEnv = "virtualbox";
deployment.virtualbox.memorySize = 4096; # megabytes
};
}

View File

@ -0,0 +1,67 @@
{createSystemVInitScript, stdenv, writeTextFile, nginx, runtimeDir, stateDir, logDir}:
{port ? 80, webapps ? [], instanceSuffix ? ""}:
interDeps:
let
instanceName = "nginx${instanceSuffix}";
nginxStateDir = "${stateDir}/${instanceName}";
dependencies = webapps ++ (builtins.attrValues interDeps);
in
import ./nginx.nix {
inherit createSystemVInitScript nginx instanceSuffix;
stateDir = nginxStateDir;
dependencies = map (webapp: webapp.pkg) dependencies;
configFile = writeTextFile {
name = "nginx.conf";
text = ''
error_log ${nginxStateDir}/logs/error.log;
pid ${runtimeDir}/${instanceName}.pid;
events {
worker_connections 190000;
}
http {
${stdenv.lib.concatMapStrings (dependency: ''
upstream webapp${toString dependency.port} {
server localhost:${toString dependency.port};
}
'') webapps}
${stdenv.lib.concatMapStrings (dependencyName:
let
dependency = builtins.getAttr dependencyName interDeps;
in
''
upstream webapp${toString dependency.port} {
server ${dependency.target.properties.hostname}:${toString dependency.port};
}
'') (builtins.attrNames interDeps)}
# Fallback virtual host displaying an error page. This is what users see
# if they connect to a non-deployed web application.
# Without it, nginx redirects to the first available virtual host, giving
# unpredictable results. This could happen while an upgrade is in progress.
server {
listen ${toString port};
server_name aaaa;
root ${./errorpage};
}
${stdenv.lib.concatMapStrings (dependency: ''
server {
listen ${toString port};
server_name ${dependency.dnsName};
location / {
proxy_pass http://webapp${toString dependency.port};
}
}
'') dependencies}
}
'';
};
}

View File

@ -0,0 +1,17 @@
{createSystemVInitScript, nginx, configFile, stateDir, dependencies ? [], instanceSuffix ? ""}:
let
instanceName = "nginx${instanceSuffix}";
in
createSystemVInitScript {
name = instanceName;
description = "Nginx";
initialize = ''
mkdir -p ${stateDir}/logs
'';
process = "${nginx}/bin/nginx";
args = [ "-c" configFile "-p" stateDir ];
runlevels = [ 3 4 5 ];
inherit dependencies instanceName;
}

View File

@ -0,0 +1,94 @@
{ pkgs ? import <nixpkgs> { inherit system; }
, system ? builtins.currentSystem
, stateDir ? "/var"
, runtimeDir ? "${stateDir}/run"
, logDir ? "${stateDir}/log"
, tmpDir ? (if stateDir == "/var" then "/tmp" else "${stateDir}/tmp")
, forceDisableUserChange ? false
}:
let
constructors = import ./constructors.nix {
inherit pkgs stateDir runtimeDir logDir tmpDir forceDisableUserChange;
};
in
rec {
webapp1 = rec {
port = 5000;
dnsName = "webapp1.local";
pkg = constructors.webapp {
inherit port;
instanceSuffix = "1";
};
};
webapp2 = rec {
port = 5001;
dnsName = "webapp2.local";
pkg = constructors.webapp {
inherit port;
instanceSuffix = "2";
};
};
webapp3 = rec {
port = 5002;
dnsName = "webapp3.local";
pkg = constructors.webapp {
inherit port;
instanceSuffix = "3";
};
};
webapp4 = rec {
port = 5003;
dnsName = "webapp4.local";
pkg = constructors.webapp {
inherit port;
instanceSuffix = "4";
};
};
nginxReverseProxy = rec {
port = 8080;
pkg = constructors.nginxReverseProxy {
webapps = [ webapp1 webapp2 webapp3 webapp4 ];
inherit port;
} {};
};
webapp5 = rec {
port = 6002;
dnsName = "webapp5.local";
pkg = constructors.webapp {
inherit port;
instanceSuffix = "5";
};
};
webapp6 = rec {
port = 6003;
dnsName = "webapp6.local";
pkg = constructors.webapp {
inherit port;
instanceSuffix = "6";
};
};
nginxReverseProxy2 = rec {
port = 8081;
pkg = constructors.nginxReverseProxy {
webapps = [ webapp5 webapp6 ];
inherit port;
instanceSuffix = "2";
} {};
};
}

View File

@ -0,0 +1,33 @@
{ pkgs ? import <nixpkgs> { inherit system; }
, system ? builtins.currentSystem
, stateDir ? "/var"
, runtimeDir ? "${stateDir}/run"
, logDir ? "${stateDir}/log"
, tmpDir ? (if stateDir == "/var" then "/tmp" else "${stateDir}/tmp")
, forceDisableUserChange ? false
}:
let
constructors = import ./constructors.nix {
inherit pkgs stateDir runtimeDir logDir tmpDir forceDisableUserChange;
};
in
rec {
webapp = rec {
port = 5000;
dnsName = "webapp.local";
pkg = constructors.webapp {
inherit port;
};
};
nginxReverseProxy = rec {
port = 8080;
pkg = constructors.nginxReverseProxy {
webapps = [ webapp ];
inherit port;
} {};
};
}

View File

@ -0,0 +1,36 @@
{ pkgs, distribution, invDistribution, system
, stateDir ? "/var"
, runtimeDir ? "${stateDir}/run"
, logDir ? "${stateDir}/log"
, tmpDir ? (if stateDir == "/var" then "/tmp" else "${stateDir}/tmp")
, forceDisableUserChange ? true
}:
let
constructors = import ./constructors.nix {
inherit pkgs stateDir runtimeDir logDir tmpDir forceDisableUserChange;
};
in
rec {
webapp = rec {
name = "webapp";
port = 5000;
dnsName = "webapp.local";
pkg = constructors.webapp {
inherit port;
};
type = "sysvinit-script";
};
nginxReverseProxy = rec {
name = "nginxReverseProxy";
port = 8080;
pkg = constructors.nginxReverseProxy {
inherit port;
};
dependsOn = {
inherit webapp;
};
type = "sysvinit-script";
};
}

View File

@ -0,0 +1,33 @@
{createSystemVInitScript, runtimeDir}:
{port, instanceSuffix ? ""}:
let
webapp = import ../../webapp;
instanceName = "webapp${instanceSuffix}";
in
createSystemVInitScript {
name = instanceName;
inherit instanceName;
process = "${webapp}/bin/webapp";
args = [ "-D" ];
environment = {
PORT = port;
PID_FILE = "${runtimeDir}/${instanceName}.pid";
};
runlevels = [ 3 4 5 ];
user = instanceName;
credentials = {
groups = {
"${instanceName}" = {};
};
users = {
"${instanceName}" = {
group = instanceName;
description = "Webapp";
};
};
};
}