diff --git a/src/nginxconfig/generators/security.conf.js b/src/nginxconfig/generators/security.conf.js
index 90e1029..3afd5df 100644
--- a/src/nginxconfig/generators/security.conf.js
+++ b/src/nginxconfig/generators/security.conf.js
@@ -1,28 +1,28 @@
 import commonHsts from '../util/common_hsts';
 
 export default (domains, global) => {
-    const config = {};
+    const config = [];
 
-    config['# security headers'] = '';
-    config['add_header X-Frame-Options'] = '"SAMEORIGIN" always';
-    config['add_header X-XSS-Protection'] = '"1; mode=block" always';
-    config['add_header X-Content-Type-Options'] = '"nosniff" always';
-    config['add_header Referrer-Policy'] = `"${global.security.referrerPolicy.computed}" always`;
+    config.push(['# security headers', '']);
+    config.push(['add_header', 'X-Frame-Options "SAMEORIGIN" always']);
+    config.push(['add_header', 'X-XSS-Protection "1; mode=block" always']);
+    config.push(['add_header', 'X-Content-Type-Options "nosniff" always']);
+    config.push(['add_header', `Referrer-Policy "${global.security.referrerPolicy.computed}" always`]);
 
     if (global.security.contentSecurityPolicy.computed)
-        config['add_header Content-Security-Policy'] = `"${global.security.contentSecurityPolicy.computed}" always`;
+        config.push(['add_header', `Content-Security-Policy "${global.security.contentSecurityPolicy.computed}" always`]);
 
     // Every domain has HSTS enabled, and they all have same hstsSubdomains/hstsPreload settings
     if (commonHsts(domains)) {
         const commonHSTSSubdomains = domains.length && domains[0].https.hstsSubdomains.computed;
         const commonHSTSPreload = domains.length && domains[0].https.hstsPreload.computed;
-        config['add_header Strict-Transport-Security'] = `"max-age=31536000${commonHSTSSubdomains ? '; includeSubDomains' : ''}${commonHSTSPreload ? '; preload' : ''}" always`;
+        config.push(['add_header', `Strict-Transport-Security "max-age=31536000${commonHSTSSubdomains ? '; includeSubDomains' : ''}${commonHSTSPreload ? '; preload' : ''}" always`]);
     }
 
-    config['# . files'] = '';
-    config['location ~ /\\.(?!well-known)'] = {
+    config.push(['# . files', '']);
+    config.push(['location ~ /\\.(?!well-known)', {
         deny: 'all',
-    };
+    }]);
 
     // Done!
     return config;
diff --git a/src/nginxconfig/generators/website.conf.js b/src/nginxconfig/generators/website.conf.js
index e1951bc..9d9c63a 100644
--- a/src/nginxconfig/generators/website.conf.js
+++ b/src/nginxconfig/generators/website.conf.js
@@ -1,7 +1,15 @@
 import { getSslCertificate, getSslCertificateKey } from '../util/get_ssl_certificate';
+import { getAccessLogDomainPath, getErrorLogDomainPath } from '../util/get_log_paths';
+import { extensions, gzipTypes } from '../util/types_extensions';
 import commonHsts from '../util/common_hsts';
 import securityConf from './security.conf';
-import { getAccessLogDomainPath, getErrorLogDomainPath } from '../util/get_log_paths';
+import pythonConf from './python_uwsgi.conf';
+import proxyConf from './proxy.conf';
+import phpConf from './php_fastcgi.conf';
+import generalConf from './general.conf';
+import wordPressConf from './wordpress.conf';
+import drupalConf from './drupal.conf';
+import magentoConf from './magento.conf';
 
 export default (domain, domains, global) => {
     // Use kv so we can use the same key multiple times
@@ -74,7 +82,7 @@ export default (domain, domains, global) => {
         serverConfig.push(['include', 'nginxconfig.io/security.conf']);
     } else {
         // Unified
-        serverConfig.push(...Object.entries(securityConf(domains, global)));
+        serverConfig.push(...securityConf(domains, global));
     }
 
     // Access log or error log for domain
@@ -97,7 +105,7 @@ export default (domain, domains, global) => {
     // Fallback index.html or index.php
     if ((domain.routing.fallbackHtml.computed || domain.routing.fallbackPhp.computed)
         && (!domain.reverseProxy.reverseProxy.computed || domain.reverseProxy.path.computed !== '/')) {
-        serverConfig.push([`# index.${domain.routing.fallbackHtml.computed ? 'html' : (domain.routing.fallbackPhp.computed ? 'php' : '' )} fallback`, '']);
+        serverConfig.push([`# index.${domain.routing.fallbackHtml.computed ? 'html' : (domain.routing.fallbackPhp.computed ? 'php' : '')} fallback`, '']);
         serverConfig.push(['location /', {
             try_files: `$uri $uri/ /index.${domain.routing.fallbackHtml.computed ? '.html' : (domain.routing.fallbackPhp.computed ? '.php?$query_string' : '')}`,
         }]);
@@ -111,10 +119,148 @@ export default (domain, domains, global) => {
         }]);
     }
 
-    // TODO: Python onwards
+    // Python
+    if (domain.python.python.computed) {
+        if (global.tools.modularizedStructure.computed) {
+            // Modularized
+            serverConfig.push(['location /', { include: 'nginxconfig.io/python_uwsgi.conf' }]);
+        } else {
+            // Unified
+            serverConfig.push(['location /', pythonConf(domains, global)]);
+        }
+
+        // Django
+        if (domain.python.djangoRules.computed) {
+            serverConfig.push(['# Django media', '']);
+            serverConfig.push(['location /media/', { alias: '$base/media/' }]);
+
+            serverConfig.push(['# Django static', '']);
+            serverConfig.push(['location /static/', { alias: '$base/static/' }]);
+        }
+    }
+
+    // Reverse proxy
+    if (domain.reverseProxy.reverseProxy.computed) {
+        const locConf = [];
+        locConf.push(['proxy_pass', domain.reverseProxy.proxyPass.computed]);
+
+        if (global.tools.modularizedStructure.computed) {
+            // Modularized
+            locConf.push(['include', 'nginxconfig.io/python_uwsgi.conf']);
+        } else {
+            // Unified
+            locConf.push(...Object.entries(proxyConf()));
+        }
+
+        serverConfig.push(['# reverse proxy', '']);
+        serverConfig.push([`location ${domain.reverseProxy.path.computed}`, locConf]);
+    }
+
+    // PHP
+    if (domain.php.php.computed) {
+        serverConfig.push(['# handle .php', '']);
+
+        const loc = `location ~ ${domain.routing.legacyPhpRouting.computed ? '[^/]\\.php(/|$)' : '\\.php$'}`;
+        if (global.tools.modularizedStructure.computed) {
+            // Modularized
+            serverConfig.push([loc, { include: 'nginxconfig.io/php_fastcgi.conf' }]);
+        } else {
+            // Unified
+            serverConfig.push([loc, phpConf(domains, global)]);
+        }
+    }
+
+    // Additional config
+    if (global.tools.modularizedStructure.computed) {
+        // Modularized
+        serverConfig.push(['# additional config', '']);
+        serverConfig.push(['include', 'nginxconfig.io/general.conf']);
+
+        if (domain.php.wordPressRules.computed) serverConfig.push(['include', 'nginxconfig.io/wordpress.conf']);
+        if (domain.php.drupalRules.computed) serverConfig.push(['include', 'nginxconfig.io/drupal.conf']);
+        if (domain.php.magentoRules.computed) serverConfig.push(['include', 'nginxconfig.io/magento.conf']);
+    } else {
+        // Unified
+        serverConfig.push(...Object.entries(generalConf(domains, global)));
+
+        if (domain.php.wordPressRules.computed) serverConfig.push(...Object.entries(wordPressConf(domains, global)));
+        if (domain.php.drupalRules.computed) serverConfig.push(...Object.entries(drupalConf(domains, global)));
+        if (domain.php.magentoRules.computed) serverConfig.push(...Object.entries(magentoConf()));
+    }
 
     // Add the server config to the parent config now its built
     config.push(['server', serverConfig]);
 
+    // CDN!
+    if (domain.server.cdnSubdomain.computed) {
+        // Build the server config on its own before adding it to the parent config
+        const cdnConfig = [];
+
+        if (domain.https.https.computed) {
+            // HTTPS
+            cdnConfig.push(['listen', `${ipv4Pre}443 ssl${domain.https.http2.computed ? ' http2' : ''}`]);
+
+            // v6
+            if (domain.server.listenIpv6.computed)
+                cdnConfig.push(['listen',
+                    `[${domain.server.listenIpv6.computed}]:443 ssl${domain.https.http2.computed ? ' http2' : ''}`]);
+        } else {
+            // Not HTTPS
+            cdnConfig.push(['listen', `${ipv4Pre}80`]);
+
+            // v6
+            if (domain.server.listenIpv6.computed)
+                cdnConfig.push(['listen', `[${domain.server.listenIpv6.computed}]:80`]);
+        }
+
+        cdnConfig.push(['server_name', `cdn.${domain.server.domain.computed}`]);
+        cdnConfig.push(['root', `${domain.server.path.computed}${domain.server.documentRoot.computed}`]);
+
+        // HTTPS
+        if (domain.https.https.computed) {
+            serverConfig.push(['# SSL', '']);
+            serverConfig.push(['ssl_certificate', getSslCertificate(domain, global)]);
+            serverConfig.push(['ssl_certificate_key', getSslCertificateKey(domain, global)]);
+
+            // Let's encrypt
+            if (domain.https.certType.computed === 'letsEncrypt')
+                serverConfig.push(['ssl_trusted_certificate',
+                    `/etc/letsencrypt/live/${domain.server.domain.computed}/chain.pem`]);
+        }
+
+        cdnConfig.push(['# disable access_log', '']);
+        cdnConfig.push(['access_log', 'off']);
+
+        // Gzip
+        if (global.performance.gzipCompression.computed) {
+            cdnConfig.push(['# gzip', '']);
+            cdnConfig.push(['gzip', 'on']);
+            cdnConfig.push(['gzip_vary', 'on']);
+            cdnConfig.push(['gzip_proxied', 'any']);
+            cdnConfig.push(['gzip_comp_level', 6]);
+            cdnConfig.push(['gzip_types', gzipTypes]);
+        }
+
+        cdnConfig.push(['# allow safe files', '']);
+        cdnConfig.push([
+            `location ~* \\.(?:${extensions.assets}|${extensions.fonts}|${extensions.svg}|${extensions.images}|${extensions.audio}|${extensions.video}|${extensions.docs})$`,
+            [
+                ['add_header', 'Access-Control-Allow-Origin "*"'],
+                ['add_header', 'Cache-Control "public"'],
+                ['expires', '30d'],
+            ],
+        ]);
+
+        cdnConfig.push(['# deny everything else', '']);
+        cdnConfig.push(['location /', { deny: 'all' }]);
+
+        // Add the CDN config to the parent config now its built
+        config.push(['# CDN', '']);
+        config.push(['server', cdnConfig]);
+    }
+
+    // TODO: subdomain redirects
+    // TODO: HTTP redirect
+
     return config;
 };