+ Optionally select additional packages to include in your build: ⚠️ Only choose plugins you need and trust
+
+
+
+
+
+
Package
+
Version
+
Modules
+
+
+
+
+
+
+ {{include "/includes/footer.html"}}
+
+
diff --git a/src/includes/account-head.html b/src/includes/account-head.html
new file mode 100644
index 0000000..c95ac06
--- /dev/null
+++ b/src/includes/account-head.html
@@ -0,0 +1,5 @@
+{{include "/includes/head.html"}}
+
+
+
+
\ No newline at end of file
diff --git a/src/includes/account-nav.html b/src/includes/account-nav.html
new file mode 100644
index 0000000..60b2d6c
--- /dev/null
+++ b/src/includes/account-nav.html
@@ -0,0 +1,16 @@
+
\ No newline at end of file
diff --git a/src/includes/docs-details.html b/src/includes/docs-details.html
index bc80e01..4125c81 100644
--- a/src/includes/docs-details.html
+++ b/src/includes/docs-details.html
@@ -1,3 +1,11 @@
+
+
+ This module does not come with Caddy. It can be added by using xcaddy or our download page. Non-standard modules may be developed by the community and are not officially endorsed or maintained by the Caddy project. The documentation is shown here only as a courtesy.
+
\ No newline at end of file
diff --git a/src/includes/header-nav.html b/src/includes/header-nav.html
index 921ba1a..dcd7643 100644
--- a/src/includes/header-nav.html
+++ b/src/includes/header-nav.html
@@ -2,10 +2,10 @@
\ No newline at end of file
diff --git a/src/includes/v1-banner.html b/src/includes/v1-banner.html
deleted file mode 100644
index 584d340..0000000
--- a/src/includes/v1-banner.html
+++ /dev/null
@@ -1 +0,0 @@
-This page is about Caddy 2. If you still need v1 docs for a limited time, click here.
\ No newline at end of file
diff --git a/src/index.html b/src/index.html
index 32da431..ceb15ba 100644
--- a/src/index.html
+++ b/src/index.html
@@ -9,7 +9,6 @@
Or use it as a dynamic reverse proxy to any number of backends, complete with active and passive health checks, load balancing, circuit breaking, caching, and more.
@@ -267,7 +264,7 @@
All changes made through the API are persisted to disk so they can continue to be used after restarts.
- Download
+ DownloadAPI DocsTutorial
@@ -998,7 +995,7 @@
';
}
}
submodList += '';
diff --git a/src/resources/js/download.js b/src/resources/js/download.js
new file mode 100644
index 0000000..2649d7d
--- /dev/null
+++ b/src/resources/js/download.js
@@ -0,0 +1,221 @@
+// download package list as soon as possible
+$.get("/api/packages").done(function(json) {
+ var packageList = json.result;
+
+ // wait until the DOM has finished loading before rendering the results
+ $(function() {
+ const optpkgTemplate =
+ '
'+
+ '
'+
+ '
'+
+ '
'+
+ '
';
+
+ const optpkgModuleTemplate =
+ '
'+
+ ' '+
+ ' '+
+ '
';
+
+ for (var i = 0; i < packageList.length; i++) {
+ var pkg = packageList[i];
+ if (isStandard(pkg.path)) {
+ // not necessary to show, since these packages
+ // come with standard distribution
+ continue;
+ }
+
+ var $optpkg = $(optpkgTemplate);
+ $('.optpkg-name', $optpkg).text(pkg.path);
+
+ if (pkg.modules && pkg.modules.length > 0) {
+ for (var j = 0; j < pkg.modules.length; j++) {
+ var mod = pkg.modules[j];
+ var $mod = $(optpkgModuleTemplate);
+ $('.module-name', $mod).attr('href', '/docs/modules/'+mod.name).text(mod.name);
+ $('.module-description', $mod).text(truncate(mod.docs, 120));
+ $('.optpkg-modules', $optpkg).append($mod);
+ }
+ } else {
+ $('.optpkg-modules', $optpkg)
+ .addClass("optpkg-no-modules")
+ .text('This package does not add any modules. Either it is another kind of plugin (such as a config adapter) or this listing is in error.');
+ }
+ $('#optional-packages').append($optpkg);
+ }
+ });
+}).fail(function(jqxhr, status, error) {
+ swal({
+ icon: "error",
+ title: "Unavailable",
+ content: $('
')[0]
+ });
+ $(function() {
+ disableFields(false);
+ });
+});
+
+$(function() {
+ autoPlatform();
+
+ downloadButtonHtml = $('#download').html();
+
+ // update the page, including the download link, when form fields change
+ $('#optional-packages').on('change', 'input[type=checkbox]', function() {
+ $(this).closest('.optpkg').toggleClass('selected');
+ updatePage();
+ });
+ $('#optional-packages').on('change keyup', 'input[name=version]', function() {
+ updatePage();
+ });
+ $('#platform').change(function() {
+ updatePage();
+ });
+
+ $('#download').click(function(event) {
+ if ($(this).hasClass('disabled')) {
+ return false;
+ }
+
+ disableFields(true);
+
+ fathom.trackGoal('U9K2UTFV', 0);
+
+ $.ajax($(this).attr('href'), { method: "HEAD" }).done(function(data, status, jqxhr) {
+ window.onbeforeunload = null; // disable exit confirmation before "redirecting" to download
+ window.location = jqxhr.getResponseHeader("Location");
+ }).fail(function(jqxhr, status, error) {
+ handleBuildError(jqxhr, status, error);
+ }).always(function() {
+ enableFields();
+ });
+
+ return false;
+ });
+})
+
+// autoPlatform choooses the platform in the list that best
+// matches the user's browser, if it's available.
+function autoPlatform() {
+ // assume 32-bit linux, then change OS and architecture if justified
+ var os = "linux", arch = "386", arm = "";
+
+ // change os
+ if (/Macintosh/i.test(navigator.userAgent)) {
+ os = "darwin";
+ } else if (/Windows/i.test(navigator.userAgent)) {
+ os = "windows";
+ } else if (/FreeBSD/i.test(navigator.userAgent)) {
+ os = "freebsd";
+ } else if (/OpenBSD/i.test(navigator.userAgent)) {
+ os = "openbsd";
+ }
+
+ // change architecture
+ if (os == "darwin" || /amd64|x64|x86_64|Win64|WOW64|i686|64-bit/i.test(navigator.userAgent)) {
+ arch = "amd64";
+ } else if (/arm64/.test(navigator.userAgent)) {
+ arch = "arm64";
+ } else if (/ ARM| armv/.test(navigator.userAgent)) {
+ arch = "arm";
+ }
+
+ // change arm version
+ if (arch == "arm") {
+ arm = "7"; // assume version 7 by default
+ if (/armv6/.test(navigator.userAgent)) {
+ arm = "6";
+ } else if (/armv5/.test(navigator.userAgent)) {
+ arm = "5";
+ }
+ }
+
+ var selString = os+"-"+arch;
+ if (arm != "") {
+ selString += "-"+arm;
+ }
+
+ $('#platform').val(selString);
+ updatePage();
+}
+
+function getDownloadLink() {
+ // get platform components
+ var platformParts = $('#platform').val().split("-");
+ var os = platformParts[0];
+ var arch = platformParts[1];
+ var arm = platformParts.length > 2 ? platformParts[2] : "";
+
+ var qs = new URLSearchParams();
+ if (os) qs.set("os", os);
+ if (arch) qs.set("arch", arch);
+ if (arm) qs.set("arm", arm);
+
+ // get plugins and their versions
+ $('#optional-packages .selected').each(function() {
+ // get package path
+ var p = $('.optpkg-name', this).text().trim();
+
+ // get package version, if user specified one
+ var ver = $('input[name=version]', this).val().trim();
+ if (ver) {
+ p += "@"+ver;
+ }
+
+ qs.append("p", p);
+ });
+
+ var idempotencyKey = Math.floor(Math.random() * 99999999999999);
+ qs.append("idempotency", idempotencyKey);
+
+ return "/api/download?"+qs.toString();
+}
+
+function handleBuildError(jqxhr, status, error) {
+ var $content = $('
');
+
+ if (jqxhr.status == 502) {
+ swal({
+ icon: "error",
+ title: "Unavailable",
+ content: $content.html('Sorry, the build server is down for maintenance right now. You can try again later or download pre-built Caddy binaries from GitHub.')[0]
+ });
+ } else {
+ swal({
+ icon: "error",
+ title: "Build failed",
+ content: $content.html('The two most common reasons are:
A plugin is not compiling. The developer must release a new version that compiles.
The build configuration is invalid. If you specified any versions, make sure they are correct and within the same major version as the path of the associated package.
In the meantime, you can download Caddy from GitHub without any plugins.')[0]
+ });
+ }
+}
+
+function updatePage() {
+ $('#package-count').text($('.optpkg.selected').length);
+ $('#download').attr('href', getDownloadLink());
+}
+
+function disableFields(building) {
+ $('#download, #optional-packages').addClass('disabled');
+ $('.download-bar select, #optional-packages input').prop('disabled', true);
+ if (building) {
+ $('#download').html(' Building');
+
+ // prevent accidentally leaving the page during a build
+ window.onbeforeunload = function() {
+ return "Your custom build is in progress.";
+ };
+ } else {
+ $('#download').html('Builds Unavailable');
+ }
+}
+
+function enableFields() {
+ $('#download, #optional-packages').removeClass('disabled');
+ $('.download-bar select, #optional-packages input').prop('disabled', false);
+ $('#download').html(downloadButtonHtml);
+
+ // allow user to leave page easily
+ window.onbeforeunload = null;
+}
+
+var downloadButtonHtml; // to restore button to its original contents
\ No newline at end of file
diff --git a/src/resources/js/json-docs.js b/src/resources/js/json-docs.js
index 5205e2d..e365cad 100644
--- a/src/resources/js/json-docs.js
+++ b/src/resources/js/json-docs.js
@@ -9,7 +9,7 @@ setPageTitle();
$.get("/api/docs/config"+configPath, function(json) {
// wait until the DOM has finished loading before rendering the results
$(function() {
- beginRendering(json);
+ beginRendering(json.result);
// establish the breadcrumb
var $bc = $('.breadcrumbs');
diff --git a/src/resources/js/module-docs.js b/src/resources/js/module-docs.js
index 89c77c5..7ac483c 100644
--- a/src/resources/js/module-docs.js
+++ b/src/resources/js/module-docs.js
@@ -9,21 +9,24 @@ if (moduleID) {
$(function() {
$('#module-docs-container').show();
$('h1').text("Module "+moduleID);
- beginRendering(json);
+ beginRendering(json.result);
});
});
} else {
// populate the module list
- $.get("/api/modules", function(moduleList) {
+ $.get("/api/modules", function(json) {
+ var moduleList = json.result;
+
// wait until the DOM has finished loading before rendering the results
$(function() {
$('#module-list-container').show();
$table = $('#module-list');
for (modID in moduleList) {
- var doc = moduleList[modID];
+ var val = moduleList[modID];
+ var standard = isStandard(val.type_name);
var $tr = $('
\n'},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(4),r=n(2),i=n(0),a=i.default.ICON,s=i.default.ICON_CUSTOM,c=["error","warning","success","info"],l={error:r.errorIconMarkup(),warning:r.warningIconMarkup(),success:r.successIconMarkup()},u=function(t,e){var n=a+"--"+t;e.classList.add(n);var o=l[t];o&&(e.innerHTML=o)},f=function(t,e){e.classList.add(s);var n=document.createElement("img");n.src=t,e.appendChild(n)},d=function(t){if(t){var e=o.injectElIntoModal(r.iconMarkup);c.includes(t)?u(t,e):f(t,e)}};e.default=d},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(2),r=n(4),i=function(t){navigator.userAgent.includes("AppleWebKit")&&(t.style.display="none",t.offsetHeight,t.style.display="")};e.initTitle=function(t){if(t){var e=r.injectElIntoModal(o.titleMarkup);e.textContent=t,i(e)}},e.initText=function(t){if(t){var e=document.createDocumentFragment();t.split("\n").forEach(function(t,n,o){e.appendChild(document.createTextNode(t)),n0}).forEach(function(t){b.classList.add(t)})}n&&t===c.CONFIRM_KEY&&b.classList.add(s),b.textContent=r;var g={};return g[t]=i,f.setActionValue(g),f.setActionOptionsFor(t,{closeModal:p}),b.addEventListener("click",function(){return u.onAction(t)}),m},p=function(t,e){var n=r.injectElIntoModal(l.footerMarkup);for(var o in t){var i=t[o],a=d(o,i,e);i.visible&&n.appendChild(a)}0===n.children.length&&n.remove()};e.default=p},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(3),r=n(4),i=n(2),a=n(5),s=n(6),c=n(0),l=c.default.CONTENT,u=function(t){t.addEventListener("input",function(t){var e=t.target,n=e.value;a.setActionValue(n)}),t.addEventListener("keyup",function(t){if("Enter"===t.key)return s.onAction(o.CONFIRM_KEY)}),setTimeout(function(){t.focus(),a.setActionValue("")},0)},f=function(t,e,n){var o=document.createElement(e),r=l+"__"+e;o.classList.add(r);for(var i in n){var a=n[i];o[i]=a}"input"===e&&u(o),t.appendChild(o)},d=function(t){if(t){var e=r.injectElIntoModal(i.contentMarkup),n=t.element,o=t.attributes;"string"==typeof n?f(e,n,o):e.appendChild(n)}};e.default=d},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(1),r=n(2),i=function(){var t=o.stringToNode(r.overlayMarkup);document.body.appendChild(t)};e.default=i},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(5),r=n(6),i=n(1),a=n(3),s=n(0),c=s.default.MODAL,l=s.default.BUTTON,u=s.default.OVERLAY,f=function(t){t.preventDefault(),v()},d=function(t){t.preventDefault(),g()},p=function(t){if(o.default.isOpen)switch(t.key){case"Escape":return r.onAction(a.CANCEL_KEY)}},m=function(t){if(o.default.isOpen)switch(t.key){case"Tab":return f(t)}},b=function(t){if(o.default.isOpen)return"Tab"===t.key&&t.shiftKey?d(t):void 0},v=function(){var t=i.getNode(l);t&&(t.tabIndex=0,t.focus())},g=function(){var t=i.getNode(c),e=t.querySelectorAll("."+l),n=e.length-1,o=e[n];o&&o.focus()},h=function(t){t[t.length-1].addEventListener("keydown",m)},w=function(t){t[0].addEventListener("keydown",b)},y=function(){var t=i.getNode(c),e=t.querySelectorAll("."+l);e.length&&(h(e),w(e))},x=function(t){if(i.getNode(u)===t.target)return r.onAction(a.CANCEL_KEY)},_=function(t){var e=i.getNode(u);e.removeEventListener("click",x),t&&e.addEventListener("click",x)},k=function(t){o.default.timer&&clearTimeout(o.default.timer),t&&(o.default.timer=window.setTimeout(function(){return r.onAction(a.CANCEL_KEY)},t))},O=function(t){t.closeOnEsc?document.addEventListener("keyup",p):document.removeEventListener("keyup",p),t.dangerMode?v():g(),y(),_(t.closeOnClickOutside),k(t.timer)};e.default=O},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(1),r=n(3),i=n(37),a=n(38),s={title:null,text:null,icon:null,buttons:r.defaultButtonList,content:null,className:null,closeOnClickOutside:!0,closeOnEsc:!0,dangerMode:!1,timer:null},c=Object.assign({},s);e.setDefaults=function(t){c=Object.assign({},s,t)};var l=function(t){var e=t&&t.button,n=t&&t.buttons;return void 0!==e&&void 0!==n&&o.throwErr("Cannot set both 'button' and 'buttons' options!"),void 0!==e?{confirm:e}:n},u=function(t){return o.ordinalSuffixOf(t+1)},f=function(t,e){o.throwErr(u(e)+" argument ('"+t+"') is invalid")},d=function(t,e){var n=t+1,r=e[n];o.isPlainObject(r)||void 0===r||o.throwErr("Expected "+u(n)+" argument ('"+r+"') to be a plain object")},p=function(t,e){var n=t+1,r=e[n];void 0!==r&&o.throwErr("Unexpected "+u(n)+" argument ("+r+")")},m=function(t,e,n,r){var i=typeof e,a="string"===i,s=e instanceof Element;if(a){if(0===n)return{text:e};if(1===n)return{text:e,title:r[0]};if(2===n)return d(n,r),{icon:e};f(e,n)}else{if(s&&0===n)return d(n,r),{content:e};if(o.isPlainObject(e))return p(n,r),e;f(e,n)}};e.getOpts=function(){for(var t=[],e=0;eStill the only web server to use TLS automatically and by default.Deploy and scale HTTPS effortlessly with Caddy 2.
- Download
+ DownloadGet Started
Caddy uses only the Apache 2.0 open source license.
@@ -470,7 +470,7 @@ http://localhost {