diff --git a/404.html b/404.html index c5338bad..6c9f2946 100644 --- a/404.html +++ b/404.html @@ -9,8 +9,8 @@ - - + + diff --git a/assets/js/0654c903.d4ebe9ef.js b/assets/js/0654c903.d4ebe9ef.js deleted file mode 100644 index 1fdb4736..00000000 --- a/assets/js/0654c903.d4ebe9ef.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2022],{445:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>l,toc:()=>d});var t=r(5893),o=r(1151);const i={sidebar_position:40,sidebar_label:"Linux VPS"},s="Self-Hosting Guide for Linux",l={id:"guides/self-hosting/self_hosting_guide",title:"Self-Hosting Guide for Linux",description:"Walkthrough Video",source:"@site/../docs/guides/self-hosting/self_hosting_guide.md",sourceDirName:"guides/self-hosting",slug:"/guides/self-hosting/self_hosting_guide",permalink:"/docs/guides/self-hosting/self_hosting_guide",draft:!1,unlisted:!1,editUrl:"https://github.com/openziti/zrok/blob/main/docs/../docs/guides/self-hosting/self_hosting_guide.md",tags:[],version:"current",sidebarPosition:40,frontMatter:{sidebar_position:40,sidebar_label:"Linux VPS"},sidebar:"tutorialSidebar",previous:{title:"Self Hosting",permalink:"/docs/category/self-hosting"},next:{title:"Nginx TLS",permalink:"/docs/guides/self-hosting/nginx_tls_guide"}},c={},d=[{value:"Walkthrough Video",id:"walkthrough-video",level:2},{value:"Before you Begin",id:"before-you-begin",level:2},{value:"OpenZiti Quickstart",id:"openziti-quickstart",level:2},{value:"Install zrok",id:"install-zrok",level:2},{value:"Configure the Controller",id:"configure-the-controller",level:2},{value:"Environment Variables",id:"environment-variables",level:2},{value:"Bootstrap OpenZiti for zrok",id:"bootstrap-openziti-for-zrok",level:2},{value:"Run zrok Controller",id:"run-zrok-controller",level:2},{value:"Create zrok Frontend",id:"create-zrok-frontend",level:2},{value:"Configure the Public Frontend",id:"configure-the-public-frontend",level:2},{value:"Start Public Frontend",id:"start-public-frontend",level:2},{value:"Invite Yourself",id:"invite-yourself",level:2},{value:"Enable Your Shell",id:"enable-your-shell",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"self-hosting-guide-for-linux",children:"Self-Hosting Guide for Linux"}),"\n",(0,t.jsx)(n.h2,{id:"walkthrough-video",children:"Walkthrough Video"}),"\n",(0,t.jsx)("iframe",{width:"100%",height:"315",src:"https://www.youtube.com/embed/870A5dke_u4",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowfullscreen:!0}),"\n",(0,t.jsx)(n.h2,{id:"before-you-begin",children:"Before you Begin"}),"\n",(0,t.jsx)(n.p,{children:"This will get you up and running with a self-hosted instance of zrok. I'll assume you have the following:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"a Linux server with a public IP"}),"\n",(0,t.jsxs)(n.li,{children:["a wildcard DNS record like ",(0,t.jsx)(n.code,{children:"*.zrok.quigley.com"})," that resolves to the server IP"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"openziti-quickstart",children:"OpenZiti Quickstart"}),"\n",(0,t.jsx)(n.p,{children:"The first step is to log in to your Linux server and run the OpenZiti quickstart. This will install a Ziti controller and Ziti router as systemd services."}),"\n",(0,t.jsx)(n.p,{children:'I specifically used the "Host OpenZiti Anywhere" variant because it provides a public controller. We\'ll need that to use zrok with multiple devices across different networks.'}),"\n",(0,t.jsxs)(n.p,{children:["Keep track of the generated admin password when running the ",(0,t.jsx)(n.code,{children:"expressInstall"})," script. The script will prompt you like this:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-text",children:"Do you want to keep the generated admin password 'XO0xHp75uuyeireO2xmmVlK91T7B9fpD'? (Y/n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You'll need that generated password (",(0,t.jsx)(n.code,{children:"XO0xHp75uuyeireO2xmmVlK91T7B9fpD"}),") when building your ",(0,t.jsx)(n.code,{children:"zrok"})," controller configuration."]}),"\n",(0,t.jsxs)(n.p,{children:["BEGIN: ",(0,t.jsx)(n.a,{href:"https://docs.openziti.io/docs/learn/quickstarts/network/hosted",children:"Run the OpenZiti Quickstart"})]}),"\n",(0,t.jsx)(n.h2,{id:"install-zrok",children:"Install zrok"}),"\n",(0,t.jsxs)(n.p,{children:["Download ",(0,t.jsx)(n.a,{href:"https://github.com/openziti/zrok/releases/latest",children:"the latest release"})," from GitHub."]}),"\n",(0,t.jsx)(n.h2,{id:"configure-the-controller",children:"Configure the Controller"}),"\n",(0,t.jsxs)(n.p,{children:["Create a controller configuration file in ",(0,t.jsx)(n.code,{children:"etc/ctrl.yml"}),". The controller does not provide server TLS, but you may front the server with a reverse proxy. This example will expose the non-TLS listener for the controller."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'# _____ __ ___ | | __\n# |_ / \'__/ _ \\| |/ /\n# / /| | | (_) | <\n# /___|_| \\___/|_|\\_\\\n# controller configuration\n\nv: 3\n\nadmin:\n # generate these admin tokens from a source of randomness, e.g. \n # LC_ALL=C tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c32\n secrets:\n - Q8V0LqnNb5wNX9kE1fgQ0H6VlcvJybB1 # be sure to change this!\n\nendpoint:\n host: 0.0.0.0\n port: 18080\n\ninvites:\n invites_open: true\n\nstore:\n path: zrok.db\n type: sqlite3\n\nziti:\n api_endpoint: "https://127.0.0.1:8441"\n username: admin\n password: "XO0xHp75uuyeireO2xmmVlK91T7B9fpD"\n\n'})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"admin"})," section defines privileged administrative credentials and must be set in the ",(0,t.jsx)(n.code,{children:"ZROK_ADMIN_TOKEN"})," environment variable in shells where you want to run ",(0,t.jsx)(n.code,{children:"zrok admin"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"endpoint"})," section defines where your ",(0,t.jsx)(n.code,{children:"zrok"})," controller will listen."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"store"})," section defines the local ",(0,t.jsx)(n.code,{children:"sqlite3"})," database used by the controller."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"ziti"})," section defines how the ",(0,t.jsx)(n.code,{children:"zrok"})," controller should communicate with your OpenZiti installation. When using the OpenZiti quickstart, an administrative password will be generated; the ",(0,t.jsx)(n.code,{children:"password"})," in the ",(0,t.jsx)(n.code,{children:"ziti"})," stanza should reflect this password."]}),"\n",(0,t.jsxs)(n.admonition,{type:"note",children:[(0,t.jsxs)(n.p,{children:["Be sure to see the ",(0,t.jsxs)(n.a,{target:"_blank","data-noBrokenLinkCheck":!0,href:r(1855).Z+"",children:["reference configuration at ",(0,t.jsx)(n.code,{children:"etc/ctrl.yml"})]})," for the complete documentation of the current configuration file format for the ",(0,t.jsx)(n.code,{children:"zrok"})," controller and service instance components."]}),(0,t.jsxs)(n.p,{children:["See the separate guides on ",(0,t.jsx)(n.a,{href:"/docs/guides/self-hosting/metrics-and-limits/configuring-metrics",children:"configuring metrics"})," and ",(0,t.jsx)(n.a,{href:"/docs/guides/self-hosting/metrics-and-limits/configuring-limits",children:"configuring limits"})," for details about both of these specialized areas of service instance configuration."]})]}),"\n",(0,t.jsx)(n.h2,{id:"environment-variables",children:"Environment Variables"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"zrok"})," binaries are configured to work with the global ",(0,t.jsx)(n.code,{children:"zrok.io"})," service, and default to using ",(0,t.jsx)(n.code,{children:"api.zrok.io"})," as the endpoint for communicating with the service."]}),"\n",(0,t.jsxs)(n.p,{children:["To work with a self-hosted ",(0,t.jsx)(n.code,{children:"zrok"})," deployment, you'll need to set the ",(0,t.jsx)(n.code,{children:"ZROK_API_ENDPOINT"})," environment variable to point to the address where your ",(0,t.jsx)(n.code,{children:"zrok"})," controller will be listening, according to ",(0,t.jsx)(n.code,{children:"endpoint"})," in the configuration file above."]}),"\n",(0,t.jsx)(n.p,{children:"In my case, I've set:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"export ZROK_API_ENDPOINT=http://127.0.0.1:18080\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsxs)(n.a,{href:"/docs/guides/self-hosting/instance-configuration",children:["Read more about configuring your self-hosted ",(0,t.jsx)(n.code,{children:"zrok"})," instance"]}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"bootstrap-openziti-for-zrok",children:"Bootstrap OpenZiti for zrok"}),"\n",(0,t.jsxs)(n.p,{children:["With your OpenZiti network running and your configuration saved to a local file (I refer to mine as ",(0,t.jsx)(n.code,{children:"etc/ctrl.yml"})," in these examples), you're ready to bootstrap the Ziti network."]}),"\n",(0,t.jsxs)(n.p,{children:["Use the ",(0,t.jsx)(n.code,{children:"zrok admin bootstrap"})," command to bootstrap like this:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ zrok admin bootstrap etc/ctrl.yml \n[ 0.002] INFO main.(*adminBootstrap).run: {\n\t...\n}\n[ 0.002] INFO zrok/controller/store.Open: database connected\n[ 0.006] INFO zrok/controller/store.(*Store).migrate: applied 0 migrations\n[ 0.006] INFO zrok/controller.Bootstrap: connecting to the ziti edge management api\n[ 0.039] INFO zrok/controller.Bootstrap: creating identity for controller ziti access\n[ 0.071] INFO zrok/controller.Bootstrap: controller identity: jKd8AINSz\n[ 0.082] INFO zrok/controller.assertIdentity: asserted identity 'jKd8AINSz'\n[ 0.085] INFO zrok/controller.assertErpForIdentity: asserted erps for 'ctrl' (jKd8AINSz)\n[ 0.085] INFO zrok/controller.Bootstrap: creating identity for frontend ziti access\n[ 0.118] INFO zrok/controller.Bootstrap: frontend identity: sqJRAINSiB\n[ 0.119] INFO zrok/controller.assertIdentity: asserted identity 'sqJRAINSiB'\n[ 0.120] INFO zrok/controller.assertErpForIdentity: asserted erps for 'frontend' (sqJRAINSiB)\n[ 0.120] WARNING zrok/controller.Bootstrap: missing public frontend for ziti id 'sqJRAINSiB'; please use 'zrok admin create frontend sqJRAINSiB public https://{token}.your.dns.name' to create a frontend instance\n[ 0.123] INFO zrok/controller.assertZrokProxyConfigType: found 'zrok.proxy.v1' config type with id '33CyjNbIepkXHN5VzGDA8L'\n[ 0.124] INFO zrok/controller.assertMetricsService: creating 'metrics' service\n[ 0.126] INFO zrok/controller.assertMetricsService: asserted 'metrics' service (5RpPZZ7T8bZf1ENjwGiPc3)\n[ 0.128] INFO zrok/controller.assertMetricsSerp: creating 'metrics' serp\n[ 0.130] INFO zrok/controller.assertMetricsSerp: asserted 'metrics' serp\n[ 0.134] INFO zrok/controller.assertCtrlMetricsBind: creating 'ctrl-metrics-bind' service policy\n[ 0.135] INFO zrok/controller.assertCtrlMetricsBind: asserted 'ctrl-metrics-bind' service policy\n[ 0.138] INFO zrok/controller.assertFrontendMetricsDial: creating 'frontend-metrics-dial' service policy\n[ 0.140] INFO zrok/controller.assertFrontendMetricsDial: asserted 'frontend-metrics-dial' service policy\n[ 0.140] INFO main.(*adminBootstrap).run: bootstrap complete!\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"zrok admin bootstrap"})," command configures the ",(0,t.jsx)(n.code,{children:"zrok"})," database, the necessary OpenZiti identities, and all of the OpenZiti policies required to run a ",(0,t.jsx)(n.code,{children:"zrok"})," service."]}),"\n",(0,t.jsx)(n.p,{children:"Notice this warning:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"[ 0.120] WARNING zrok/controller.Bootstrap: missing public frontend for ziti id 'sqJRAINSiB'; please use 'zrok admin create frontend sqJRAINSiB public https://{token}.your.dns.name' to create a frontend instance\n"})}),"\n",(0,t.jsx)(n.h2,{id:"run-zrok-controller",children:"Run zrok Controller"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"zrok"}),' bootstrap process wants us to create a "public frontend" for our service. ',(0,t.jsx)(n.code,{children:"zrok"})," uses public frontends to allow users to specify where they would like public traffic to ingress from."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"zrok admin create frontend"})," command requires a running ",(0,t.jsx)(n.code,{children:"zrok"})," controller, so let's start that up first:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ zrok controller etc/ctrl.yml \n[ 0.003] INFO main.(*controllerCommand).run: {\n\t...\n}\n[ 0.016] INFO zrok/controller.inspectZiti: inspecting ziti controller configuration\n[ 0.048] INFO zrok/controller.findZrokProxyConfigType: found 'zrok.proxy.v1' config type with id '33CyjNbIepkXHN5VzGDA8L'\n[ 0.048] INFO zrok/controller/store.Open: database connected\n[ 0.048] INFO zrok/controller/store.(*Store).migrate: applied 0 migrations\n[ 0.049] INFO zrok/controller.(*metricsAgent).run: starting\n[ 0.064] INFO zrok/rest_server_zrok.setupGlobalMiddleware: configuring\n[ 0.064] INFO zrok/ui.StaticBuilder: building\n[ 0.065] INFO zrok/rest_server_zrok.(*Server).Logf: Serving zrok at http://[::]:18080\n[ 0.085] INFO zrok/controller.(*metricsAgent).listen: started\n"})}),"\n",(0,t.jsx)(n.h2,{id:"create-zrok-frontend",children:"Create zrok Frontend"}),"\n",(0,t.jsxs)(n.p,{children:["With our ",(0,t.jsx)(n.code,{children:"ZROK_ADMIN_TOKEN"})," and ",(0,t.jsx)(n.code,{children:"ZROK_API_ENDPOINT"})," environment variables set, we can create our public frontend like this:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ zrok admin create frontend sqJRAINSiB public http://{token}.zrok.quigley.com:8080\n[ 0.037] INFO main.(*adminCreateFrontendCommand).run: created global public frontend 'WEirJNHVlcW9'\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The id of the frontend was emitted earlier in by the zrok controller when we ran the bootstrap command. If you don't have that log message the you can find the id again with the ",(0,t.jsx)(n.code,{children:"ziti"})," CLI like this:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"# initialize the Ziti quickstart env\nsource ~/.ziti/quickstart/$(hostname -s)/$(hostname -s).env\n# login as admin\nzitiLogin\n# list Ziti identities created by the quickstart and bootstrap\nziti edge list identities\n"})}),"\n",(0,t.jsx)(n.p,{children:'The id is shown for the "frontend" identity.'}),"\n",(0,t.jsxs)(n.p,{children:["Nice work! The ",(0,t.jsx)(n.code,{children:"zrok"})," controller is fully configured now that you have created the zrok frontend."]}),"\n",(0,t.jsx)(n.h2,{id:"configure-the-public-frontend",children:"Configure the Public Frontend"}),"\n",(0,t.jsxs)(n.p,{children:["Create an http frontend configuration file in ",(0,t.jsx)(n.code,{children:"etc/http-frontend.yml"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"v: 3\nhost_match: zrok.quigley.com\naddress: 0.0.0.0:8080\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This frontend config file has a ",(0,t.jsx)(n.code,{children:"host_match"})," pattern that represents the DNS zone you're using with this instance of zrok. Incoming HTTP requests with a matching ",(0,t.jsx)(n.code,{children:"Host"})," header will be handled by this frontend. You may also specify the interface address where the frontend will listen for public access requests."]}),"\n",(0,t.jsxs)(n.p,{children:["The frontend does not provide server TLS, but you may front the server with a reverse proxy. It is essential the reverse proxy forwards the ",(0,t.jsx)(n.code,{children:"Host"})," header supplied by the viewer. This example will expose the non-TLS listener for the frontend."]}),"\n",(0,t.jsxs)(n.p,{children:["You can also specify an ",(0,t.jsx)(n.code,{children:"oauth"})," configuration in this file, full details of are found in ",(0,t.jsx)(n.a,{href:"/docs/guides/self-hosting/oauth/configuring-oauth#configuring-your-public-frontend",children:"OAuth Public Frontend Configuration"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"start-public-frontend",children:"Start Public Frontend"}),"\n",(0,t.jsx)(n.p,{children:"In another terminal window, run:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ zrok access public etc/http-frontend.yml\n[ 0.002] INFO main.(*accessPublicCommand).run: {\n\t...\n}\n[ 0.002] INFO zrok/endpoints/public_frontend.newMetricsAgent: loaded 'frontend' identity\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This process uses the ",(0,t.jsx)(n.code,{children:"frontend"})," identity created during the bootstrap process to provide public access for the ",(0,t.jsx)(n.code,{children:"zrok"})," deployment. It is expected that the configured listener for this ",(0,t.jsx)(n.code,{children:"frontend"})," corresponds to the DNS template specified when creating the public frontend record above."]}),"\n",(0,t.jsx)(n.h2,{id:"invite-yourself",children:"Invite Yourself"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ zrok invite\nNew Email: user@domain.com\nConfirm Email: user@domain.com\ninvitation sent to 'user@domain.com'!\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If you look at the console output from your ",(0,t.jsx)(n.code,{children:"zrok"})," controller, you'll see a message like this:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"[ 238.168] INFO zrok/controller.(*inviteHandler).Handle: account request for 'user@domain.com' has registration token 'U2Ewt1UCn3ql'\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You can access your ",(0,t.jsx)(n.code,{children:"zrok"})," controller's registration UI by pointing a web browser at:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"http://localhost:18080/register/U2Ewt1UCn3ql\n"})}),"\n",(0,t.jsx)(n.p,{children:"The UI will ask you to set a password for your new account. Go ahead and do that."}),"\n",(0,t.jsx)(n.p,{children:"After doing that, I see the following output in my controller console:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"[ 516.778] INFO zrok/controller.(*registerHandler).Handle: created account 'user@domain.com' with token 'SuGzRPjVDIcF'\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Keep track of the token listed above (",(0,t.jsx)(n.code,{children:"SuGzRPjVDIcF"}),"). We'll use this to enable our shell for this ",(0,t.jsx)(n.code,{children:"zrok"})," deployment."]}),"\n",(0,t.jsx)(n.h2,{id:"enable-your-shell",children:"Enable Your Shell"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ zrok enable SuGzRPjVDIcF\nzrok environment '2AS1WZ3Sz' enabled for 'SuGzRPjVDIcF'\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Congratulations. You have a working ",(0,t.jsx)(n.code,{children:"zrok"})," environment!"]})]})}function h(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(a,{...e})}):a(e)}},1855:(e,n,r)=>{r.d(n,{Z:()=>t});const t=r.p+"assets/files/ctrl-6c22ae02cafe307b82e5a1f783497950.yml"},1151:(e,n,r)=>{r.d(n,{Z:()=>l,a:()=>s});var t=r(7294);const o={},i=t.createContext(o);function s(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0c66edb9.025d65ff.js b/assets/js/0c66edb9.025d65ff.js new file mode 100644 index 00000000..15d9e529 --- /dev/null +++ b/assets/js/0c66edb9.025d65ff.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[58],{2732:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>c,contentTitle:()=>a,default:()=>l,frontMatter:()=>i,metadata:()=>t,toc:()=>d});var r=n(5893),o=n(1151);const i={sidebar_position:22,sidebar_label:"Permission Modes"},a="Permission Modes",t={id:"guides/permission-modes",title:"Permission Modes",description:"Shares created in zrok v0.4.26 and newer now include a choice of permission mode.",source:"@site/../docs/guides/permission-modes.md",sourceDirName:"guides",slug:"/guides/permission-modes",permalink:"/docs/guides/permission-modes",draft:!1,unlisted:!1,editUrl:"https://github.com/openziti/zrok/blob/main/docs/../docs/guides/permission-modes.md",tags:[],version:"current",sidebarPosition:22,frontMatter:{sidebar_position:22,sidebar_label:"Permission Modes"},sidebar:"tutorialSidebar",previous:{title:"frontdoor",permalink:"/docs/guides/frontdoor"},next:{title:"Getting Started with Docker",permalink:"/docs/guides/docker-share/"}},c={},d=[{value:"Creating a Share with Closed Permission Mode",id:"creating-a-share-with-closed-permission-mode",level:2},{value:"Adding and Removing Access Grants for Existing Shares",id:"adding-and-removing-access-grants-for-existing-shares",level:2},{value:"Limitations",id:"limitations",level:2}];function h(e){const s={code:"code",em:"em",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,o.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.h1,{id:"permission-modes",children:"Permission Modes"}),"\n",(0,r.jsxs)(s.p,{children:["Shares created in zrok ",(0,r.jsx)(s.code,{children:"v0.4.26"})," and newer now include a choice of ",(0,r.jsx)(s.em,{children:"permission mode"}),"."]}),"\n",(0,r.jsxs)(s.p,{children:["Shares created with zrok ",(0,r.jsx)(s.code,{children:"v0.4.25"})," and older were created using what is now called the ",(0,r.jsx)(s.em,{children:"open permission mode"}),". Whether ",(0,r.jsx)(s.em,{children:"public"})," or ",(0,r.jsx)(s.em,{children:"private"}),", these shares can be accessed by any user of the zrok service instance, as long as they know the ",(0,r.jsx)(s.em,{children:"share token"})," of the share. Effectively shares with the ",(0,r.jsx)(s.em,{children:"open permission mode"})," are accessible by any user of the zrok service instance."]}),"\n",(0,r.jsxs)(s.p,{children:["zrok now supports a ",(0,r.jsx)(s.em,{children:"closed permission mode"}),", which allows for more fine-grained control over which zrok users are allowed to privately access your shares using ",(0,r.jsx)(s.code,{children:"zrok access private"}),"."]}),"\n",(0,r.jsxs)(s.p,{children:["zrok defaults to continuing to create shares with the ",(0,r.jsx)(s.em,{children:"open permission mode"}),". This will likely change in a future release. We're leaving the default behavior in place to allow users a period of time to get comfortable with the new permission modes."]}),"\n",(0,r.jsx)(s.h2,{id:"creating-a-share-with-closed-permission-mode",children:"Creating a Share with Closed Permission Mode"}),"\n",(0,r.jsxs)(s.p,{children:["Adding the ",(0,r.jsx)(s.code,{children:"--closed"})," flag to the ",(0,r.jsx)(s.code,{children:"zrok share"})," or ",(0,r.jsx)(s.code,{children:"zrok reserve"})," commands will create shares using the ",(0,r.jsx)(s.em,{children:"closed permission mode"}),":"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"$ zrok share private --headless --closed -b web .\n[ 0.066] INFO main.(*sharePrivateCommand).run: allow other to access your share with the following command:\nzrok access private 0vzwzodf0c7g\n"})}),"\n",(0,r.jsxs)(s.p,{children:["By default any environment owned by the account that created the share is ",(0,r.jsx)(s.em,{children:"allowed"})," to access the new share. But a user trying to access the share from an environment owned by a different account will enounter the following error message:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"$ zrok access private 0vzwzodf0c7g\n[ERROR]: unable to access ([POST /access][401] accessUnauthorized)\n"})}),"\n",(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.code,{children:"zrok share"})," and ",(0,r.jsx)(s.code,{children:"zrok reserve"})," commands now include an ",(0,r.jsx)(s.code,{children:"--access-grant"})," flag, which allows you to specify additional zrok accounts that are allowed to access your shares:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"$ zrok share private --headless --closed --access-grant anotheruser@test.com -b web .\n[ 0.062] INFO main.(*sharePrivateCommand).run: allow other to access your share with the following command:\nzrok access private y6h4at5xvn6o\n"})}),"\n",(0,r.jsxs)(s.p,{children:["And now ",(0,r.jsx)(s.code,{children:"anotheruser@test.com"})," will be allowed to access the share:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"$ zrok access private --headless y6h4at5xvn6o\n[ 0.049] INFO main.(*accessPrivateCommand).run: allocated frontend 'VyvrJihAOEHD'\n[ 0.051] INFO main.(*accessPrivateCommand).run: access the zrok share at the following endpoint: http://127.0.0.1:9191\n"})}),"\n",(0,r.jsx)(s.h2,{id:"adding-and-removing-access-grants-for-existing-shares",children:"Adding and Removing Access Grants for Existing Shares"}),"\n",(0,r.jsxs)(s.p,{children:["If you've created a share (either reserved or ephemeral) and you forgot to include an access grant, or want to remove an access grant that was mistakenly added, you can use the ",(0,r.jsx)(s.code,{children:"zrok modify share"})," command to make the adjustments:"]}),"\n",(0,r.jsx)(s.p,{children:"Create a share:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"$ zrok share private --headless --closed -b web .\n[ 0.064] INFO main.(*sharePrivateCommand).run: allow other to access your share with the following command:\nzrok access private s4czjylwk7wa\n"})}),"\n",(0,r.jsx)(s.p,{children:"In another shell in the same environment you can execute:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"$ zrok modify share s4czjylwk7wa --add-access-grant anotheruser@test.com\nupdated\n"})}),"\n",(0,r.jsx)(s.p,{children:"And to remove the grant:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"$ zrok modify share s4czjylwk7wa --remove-access-grant anotheruser@test.com\nupdated\n"})}),"\n",(0,r.jsx)(s.h2,{id:"limitations",children:"Limitations"}),"\n",(0,r.jsxs)(s.p,{children:["As of ",(0,r.jsx)(s.code,{children:"v0.4.26"})," there is currently no way to ",(0,r.jsx)(s.em,{children:"list"})," the current access grants. This will be addressed shortly in a subsequent update."]})]})}function l(e={}){const{wrapper:s}={...(0,o.a)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},1151:(e,s,n)=>{n.d(s,{Z:()=>t,a:()=>a});var r=n(7294);const o={},i=r.createContext(o);function a(e){const s=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function t(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),r.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0c66edb9.2f7977ae.js b/assets/js/0c66edb9.2f7977ae.js deleted file mode 100644 index a573afb1..00000000 --- a/assets/js/0c66edb9.2f7977ae.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[58],{2732:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>c,contentTitle:()=>a,default:()=>l,frontMatter:()=>i,metadata:()=>t,toc:()=>d});var r=n(5893),o=n(1151);const i={sidebar_position:22,sidebar_label:"Permission Modes"},a="Permission Modes",t={id:"guides/permission-modes",title:"Permission Modes",description:"Shares created in zrok v0.4.26 and newer now include a choice of permission mode.",source:"@site/../docs/guides/permission-modes.md",sourceDirName:"guides",slug:"/guides/permission-modes",permalink:"/docs/guides/permission-modes",draft:!1,unlisted:!1,editUrl:"https://github.com/openziti/zrok/blob/main/docs/../docs/guides/permission-modes.md",tags:[],version:"current",sidebarPosition:22,frontMatter:{sidebar_position:22,sidebar_label:"Permission Modes"},sidebar:"tutorialSidebar",previous:{title:"frontdoor",permalink:"/docs/guides/frontdoor"},next:{title:"Docker Share",permalink:"/docs/category/docker-share"}},c={},d=[{value:"Creating a Share with Closed Permission Mode",id:"creating-a-share-with-closed-permission-mode",level:2},{value:"Adding and Removing Access Grants for Existing Shares",id:"adding-and-removing-access-grants-for-existing-shares",level:2},{value:"Limitations",id:"limitations",level:2}];function h(e){const s={code:"code",em:"em",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,o.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.h1,{id:"permission-modes",children:"Permission Modes"}),"\n",(0,r.jsxs)(s.p,{children:["Shares created in zrok ",(0,r.jsx)(s.code,{children:"v0.4.26"})," and newer now include a choice of ",(0,r.jsx)(s.em,{children:"permission mode"}),"."]}),"\n",(0,r.jsxs)(s.p,{children:["Shares created with zrok ",(0,r.jsx)(s.code,{children:"v0.4.25"})," and older were created using what is now called the ",(0,r.jsx)(s.em,{children:"open permission mode"}),". Whether ",(0,r.jsx)(s.em,{children:"public"})," or ",(0,r.jsx)(s.em,{children:"private"}),", these shares can be accessed by any user of the zrok service instance, as long as they know the ",(0,r.jsx)(s.em,{children:"share token"})," of the share. Effectively shares with the ",(0,r.jsx)(s.em,{children:"open permission mode"})," are accessible by any user of the zrok service instance."]}),"\n",(0,r.jsxs)(s.p,{children:["zrok now supports a ",(0,r.jsx)(s.em,{children:"closed permission mode"}),", which allows for more fine-grained control over which zrok users are allowed to privately access your shares using ",(0,r.jsx)(s.code,{children:"zrok access private"}),"."]}),"\n",(0,r.jsxs)(s.p,{children:["zrok defaults to continuing to create shares with the ",(0,r.jsx)(s.em,{children:"open permission mode"}),". This will likely change in a future release. We're leaving the default behavior in place to allow users a period of time to get comfortable with the new permission modes."]}),"\n",(0,r.jsx)(s.h2,{id:"creating-a-share-with-closed-permission-mode",children:"Creating a Share with Closed Permission Mode"}),"\n",(0,r.jsxs)(s.p,{children:["Adding the ",(0,r.jsx)(s.code,{children:"--closed"})," flag to the ",(0,r.jsx)(s.code,{children:"zrok share"})," or ",(0,r.jsx)(s.code,{children:"zrok reserve"})," commands will create shares using the ",(0,r.jsx)(s.em,{children:"closed permission mode"}),":"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"$ zrok share private --headless --closed -b web .\n[ 0.066] INFO main.(*sharePrivateCommand).run: allow other to access your share with the following command:\nzrok access private 0vzwzodf0c7g\n"})}),"\n",(0,r.jsxs)(s.p,{children:["By default any environment owned by the account that created the share is ",(0,r.jsx)(s.em,{children:"allowed"})," to access the new share. But a user trying to access the share from an environment owned by a different account will enounter the following error message:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"$ zrok access private 0vzwzodf0c7g\n[ERROR]: unable to access ([POST /access][401] accessUnauthorized)\n"})}),"\n",(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.code,{children:"zrok share"})," and ",(0,r.jsx)(s.code,{children:"zrok reserve"})," commands now include an ",(0,r.jsx)(s.code,{children:"--access-grant"})," flag, which allows you to specify additional zrok accounts that are allowed to access your shares:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"$ zrok share private --headless --closed --access-grant anotheruser@test.com -b web .\n[ 0.062] INFO main.(*sharePrivateCommand).run: allow other to access your share with the following command:\nzrok access private y6h4at5xvn6o\n"})}),"\n",(0,r.jsxs)(s.p,{children:["And now ",(0,r.jsx)(s.code,{children:"anotheruser@test.com"})," will be allowed to access the share:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"$ zrok access private --headless y6h4at5xvn6o\n[ 0.049] INFO main.(*accessPrivateCommand).run: allocated frontend 'VyvrJihAOEHD'\n[ 0.051] INFO main.(*accessPrivateCommand).run: access the zrok share at the following endpoint: http://127.0.0.1:9191\n"})}),"\n",(0,r.jsx)(s.h2,{id:"adding-and-removing-access-grants-for-existing-shares",children:"Adding and Removing Access Grants for Existing Shares"}),"\n",(0,r.jsxs)(s.p,{children:["If you've created a share (either reserved or ephemeral) and you forgot to include an access grant, or want to remove an access grant that was mistakenly added, you can use the ",(0,r.jsx)(s.code,{children:"zrok modify share"})," command to make the adjustments:"]}),"\n",(0,r.jsx)(s.p,{children:"Create a share:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"$ zrok share private --headless --closed -b web .\n[ 0.064] INFO main.(*sharePrivateCommand).run: allow other to access your share with the following command:\nzrok access private s4czjylwk7wa\n"})}),"\n",(0,r.jsx)(s.p,{children:"In another shell in the same environment you can execute:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"$ zrok modify share s4czjylwk7wa --add-access-grant anotheruser@test.com\nupdated\n"})}),"\n",(0,r.jsx)(s.p,{children:"And to remove the grant:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"$ zrok modify share s4czjylwk7wa --remove-access-grant anotheruser@test.com\nupdated\n"})}),"\n",(0,r.jsx)(s.h2,{id:"limitations",children:"Limitations"}),"\n",(0,r.jsxs)(s.p,{children:["As of ",(0,r.jsx)(s.code,{children:"v0.4.26"})," there is currently no way to ",(0,r.jsx)(s.em,{children:"list"})," the current access grants. This will be addressed shortly in a subsequent update."]})]})}function l(e={}){const{wrapper:s}={...(0,o.a)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},1151:(e,s,n)=>{n.d(s,{Z:()=>t,a:()=>a});var r=n(7294);const o={},i=r.createContext(o);function a(e){const s=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function t(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),r.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/17896441.21664ee7.js b/assets/js/17896441.21664ee7.js deleted file mode 100644 index 36fb04fb..00000000 --- a/assets/js/17896441.21664ee7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7918],{1310:(e,t,n)=>{n.d(t,{Z:()=>v});n(7294);var s=n(6905),i=n(5281),a=n(3438),l=n(8596),o=n(3692),r=n(5999),c=n(4996),d=n(5893);function u(e){return(0,d.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,d.jsx)("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"})})}const m={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function h(){const e=(0,c.Z)("/");return(0,d.jsx)("li",{className:"breadcrumbs__item",children:(0,d.jsx)(o.Z,{"aria-label":(0,r.I)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e,children:(0,d.jsx)(u,{className:m.breadcrumbHomeIcon})})})}const x={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function p(e){let{children:t,href:n,isLast:s}=e;const i="breadcrumbs__link";return s?(0,d.jsx)("span",{className:i,itemProp:"name",children:t}):n?(0,d.jsx)(o.Z,{className:i,href:n,itemProp:"item",children:(0,d.jsx)("span",{itemProp:"name",children:t})}):(0,d.jsx)("span",{className:i,children:t})}function f(e){let{children:t,active:n,index:i,addMicrodata:a}=e;return(0,d.jsxs)("li",{...a&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},className:(0,s.Z)("breadcrumbs__item",{"breadcrumbs__item--active":n}),children:[t,(0,d.jsx)("meta",{itemProp:"position",content:String(i+1)})]})}function v(){const e=(0,a.s1)(),t=(0,l.Ns)();return e?(0,d.jsx)("nav",{className:(0,s.Z)(i.k.docs.docBreadcrumbs,x.breadcrumbsContainer),"aria-label":(0,r.I)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"}),children:(0,d.jsxs)("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList",children:[t&&(0,d.jsx)(h,{}),e.map(((t,n)=>{const s=n===e.length-1,i="category"===t.type&&t.linkUnlisted?void 0:t.href;return(0,d.jsx)(f,{active:s,index:n,addMicrodata:!!i,children:(0,d.jsx)(p,{href:i,isLast:s,children:t.label})},n)}))]})}):null}},1720:(e,t,n)=>{n.r(t),n.d(t,{default:()=>et});var s=n(7294),i=n(833),a=n(902),l=n(5893);const o=s.createContext(null);function r(e){let{children:t,content:n}=e;const i=function(e){return(0,s.useMemo)((()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,contentTitle:e.contentTitle,toc:e.toc})),[e])}(n);return(0,l.jsx)(o.Provider,{value:i,children:t})}function c(){const e=(0,s.useContext)(o);if(null===e)throw new a.i6("DocProvider");return e}function d(){const{metadata:e,frontMatter:t,assets:n}=c();return(0,l.jsx)(i.d,{title:e.title,description:e.description,keywords:t.keywords,image:n.image??t.image})}var u=n(6905),m=n(7524),h=n(4966);function x(){const{metadata:e}=c();return(0,l.jsx)(h.Z,{previous:e.previous,next:e.next})}var p=n(3120),f=n(4364),v=n(5281),j=n(5999);function g(e){let{lastUpdatedAt:t,formattedLastUpdatedAt:n}=e;return(0,l.jsx)(j.Z,{id:"theme.lastUpdated.atDate",description:"The words used to describe on which date a page has been last updated",values:{date:(0,l.jsx)("b",{children:(0,l.jsx)("time",{dateTime:new Date(1e3*t).toISOString(),children:n})})},children:" on {date}"})}function b(e){let{lastUpdatedBy:t}=e;return(0,l.jsx)(j.Z,{id:"theme.lastUpdated.byUser",description:"The words used to describe by who the page has been last updated",values:{user:(0,l.jsx)("b",{children:t})},children:" by {user}"})}function N(e){let{lastUpdatedAt:t,formattedLastUpdatedAt:n,lastUpdatedBy:s}=e;return(0,l.jsxs)("span",{className:v.k.common.lastUpdated,children:[(0,l.jsx)(j.Z,{id:"theme.lastUpdated.lastUpdatedAtBy",description:"The sentence used to display when a page has been last updated, and by who",values:{atDate:t&&n?(0,l.jsx)(g,{lastUpdatedAt:t,formattedLastUpdatedAt:n}):"",byUser:s?(0,l.jsx)(b,{lastUpdatedBy:s}):""},children:"Last updated{atDate}{byUser}"}),!1]})}var C=n(3692);const L={iconEdit:"iconEdit_Z9Sw"};function Z(e){let{className:t,...n}=e;return(0,l.jsx)("svg",{fill:"currentColor",height:"20",width:"20",viewBox:"0 0 40 40",className:(0,u.Z)(L.iconEdit,t),"aria-hidden":"true",...n,children:(0,l.jsx)("g",{children:(0,l.jsx)("path",{d:"m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"})})})}function _(e){let{editUrl:t}=e;return(0,l.jsxs)(C.Z,{to:t,className:v.k.common.editThisPage,children:[(0,l.jsx)(Z,{}),(0,l.jsx)(j.Z,{id:"theme.common.editThisPage",description:"The link label to edit the current page",children:"Edit this page"})]})}const k={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};function T(e){let{permalink:t,label:n,count:s}=e;return(0,l.jsxs)(C.Z,{href:t,className:(0,u.Z)(k.tag,s?k.tagWithCount:k.tagRegular),children:[n,s&&(0,l.jsx)("span",{children:s})]})}const y={tags:"tags_jXut",tag:"tag_QGVx"};function w(e){let{tags:t}=e;return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)("b",{children:(0,l.jsx)(j.Z,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list",children:"Tags:"})}),(0,l.jsx)("ul",{className:(0,u.Z)(y.tags,"padding--none","margin-left--sm"),children:t.map((e=>{let{label:t,permalink:n}=e;return(0,l.jsx)("li",{className:y.tag,children:(0,l.jsx)(T,{label:t,permalink:n})},n)}))})]})}const H={lastUpdated:"lastUpdated_vwxv"};function U(e){return(0,l.jsx)("div",{className:(0,u.Z)(v.k.docs.docFooterTagsRow,"row margin-bottom--sm"),children:(0,l.jsx)("div",{className:"col",children:(0,l.jsx)(w,{...e})})})}function M(e){let{editUrl:t,lastUpdatedAt:n,lastUpdatedBy:s,formattedLastUpdatedAt:i}=e;return(0,l.jsxs)("div",{className:(0,u.Z)(v.k.docs.docFooterEditMetaRow,"row"),children:[(0,l.jsx)("div",{className:"col",children:t&&(0,l.jsx)(_,{editUrl:t})}),(0,l.jsx)("div",{className:(0,u.Z)("col",H.lastUpdated),children:(n||s)&&(0,l.jsx)(N,{lastUpdatedAt:n,formattedLastUpdatedAt:i,lastUpdatedBy:s})})]})}function A(){const{metadata:e}=c(),{editUrl:t,lastUpdatedAt:n,formattedLastUpdatedAt:s,lastUpdatedBy:i,tags:a}=e,o=a.length>0,r=!!(t||n||i);return o||r?(0,l.jsxs)("footer",{className:(0,u.Z)(v.k.docs.docFooter,"docusaurus-mt-lg"),children:[o&&(0,l.jsx)(U,{tags:a}),r&&(0,l.jsx)(M,{editUrl:t,lastUpdatedAt:n,lastUpdatedBy:i,formattedLastUpdatedAt:s})]}):null}var B=n(6043),E=n(6668);function I(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const s=n.slice(2,e.level);e.parentIndex=Math.max(...s),n[e.level]=t}));const s=[];return t.forEach((e=>{const{parentIndex:n,...i}=e;n>=0?t[n].children.push(i):s.push(i)})),s}function z(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:s}=e;return t.flatMap((e=>{const t=z({toc:e.children,minHeadingLevel:n,maxHeadingLevel:s});return function(e){return e.level>=n&&e.level<=s}(e)?[{...e,children:t}]:t}))}function S(e){const t=e.getBoundingClientRect();return t.top===t.bottom?S(e.parentNode):t}function R(e,t){let{anchorTopOffset:n}=t;const s=e.find((e=>S(e).top>=n));if(s){return function(e){return e.top>0&&e.bottom{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function D(e){const t=(0,s.useRef)(void 0),n=V();(0,s.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:s,linkActiveClassName:i,minHeadingLevel:a,maxHeadingLevel:l}=e;function o(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(s),o=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const s=[];for(let i=t;i<=n;i+=1)s.push(`h${i}.anchor`);return Array.from(document.querySelectorAll(s.join()))}({minHeadingLevel:a,maxHeadingLevel:l}),r=R(o,{anchorTopOffset:n.current}),c=e.find((e=>r&&r.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(i),e.classList.add(i),t.current=e):e.classList.remove(i)}(e,e===c)}))}return document.addEventListener("scroll",o),document.addEventListener("resize",o),o(),()=>{document.removeEventListener("scroll",o),document.removeEventListener("resize",o)}}),[e,n])}function O(e){let{toc:t,className:n,linkClassName:s,isChild:i}=e;return t.length?(0,l.jsx)("ul",{className:i?void 0:n,children:t.map((e=>(0,l.jsxs)("li",{children:[(0,l.jsx)(C.Z,{to:`#${e.id}`,className:s??void 0,dangerouslySetInnerHTML:{__html:e.value}}),(0,l.jsx)(O,{isChild:!0,toc:e.children,className:n,linkClassName:s})]},e.id)))}):null}const P=s.memo(O);function F(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:i="table-of-contents__link",linkActiveClassName:a,minHeadingLevel:o,maxHeadingLevel:r,...c}=e;const d=(0,E.L)(),u=o??d.tableOfContents.minHeadingLevel,m=r??d.tableOfContents.maxHeadingLevel,h=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:i}=e;return(0,s.useMemo)((()=>z({toc:I(t),minHeadingLevel:n,maxHeadingLevel:i})),[t,n,i])}({toc:t,minHeadingLevel:u,maxHeadingLevel:m});return D((0,s.useMemo)((()=>{if(i&&a)return{linkClassName:i,linkActiveClassName:a,minHeadingLevel:u,maxHeadingLevel:m}}),[i,a,u,m])),(0,l.jsx)(P,{toc:h,className:n,linkClassName:i,...c})}const q={tocCollapsibleButton:"tocCollapsibleButton_TO0P",tocCollapsibleButtonExpanded:"tocCollapsibleButtonExpanded_MG3E"};function G(e){let{collapsed:t,...n}=e;return(0,l.jsx)("button",{type:"button",...n,className:(0,u.Z)("clean-btn",q.tocCollapsibleButton,!t&&q.tocCollapsibleButtonExpanded,n.className),children:(0,l.jsx)(j.Z,{id:"theme.TOCCollapsible.toggleButtonLabel",description:"The label used by the button on the collapsible TOC component",children:"On this page"})})}const W={tocCollapsible:"tocCollapsible_ETCw",tocCollapsibleContent:"tocCollapsibleContent_vkbj",tocCollapsibleExpanded:"tocCollapsibleExpanded_sAul"};function $(e){let{toc:t,className:n,minHeadingLevel:s,maxHeadingLevel:i}=e;const{collapsed:a,toggleCollapsed:o}=(0,B.u)({initialState:!0});return(0,l.jsxs)("div",{className:(0,u.Z)(W.tocCollapsible,!a&&W.tocCollapsibleExpanded,n),children:[(0,l.jsx)(G,{collapsed:a,onClick:o}),(0,l.jsx)(B.z,{lazy:!0,className:W.tocCollapsibleContent,collapsed:a,children:(0,l.jsx)(F,{toc:t,minHeadingLevel:s,maxHeadingLevel:i})})]})}const J={tocMobile:"tocMobile_ITEo"};function Y(){const{toc:e,frontMatter:t}=c();return(0,l.jsx)($,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:(0,u.Z)(v.k.docs.docTocMobile,J.tocMobile)})}const Q={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"},X="table-of-contents__link toc-highlight",K="table-of-contents__link--active";function ee(e){let{className:t,...n}=e;return(0,l.jsx)("div",{className:(0,u.Z)(Q.tableOfContents,"thin-scrollbar",t),children:(0,l.jsx)(F,{...n,linkClassName:X,linkActiveClassName:K})})}function te(){const{toc:e,frontMatter:t}=c();return(0,l.jsx)(ee,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:v.k.docs.docTocDesktop})}var ne=n(2503),se=n(1151),ie=n(5742),ae=n(9286);function le(e){return(0,l.jsx)("code",{...e})}var oe=n(788),re=n(2389);const ce={details:"details_lb9f",isBrowser:"isBrowser_bmU9",collapsibleContent:"collapsibleContent_i85q"};function de(e){return!!e&&("SUMMARY"===e.tagName||de(e.parentElement))}function ue(e,t){return!!e&&(e===t||ue(e.parentElement,t))}function me(e){let{summary:t,children:n,...i}=e;const a=(0,re.Z)(),o=(0,s.useRef)(null),{collapsed:r,setCollapsed:c}=(0,B.u)({initialState:!i.open}),[d,u]=(0,s.useState)(i.open),m=s.isValidElement(t)?t:(0,l.jsx)("summary",{children:t??"Details"});return(0,l.jsxs)("details",{...i,ref:o,open:d,"data-collapsed":r,className:(0,oe.Z)(ce.details,a&&ce.isBrowser,i.className),onMouseDown:e=>{de(e.target)&&e.detail>1&&e.preventDefault()},onClick:e=>{e.stopPropagation();const t=e.target;de(t)&&ue(t,o.current)&&(e.preventDefault(),r?(c(!1),u(!0)):c(!0))},children:[m,(0,l.jsx)(B.z,{lazy:!1,collapsed:r,disableSSRStyle:!0,onCollapseTransitionEnd:e=>{c(e),u(!e)},children:(0,l.jsx)("div",{className:ce.collapsibleContent,children:n})})]})}const he={details:"details_b_Ee"},xe="alert alert--info";function pe(e){let{...t}=e;return(0,l.jsx)(me,{...t,className:(0,u.Z)(xe,he.details,t.className)})}function fe(e){const t=s.Children.toArray(e.children),n=t.find((e=>s.isValidElement(e)&&"summary"===e.type)),i=(0,l.jsx)(l.Fragment,{children:t.filter((e=>e!==n))});return(0,l.jsx)(pe,{...e,summary:n,children:i})}function ve(e){return(0,l.jsx)(ne.Z,{...e})}const je={containsTaskList:"containsTaskList_mC6p"};function ge(e){if(void 0!==e)return(0,u.Z)(e,e?.includes("contains-task-list")&&je.containsTaskList)}const be={img:"img_ev3q"};function Ne(e){const{mdxAdmonitionTitle:t,rest:n}=function(e){const t=s.Children.toArray(e),n=t.find((e=>s.isValidElement(e)&&"mdxAdmonitionTitle"===e.type)),i=t.filter((e=>e!==n)),a=n?.props.children;return{mdxAdmonitionTitle:a,rest:i.length>0?(0,l.jsx)(l.Fragment,{children:i}):null}}(e.children),i=e.title??t;return{...e,...i&&{title:i},children:n}}const Ce={admonition:"admonition_xJq3",admonitionHeading:"admonitionHeading_Gvgb",admonitionIcon:"admonitionIcon_Rf37",admonitionContent:"admonitionContent_BuS1"};function Le(e){let{type:t,className:n,children:s}=e;return(0,l.jsx)("div",{className:(0,u.Z)(v.k.common.admonition,v.k.common.admonitionType(t),Ce.admonition,n),children:s})}function Ze(e){let{icon:t,title:n}=e;return(0,l.jsxs)("div",{className:Ce.admonitionHeading,children:[(0,l.jsx)("span",{className:Ce.admonitionIcon,children:t}),n]})}function _e(e){let{children:t}=e;return t?(0,l.jsx)("div",{className:Ce.admonitionContent,children:t}):null}function ke(e){const{type:t,icon:n,title:s,children:i,className:a}=e;return(0,l.jsxs)(Le,{type:t,className:a,children:[(0,l.jsx)(Ze,{title:s,icon:n}),(0,l.jsx)(_e,{children:i})]})}function Te(e){return(0,l.jsx)("svg",{viewBox:"0 0 14 16",...e,children:(0,l.jsx)("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"})})}const ye={icon:(0,l.jsx)(Te,{}),title:(0,l.jsx)(j.Z,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)",children:"note"})};function we(e){return(0,l.jsx)(ke,{...ye,...e,className:(0,u.Z)("alert alert--secondary",e.className),children:e.children})}function He(e){return(0,l.jsx)("svg",{viewBox:"0 0 12 16",...e,children:(0,l.jsx)("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"})})}const Ue={icon:(0,l.jsx)(He,{}),title:(0,l.jsx)(j.Z,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)",children:"tip"})};function Me(e){return(0,l.jsx)(ke,{...Ue,...e,className:(0,u.Z)("alert alert--success",e.className),children:e.children})}function Ae(e){return(0,l.jsx)("svg",{viewBox:"0 0 14 16",...e,children:(0,l.jsx)("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"})})}const Be={icon:(0,l.jsx)(Ae,{}),title:(0,l.jsx)(j.Z,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)",children:"info"})};function Ee(e){return(0,l.jsx)(ke,{...Be,...e,className:(0,u.Z)("alert alert--info",e.className),children:e.children})}function Ie(e){return(0,l.jsx)("svg",{viewBox:"0 0 16 16",...e,children:(0,l.jsx)("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"})})}const ze={icon:(0,l.jsx)(Ie,{}),title:(0,l.jsx)(j.Z,{id:"theme.admonition.warning",description:"The default label used for the Warning admonition (:::warning)",children:"warning"})};function Se(e){return(0,l.jsx)("svg",{viewBox:"0 0 12 16",...e,children:(0,l.jsx)("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"})})}const Re={icon:(0,l.jsx)(Se,{}),title:(0,l.jsx)(j.Z,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)",children:"danger"})};const Ve={icon:(0,l.jsx)(Ie,{}),title:(0,l.jsx)(j.Z,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)",children:"caution"})};const De={...{note:we,tip:Me,info:Ee,warning:function(e){return(0,l.jsx)(ke,{...ze,...e,className:(0,u.Z)("alert alert--warning",e.className),children:e.children})},danger:function(e){return(0,l.jsx)(ke,{...Re,...e,className:(0,u.Z)("alert alert--danger",e.className),children:e.children})}},...{secondary:e=>(0,l.jsx)(we,{title:"secondary",...e}),important:e=>(0,l.jsx)(Ee,{title:"important",...e}),success:e=>(0,l.jsx)(Me,{title:"success",...e}),caution:function(e){return(0,l.jsx)(ke,{...Ve,...e,className:(0,u.Z)("alert alert--warning",e.className),children:e.children})}}};function Oe(e){const t=Ne(e),n=(s=t.type,De[s]||(console.warn(`No admonition component found for admonition type "${s}". Using Info as fallback.`),De.info));var s;return(0,l.jsx)(n,{...t})}const Pe={Head:ie.Z,details:fe,Details:fe,code:function(e){return function(e){return void 0!==e.children&&s.Children.toArray(e.children).every((e=>"string"==typeof e&&!e.includes("\n")))}(e)?(0,l.jsx)(le,{...e}):(0,l.jsx)(ae.Z,{...e})},a:function(e){return(0,l.jsx)(C.Z,{...e})},pre:function(e){return(0,l.jsx)(l.Fragment,{children:e.children})},ul:function(e){return(0,l.jsx)("ul",{...e,className:ge(e.className)})},img:function(e){return(0,l.jsx)("img",{loading:"lazy",...e,className:(t=e.className,(0,u.Z)(t,be.img))});var t},h1:e=>(0,l.jsx)(ve,{as:"h1",...e}),h2:e=>(0,l.jsx)(ve,{as:"h2",...e}),h3:e=>(0,l.jsx)(ve,{as:"h3",...e}),h4:e=>(0,l.jsx)(ve,{as:"h4",...e}),h5:e=>(0,l.jsx)(ve,{as:"h5",...e}),h6:e=>(0,l.jsx)(ve,{as:"h6",...e}),admonition:Oe,mermaid:()=>null};function Fe(e){let{children:t}=e;return(0,l.jsx)(se.Z,{components:Pe,children:t})}function qe(e){let{children:t}=e;const n=function(){const{metadata:e,frontMatter:t,contentTitle:n}=c();return t.hide_title||void 0!==n?null:e.title}();return(0,l.jsxs)("div",{className:(0,u.Z)(v.k.docs.docMarkdown,"markdown"),children:[n&&(0,l.jsx)("header",{children:(0,l.jsx)(ne.Z,{as:"h1",children:n})}),(0,l.jsx)(Fe,{children:t})]})}var Ge=n(1310);function We(){return(0,l.jsx)(j.Z,{id:"theme.unlistedContent.title",description:"The unlisted content banner title",children:"Unlisted page"})}function $e(){return(0,l.jsx)(j.Z,{id:"theme.unlistedContent.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function Je(){return(0,l.jsx)(ie.Z,{children:(0,l.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function Ye(e){let{className:t}=e;return(0,l.jsx)(Oe,{type:"caution",title:(0,l.jsx)(We,{}),className:(0,u.Z)(t,v.k.common.unlistedBanner),children:(0,l.jsx)($e,{})})}function Qe(e){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(Je,{}),(0,l.jsx)(Ye,{...e})]})}const Xe={docItemContainer:"docItemContainer_Djhp",docItemCol:"docItemCol_VOVn"};function Ke(e){let{children:t}=e;const n=function(){const{frontMatter:e,toc:t}=c(),n=(0,m.i)(),s=e.hide_table_of_contents,i=!s&&t.length>0;return{hidden:s,mobile:i?(0,l.jsx)(Y,{}):void 0,desktop:!i||"desktop"!==n&&"ssr"!==n?void 0:(0,l.jsx)(te,{})}}(),{metadata:{unlisted:s}}=c();return(0,l.jsxs)("div",{className:"row",children:[(0,l.jsxs)("div",{className:(0,u.Z)("col",!n.hidden&&Xe.docItemCol),children:[s&&(0,l.jsx)(Qe,{}),(0,l.jsx)(p.Z,{}),(0,l.jsxs)("div",{className:Xe.docItemContainer,children:[(0,l.jsxs)("article",{children:[(0,l.jsx)(Ge.Z,{}),(0,l.jsx)(f.Z,{}),n.mobile,(0,l.jsx)(qe,{children:t}),(0,l.jsx)(A,{})]}),(0,l.jsx)(x,{})]})]}),n.desktop&&(0,l.jsx)("div",{className:"col col--3",children:n.desktop})]})}function et(e){const t=`docs-doc-id-${e.content.metadata.id}`,n=e.content;return(0,l.jsx)(r,{content:e.content,children:(0,l.jsxs)(i.FG,{className:t,children:[(0,l.jsx)(d,{}),(0,l.jsx)(Ke,{children:(0,l.jsx)(n,{})})]})})}},4966:(e,t,n)=>{n.d(t,{Z:()=>r});n(7294);var s=n(5999),i=n(6905),a=n(3692),l=n(5893);function o(e){const{permalink:t,title:n,subLabel:s,isNext:o}=e;return(0,l.jsxs)(a.Z,{className:(0,i.Z)("pagination-nav__link",o?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t,children:[s&&(0,l.jsx)("div",{className:"pagination-nav__sublabel",children:s}),(0,l.jsx)("div",{className:"pagination-nav__label",children:n})]})}function r(e){const{previous:t,next:n}=e;return(0,l.jsxs)("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,s.I)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"}),children:[t&&(0,l.jsx)(o,{...t,subLabel:(0,l.jsx)(s.Z,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc",children:"Previous"})}),n&&(0,l.jsx)(o,{...n,subLabel:(0,l.jsx)(s.Z,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc",children:"Next"}),isNext:!0})]})}},4364:(e,t,n)=>{n.d(t,{Z:()=>r});n(7294);var s=n(6905),i=n(5999),a=n(5281),l=n(4477),o=n(5893);function r(e){let{className:t}=e;const n=(0,l.E)();return n.badge?(0,o.jsx)("span",{className:(0,s.Z)(t,a.k.docs.docVersionBadge,"badge badge--secondary"),children:(0,o.jsx)(i.Z,{id:"theme.docs.versionBadge.label",values:{versionLabel:n.label},children:"Version: {versionLabel}"})}):null}},3120:(e,t,n)=>{n.d(t,{Z:()=>f});n(7294);var s=n(6905),i=n(2263),a=n(3692),l=n(5999),o=n(143),r=n(5281),c=n(373),d=n(4477),u=n(5893);const m={unreleased:function(e){let{siteTitle:t,versionMetadata:n}=e;return(0,u.jsx)(l.Z,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:t,versionLabel:(0,u.jsx)("b",{children:n.label})},children:"This is unreleased documentation for {siteTitle} {versionLabel} version."})},unmaintained:function(e){let{siteTitle:t,versionMetadata:n}=e;return(0,u.jsx)(l.Z,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:t,versionLabel:(0,u.jsx)("b",{children:n.label})},children:"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained."})}};function h(e){const t=m[e.versionMetadata.banner];return(0,u.jsx)(t,{...e})}function x(e){let{versionLabel:t,to:n,onClick:s}=e;return(0,u.jsx)(l.Z,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:t,latestVersionLink:(0,u.jsx)("b",{children:(0,u.jsx)(a.Z,{to:n,onClick:s,children:(0,u.jsx)(l.Z,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label",children:"latest version"})})})},children:"For up-to-date documentation, see the {latestVersionLink} ({versionLabel})."})}function p(e){let{className:t,versionMetadata:n}=e;const{siteConfig:{title:a}}=(0,i.Z)(),{pluginId:l}=(0,o.gA)({failfast:!0}),{savePreferredVersionName:d}=(0,c.J)(l),{latestDocSuggestion:m,latestVersionSuggestion:p}=(0,o.Jo)(l),f=m??(v=p).docs.find((e=>e.id===v.mainDocId));var v;return(0,u.jsxs)("div",{className:(0,s.Z)(t,r.k.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert",children:[(0,u.jsx)("div",{children:(0,u.jsx)(h,{siteTitle:a,versionMetadata:n})}),(0,u.jsx)("div",{className:"margin-top--md",children:(0,u.jsx)(x,{versionLabel:p.label,to:f.path,onClick:()=>d(p.name)})})]})}function f(e){let{className:t}=e;const n=(0,d.E)();return n.banner?(0,u.jsx)(p,{className:t,versionMetadata:n}):null}}}]); \ No newline at end of file diff --git a/assets/js/17896441.d85d0af9.js b/assets/js/17896441.d85d0af9.js new file mode 100644 index 00000000..87cc34b4 --- /dev/null +++ b/assets/js/17896441.d85d0af9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7918],{1310:(e,t,n)=>{n.d(t,{Z:()=>v});n(7294);var s=n(6905),i=n(5281),a=n(3438),l=n(8596),o=n(3692),r=n(5999),c=n(4996),d=n(5893);function u(e){return(0,d.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,d.jsx)("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"})})}const m={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function h(){const e=(0,c.Z)("/");return(0,d.jsx)("li",{className:"breadcrumbs__item",children:(0,d.jsx)(o.Z,{"aria-label":(0,r.I)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e,children:(0,d.jsx)(u,{className:m.breadcrumbHomeIcon})})})}const x={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function p(e){let{children:t,href:n,isLast:s}=e;const i="breadcrumbs__link";return s?(0,d.jsx)("span",{className:i,itemProp:"name",children:t}):n?(0,d.jsx)(o.Z,{className:i,href:n,itemProp:"item",children:(0,d.jsx)("span",{itemProp:"name",children:t})}):(0,d.jsx)("span",{className:i,children:t})}function f(e){let{children:t,active:n,index:i,addMicrodata:a}=e;return(0,d.jsxs)("li",{...a&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},className:(0,s.Z)("breadcrumbs__item",{"breadcrumbs__item--active":n}),children:[t,(0,d.jsx)("meta",{itemProp:"position",content:String(i+1)})]})}function v(){const e=(0,a.s1)(),t=(0,l.Ns)();return e?(0,d.jsx)("nav",{className:(0,s.Z)(i.k.docs.docBreadcrumbs,x.breadcrumbsContainer),"aria-label":(0,r.I)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"}),children:(0,d.jsxs)("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList",children:[t&&(0,d.jsx)(h,{}),e.map(((t,n)=>{const s=n===e.length-1,i="category"===t.type&&t.linkUnlisted?void 0:t.href;return(0,d.jsx)(f,{active:s,index:n,addMicrodata:!!i,children:(0,d.jsx)(p,{href:i,isLast:s,children:t.label})},n)}))]})}):null}},9814:(e,t,n)=>{n.r(t),n.d(t,{default:()=>qe});var s=n(7294),i=n(833),a=n(902),l=n(5893);const o=s.createContext(null);function r(e){let{children:t,content:n}=e;const i=function(e){return(0,s.useMemo)((()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,contentTitle:e.contentTitle,toc:e.toc})),[e])}(n);return(0,l.jsx)(o.Provider,{value:i,children:t})}function c(){const e=(0,s.useContext)(o);if(null===e)throw new a.i6("DocProvider");return e}function d(){const{metadata:e,frontMatter:t,assets:n}=c();return(0,l.jsx)(i.d,{title:e.title,description:e.description,keywords:t.keywords,image:n.image??t.image})}var u=n(6905),m=n(7524),h=n(4966);function x(){const{metadata:e}=c();return(0,l.jsx)(h.Z,{previous:e.previous,next:e.next})}var p=n(3120),f=n(4364),v=n(5281),j=n(5999);function g(e){let{lastUpdatedAt:t,formattedLastUpdatedAt:n}=e;return(0,l.jsx)(j.Z,{id:"theme.lastUpdated.atDate",description:"The words used to describe on which date a page has been last updated",values:{date:(0,l.jsx)("b",{children:(0,l.jsx)("time",{dateTime:new Date(1e3*t).toISOString(),children:n})})},children:" on {date}"})}function b(e){let{lastUpdatedBy:t}=e;return(0,l.jsx)(j.Z,{id:"theme.lastUpdated.byUser",description:"The words used to describe by who the page has been last updated",values:{user:(0,l.jsx)("b",{children:t})},children:" by {user}"})}function N(e){let{lastUpdatedAt:t,formattedLastUpdatedAt:n,lastUpdatedBy:s}=e;return(0,l.jsxs)("span",{className:v.k.common.lastUpdated,children:[(0,l.jsx)(j.Z,{id:"theme.lastUpdated.lastUpdatedAtBy",description:"The sentence used to display when a page has been last updated, and by who",values:{atDate:t&&n?(0,l.jsx)(g,{lastUpdatedAt:t,formattedLastUpdatedAt:n}):"",byUser:s?(0,l.jsx)(b,{lastUpdatedBy:s}):""},children:"Last updated{atDate}{byUser}"}),!1]})}var C=n(3692);const L={iconEdit:"iconEdit_Z9Sw"};function Z(e){let{className:t,...n}=e;return(0,l.jsx)("svg",{fill:"currentColor",height:"20",width:"20",viewBox:"0 0 40 40",className:(0,u.Z)(L.iconEdit,t),"aria-hidden":"true",...n,children:(0,l.jsx)("g",{children:(0,l.jsx)("path",{d:"m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"})})})}function _(e){let{editUrl:t}=e;return(0,l.jsxs)(C.Z,{to:t,className:v.k.common.editThisPage,children:[(0,l.jsx)(Z,{}),(0,l.jsx)(j.Z,{id:"theme.common.editThisPage",description:"The link label to edit the current page",children:"Edit this page"})]})}const k={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};function T(e){let{permalink:t,label:n,count:s}=e;return(0,l.jsxs)(C.Z,{href:t,className:(0,u.Z)(k.tag,s?k.tagWithCount:k.tagRegular),children:[n,s&&(0,l.jsx)("span",{children:s})]})}const y={tags:"tags_jXut",tag:"tag_QGVx"};function w(e){let{tags:t}=e;return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)("b",{children:(0,l.jsx)(j.Z,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list",children:"Tags:"})}),(0,l.jsx)("ul",{className:(0,u.Z)(y.tags,"padding--none","margin-left--sm"),children:t.map((e=>{let{label:t,permalink:n}=e;return(0,l.jsx)("li",{className:y.tag,children:(0,l.jsx)(T,{label:t,permalink:n})},n)}))})]})}const H={lastUpdated:"lastUpdated_vwxv"};function U(e){return(0,l.jsx)("div",{className:(0,u.Z)(v.k.docs.docFooterTagsRow,"row margin-bottom--sm"),children:(0,l.jsx)("div",{className:"col",children:(0,l.jsx)(w,{...e})})})}function M(e){let{editUrl:t,lastUpdatedAt:n,lastUpdatedBy:s,formattedLastUpdatedAt:i}=e;return(0,l.jsxs)("div",{className:(0,u.Z)(v.k.docs.docFooterEditMetaRow,"row"),children:[(0,l.jsx)("div",{className:"col",children:t&&(0,l.jsx)(_,{editUrl:t})}),(0,l.jsx)("div",{className:(0,u.Z)("col",H.lastUpdated),children:(n||s)&&(0,l.jsx)(N,{lastUpdatedAt:n,formattedLastUpdatedAt:i,lastUpdatedBy:s})})]})}function A(){const{metadata:e}=c(),{editUrl:t,lastUpdatedAt:n,formattedLastUpdatedAt:s,lastUpdatedBy:i,tags:a}=e,o=a.length>0,r=!!(t||n||i);return o||r?(0,l.jsxs)("footer",{className:(0,u.Z)(v.k.docs.docFooter,"docusaurus-mt-lg"),children:[o&&(0,l.jsx)(U,{tags:a}),r&&(0,l.jsx)(M,{editUrl:t,lastUpdatedAt:n,lastUpdatedBy:i,formattedLastUpdatedAt:s})]}):null}var B=n(6043),E=n(6668);function I(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const s=n.slice(2,e.level);e.parentIndex=Math.max(...s),n[e.level]=t}));const s=[];return t.forEach((e=>{const{parentIndex:n,...i}=e;n>=0?t[n].children.push(i):s.push(i)})),s}function z(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:s}=e;return t.flatMap((e=>{const t=z({toc:e.children,minHeadingLevel:n,maxHeadingLevel:s});return function(e){return e.level>=n&&e.level<=s}(e)?[{...e,children:t}]:t}))}function S(e){const t=e.getBoundingClientRect();return t.top===t.bottom?S(e.parentNode):t}function R(e,t){let{anchorTopOffset:n}=t;const s=e.find((e=>S(e).top>=n));if(s){return function(e){return e.top>0&&e.bottom{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function D(e){const t=(0,s.useRef)(void 0),n=V();(0,s.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:s,linkActiveClassName:i,minHeadingLevel:a,maxHeadingLevel:l}=e;function o(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(s),o=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const s=[];for(let i=t;i<=n;i+=1)s.push(`h${i}.anchor`);return Array.from(document.querySelectorAll(s.join()))}({minHeadingLevel:a,maxHeadingLevel:l}),r=R(o,{anchorTopOffset:n.current}),c=e.find((e=>r&&r.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(i),e.classList.add(i),t.current=e):e.classList.remove(i)}(e,e===c)}))}return document.addEventListener("scroll",o),document.addEventListener("resize",o),o(),()=>{document.removeEventListener("scroll",o),document.removeEventListener("resize",o)}}),[e,n])}function O(e){let{toc:t,className:n,linkClassName:s,isChild:i}=e;return t.length?(0,l.jsx)("ul",{className:i?void 0:n,children:t.map((e=>(0,l.jsxs)("li",{children:[(0,l.jsx)(C.Z,{to:`#${e.id}`,className:s??void 0,dangerouslySetInnerHTML:{__html:e.value}}),(0,l.jsx)(O,{isChild:!0,toc:e.children,className:n,linkClassName:s})]},e.id)))}):null}const P=s.memo(O);function F(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:i="table-of-contents__link",linkActiveClassName:a,minHeadingLevel:o,maxHeadingLevel:r,...c}=e;const d=(0,E.L)(),u=o??d.tableOfContents.minHeadingLevel,m=r??d.tableOfContents.maxHeadingLevel,h=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:i}=e;return(0,s.useMemo)((()=>z({toc:I(t),minHeadingLevel:n,maxHeadingLevel:i})),[t,n,i])}({toc:t,minHeadingLevel:u,maxHeadingLevel:m});return D((0,s.useMemo)((()=>{if(i&&a)return{linkClassName:i,linkActiveClassName:a,minHeadingLevel:u,maxHeadingLevel:m}}),[i,a,u,m])),(0,l.jsx)(P,{toc:h,className:n,linkClassName:i,...c})}const q={tocCollapsibleButton:"tocCollapsibleButton_TO0P",tocCollapsibleButtonExpanded:"tocCollapsibleButtonExpanded_MG3E"};function G(e){let{collapsed:t,...n}=e;return(0,l.jsx)("button",{type:"button",...n,className:(0,u.Z)("clean-btn",q.tocCollapsibleButton,!t&&q.tocCollapsibleButtonExpanded,n.className),children:(0,l.jsx)(j.Z,{id:"theme.TOCCollapsible.toggleButtonLabel",description:"The label used by the button on the collapsible TOC component",children:"On this page"})})}const W={tocCollapsible:"tocCollapsible_ETCw",tocCollapsibleContent:"tocCollapsibleContent_vkbj",tocCollapsibleExpanded:"tocCollapsibleExpanded_sAul"};function $(e){let{toc:t,className:n,minHeadingLevel:s,maxHeadingLevel:i}=e;const{collapsed:a,toggleCollapsed:o}=(0,B.u)({initialState:!0});return(0,l.jsxs)("div",{className:(0,u.Z)(W.tocCollapsible,!a&&W.tocCollapsibleExpanded,n),children:[(0,l.jsx)(G,{collapsed:a,onClick:o}),(0,l.jsx)(B.z,{lazy:!0,className:W.tocCollapsibleContent,collapsed:a,children:(0,l.jsx)(F,{toc:t,minHeadingLevel:s,maxHeadingLevel:i})})]})}const J={tocMobile:"tocMobile_ITEo"};function Y(){const{toc:e,frontMatter:t}=c();return(0,l.jsx)($,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:(0,u.Z)(v.k.docs.docTocMobile,J.tocMobile)})}const Q={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"},X="table-of-contents__link toc-highlight",K="table-of-contents__link--active";function ee(e){let{className:t,...n}=e;return(0,l.jsx)("div",{className:(0,u.Z)(Q.tableOfContents,"thin-scrollbar",t),children:(0,l.jsx)(F,{...n,linkClassName:X,linkActiveClassName:K})})}function te(){const{toc:e,frontMatter:t}=c();return(0,l.jsx)(ee,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:v.k.docs.docTocDesktop})}var ne=n(2503),se=n(1151),ie=n(5742),ae=n(9286);function le(e){return(0,l.jsx)("code",{...e})}var oe=n(5471);function re(e){return(0,l.jsx)(ne.Z,{...e})}const ce={containsTaskList:"containsTaskList_mC6p"};function de(e){if(void 0!==e)return(0,u.Z)(e,e?.includes("contains-task-list")&&ce.containsTaskList)}const ue={img:"img_ev3q"};function me(e){const{mdxAdmonitionTitle:t,rest:n}=function(e){const t=s.Children.toArray(e),n=t.find((e=>s.isValidElement(e)&&"mdxAdmonitionTitle"===e.type)),i=t.filter((e=>e!==n)),a=n?.props.children;return{mdxAdmonitionTitle:a,rest:i.length>0?(0,l.jsx)(l.Fragment,{children:i}):null}}(e.children),i=e.title??t;return{...e,...i&&{title:i},children:n}}const he={admonition:"admonition_xJq3",admonitionHeading:"admonitionHeading_Gvgb",admonitionIcon:"admonitionIcon_Rf37",admonitionContent:"admonitionContent_BuS1"};function xe(e){let{type:t,className:n,children:s}=e;return(0,l.jsx)("div",{className:(0,u.Z)(v.k.common.admonition,v.k.common.admonitionType(t),he.admonition,n),children:s})}function pe(e){let{icon:t,title:n}=e;return(0,l.jsxs)("div",{className:he.admonitionHeading,children:[(0,l.jsx)("span",{className:he.admonitionIcon,children:t}),n]})}function fe(e){let{children:t}=e;return t?(0,l.jsx)("div",{className:he.admonitionContent,children:t}):null}function ve(e){const{type:t,icon:n,title:s,children:i,className:a}=e;return(0,l.jsxs)(xe,{type:t,className:a,children:[(0,l.jsx)(pe,{title:s,icon:n}),(0,l.jsx)(fe,{children:i})]})}function je(e){return(0,l.jsx)("svg",{viewBox:"0 0 14 16",...e,children:(0,l.jsx)("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"})})}const ge={icon:(0,l.jsx)(je,{}),title:(0,l.jsx)(j.Z,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)",children:"note"})};function be(e){return(0,l.jsx)(ve,{...ge,...e,className:(0,u.Z)("alert alert--secondary",e.className),children:e.children})}function Ne(e){return(0,l.jsx)("svg",{viewBox:"0 0 12 16",...e,children:(0,l.jsx)("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"})})}const Ce={icon:(0,l.jsx)(Ne,{}),title:(0,l.jsx)(j.Z,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)",children:"tip"})};function Le(e){return(0,l.jsx)(ve,{...Ce,...e,className:(0,u.Z)("alert alert--success",e.className),children:e.children})}function Ze(e){return(0,l.jsx)("svg",{viewBox:"0 0 14 16",...e,children:(0,l.jsx)("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"})})}const _e={icon:(0,l.jsx)(Ze,{}),title:(0,l.jsx)(j.Z,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)",children:"info"})};function ke(e){return(0,l.jsx)(ve,{..._e,...e,className:(0,u.Z)("alert alert--info",e.className),children:e.children})}function Te(e){return(0,l.jsx)("svg",{viewBox:"0 0 16 16",...e,children:(0,l.jsx)("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"})})}const ye={icon:(0,l.jsx)(Te,{}),title:(0,l.jsx)(j.Z,{id:"theme.admonition.warning",description:"The default label used for the Warning admonition (:::warning)",children:"warning"})};function we(e){return(0,l.jsx)("svg",{viewBox:"0 0 12 16",...e,children:(0,l.jsx)("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"})})}const He={icon:(0,l.jsx)(we,{}),title:(0,l.jsx)(j.Z,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)",children:"danger"})};const Ue={icon:(0,l.jsx)(Te,{}),title:(0,l.jsx)(j.Z,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)",children:"caution"})};const Me={...{note:be,tip:Le,info:ke,warning:function(e){return(0,l.jsx)(ve,{...ye,...e,className:(0,u.Z)("alert alert--warning",e.className),children:e.children})},danger:function(e){return(0,l.jsx)(ve,{...He,...e,className:(0,u.Z)("alert alert--danger",e.className),children:e.children})}},...{secondary:e=>(0,l.jsx)(be,{title:"secondary",...e}),important:e=>(0,l.jsx)(ke,{title:"important",...e}),success:e=>(0,l.jsx)(Le,{title:"success",...e}),caution:function(e){return(0,l.jsx)(ve,{...Ue,...e,className:(0,u.Z)("alert alert--warning",e.className),children:e.children})}}};function Ae(e){const t=me(e),n=(s=t.type,Me[s]||(console.warn(`No admonition component found for admonition type "${s}". Using Info as fallback.`),Me.info));var s;return(0,l.jsx)(n,{...t})}const Be={Head:ie.Z,details:oe.Z,Details:oe.Z,code:function(e){return function(e){return void 0!==e.children&&s.Children.toArray(e.children).every((e=>"string"==typeof e&&!e.includes("\n")))}(e)?(0,l.jsx)(le,{...e}):(0,l.jsx)(ae.Z,{...e})},a:function(e){return(0,l.jsx)(C.Z,{...e})},pre:function(e){return(0,l.jsx)(l.Fragment,{children:e.children})},ul:function(e){return(0,l.jsx)("ul",{...e,className:de(e.className)})},img:function(e){return(0,l.jsx)("img",{loading:"lazy",...e,className:(t=e.className,(0,u.Z)(t,ue.img))});var t},h1:e=>(0,l.jsx)(re,{as:"h1",...e}),h2:e=>(0,l.jsx)(re,{as:"h2",...e}),h3:e=>(0,l.jsx)(re,{as:"h3",...e}),h4:e=>(0,l.jsx)(re,{as:"h4",...e}),h5:e=>(0,l.jsx)(re,{as:"h5",...e}),h6:e=>(0,l.jsx)(re,{as:"h6",...e}),admonition:Ae,mermaid:()=>null};function Ee(e){let{children:t}=e;return(0,l.jsx)(se.Z,{components:Be,children:t})}function Ie(e){let{children:t}=e;const n=function(){const{metadata:e,frontMatter:t,contentTitle:n}=c();return t.hide_title||void 0!==n?null:e.title}();return(0,l.jsxs)("div",{className:(0,u.Z)(v.k.docs.docMarkdown,"markdown"),children:[n&&(0,l.jsx)("header",{children:(0,l.jsx)(ne.Z,{as:"h1",children:n})}),(0,l.jsx)(Ee,{children:t})]})}var ze=n(1310);function Se(){return(0,l.jsx)(j.Z,{id:"theme.unlistedContent.title",description:"The unlisted content banner title",children:"Unlisted page"})}function Re(){return(0,l.jsx)(j.Z,{id:"theme.unlistedContent.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function Ve(){return(0,l.jsx)(ie.Z,{children:(0,l.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function De(e){let{className:t}=e;return(0,l.jsx)(Ae,{type:"caution",title:(0,l.jsx)(Se,{}),className:(0,u.Z)(t,v.k.common.unlistedBanner),children:(0,l.jsx)(Re,{})})}function Oe(e){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(Ve,{}),(0,l.jsx)(De,{...e})]})}const Pe={docItemContainer:"docItemContainer_Djhp",docItemCol:"docItemCol_VOVn"};function Fe(e){let{children:t}=e;const n=function(){const{frontMatter:e,toc:t}=c(),n=(0,m.i)(),s=e.hide_table_of_contents,i=!s&&t.length>0;return{hidden:s,mobile:i?(0,l.jsx)(Y,{}):void 0,desktop:!i||"desktop"!==n&&"ssr"!==n?void 0:(0,l.jsx)(te,{})}}(),{metadata:{unlisted:s}}=c();return(0,l.jsxs)("div",{className:"row",children:[(0,l.jsxs)("div",{className:(0,u.Z)("col",!n.hidden&&Pe.docItemCol),children:[s&&(0,l.jsx)(Oe,{}),(0,l.jsx)(p.Z,{}),(0,l.jsxs)("div",{className:Pe.docItemContainer,children:[(0,l.jsxs)("article",{children:[(0,l.jsx)(ze.Z,{}),(0,l.jsx)(f.Z,{}),n.mobile,(0,l.jsx)(Ie,{children:t}),(0,l.jsx)(A,{})]}),(0,l.jsx)(x,{})]})]}),n.desktop&&(0,l.jsx)("div",{className:"col col--3",children:n.desktop})]})}function qe(e){const t=`docs-doc-id-${e.content.metadata.id}`,n=e.content;return(0,l.jsx)(r,{content:e.content,children:(0,l.jsxs)(i.FG,{className:t,children:[(0,l.jsx)(d,{}),(0,l.jsx)(Fe,{children:(0,l.jsx)(n,{})})]})})}},4966:(e,t,n)=>{n.d(t,{Z:()=>r});n(7294);var s=n(5999),i=n(6905),a=n(3692),l=n(5893);function o(e){const{permalink:t,title:n,subLabel:s,isNext:o}=e;return(0,l.jsxs)(a.Z,{className:(0,i.Z)("pagination-nav__link",o?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t,children:[s&&(0,l.jsx)("div",{className:"pagination-nav__sublabel",children:s}),(0,l.jsx)("div",{className:"pagination-nav__label",children:n})]})}function r(e){const{previous:t,next:n}=e;return(0,l.jsxs)("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,s.I)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"}),children:[t&&(0,l.jsx)(o,{...t,subLabel:(0,l.jsx)(s.Z,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc",children:"Previous"})}),n&&(0,l.jsx)(o,{...n,subLabel:(0,l.jsx)(s.Z,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc",children:"Next"}),isNext:!0})]})}},4364:(e,t,n)=>{n.d(t,{Z:()=>r});n(7294);var s=n(6905),i=n(5999),a=n(5281),l=n(4477),o=n(5893);function r(e){let{className:t}=e;const n=(0,l.E)();return n.badge?(0,o.jsx)("span",{className:(0,s.Z)(t,a.k.docs.docVersionBadge,"badge badge--secondary"),children:(0,o.jsx)(i.Z,{id:"theme.docs.versionBadge.label",values:{versionLabel:n.label},children:"Version: {versionLabel}"})}):null}},3120:(e,t,n)=>{n.d(t,{Z:()=>f});n(7294);var s=n(6905),i=n(2263),a=n(3692),l=n(5999),o=n(143),r=n(5281),c=n(373),d=n(4477),u=n(5893);const m={unreleased:function(e){let{siteTitle:t,versionMetadata:n}=e;return(0,u.jsx)(l.Z,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:t,versionLabel:(0,u.jsx)("b",{children:n.label})},children:"This is unreleased documentation for {siteTitle} {versionLabel} version."})},unmaintained:function(e){let{siteTitle:t,versionMetadata:n}=e;return(0,u.jsx)(l.Z,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:t,versionLabel:(0,u.jsx)("b",{children:n.label})},children:"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained."})}};function h(e){const t=m[e.versionMetadata.banner];return(0,u.jsx)(t,{...e})}function x(e){let{versionLabel:t,to:n,onClick:s}=e;return(0,u.jsx)(l.Z,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:t,latestVersionLink:(0,u.jsx)("b",{children:(0,u.jsx)(a.Z,{to:n,onClick:s,children:(0,u.jsx)(l.Z,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label",children:"latest version"})})})},children:"For up-to-date documentation, see the {latestVersionLink} ({versionLabel})."})}function p(e){let{className:t,versionMetadata:n}=e;const{siteConfig:{title:a}}=(0,i.Z)(),{pluginId:l}=(0,o.gA)({failfast:!0}),{savePreferredVersionName:d}=(0,c.J)(l),{latestDocSuggestion:m,latestVersionSuggestion:p}=(0,o.Jo)(l),f=m??(v=p).docs.find((e=>e.id===v.mainDocId));var v;return(0,u.jsxs)("div",{className:(0,s.Z)(t,r.k.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert",children:[(0,u.jsx)("div",{children:(0,u.jsx)(h,{siteTitle:a,versionMetadata:n})}),(0,u.jsx)("div",{className:"margin-top--md",children:(0,u.jsx)(x,{versionLabel:p.label,to:f.path,onClick:()=>d(p.name)})})]})}function f(e){let{className:t}=e;const n=(0,d.E)();return n.banner?(0,u.jsx)(p,{className:t,versionMetadata:n}):null}},5471:(e,t,n)=>{n.d(t,{Z:()=>f});var s=n(7294),i=n(6905),a=n(788),l=n(2389),o=n(6043);const r={details:"details_lb9f",isBrowser:"isBrowser_bmU9",collapsibleContent:"collapsibleContent_i85q"};var c=n(5893);function d(e){return!!e&&("SUMMARY"===e.tagName||d(e.parentElement))}function u(e,t){return!!e&&(e===t||u(e.parentElement,t))}function m(e){let{summary:t,children:n,...i}=e;const m=(0,l.Z)(),h=(0,s.useRef)(null),{collapsed:x,setCollapsed:p}=(0,o.u)({initialState:!i.open}),[f,v]=(0,s.useState)(i.open),j=s.isValidElement(t)?t:(0,c.jsx)("summary",{children:t??"Details"});return(0,c.jsxs)("details",{...i,ref:h,open:f,"data-collapsed":x,className:(0,a.Z)(r.details,m&&r.isBrowser,i.className),onMouseDown:e=>{d(e.target)&&e.detail>1&&e.preventDefault()},onClick:e=>{e.stopPropagation();const t=e.target;d(t)&&u(t,h.current)&&(e.preventDefault(),x?(p(!1),v(!0)):p(!0))},children:[j,(0,c.jsx)(o.z,{lazy:!1,collapsed:x,disableSSRStyle:!0,onCollapseTransitionEnd:e=>{p(e),v(!e)},children:(0,c.jsx)("div",{className:r.collapsibleContent,children:n})})]})}const h={details:"details_b_Ee"},x="alert alert--info";function p(e){let{...t}=e;return(0,c.jsx)(m,{...t,className:(0,i.Z)(x,h.details,t.className)})}function f(e){const t=s.Children.toArray(e.children),n=t.find((e=>s.isValidElement(e)&&"summary"===e.type)),i=(0,c.jsx)(c.Fragment,{children:t.filter((e=>e!==n))});return(0,c.jsx)(p,{...e,summary:n,children:i})}}}]); \ No newline at end of file diff --git a/assets/js/2da89d45.84ef86b3.js b/assets/js/2da89d45.84ef86b3.js new file mode 100644 index 00000000..d8a071c7 --- /dev/null +++ b/assets/js/2da89d45.84ef86b3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5893],{6071:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>u,frontMatter:()=>i,metadata:()=>a,toc:()=>d});var s=r(5893),t=r(1151),o=r(5471);const i={title:"Getting Started with Docker"},c=void 0,a={id:"guides/docker-share/index",title:"Getting Started with Docker",description:"Overview",source:"@site/../docs/guides/docker-share/index.mdx",sourceDirName:"guides/docker-share",slug:"/guides/docker-share/",permalink:"/docs/guides/docker-share/",draft:!1,unlisted:!1,editUrl:"https://github.com/openziti/zrok/blob/main/docs/../docs/guides/docker-share/index.mdx",tags:[],version:"current",frontMatter:{title:"Getting Started with Docker"},sidebar:"tutorialSidebar",previous:{title:"Permission Modes",permalink:"/docs/guides/permission-modes"},next:{title:"Public Share",permalink:"/docs/guides/docker-share/docker_public_share_guide"}},l={},d=[{value:"Overview",id:"overview",level:2},{value:"Permanent Public Share",id:"permanent-public-share",level:2},{value:"Temporary Public Share",id:"temporary-public-share",level:2}];function h(e){const n={a:"a",code:"code",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,s.jsxs)(n.p,{children:["To follow the guides in this section you will need ",(0,s.jsx)(n.a,{href:"https://docs.docker.com/get-docker/",children:"Docker"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["You have the option to enable a ",(0,s.jsx)(n.code,{children:"zrok"})," account on the Docker host and mount it on the container or you can use the provided Docker Compose project files (",(0,s.jsx)(n.code,{children:"compose.yml"}),") to enable a separate ",(0,s.jsx)(n.code,{children:"zrok"})," environment for each project."]}),"\n",(0,s.jsxs)(n.p,{children:["This page provides ",(0,s.jsx)(n.code,{children:"docker"})," and ",(0,s.jsx)(n.code,{children:"docker compose"})," examples of mounting the host's ",(0,s.jsx)(n.code,{children:"zrok"})," environment on the container. You'll need to first ",(0,s.jsx)(n.a,{href:"/docs/getting-started/#installing-the-zrok-command",children:"enable zrok on the Docker host"})," to use this approach."]}),"\n",(0,s.jsx)(n.h2,{id:"permanent-public-share",children:"Permanent Public Share"}),"\n",(0,s.jsxs)(n.p,{children:["Let's say you have a ",(0,s.jsx)(n.code,{children:"compose.yml"})," file that defines a web app known within the project's bridge network as ",(0,s.jsx)(n.code,{children:"https://myapp:8080"})," and you want to publish it as a reliable, public site."]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Reserve a subdomain by running ",(0,s.jsx)(n.code,{children:'zrok reserve public --unique-name "myapp" https://myapp:8080'})," on the Docker host."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Merge this YAML with ",(0,s.jsx)(n.code,{children:"compose.yml"})," or save it in the same directory as ",(0,s.jsx)(n.code,{children:"compose.override.yml"})," to let ",(0,s.jsx)(n.code,{children:"docker compose up"})," merge it for you."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'services:\n zrok:\n image: openziti/zrok\n restart: unless-stopped\n user: "${UID}"\n volumes:\n - ${HOME}/.zrok:/.zrok\n environment:\n PFXLOG_NO_JSON: "true"\n command: share reserved "myapp" --headless\n'})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The reserved share will be available at ",(0,s.jsx)(n.code,{children:"https://myapp.share.zrok.io"})," each time the ",(0,s.jsx)(n.code,{children:"zrok"})," container starts up."]}),"\n",(0,s.jsx)(n.h2,{id:"temporary-public-share",children:"Temporary Public Share"}),"\n",(0,s.jsxs)(n.p,{children:["Let's say you have a web server running on the host's private network at ",(0,s.jsx)(n.code,{children:"https://10.11.12.13:8080"}),". With one additional ",(0,s.jsx)(n.code,{children:"docker"})," command, you can share the web server publicly as long as the ",(0,s.jsx)(n.code,{children:"zrok"})," container stays running."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="BASH"',children:'docker run \\\n --rm \\\n --network=host \\\n --volume ~/.zrok:/.zrok \\\n --user "${UID}" \\\n openziti/zrok share public \\\n --headless \\\n https://10.11.12.13:8080\n'})}),"\n",(0,s.jsxs)(o.Z,{children:[(0,s.jsx)("summary",{children:"PowerShell"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-powershell",children:'docker.exe run `\n --rm `\n --network "host" `\n --volume "${env:USERPROFILE}\\.zrok:/.zrok" `\n --user "1000" `\n openziti/zrok share public `\n --headless `\n https://10.11.12.13:8080\n'})})]}),"\n",(0,s.jsxs)(o.Z,{children:[(0,s.jsx)("summary",{children:"Command Prompt (batch)"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-cmd",children:'docker.exe run ^\n --rm ^\n --network "host" ^\n --volume "%USERPROFILE%\\.zrok:/.zrok" ^\n --user "1000" ^\n openziti/zrok share public ^\n --headless ^\n https://10.11.12.13:8080\n'})})]}),"\n",(0,s.jsxs)(o.Z,{children:[(0,s.jsx)("summary",{children:"Windows Subsystem for Linux (WSL)"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'docker run \\\n --rm \\\n --network "host" \\\n --volume "/mnt/c/Users/$(powershell.exe -Command \'Write-Output $env:USERNAME\' | tr -d \'\\r\')/.zrok:/.zrok" \\\n --user "$UID" \\\n openziti/zrok share public \\\n --headless \\\n https://10.11.12.13:8080\n'})})]}),"\n",(0,s.jsx)(n.p,{children:"The public share URL appears near the beginning of the container's log."}),"\n",(0,s.jsx)(n.p,{children:"Let's break down those options and arguments."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"--rm"})," don't save this container because it's providing a temporary public share that's destroyed when the container stops"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"--network=host"})," shares the host's network with the container so that the container can reach the web server directly. This is always necessary when the web server is listening only on the host's loopback interface, e.g., ",(0,s.jsx)(n.code,{children:"https://::1:8080"}),", and may not be strictly necessary if the target is routeable from the default Docker bridge."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"--volume ~/.zrok:/.zrok"})," mounts the ",(0,s.jsx)(n.code,{children:"zrok"})," configuration from the Docker host into the container."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:'--user "${UID}:${GID}"'})," sets the container's user to the current user on the Docker host to avoid permission issues with reading the mounted ",(0,s.jsx)(n.code,{children:"zrok"})," configuration."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"openziti/zrok"})," is the ",(0,s.jsx)(n.code,{children:"zrok"})," Docker image."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"share public"})," is the ",(0,s.jsx)(n.code,{children:"zrok"})," command to share the target publicly until zrok exits."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"--headless"})," runs the ",(0,s.jsx)(n.code,{children:"zrok"})," command without the interactive terminal UI."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"https://10.11.12.13:8080"})," is the target web server to share."]}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},5471:(e,n,r)=>{r.d(n,{Z:()=>j});var s=r(7294),t=r(6905),o=r(788),i=r(2389),c=r(6043);const a={details:"details_lb9f",isBrowser:"isBrowser_bmU9",collapsibleContent:"collapsibleContent_i85q"};var l=r(5893);function d(e){return!!e&&("SUMMARY"===e.tagName||d(e.parentElement))}function h(e,n){return!!e&&(e===n||h(e.parentElement,n))}function u(e){let{summary:n,children:r,...t}=e;const u=(0,i.Z)(),p=(0,s.useRef)(null),{collapsed:m,setCollapsed:x}=(0,c.u)({initialState:!t.open}),[j,k]=(0,s.useState)(t.open),b=s.isValidElement(n)?n:(0,l.jsx)("summary",{children:n??"Details"});return(0,l.jsxs)("details",{...t,ref:p,open:j,"data-collapsed":m,className:(0,o.Z)(a.details,u&&a.isBrowser,t.className),onMouseDown:e=>{d(e.target)&&e.detail>1&&e.preventDefault()},onClick:e=>{e.stopPropagation();const n=e.target;d(n)&&h(n,p.current)&&(e.preventDefault(),m?(x(!1),k(!0)):x(!0))},children:[b,(0,l.jsx)(c.z,{lazy:!1,collapsed:m,disableSSRStyle:!0,onCollapseTransitionEnd:e=>{x(e),k(!e)},children:(0,l.jsx)("div",{className:a.collapsibleContent,children:r})})]})}const p={details:"details_b_Ee"},m="alert alert--info";function x(e){let{...n}=e;return(0,l.jsx)(u,{...n,className:(0,t.Z)(m,p.details,n.className)})}function j(e){const n=s.Children.toArray(e.children),r=n.find((e=>s.isValidElement(e)&&"summary"===e.type)),t=(0,l.jsx)(l.Fragment,{children:n.filter((e=>e!==r))});return(0,l.jsx)(x,{...e,summary:r,children:t})}},1151:(e,n,r)=>{r.d(n,{Z:()=>c,a:()=>i});var s=r(7294);const t={},o=s.createContext(t);function i(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2e812224.5284992e.js b/assets/js/2e812224.5284992e.js new file mode 100644 index 00000000..61b979a6 --- /dev/null +++ b/assets/js/2e812224.5284992e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7076],{4695:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>c,contentTitle:()=>t,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>d});var s=n(5893),o=n(1151);const i={title:"Docker Compose Public Share",sidebar_position:10,sidebar_label:"Public Share"},t=void 0,a={id:"guides/docker-share/docker_public_share_guide",title:"Docker Compose Public Share",description:"Goal",source:"@site/../docs/guides/docker-share/docker_public_share_guide.md",sourceDirName:"guides/docker-share",slug:"/guides/docker-share/docker_public_share_guide",permalink:"/docs/guides/docker-share/docker_public_share_guide",draft:!1,unlisted:!1,editUrl:"https://github.com/openziti/zrok/blob/main/docs/../docs/guides/docker-share/docker_public_share_guide.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{title:"Docker Compose Public Share",sidebar_position:10,sidebar_label:"Public Share"},sidebar:"tutorialSidebar",previous:{title:"Getting Started with Docker",permalink:"/docs/guides/docker-share/"},next:{title:"Private Share",permalink:"/docs/guides/docker-share/docker_private_share_guide"}},c={},d=[{value:"Goal",id:"goal",level:2},{value:"Overview",id:"overview",level:2},{value:"Walkthrough Video",id:"walkthrough-video",level:2},{value:"How it Works",id:"how-it-works",level:2},{value:"Create the Docker Project",id:"create-the-docker-project",level:2},{value:"Proxy Any Web Server",id:"proxy-any-web-server",level:2},{value:"Require Authentication",id:"require-authentication",level:2},{value:"OAuth Email",id:"oauth-email",level:3},{value:"Caddy is Powerful",id:"caddy-is-powerful",level:2}];function l(e){const r={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",...(0,o.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(r.h2,{id:"goal",children:"Goal"}),"\n",(0,s.jsx)(r.p,{children:"Publicly share a Docker Compose service with a separate zrok environment and a permanent zrok share URL."}),"\n",(0,s.jsx)(r.h2,{id:"overview",children:"Overview"}),"\n",(0,s.jsx)(r.p,{children:"With zrok, you can publicly share a service that's running in Docker. You need a zrok public share running somewhere that it can reach the service you're sharing. As long as that public share is running and your service is available, anyone with the address can use your service."}),"\n",(0,s.jsxs)(r.p,{children:["Here's a short article with an overview of ",(0,s.jsx)(r.a,{href:"/docs/concepts/sharing-public",children:"public sharing with zrok"}),"."]}),"\n",(0,s.jsx)(r.h2,{id:"walkthrough-video",children:"Walkthrough Video"}),"\n",(0,s.jsx)("iframe",{width:"100%",height:"315",src:"https://www.youtube.com/embed/ycov--9ZtB4",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowfullscreen:!0}),"\n",(0,s.jsx)(r.h2,{id:"how-it-works",children:"How it Works"}),"\n",(0,s.jsx)(r.p,{children:"The Docker Compose project uses your zrok account token to reserve a public subdomain and keep sharing the backend\ntarget."}),"\n",(0,s.jsx)(r.p,{children:"When the project runs it will:"}),"\n",(0,s.jsxs)(r.ol,{children:["\n",(0,s.jsxs)(r.li,{children:["enable a zrok environment unless ",(0,s.jsx)(r.code,{children:"/mnt/.zrok/environment.json"})," exists in the ",(0,s.jsx)(r.code,{children:"zrok_env"})," volume"]}),"\n",(0,s.jsxs)(r.li,{children:["reserve a public subdomain for the service unless ",(0,s.jsx)(r.code,{children:"/mnt/.zrok/reserved.json"})," exists"]}),"\n",(0,s.jsxs)(r.li,{children:["start sharing the target specified in the ",(0,s.jsx)(r.code,{children:"ZROK_TARGET"})," environment variable"]}),"\n"]}),"\n",(0,s.jsx)(r.h2,{id:"create-the-docker-project",children:"Create the Docker Project"}),"\n",(0,s.jsxs)(r.ol,{children:["\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsx)(r.p,{children:"Make a folder on your computer to use as a Docker Compose project for your zrok public share with a reserved subdomain and switch to the new directory in your terminal."}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsxs)(r.p,{children:["Download ",(0,s.jsxs)(r.a,{href:"pathname:///zrok-public-reserved/compose.yml",children:["the reserved public share ",(0,s.jsx)(r.code,{children:"compose.yml"})," project file"]})," into the same directory."]}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsxs)(r.p,{children:["Copy your zrok account's enable token from the zrok web console to your clipboard and paste it in a file named ",(0,s.jsx)(r.code,{children:".env"})," in the same folder like this:"]}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",metastring:'title=".env"',children:'ZROK_ENABLE_TOKEN="8UL9-48rN0ua"\n'})}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsx)(r.p,{children:"Name the Share"}),"\n",(0,s.jsxs)(r.p,{children:["This unique name becomes part of the domain name of the share, e.g. ",(0,s.jsx)(r.code,{children:"https://my-prod-app.in.zrok.io"}),". A random name is generated if you don't specify one."]}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",metastring:'title=".env"',children:'ZROK_UNIQUE_NAME="my-prod-app"\n'})}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsxs)(r.p,{children:["Run the Compose project to start sharing the built-in demo web server. Be sure to ",(0,s.jsx)(r.code,{children:"--detach"})," so the project runs in the background if you want it to auto-restart when your computer reboots."]}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",children:"docker compose up --detach\n"})}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsxs)(r.p,{children:["Get the public share URL from the output of the ",(0,s.jsx)(r.code,{children:"zrok-share"})," service or by peeking in the zrok console where the share will appear in the graph."]}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",children:"docker compose logs zrok-share\n"})}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-buttonless",metastring:'title="Output"',children:"zrok-public-share-1 | https://w6r1vesearkj.in.zrok.io/\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(r.p,{children:"This concludes the minimum steps to begin sharing the demo web server. Read on to learn how to pivot to sharing any website or web service by leveraging additional zrok backend modes."}),"\n",(0,s.jsx)(r.h2,{id:"proxy-any-web-server",children:"Proxy Any Web Server"}),"\n",(0,s.jsxs)(r.p,{children:["The simplest way to share your existing HTTP server is to set ",(0,s.jsx)(r.code,{children:"ZROK_TARGET"})," (e.g. ",(0,s.jsx)(r.code,{children:"https://example.com"}),") in the environment of the ",(0,s.jsx)(r.code,{children:"docker compose up"})," command. When you restart the share will auto-configure for that URL."]}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",metastring:'title=".env"',children:'ZROK_TARGET="http://example.com:8080"\n'})}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",children:"docker compose down && docker compose up\n"})}),"\n",(0,s.jsx)(r.h2,{id:"require-authentication",children:"Require Authentication"}),"\n",(0,s.jsx)(r.p,{children:"You can require a password or an OAuth login with certain email addresses."}),"\n",(0,s.jsx)(r.h3,{id:"oauth-email",children:"OAuth Email"}),"\n",(0,s.jsxs)(r.p,{children:["You can allow specific email addresse patterns by setting ",(0,s.jsx)(r.code,{children:"ZROK_OAUTH_PROVIDER"})," to ",(0,s.jsx)(r.code,{children:"github"})," or ",(0,s.jsx)(r.code,{children:"google"})," and\n",(0,s.jsx)(r.code,{children:"ZROK_OAUTH_EMAILS"}),". Read more about the OAuth features in ",(0,s.jsx)(r.a,{href:"https://blog.openziti.io/the-zrok-oauth-public-frontend",children:"this blog\npost"}),"."]}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",metastring:'title=".env"',children:'ZROK_OAUTH_PROVIDER="github"\nZROK_OAUTH_EMAILS="alice@example.com *@acme.example.com"\n'})}),"\n",(0,s.jsx)(r.h2,{id:"caddy-is-powerful",children:"Caddy is Powerful"}),"\n",(0,s.jsxs)(r.p,{children:["The reserved public share project uses zrok's default backend mode, ",(0,s.jsx)(r.code,{children:"proxy"}),". Another backend mode, ",(0,s.jsx)(r.code,{children:"caddy"}),", accepts a path to ",(0,s.jsx)(r.a,{href:"https://caddyserver.com/docs/caddyfile",children:"a Caddyfile"})," as the value of ",(0,s.jsx)(r.code,{children:"ZROK_TARGET"})," (",(0,s.jsx)(r.a,{href:"https://github.com/openziti/zrok/tree/main/etc/caddy",children:"zrok Caddyfile examples"}),")."]}),"\n",(0,s.jsxs)(r.p,{children:["Caddy is the most powerful and flexible backend mode in zrok. You must reserve a new public subdomain whenever you switch the backend mode, so using ",(0,s.jsx)(r.code,{children:"caddy"})," reduces the risk that you'll have to share a new frontend URL with your users."]}),"\n",(0,s.jsx)(r.p,{children:"With Caddy, you can balance the workload for websites or web services or share static sites and files or all of the above at the same time. You can update the Caddyfile and restart the Docker Compose project to start sharing the new configuration with the same reserved public subdomain."}),"\n",(0,s.jsxs)(r.ol,{children:["\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsx)(r.p,{children:"Create a Caddyfile. This example demonstrates proxying two HTTP servers with a weighted round-robin load balancer."}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-console",metastring:'title="Caddyfile"',children:"http:// {\n # zrok requires this bind address template\n bind {{ .ZrokBindAddress }}\n reverse_proxy /* {\n to http://httpbin1:8080 http://httpbin2:8080\n lb_policy weighted_round_robin 3 2\n }\n}\n"})}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsxs)(r.p,{children:["Create a file ",(0,s.jsx)(r.code,{children:"compose.override.yml"}),". This example adds two ",(0,s.jsx)(r.code,{children:"httpbin"})," containers for load balancing, and mounts the Caddyfile into the container."]}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-yaml",metastring:'title="compose.override.yml"',children:"services:\n httpbin1:\n image: mccutchen/go-httpbin # 8080/tcp\n httpbin2:\n image: mccutchen/go-httpbin # 8080/tcp\n zrok-share:\n volumes:\n - ./Caddyfile:/mnt/.zrok/Caddyfile\n"})}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsx)(r.p,{children:"Start a new Docker Compose project or delete the existing state volume."}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",children:"docker compose down --volumes\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(r.p,{children:["If you prefer to keep using the same zrok environment with the new share then delete ",(0,s.jsx)(r.code,{children:"/mnt/.zrok/reserved.json"})," instead of the entire volume."]}),"\n",(0,s.jsxs)(r.ol,{children:["\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsx)(r.p,{children:"Run the project to load the new configuration."}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",children:"docker compose up --detach\n"})}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsx)(r.p,{children:"Note the new reserved share URL from the log."}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",children:"docker compose logs zrok-share\n"})}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-buttonless",metastring:'title="Output"',children:"INFO: zrok public URL: https://88s803f2qvao.in.zrok.io/\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:r}={...(0,o.a)(),...e.components};return r?(0,s.jsx)(r,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},1151:(e,r,n)=>{n.d(r,{Z:()=>a,a:()=>t});var s=n(7294);const o={},i=s.createContext(o);function t(e){const r=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),s.createElement(i.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2e812224.54d10332.js b/assets/js/2e812224.54d10332.js deleted file mode 100644 index 8508629c..00000000 --- a/assets/js/2e812224.54d10332.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7076],{4695:(e,r,o)=>{o.r(r),o.d(r,{assets:()=>c,contentTitle:()=>t,default:()=>d,frontMatter:()=>s,metadata:()=>a,toc:()=>l});var n=o(5893),i=o(1151);const s={title:"Docker Public Share",sidebar_position:10,sidebar_label:"Public Share"},t=void 0,a={id:"guides/docker-share/docker_public_share_guide",title:"Docker Public Share",description:"With zrok and Docker, you can publicly share a web server that's running in a local container or anywhere that's reachable by the zrok container. The share can be reached through a temporary public URL that expires when the container is stopped. If you're looking for a reserved subdomain for the share, check out zrok frontdoor.",source:"@site/../docs/guides/docker-share/docker_public_share_guide.md",sourceDirName:"guides/docker-share",slug:"/guides/docker-share/docker_public_share_guide",permalink:"/docs/guides/docker-share/docker_public_share_guide",draft:!1,unlisted:!1,editUrl:"https://github.com/openziti/zrok/blob/main/docs/../docs/guides/docker-share/docker_public_share_guide.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{title:"Docker Public Share",sidebar_position:10,sidebar_label:"Public Share"},sidebar:"tutorialSidebar",previous:{title:"Docker Share",permalink:"/docs/category/docker-share"},next:{title:"Private Share",permalink:"/docs/guides/docker-share/docker_private_share_guide"}},c={},l=[{value:"Walkthrough Video",id:"walkthrough-video",level:2},{value:"Before You Begin",id:"before-you-begin",level:2},{value:"Begin Sharing with Docker Compose",id:"begin-sharing-with-docker-compose",level:2},{value:"Proxy Any Web Server",id:"proxy-any-web-server",level:2},{value:"Require Authentication",id:"require-authentication",level:2},{value:"Customize Temporary Public Share",id:"customize-temporary-public-share",level:2},{value:"Destroy the zrok Environment",id:"destroy-the-zrok-environment",level:2}];function h(e){const r={a:"a",code:"code",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",...(0,i.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)(r.p,{children:["With zrok and Docker, you can publicly share a web server that's running in a local container or anywhere that's reachable by the zrok container. The share can be reached through a temporary public URL that expires when the container is stopped. If you're looking for a reserved subdomain for the share, check out ",(0,n.jsx)(r.a,{href:"/docs/guides/frontdoor",children:"zrok frontdoor"}),"."]}),"\n",(0,n.jsxs)(r.p,{children:["Here's a short article with an overview of ",(0,n.jsx)(r.a,{href:"/docs/concepts/sharing-public",children:"public sharing with zrok"}),"."]}),"\n",(0,n.jsx)(r.h2,{id:"walkthrough-video",children:"Walkthrough Video"}),"\n",(0,n.jsx)("iframe",{width:"100%",height:"315",src:"https://www.youtube.com/embed/ycov--9ZtB4",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowfullscreen:!0}),"\n",(0,n.jsx)(r.h2,{id:"before-you-begin",children:"Before You Begin"}),"\n",(0,n.jsxs)(r.p,{children:["To follow this guide you will need ",(0,n.jsx)(r.a,{href:"https://docs.docker.com/get-docker/",children:"Docker"})," and ",(0,n.jsx)(r.a,{href:"https://docs.docker.com/compose/install/",children:"the Docker Compose plugin"})," for running ",(0,n.jsx)(r.code,{children:"docker compose"})," commands in your terminal."]}),"\n",(0,n.jsx)(r.h2,{id:"begin-sharing-with-docker-compose",children:"Begin Sharing with Docker Compose"}),"\n",(0,n.jsx)(r.p,{children:"A temporary public share is a great way to share a web server running in a container with someone else for a short time."}),"\n",(0,n.jsxs)(r.ol,{children:["\n",(0,n.jsx)(r.li,{children:"Make a folder on your computer to use as a Docker Compose project for your zrok public share."}),"\n",(0,n.jsx)(r.li,{children:"In your terminal, change directory to the newly-created project folder."}),"\n",(0,n.jsxs)(r.li,{children:["Download ",(0,n.jsx)(r.a,{href:"pathname:///zrok-public-share/compose.yml",children:"the temporary public share project file"}),"."]}),"\n",(0,n.jsxs)(r.li,{children:["Copy your zrok environment token from the zrok web console to your clipboard and paste it in a file named ",(0,n.jsx)(r.code,{children:".env"})," in the same folder like this:"]}),"\n"]}),"\n",(0,n.jsx)(r.pre,{children:(0,n.jsx)(r.code,{className:"language-bash",metastring:'title=".env"',children:'ZROK_ENABLE_TOKEN="8UL9-48rN0ua"\n'})}),"\n",(0,n.jsxs)(r.ol,{children:["\n",(0,n.jsx)(r.li,{children:"Set the zrok API endpoint if self-hosting zrok. Skip this if using zrok.io."}),"\n"]}),"\n",(0,n.jsx)(r.pre,{children:(0,n.jsx)(r.code,{className:"language-bash",metastring:'title=".env"',children:'ZROK_API_ENDPOINT="https://zrok.example.com"\n'})}),"\n",(0,n.jsxs)(r.ol,{children:["\n",(0,n.jsx)(r.li,{children:"Run the Compose project to start sharing the built-in demo web server."}),"\n"]}),"\n",(0,n.jsx)(r.pre,{children:(0,n.jsx)(r.code,{className:"language-bash",children:"docker compose up --detach\n"})}),"\n",(0,n.jsxs)(r.ol,{children:["\n",(0,n.jsxs)(r.li,{children:["Get the public share URL from the output of the ",(0,n.jsx)(r.code,{children:"zrok-share"})," service or by peeking in the zrok console where the share will be graphed."]}),"\n"]}),"\n",(0,n.jsx)(r.pre,{children:(0,n.jsx)(r.code,{className:"language-bash",children:"docker compose logs zrok-share\n"})}),"\n",(0,n.jsx)(r.pre,{children:(0,n.jsx)(r.code,{className:"language-buttonless",metastring:'title="Output"',children:"zrok-public-share-1 | https://w6r1vesearkj.in.zrok.io/\n"})}),"\n",(0,n.jsx)(r.p,{children:"This concludes sharing the demo web server. Read on to learn how to pivot to sharing any web server leveraging additional zrok backend modes."}),"\n",(0,n.jsx)(r.h2,{id:"proxy-any-web-server",children:"Proxy Any Web Server"}),"\n",(0,n.jsxs)(r.p,{children:["The simplest way to share your web server is to set ",(0,n.jsx)(r.code,{children:"ZROK_TARGET"})," (e.g. ",(0,n.jsx)(r.code,{children:"https://example.com"}),") in the environment file."]}),"\n",(0,n.jsx)(r.pre,{children:(0,n.jsx)(r.code,{className:"language-bash",metastring:'title=".env"',children:'ZROK_TARGET="http://example.com:8080"\n'})}),"\n",(0,n.jsx)(r.h2,{id:"require-authentication",children:"Require Authentication"}),"\n",(0,n.jsxs)(r.p,{children:["You can require authentication for your public share by setting ",(0,n.jsx)(r.code,{children:"ZROK_OAUTH_PROVIDER"})," to ",(0,n.jsx)(r.code,{children:"github"})," or ",(0,n.jsx)(r.code,{children:"google"})," with zrok.io. You could parse the authenticated email address from the request cookie if you're building a custom server app. Read more about the OAuth features in ",(0,n.jsx)(r.a,{href:"https://blog.openziti.io/the-zrok-oauth-public-frontend",children:"this blog post"}),"."]}),"\n",(0,n.jsx)(r.pre,{children:(0,n.jsx)(r.code,{className:"language-bash",metastring:'title=".env"',children:'ZROK_OAUTH_PROVIDER="github"\n'})}),"\n",(0,n.jsx)(r.h2,{id:"customize-temporary-public-share",children:"Customize Temporary Public Share"}),"\n",(0,n.jsx)(r.p,{children:"This technique is useful for adding a containerized service to the project, or mounting a filesystem directory into the container to share as a static website or file server."}),"\n",(0,n.jsxs)(r.p,{children:["Any additional services specified in the override file will be merged with ",(0,n.jsx)(r.code,{children:"compose.yml"})," when you ",(0,n.jsx)(r.code,{children:"up"})," the project."]}),"\n",(0,n.jsxs)(r.p,{children:["You may override individual values from in ",(0,n.jsx)(r.code,{children:"compose.yml"})," by specifying them in the override file."]}),"\n",(0,n.jsxs)(r.ol,{children:["\n",(0,n.jsxs)(r.li,{children:["Create a file ",(0,n.jsx)(r.code,{children:"compose.override.yml"}),". This example demonstrates sharing a static HTML directory ",(0,n.jsx)(r.code,{children:"/tmp/html"})," from the Docker host's filesystem."]}),"\n"]}),"\n",(0,n.jsx)(r.pre,{children:(0,n.jsx)(r.code,{className:"language-yaml",metastring:'title="compose.override.yml"',children:"services:\n zrok-share:\n command: share public --headless --backend-mode web /tmp/html\n volumes:\n - /tmp/html:/tmp/html\n"})}),"\n",(0,n.jsxs)(r.ol,{children:["\n",(0,n.jsx)(r.li,{children:"Re-run the project to load the new configuration."}),"\n"]}),"\n",(0,n.jsx)(r.pre,{children:(0,n.jsx)(r.code,{className:"language-bash",children:"docker compose up --force-recreate --detach\n"})}),"\n",(0,n.jsxs)(r.ol,{children:["\n",(0,n.jsxs)(r.li,{children:["Get the new tempoary public share URL for the ",(0,n.jsx)(r.code,{children:"zrok-share"})," container."]}),"\n"]}),"\n",(0,n.jsx)(r.pre,{children:(0,n.jsx)(r.code,{className:"language-bash",children:"docker compose logs zrok-share\n"})}),"\n",(0,n.jsx)(r.pre,{children:(0,n.jsx)(r.code,{className:"language-buttonless",metastring:'title="Output"',children:"zrok-public-share-1 | https://w6r1vesearkj.in.zrok.io/\n"})}),"\n",(0,n.jsx)(r.h2,{id:"destroy-the-zrok-environment",children:"Destroy the zrok Environment"}),"\n",(0,n.jsx)(r.p,{children:"This destroys the Docker volumes containing the zrok environment secrets. The zrok environment can also be destroyed in the web console."}),"\n",(0,n.jsx)(r.pre,{children:(0,n.jsx)(r.code,{className:"language-bash",children:"docker compose down --volumes\n"})})]})}function d(e={}){const{wrapper:r}={...(0,i.a)(),...e.components};return r?(0,n.jsx)(r,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},1151:(e,r,o)=>{o.d(r,{Z:()=>a,a:()=>t});var n=o(7294);const i={},s=n.createContext(i);function t(e){const r=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),n.createElement(s.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/48230885.7b250f86.js b/assets/js/48230885.7b250f86.js deleted file mode 100644 index f7405774..00000000 --- a/assets/js/48230885.7b250f86.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9828],{7569:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var t=r(5893),i=r(1151);const o={sidebar_position:50,sidebar_label:"Nginx TLS"},s="Nginx Reverse Proxy for zrok",l={id:"guides/self-hosting/nginx_tls_guide",title:"Nginx Reverse Proxy for zrok",description:"Walkthrough Video",source:"@site/../docs/guides/self-hosting/nginx_tls_guide.md",sourceDirName:"guides/self-hosting",slug:"/guides/self-hosting/nginx_tls_guide",permalink:"/docs/guides/self-hosting/nginx_tls_guide",draft:!1,unlisted:!1,editUrl:"https://github.com/openziti/zrok/blob/main/docs/../docs/guides/self-hosting/nginx_tls_guide.md",tags:[],version:"current",sidebarPosition:50,frontMatter:{sidebar_position:50,sidebar_label:"Nginx TLS"},sidebar:"tutorialSidebar",previous:{title:"Linux VPS",permalink:"/docs/guides/self-hosting/self_hosting_guide"},next:{title:"Metrics and Limits",permalink:"/docs/category/metrics-and-limits"}},a={},c=[{value:"Walkthrough Video",id:"walkthrough-video",level:2},{value:"Before You Begin",id:"before-you-begin",level:2},{value:"Choose a Reverse Proxy Address",id:"choose-a-reverse-proxy-address",level:2},{value:"Obtain a Wildcard Server Certificate",id:"obtain-a-wildcard-server-certificate",level:2},{value:"Install Nginx",id:"install-nginx",level:2},{value:"Configure Nginx",id:"configure-nginx",level:2},{value:"Restart Nginx",id:"restart-nginx",level:2},{value:"Check the Firewall",id:"check-the-firewall",level:2},{value:"Update the zrok Frontend",id:"update-the-zrok-frontend",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",...(0,i.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"nginx-reverse-proxy-for-zrok",children:"Nginx Reverse Proxy for zrok"}),"\n",(0,t.jsx)(n.h2,{id:"walkthrough-video",children:"Walkthrough Video"}),"\n",(0,t.jsx)("iframe",{width:"100%",height:"315",src:"https://www.youtube.com/embed/870A5dke_u4?start=1080",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowfullscreen:!0}),"\n",(0,t.jsx)(n.h2,{id:"before-you-begin",children:"Before You Begin"}),"\n",(0,t.jsxs)(n.p,{children:["I'll assume you have a running zrok controller and public frontend and wish to front both with Nginx providing server TLS. Go back to ",(0,t.jsx)(n.a,{href:"/docs/guides/self-hosting/self_hosting_guide",children:"Self-Hosting Guide"})," if you still need to spin those up."]}),"\n",(0,t.jsx)(n.h2,{id:"choose-a-reverse-proxy-address",children:"Choose a Reverse Proxy Address"}),"\n",(0,t.jsxs)(n.p,{children:["I'll use ",(0,t.jsx)(n.code,{children:"https://api.zrok.quigley.com:443"})," in this example, and assume you already set up wildcard DNS like ",(0,t.jsx)(n.code,{children:"*.zrok.quigley.com"}),". This lets us elect ",(0,t.jsx)(n.code,{children:"api.zrok.quigley.com"})," as the controller DNS name, and forward any other incoming requests to the zrok public frontend."]}),"\n",(0,t.jsx)(n.h2,{id:"obtain-a-wildcard-server-certificate",children:"Obtain a Wildcard Server Certificate"}),"\n",(0,t.jsx)(n.p,{children:"You must complete a DNS challenge to obtain a wildcard certificate from Let's Encrypt. I'll assume you know how to create the necessary TXT record in the DNS zone you're using with zrok."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Install certbot: ",(0,t.jsx)(n.a,{href:"https://eff-certbot.readthedocs.io/en/stable/install.html",children:"https://eff-certbot.readthedocs.io/en/stable/install.html"})]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Run certbot with the manual plugin: ",(0,t.jsx)(n.a,{href:"https://certbot.eff.org/docs/using.html#manual",children:"https://certbot.eff.org/docs/using.html#manual"})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"# install cert for *.zrok.quigley.com in /etc/letsencrypt\nsudo certbot certonly --manual\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"install-nginx",children:(0,t.jsx)(n.a,{href:"https://www.nginx.com/resources/wiki/start/topics/tutorials/install/",children:"Install Nginx"})}),"\n",(0,t.jsx)(n.h2,{id:"configure-nginx",children:"Configure Nginx"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"server {\n listen 443 ssl;\n server_name api.zrok.quigley.com;\n ssl_certificate /etc/letsencrypt/live/zrok.quigley.com/fullchain.pem;\n ssl_certificate_key /etc/letsencrypt/live/zrok.quigley.com/privkey.pem;\n ssl_protocols TLSv1 TLSv1.1 TLSv1.2;\n ssl_ciphers HIGH:!aNULL:!MD5;\n\n location / {\n proxy_pass http://127.0.0.1:18080;\n error_log /var/log/nginx/zrok-controller.log;\n }\n\n}\n\nmap $http_upgrade $connection_upgrade {\n default keep-alive;\n 'websocket' upgrade;\n '' close;\n}\n\nserver {\n listen 443 ssl;\n server_name *.zrok.quigley.com;\n ssl_certificate /etc/letsencrypt/live/zrok.quigley.com/fullchain.pem;\n ssl_certificate_key /etc/letsencrypt/live/zrok.quigley.com/privkey.pem;\n ssl_protocols TLSv1 TLSv1.1 TLSv1.2;\n ssl_ciphers HIGH:!aNULL:!MD5;\n\n location / {\n proxy_pass http://127.0.0.1:8080;\n proxy_set_header Host $host;\n error_log /var/log/nginx/zrok-frontend.log;\n proxy_busy_buffers_size 512k;\n proxy_buffers 4 512k;\n proxy_buffer_size 256k;\n\n proxy_http_version 1.1;\n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection \"upgrade\";\n }\n}\n"})}),"\n",(0,t.jsx)(n.h2,{id:"restart-nginx",children:"Restart Nginx"}),"\n",(0,t.jsx)(n.p,{children:"Load the new configuration by restarting Nginx. Check the logs to make sure it's happy."}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Started A high performance web server and a reverse proxy server."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"check-the-firewall",children:"Check the Firewall"}),"\n",(0,t.jsx)(n.p,{children:"If you followed the non-TLS quickstart then you may have opened 8080,108080/tcp in your firewall. You can go ahead and replace those exceptions with 443/tcp because only Nginx needs to be reachable for zrok to function."}),"\n",(0,t.jsx)(n.h2,{id:"update-the-zrok-frontend",children:"Update the zrok Frontend"}),"\n",(0,t.jsxs)(n.p,{children:['List available frontends to obtain the token identifier of the frontend named "public". You may need to set ',(0,t.jsx)(n.code,{children:"ZROK_ADMIN_TOKEN"})," or ",(0,t.jsx)(n.code,{children:"ZROK_API_ENDPOINT"})," before running ",(0,t.jsx)(n.code,{children:"zrok admin"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ zrok admin list frontends\n\n TOKEN ZID PUBLIC NAME URL TEMPLATE CREATED AT UPDATED AT \n 2NiDTRYUww18 7DsLh9DXG public http://{token}.zrok.quigley.com:8080 2023-01-19 05:29:20.793 +0000 UTC 2023-01-19 06:17:25 +0000 UTC \n"})}),"\n",(0,t.jsx)(n.p,{children:"Update the URL template to use Nginx."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ zrok admin update frontend 2NiDTRYUww18 --url-template https://{token}.zrok.quigley.com:443\n[ 0.028] INFO main.(*adminUpdateFrontendCommand).run: updated global frontend '2NiDTRYUww18'\n"})})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>l,a:()=>s});var t=r(7294);const i={},o=t.createContext(i);function s(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/48230885.8703845c.js b/assets/js/48230885.8703845c.js new file mode 100644 index 00000000..497f086f --- /dev/null +++ b/assets/js/48230885.8703845c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9828],{7569:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var t=r(5893),o=r(1151);const i={sidebar_position:50,sidebar_label:"NGINX TLS"},s="NGINX Reverse Proxy for zrok",l={id:"guides/self-hosting/nginx_tls_guide",title:"NGINX Reverse Proxy for zrok",description:"Walkthrough Video",source:"@site/../docs/guides/self-hosting/nginx_tls_guide.md",sourceDirName:"guides/self-hosting",slug:"/guides/self-hosting/nginx_tls_guide",permalink:"/docs/guides/self-hosting/nginx_tls_guide",draft:!1,unlisted:!1,editUrl:"https://github.com/openziti/zrok/blob/main/docs/../docs/guides/self-hosting/nginx_tls_guide.md",tags:[],version:"current",sidebarPosition:50,frontMatter:{sidebar_position:50,sidebar_label:"NGINX TLS"},sidebar:"tutorialSidebar",previous:{title:"Linux",permalink:"/docs/guides/self-hosting/linux"},next:{title:"Metrics and Limits",permalink:"/docs/category/metrics-and-limits"}},a={},c=[{value:"Walkthrough Video",id:"walkthrough-video",level:2},{value:"Before You Begin",id:"before-you-begin",level:2},{value:"Choose a Reverse Proxy Address",id:"choose-a-reverse-proxy-address",level:2},{value:"Obtain a Wildcard Server Certificate",id:"obtain-a-wildcard-server-certificate",level:2},{value:"Install NGINX",id:"install-nginx",level:2},{value:"Configure NGINX",id:"configure-nginx",level:2},{value:"Restart NGINX",id:"restart-nginx",level:2},{value:"Check the Firewall",id:"check-the-firewall",level:2},{value:"Update the zrok Frontend",id:"update-the-zrok-frontend",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",...(0,o.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"nginx-reverse-proxy-for-zrok",children:"NGINX Reverse Proxy for zrok"}),"\n",(0,t.jsx)(n.h2,{id:"walkthrough-video",children:"Walkthrough Video"}),"\n",(0,t.jsx)("iframe",{width:"100%",height:"315",src:"https://www.youtube.com/embed/870A5dke_u4?start=1080",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowfullscreen:!0}),"\n",(0,t.jsx)(n.h2,{id:"before-you-begin",children:"Before You Begin"}),"\n",(0,t.jsxs)(n.p,{children:["I'll assume you have a running zrok controller and frontend and wish to front both with NGINX providing server TLS. Go back to ",(0,t.jsx)(n.a,{href:"/docs/guides/self-hosting/linux",children:"Self-Hosting Guide"})," if you still need to spin those up."]}),"\n",(0,t.jsx)(n.h2,{id:"choose-a-reverse-proxy-address",children:"Choose a Reverse Proxy Address"}),"\n",(0,t.jsxs)(n.p,{children:["I'll use ",(0,t.jsx)(n.code,{children:"https://api.zrok.quigley.com:443"})," in this example, and assume you already set up wildcard DNS like ",(0,t.jsx)(n.code,{children:"*.zrok.quigley.com"}),". This lets us elect ",(0,t.jsx)(n.code,{children:"api.zrok.quigley.com"})," as the controller DNS name, and forward any other incoming requests to the zrok public frontend."]}),"\n",(0,t.jsx)(n.h2,{id:"obtain-a-wildcard-server-certificate",children:"Obtain a Wildcard Server Certificate"}),"\n",(0,t.jsx)(n.p,{children:"You must complete a DNS challenge to obtain a wildcard certificate from Let's Encrypt. I'll assume you know how to create the necessary TXT record in the DNS zone you're using with zrok."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Install certbot: ",(0,t.jsx)(n.a,{href:"https://eff-certbot.readthedocs.io/en/stable/install.html",children:"https://eff-certbot.readthedocs.io/en/stable/install.html"})]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Run certbot with the manual plugin: ",(0,t.jsx)(n.a,{href:"https://certbot.eff.org/docs/using.html#manual",children:"https://certbot.eff.org/docs/using.html#manual"})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"# install cert for *.zrok.quigley.com in /etc/letsencrypt\nsudo certbot certonly --manual\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"install-nginx",children:(0,t.jsx)(n.a,{href:"https://www.nginx.com/resources/wiki/start/topics/tutorials/install/",children:"Install NGINX"})}),"\n",(0,t.jsx)(n.h2,{id:"configure-nginx",children:"Configure NGINX"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"server {\n listen 443 ssl;\n server_name api.zrok.quigley.com;\n ssl_certificate /etc/letsencrypt/live/zrok.quigley.com/fullchain.pem;\n ssl_certificate_key /etc/letsencrypt/live/zrok.quigley.com/privkey.pem;\n ssl_protocols TLSv1 TLSv1.1 TLSv1.2;\n ssl_ciphers HIGH:!aNULL:!MD5;\n\n location / {\n proxy_pass http://127.0.0.1:18080;\n error_log /var/log/nginx/zrok-controller.log;\n }\n\n}\n\nmap $http_upgrade $connection_upgrade {\n default keep-alive;\n 'websocket' upgrade;\n '' close;\n}\n\nserver {\n listen 443 ssl;\n server_name *.zrok.quigley.com;\n ssl_certificate /etc/letsencrypt/live/zrok.quigley.com/fullchain.pem;\n ssl_certificate_key /etc/letsencrypt/live/zrok.quigley.com/privkey.pem;\n ssl_protocols TLSv1 TLSv1.1 TLSv1.2;\n ssl_ciphers HIGH:!aNULL:!MD5;\n\n location / {\n proxy_pass http://127.0.0.1:8080;\n proxy_set_header Host $host;\n error_log /var/log/nginx/zrok-frontend.log;\n proxy_busy_buffers_size 512k;\n proxy_buffers 4 512k;\n proxy_buffer_size 256k;\n\n proxy_http_version 1.1;\n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection \"upgrade\";\n }\n}\n"})}),"\n",(0,t.jsx)(n.h2,{id:"restart-nginx",children:"Restart NGINX"}),"\n",(0,t.jsx)(n.p,{children:"Load the new configuration by restarting NGINX. Check the logs to make sure it's happy."}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Started A high performance web server and a reverse proxy server."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"check-the-firewall",children:"Check the Firewall"}),"\n",(0,t.jsx)(n.p,{children:"If you followed the non-TLS quickstart then you may have opened 8080,108080/tcp in your firewall. You can go ahead and replace those exceptions with 443/tcp because only NGINX needs to be reachable for zrok to function."}),"\n",(0,t.jsx)(n.h2,{id:"update-the-zrok-frontend",children:"Update the zrok Frontend"}),"\n",(0,t.jsxs)(n.p,{children:['List available frontends to obtain the token identifier of the frontend named "public". You may need to set ',(0,t.jsx)(n.code,{children:"ZROK_ADMIN_TOKEN"})," or ",(0,t.jsx)(n.code,{children:"ZROK_API_ENDPOINT"})," before running ",(0,t.jsx)(n.code,{children:"zrok admin"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ zrok admin list frontends\n\n TOKEN ZID PUBLIC NAME URL TEMPLATE CREATED AT UPDATED AT \n 2NiDTRYUww18 7DsLh9DXG public http://{token}.zrok.quigley.com:8080 2023-01-19 05:29:20.793 +0000 UTC 2023-01-19 06:17:25 +0000 UTC \n"})}),"\n",(0,t.jsx)(n.p,{children:"Update the URL template to use NGINX."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ zrok admin update frontend 2NiDTRYUww18 --url-template https://{token}.zrok.quigley.com:443\n[ 0.028] INFO main.(*adminUpdateFrontendCommand).run: updated global frontend '2NiDTRYUww18'\n"})})]})}function h(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>l,a:()=>s});var t=r(7294);const o={},i=t.createContext(o);function s(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/50ef9c44.00b81556.js b/assets/js/50ef9c44.00b81556.js new file mode 100644 index 00000000..06f4b5b3 --- /dev/null +++ b/assets/js/50ef9c44.00b81556.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8198],{8413:(e,o,s)=>{s.r(o),s.d(o,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>a});var t=s(5893),n=s(1151);const i={sidebar_position:200},r="Hosting",c={id:"concepts/hosting",title:"Hosting",description:"Self-Hosted",source:"@site/../docs/concepts/hosting.md",sourceDirName:"concepts",slug:"/concepts/hosting",permalink:"/docs/concepts/hosting",draft:!1,unlisted:!1,editUrl:"https://github.com/openziti/zrok/blob/main/docs/../docs/concepts/hosting.md",tags:[],version:"current",sidebarPosition:200,frontMatter:{sidebar_position:200},sidebar:"tutorialSidebar",previous:{title:"Open Source",permalink:"/docs/concepts/opensource"},next:{title:"Guides",permalink:"/docs/category/guides"}},d={},a=[{value:"Self-Hosted",id:"self-hosted",level:2},{value:"Managed Service",id:"managed-service",level:2}];function l(e){const o={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",...(0,n.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(o.h1,{id:"hosting",children:"Hosting"}),"\n",(0,t.jsx)(o.h2,{id:"self-hosted",children:"Self-Hosted"}),"\n",(0,t.jsxs)(o.p,{children:[(0,t.jsx)(o.code,{children:"zrok"})," is not limited to a managed offering. You can ",(0,t.jsx)(o.a,{href:"/docs/guides/self-hosting/linux",children:"host your own"})," instance of ",(0,t.jsx)(o.code,{children:"zrok"})," as well. ",(0,t.jsx)(o.code,{children:"zrok"})," is\nalso freely available as open source software hosted by GitHub under a very permissive Apache v2 license."]}),"\n",(0,t.jsx)(o.h2,{id:"managed-service",children:"Managed Service"}),"\n",(0,t.jsxs)(o.p,{children:[(0,t.jsx)(o.code,{children:"zrok"})," is also offered as a cloud service, making it instantly accessible to a large population immediately.\nNetFoundry provides a manged version of ",(0,t.jsx)(o.code,{children:"zrok"})," at ",(0,t.jsx)(o.a,{href:"https://zrok.io",children:"https://zrok.io"}),". This provides the easy-to-use,\nquick to demonstrate features of ",(0,t.jsx)(o.code,{children:"zrok"})," without needing to deploy and host ",(0,t.jsx)(o.code,{children:"zrok"})," yourself."]})]})}function h(e={}){const{wrapper:o}={...(0,n.a)(),...e.components};return o?(0,t.jsx)(o,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},1151:(e,o,s)=>{s.d(o,{Z:()=>c,a:()=>r});var t=s(7294);const n={},i=t.createContext(n);function r(e){const o=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function c(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:r(e.components),t.createElement(i.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/50ef9c44.4785f919.js b/assets/js/50ef9c44.4785f919.js deleted file mode 100644 index a7b02b17..00000000 --- a/assets/js/50ef9c44.4785f919.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8198],{8413:(e,o,s)=>{s.r(o),s.d(o,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>a});var t=s(5893),n=s(1151);const i={sidebar_position:200},r="Hosting",c={id:"concepts/hosting",title:"Hosting",description:"Self-Hosted",source:"@site/../docs/concepts/hosting.md",sourceDirName:"concepts",slug:"/concepts/hosting",permalink:"/docs/concepts/hosting",draft:!1,unlisted:!1,editUrl:"https://github.com/openziti/zrok/blob/main/docs/../docs/concepts/hosting.md",tags:[],version:"current",sidebarPosition:200,frontMatter:{sidebar_position:200},sidebar:"tutorialSidebar",previous:{title:"Open Source",permalink:"/docs/concepts/opensource"},next:{title:"Guides",permalink:"/docs/category/guides"}},d={},a=[{value:"Self-Hosted",id:"self-hosted",level:2},{value:"Managed Service",id:"managed-service",level:2}];function l(e){const o={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",...(0,n.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(o.h1,{id:"hosting",children:"Hosting"}),"\n",(0,t.jsx)(o.h2,{id:"self-hosted",children:"Self-Hosted"}),"\n",(0,t.jsxs)(o.p,{children:[(0,t.jsx)(o.code,{children:"zrok"})," is not limited to a managed offering. You can ",(0,t.jsx)(o.a,{href:"/docs/guides/self-hosting/self_hosting_guide",children:"host your own"})," instance of ",(0,t.jsx)(o.code,{children:"zrok"})," as well. ",(0,t.jsx)(o.code,{children:"zrok"})," is\nalso freely available as open source software hosted by GitHub under a very permissive Apache v2 license."]}),"\n",(0,t.jsx)(o.h2,{id:"managed-service",children:"Managed Service"}),"\n",(0,t.jsxs)(o.p,{children:[(0,t.jsx)(o.code,{children:"zrok"})," is also offered as a cloud service, making it instantly accessible to a large population immediately.\nNetFoundry provides a manged version of ",(0,t.jsx)(o.code,{children:"zrok"})," at ",(0,t.jsx)(o.a,{href:"https://zrok.io",children:"https://zrok.io"}),". This provides the easy-to-use,\nquick to demonstrate features of ",(0,t.jsx)(o.code,{children:"zrok"})," without needing to deploy and host ",(0,t.jsx)(o.code,{children:"zrok"})," yourself."]})]})}function h(e={}){const{wrapper:o}={...(0,n.a)(),...e.components};return o?(0,t.jsx)(o,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},1151:(e,o,s)=>{s.d(o,{Z:()=>c,a:()=>r});var t=s(7294);const n={},i=t.createContext(n);function r(e){const o=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function c(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:r(e.components),t.createElement(i.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5b30ef33.a4f801ab.js b/assets/js/5b30ef33.a4f801ab.js deleted file mode 100644 index fb6ba634..00000000 --- a/assets/js/5b30ef33.a4f801ab.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1402],{5975:e=>{e.exports=JSON.parse('{"title":"Docker Share","slug":"/category/docker-share","permalink":"/docs/category/docker-share","navigation":{"previous":{"title":"Permission Modes","permalink":"/docs/guides/permission-modes"},"next":{"title":"Public Share","permalink":"/docs/guides/docker-share/docker_public_share_guide"}}}')}}]); \ No newline at end of file diff --git a/assets/js/8d96318d.2ba3681d.js b/assets/js/8d96318d.2ba3681d.js new file mode 100644 index 00000000..3775180a --- /dev/null +++ b/assets/js/8d96318d.2ba3681d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5079],{1667:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>l,toc:()=>d});var t=r(5893),o=r(1151);const i={sidebar_position:40,title:"Self-Hosting Guide for Linux",sidebar_label:"Linux"},s=void 0,l={id:"guides/self-hosting/linux",title:"Self-Hosting Guide for Linux",description:"Walkthrough Video",source:"@site/../docs/guides/self-hosting/linux.mdx",sourceDirName:"guides/self-hosting",slug:"/guides/self-hosting/linux",permalink:"/docs/guides/self-hosting/linux",draft:!1,unlisted:!1,editUrl:"https://github.com/openziti/zrok/blob/main/docs/../docs/guides/self-hosting/linux.mdx",tags:[],version:"current",sidebarPosition:40,frontMatter:{sidebar_position:40,title:"Self-Hosting Guide for Linux",sidebar_label:"Linux"},sidebar:"tutorialSidebar",previous:{title:"Self Hosting",permalink:"/docs/category/self-hosting"},next:{title:"NGINX TLS",permalink:"/docs/guides/self-hosting/nginx_tls_guide"}},c={},d=[{value:"Walkthrough Video",id:"walkthrough-video",level:2},{value:"Before you Begin",id:"before-you-begin",level:2},{value:"OpenZiti Quickstart",id:"openziti-quickstart",level:2},{value:"Install zrok",id:"install-zrok",level:2},{value:"Configure the Controller",id:"configure-the-controller",level:2},{value:"Environment Variables",id:"environment-variables",level:2},{value:"Bootstrap OpenZiti for zrok",id:"bootstrap-openziti-for-zrok",level:2},{value:"Run zrok Controller",id:"run-zrok-controller",level:2},{value:"Create zrok Frontend",id:"create-zrok-frontend",level:2},{value:"Configure the Public Frontend",id:"configure-the-public-frontend",level:2},{value:"Start Public Frontend",id:"start-public-frontend",level:2},{value:"Invite Yourself",id:"invite-yourself",level:2},{value:"Enable Your Shell",id:"enable-your-shell",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h2,{id:"walkthrough-video",children:"Walkthrough Video"}),"\n",(0,t.jsx)("iframe",{width:"100%",height:"315",src:"https://www.youtube.com/embed/870A5dke_u4",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowfullscreen:!0}),"\n",(0,t.jsx)(n.h2,{id:"before-you-begin",children:"Before you Begin"}),"\n",(0,t.jsx)(n.p,{children:"This will get you up and running with a self-hosted instance of zrok. I'll assume you have the following:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"a Linux server with a public IP"}),"\n",(0,t.jsxs)(n.li,{children:["a wildcard DNS record like ",(0,t.jsx)(n.code,{children:"*.zrok.quigley.com"})," that resolves to the server IP"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"openziti-quickstart",children:"OpenZiti Quickstart"}),"\n",(0,t.jsx)(n.p,{children:"The first step is to log in to your Linux server and run the OpenZiti quickstart. This will install a Ziti controller and Ziti router as systemd services."}),"\n",(0,t.jsx)(n.p,{children:'I specifically used the "Host OpenZiti Anywhere" variant because it provides a public controller. We\'ll need that to use zrok with multiple devices across different networks.'}),"\n",(0,t.jsxs)(n.p,{children:["Keep track of the generated admin password when running the ",(0,t.jsx)(n.code,{children:"expressInstall"})," script. The script will prompt you like this:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-text",children:"Do you want to keep the generated admin password 'XO0xHp75uuyeireO2xmmVlK91T7B9fpD'? (Y/n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You'll need that generated password (",(0,t.jsx)(n.code,{children:"XO0xHp75uuyeireO2xmmVlK91T7B9fpD"}),") when building your ",(0,t.jsx)(n.code,{children:"zrok"})," controller configuration."]}),"\n",(0,t.jsxs)(n.p,{children:["BEGIN: ",(0,t.jsx)(n.a,{href:"https://docs.openziti.io/docs/learn/quickstarts/network/hosted",children:"Run the OpenZiti Quickstart"})]}),"\n",(0,t.jsx)(n.h2,{id:"install-zrok",children:"Install zrok"}),"\n",(0,t.jsxs)(n.p,{children:["Download ",(0,t.jsx)(n.a,{href:"https://github.com/openziti/zrok/releases/latest",children:"the latest release"})," from GitHub."]}),"\n",(0,t.jsx)(n.h2,{id:"configure-the-controller",children:"Configure the Controller"}),"\n",(0,t.jsxs)(n.p,{children:["Create a controller configuration file in ",(0,t.jsx)(n.code,{children:"etc/ctrl.yml"}),". The controller does not provide server TLS, but you may front the server with a reverse proxy. This example will expose the non-TLS listener for the controller."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'# _____ __ ___ | | __\n# |_ / \'__/ _ \\| |/ /\n# / /| | | (_) | <\n# /___|_| \\___/|_|\\_\\\n# controller configuration\n\nv: 3\n\nadmin:\n # generate these admin tokens from a source of randomness, e.g. \n # LC_ALL=C tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c32\n secrets:\n - Q8V0LqnNb5wNX9kE1fgQ0H6VlcvJybB1 # be sure to change this!\n\nendpoint:\n host: 0.0.0.0\n port: 18080\n\ninvites:\n invites_open: true\n\nstore:\n path: zrok.db\n type: sqlite3\n\nziti:\n api_endpoint: "https://127.0.0.1:8441"\n username: admin\n password: "XO0xHp75uuyeireO2xmmVlK91T7B9fpD"\n\n'})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"admin"})," section defines privileged administrative credentials and must be set in the ",(0,t.jsx)(n.code,{children:"ZROK_ADMIN_TOKEN"})," environment variable in shells where you want to run ",(0,t.jsx)(n.code,{children:"zrok admin"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"endpoint"})," section defines where your ",(0,t.jsx)(n.code,{children:"zrok"})," controller will listen."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"store"})," section defines the local ",(0,t.jsx)(n.code,{children:"sqlite3"})," database used by the controller."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"ziti"})," section defines how the ",(0,t.jsx)(n.code,{children:"zrok"})," controller should communicate with your OpenZiti installation. When using the OpenZiti quickstart, an administrative password will be generated; the ",(0,t.jsx)(n.code,{children:"password"})," in the ",(0,t.jsx)(n.code,{children:"ziti"})," stanza should reflect this password."]}),"\n",(0,t.jsxs)(n.admonition,{type:"note",children:[(0,t.jsxs)(n.p,{children:["Be sure to see the ",(0,t.jsxs)(n.a,{target:"_blank","data-noBrokenLinkCheck":!0,href:r(1855).Z+"",children:["reference configuration at ",(0,t.jsx)(n.code,{children:"etc/ctrl.yml"})]})," for the complete documentation of the current configuration file format for the ",(0,t.jsx)(n.code,{children:"zrok"})," controller and service instance components."]}),(0,t.jsxs)(n.p,{children:["See the separate guides on ",(0,t.jsx)(n.a,{href:"/docs/guides/self-hosting/metrics-and-limits/configuring-metrics",children:"configuring metrics"})," and ",(0,t.jsx)(n.a,{href:"/docs/guides/self-hosting/metrics-and-limits/configuring-limits",children:"configuring limits"})," for details about both of these specialized areas of service instance configuration."]})]}),"\n",(0,t.jsx)(n.h2,{id:"environment-variables",children:"Environment Variables"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"zrok"})," binaries are configured to work with the global ",(0,t.jsx)(n.code,{children:"zrok.io"})," service, and default to using ",(0,t.jsx)(n.code,{children:"api.zrok.io"})," as the endpoint for communicating with the service."]}),"\n",(0,t.jsxs)(n.p,{children:["To work with a self-hosted ",(0,t.jsx)(n.code,{children:"zrok"})," deployment, you'll need to set the ",(0,t.jsx)(n.code,{children:"ZROK_API_ENDPOINT"})," environment variable to point to the address where your ",(0,t.jsx)(n.code,{children:"zrok"})," controller will be listening, according to ",(0,t.jsx)(n.code,{children:"endpoint"})," in the configuration file above."]}),"\n",(0,t.jsx)(n.p,{children:"In my case, I've set:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"export ZROK_API_ENDPOINT=http://127.0.0.1:18080\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsxs)(n.a,{href:"/docs/guides/self-hosting/instance-configuration",children:["Read more about configuring your self-hosted ",(0,t.jsx)(n.code,{children:"zrok"})," instance"]}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"bootstrap-openziti-for-zrok",children:"Bootstrap OpenZiti for zrok"}),"\n",(0,t.jsxs)(n.p,{children:["With your OpenZiti network running and your configuration saved to a local file (I refer to mine as ",(0,t.jsx)(n.code,{children:"etc/ctrl.yml"})," in these examples), you're ready to bootstrap the Ziti network."]}),"\n",(0,t.jsxs)(n.p,{children:["Use the ",(0,t.jsx)(n.code,{children:"zrok admin bootstrap"})," command to bootstrap like this:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ zrok admin bootstrap etc/ctrl.yml \n[ 0.002] INFO main.(*adminBootstrap).run: {\n\t...\n}\n[ 0.002] INFO zrok/controller/store.Open: database connected\n[ 0.006] INFO zrok/controller/store.(*Store).migrate: applied 0 migrations\n[ 0.006] INFO zrok/controller.Bootstrap: connecting to the ziti edge management api\n[ 0.039] INFO zrok/controller.Bootstrap: creating identity for controller ziti access\n[ 0.071] INFO zrok/controller.Bootstrap: controller identity: jKd8AINSz\n[ 0.082] INFO zrok/controller.assertIdentity: asserted identity 'jKd8AINSz'\n[ 0.085] INFO zrok/controller.assertErpForIdentity: asserted erps for 'ctrl' (jKd8AINSz)\n[ 0.085] INFO zrok/controller.Bootstrap: creating identity for frontend ziti access\n[ 0.118] INFO zrok/controller.Bootstrap: frontend identity: sqJRAINSiB\n[ 0.119] INFO zrok/controller.assertIdentity: asserted identity 'sqJRAINSiB'\n[ 0.120] INFO zrok/controller.assertErpForIdentity: asserted erps for 'frontend' (sqJRAINSiB)\n[ 0.120] WARNING zrok/controller.Bootstrap: missing public frontend for ziti id 'sqJRAINSiB'; please use 'zrok admin create frontend sqJRAINSiB public https://{token}.your.dns.name' to create a frontend instance\n[ 0.123] INFO zrok/controller.assertZrokProxyConfigType: found 'zrok.proxy.v1' config type with id '33CyjNbIepkXHN5VzGDA8L'\n[ 0.124] INFO zrok/controller.assertMetricsService: creating 'metrics' service\n[ 0.126] INFO zrok/controller.assertMetricsService: asserted 'metrics' service (5RpPZZ7T8bZf1ENjwGiPc3)\n[ 0.128] INFO zrok/controller.assertMetricsSerp: creating 'metrics' serp\n[ 0.130] INFO zrok/controller.assertMetricsSerp: asserted 'metrics' serp\n[ 0.134] INFO zrok/controller.assertCtrlMetricsBind: creating 'ctrl-metrics-bind' service policy\n[ 0.135] INFO zrok/controller.assertCtrlMetricsBind: asserted 'ctrl-metrics-bind' service policy\n[ 0.138] INFO zrok/controller.assertFrontendMetricsDial: creating 'frontend-metrics-dial' service policy\n[ 0.140] INFO zrok/controller.assertFrontendMetricsDial: asserted 'frontend-metrics-dial' service policy\n[ 0.140] INFO main.(*adminBootstrap).run: bootstrap complete!\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"zrok admin bootstrap"})," command configures the ",(0,t.jsx)(n.code,{children:"zrok"})," database, the necessary OpenZiti identities, and all of the OpenZiti policies required to run a ",(0,t.jsx)(n.code,{children:"zrok"})," service."]}),"\n",(0,t.jsx)(n.p,{children:"Notice this warning:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"[ 0.120] WARNING zrok/controller.Bootstrap: missing public frontend for ziti id 'sqJRAINSiB'; please use 'zrok admin create frontend sqJRAINSiB public https://{token}.your.dns.name' to create a frontend instance\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If you find it necessary to re-run the ",(0,t.jsx)(n.code,{children:"zrok admin bootstrap"})," command, you may need to add the ",(0,t.jsx)(n.code,{children:"--skip-frontend"})," flag to avoid re-creating the default ",(0,t.jsx)(n.code,{children:"public"})," frontend's Ziti identity and router policy."]}),"\n",(0,t.jsx)(n.h2,{id:"run-zrok-controller",children:"Run zrok Controller"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"zrok"}),' bootstrap process wants us to create a "public frontend" for our service. ',(0,t.jsx)(n.code,{children:"zrok"})," uses public frontends to allow users to specify where they would like public traffic to ingress from."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"zrok admin create frontend"})," command requires a running ",(0,t.jsx)(n.code,{children:"zrok"})," controller, so let's start that up first:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ zrok controller etc/ctrl.yml \n[ 0.003] INFO main.(*controllerCommand).run: {\n\t...\n}\n[ 0.016] INFO zrok/controller.inspectZiti: inspecting ziti controller configuration\n[ 0.048] INFO zrok/controller.findZrokProxyConfigType: found 'zrok.proxy.v1' config type with id '33CyjNbIepkXHN5VzGDA8L'\n[ 0.048] INFO zrok/controller/store.Open: database connected\n[ 0.048] INFO zrok/controller/store.(*Store).migrate: applied 0 migrations\n[ 0.049] INFO zrok/controller.(*metricsAgent).run: starting\n[ 0.064] INFO zrok/rest_server_zrok.setupGlobalMiddleware: configuring\n[ 0.064] INFO zrok/ui.StaticBuilder: building\n[ 0.065] INFO zrok/rest_server_zrok.(*Server).Logf: Serving zrok at http://[::]:18080\n[ 0.085] INFO zrok/controller.(*metricsAgent).listen: started\n"})}),"\n",(0,t.jsx)(n.h2,{id:"create-zrok-frontend",children:"Create zrok Frontend"}),"\n",(0,t.jsxs)(n.p,{children:["With our ",(0,t.jsx)(n.code,{children:"ZROK_ADMIN_TOKEN"})," and ",(0,t.jsx)(n.code,{children:"ZROK_API_ENDPOINT"})," environment variables set, we can create our public frontend like this:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ zrok admin create frontend sqJRAINSiB public http://{token}.zrok.quigley.com:8080\n[ 0.037] INFO main.(*adminCreateFrontendCommand).run: created global public frontend 'WEirJNHVlcW9'\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The id of the frontend was emitted earlier in by the zrok controller when we ran the bootstrap command. If you don't have that log message the you can find the id again with the ",(0,t.jsx)(n.code,{children:"ziti"})," CLI like this:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"# initialize the Ziti quickstart env\nsource ~/.ziti/quickstart/$(hostname -s)/$(hostname -s).env\n# login as admin\nzitiLogin\n# list Ziti identities created by the quickstart and bootstrap\nziti edge list identities\n"})}),"\n",(0,t.jsx)(n.p,{children:'The id is shown for the frontend identity named "public."'}),"\n",(0,t.jsxs)(n.p,{children:["Nice work! The ",(0,t.jsx)(n.code,{children:"zrok"})," controller is fully configured now that you have created the zrok frontend."]}),"\n",(0,t.jsx)(n.h2,{id:"configure-the-public-frontend",children:"Configure the Public Frontend"}),"\n",(0,t.jsxs)(n.p,{children:["Create an http frontend configuration file in ",(0,t.jsx)(n.code,{children:"etc/http-frontend.yml"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"v: 3\nhost_match: zrok.quigley.com\naddress: 0.0.0.0:8080\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This frontend config file has a ",(0,t.jsx)(n.code,{children:"host_match"})," pattern that represents the DNS zone you're using with this instance of zrok. Incoming HTTP requests with a matching ",(0,t.jsx)(n.code,{children:"Host"})," header will be handled by this frontend. You may also specify the interface address where the frontend will listen for public access requests."]}),"\n",(0,t.jsxs)(n.p,{children:["The frontend does not provide server TLS, but you may front the server with a reverse proxy. It is essential the reverse proxy forwards the ",(0,t.jsx)(n.code,{children:"Host"})," header supplied by the viewer. This example will expose the non-TLS listener for the frontend."]}),"\n",(0,t.jsxs)(n.p,{children:["You can also specify an ",(0,t.jsx)(n.code,{children:"oauth"})," configuration in this file, full details of are found in ",(0,t.jsx)(n.a,{href:"/docs/guides/self-hosting/oauth/configuring-oauth#configuring-your-public-frontend",children:"OAuth Public Frontend Configuration"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"start-public-frontend",children:"Start Public Frontend"}),"\n",(0,t.jsx)(n.p,{children:"In another terminal window, run:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ zrok access public etc/http-frontend.yml\n[ 0.002] INFO main.(*accessPublicCommand).run: {\n\t...\n}\n[ 0.002] INFO zrok/endpoints/public_frontend.newMetricsAgent: loaded 'public' identity\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The zrok frontend uses the ",(0,t.jsx)(n.code,{children:"public"})," identity created during the bootstrap process to securely access zrok backends. to provide public access for the ",(0,t.jsx)(n.code,{children:"zrok"})," deployment. It is expected that the configured listener for this frontend corresponds to the DNS template specified when creating the public frontend record above."]}),"\n",(0,t.jsx)(n.h2,{id:"invite-yourself",children:"Invite Yourself"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ zrok invite\nNew Email: user@domain.com\nConfirm Email: user@domain.com\ninvitation sent to 'user@domain.com'!\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If you look at the console output from your ",(0,t.jsx)(n.code,{children:"zrok"})," controller, you'll see a message like this:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"[ 238.168] INFO zrok/controller.(*inviteHandler).Handle: account request for 'user@domain.com' has registration token 'U2Ewt1UCn3ql'\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You can access your ",(0,t.jsx)(n.code,{children:"zrok"})," controller's registration UI by pointing a web browser at:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"http://localhost:18080/register/U2Ewt1UCn3ql\n"})}),"\n",(0,t.jsx)(n.p,{children:"The UI will ask you to set a password for your new account. Go ahead and do that."}),"\n",(0,t.jsx)(n.p,{children:"After doing that, I see the following output in my controller console:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"[ 516.778] INFO zrok/controller.(*registerHandler).Handle: created account 'user@domain.com' with token 'SuGzRPjVDIcF'\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Keep track of the token listed above (",(0,t.jsx)(n.code,{children:"SuGzRPjVDIcF"}),"). We'll use this to enable our shell for this ",(0,t.jsx)(n.code,{children:"zrok"})," deployment."]}),"\n",(0,t.jsx)(n.h2,{id:"enable-your-shell",children:"Enable Your Shell"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ zrok enable SuGzRPjVDIcF\nzrok environment '2AS1WZ3Sz' enabled for 'SuGzRPjVDIcF'\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Congratulations. You have a working ",(0,t.jsx)(n.code,{children:"zrok"})," environment!"]})]})}function h(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(a,{...e})}):a(e)}},1855:(e,n,r)=>{r.d(n,{Z:()=>t});const t=r.p+"assets/files/ctrl-6c22ae02cafe307b82e5a1f783497950.yml"},1151:(e,n,r)=>{r.d(n,{Z:()=>l,a:()=>s});var t=r(7294);const o={},i=t.createContext(o);function s(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8ef4b25e.6f594527.js b/assets/js/8ef4b25e.8506f920.js similarity index 86% rename from assets/js/8ef4b25e.6f594527.js rename to assets/js/8ef4b25e.8506f920.js index 1c930284..5881fe84 100644 --- a/assets/js/8ef4b25e.6f594527.js +++ b/assets/js/8ef4b25e.8506f920.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[318],{2636:i=>{i.exports=JSON.parse('{"title":"Metrics and Limits","slug":"/category/metrics-and-limits","permalink":"/docs/category/metrics-and-limits","navigation":{"previous":{"title":"Nginx TLS","permalink":"/docs/guides/self-hosting/nginx_tls_guide"},"next":{"title":"Configuring Metrics","permalink":"/docs/guides/self-hosting/metrics-and-limits/configuring-metrics"}}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[318],{2636:i=>{i.exports=JSON.parse('{"title":"Metrics and Limits","slug":"/category/metrics-and-limits","permalink":"/docs/category/metrics-and-limits","navigation":{"previous":{"title":"NGINX TLS","permalink":"/docs/guides/self-hosting/nginx_tls_guide"},"next":{"title":"Configuring Metrics","permalink":"/docs/guides/self-hosting/metrics-and-limits/configuring-metrics"}}}')}}]); \ No newline at end of file diff --git a/assets/js/935f2afb.658be620.js b/assets/js/935f2afb.658be620.js deleted file mode 100644 index 1e973bbe..00000000 --- a/assets/js/935f2afb.658be620.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[53],{1109:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Getting Started","href":"/docs/getting-started","docId":"getting-started","unlisted":false},{"type":"category","label":"Concepts","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Private Shares","href":"/docs/concepts/sharing-private","docId":"concepts/sharing-private","unlisted":false},{"type":"link","label":"Public Shares","href":"/docs/concepts/sharing-public","docId":"concepts/sharing-public","unlisted":false},{"type":"link","label":"Reserved Shares","href":"/docs/concepts/sharing-reserved","docId":"concepts/sharing-reserved","unlisted":false},{"type":"link","label":"Sharing HTTP Servers","href":"/docs/concepts/http","docId":"concepts/http","unlisted":false},{"type":"link","label":"Sharing TCP and UDP Servers","href":"/docs/concepts/tunnels","docId":"concepts/tunnels","unlisted":false},{"type":"link","label":"Sharing Websites and Files","href":"/docs/concepts/files","docId":"concepts/files","unlisted":false},{"type":"link","label":"Open Source","href":"/docs/concepts/opensource","docId":"concepts/opensource","unlisted":false},{"type":"link","label":"Hosting","href":"/docs/concepts/hosting","docId":"concepts/hosting","unlisted":false}],"href":"/docs/concepts/"},{"type":"category","label":"Guides","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Install","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Linux","href":"/docs/guides/install/linux","docId":"guides/install/linux","unlisted":false},{"type":"link","label":"macOS","href":"/docs/guides/install/macos","docId":"guides/install/macos","unlisted":false},{"type":"link","label":"Windows","href":"/docs/guides/install/windows","docId":"guides/install/windows","unlisted":false}],"href":"/docs/guides/install/"},{"type":"link","label":"frontdoor","href":"/docs/guides/frontdoor","docId":"guides/frontdoor","unlisted":false},{"type":"link","label":"Permission Modes","href":"/docs/guides/permission-modes","docId":"guides/permission-modes","unlisted":false},{"type":"category","label":"Docker Share","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Public Share","href":"/docs/guides/docker-share/docker_public_share_guide","docId":"guides/docker-share/docker_public_share_guide","unlisted":false},{"type":"link","label":"Private Share","href":"/docs/guides/docker-share/docker_private_share_guide","docId":"guides/docker-share/docker_private_share_guide","unlisted":false}],"href":"/docs/category/docker-share"},{"type":"category","label":"Self Hosting","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Linux VPS","href":"/docs/guides/self-hosting/self_hosting_guide","docId":"guides/self-hosting/self_hosting_guide","unlisted":false},{"type":"link","label":"Nginx TLS","href":"/docs/guides/self-hosting/nginx_tls_guide","docId":"guides/self-hosting/nginx_tls_guide","unlisted":false},{"type":"category","label":"Metrics and Limits","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Configuring Metrics","href":"/docs/guides/self-hosting/metrics-and-limits/configuring-metrics","docId":"guides/self-hosting/metrics-and-limits/configuring-metrics","unlisted":false},{"type":"link","label":"Configuring Limits","href":"/docs/guides/self-hosting/metrics-and-limits/configuring-limits","docId":"guides/self-hosting/metrics-and-limits/configuring-limits","unlisted":false}],"href":"/docs/category/metrics-and-limits"},{"type":"category","label":"OAuth","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"OAuth Public Frontend Configuration","href":"/docs/guides/self-hosting/oauth/configuring-oauth","docId":"guides/self-hosting/oauth/configuring-oauth","unlisted":false}],"href":"/docs/category/oauth"},{"type":"link","label":"Instance Config","href":"/docs/guides/self-hosting/instance-configuration","docId":"guides/self-hosting/instance-configuration","unlisted":false}],"href":"/docs/category/self-hosting"},{"type":"category","label":"drives","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"The Drives CLI","href":"/docs/guides/drives/cli","docId":"guides/drives/cli","unlisted":false}]},{"type":"link","label":"VPN","href":"/docs/guides/vpn/","docId":"guides/vpn/vpn","unlisted":false}],"href":"/docs/category/guides"}]},"docs":{"concepts/files":{"id":"concepts/files","title":"Sharing Websites and Files","description":"With zrok it is possible to share files quickly and easily as well. To share files using zrok use","sidebar":"tutorialSidebar"},"concepts/hosting":{"id":"concepts/hosting","title":"Hosting","description":"Self-Hosted","sidebar":"tutorialSidebar"},"concepts/http":{"id":"concepts/http","title":"Sharing HTTP Servers","description":"zrok can share HTTP and HTTPS resources natively. If you have an existing web server that you want to share with other users, you can use the zrok share command using the --backend-mode proxy flag.","sidebar":"tutorialSidebar"},"concepts/index":{"id":"concepts/index","title":"Concepts","description":"zrok was designed to make sharing local resources both secure and easy. In this section of the zrok documentation, we\'ll tour through all of the most important features.","sidebar":"tutorialSidebar"},"concepts/opensource":{"id":"concepts/opensource","title":"Open Source","description":"It\'s important to the zrok project that it remain free and open source software. The code is available on GitHub","sidebar":"tutorialSidebar"},"concepts/sharing-private":{"id":"concepts/sharing-private","title":"Private Shares","description":"zrok was built to share and access digital resources. A private share allows a resource to be","sidebar":"tutorialSidebar"},"concepts/sharing-public":{"id":"concepts/sharing-public","title":"Public Shares","description":"zrok supports public sharing for web-based (HTTP and HTTPS) resources. These resources are easily shared with the general internet through public access points.","sidebar":"tutorialSidebar"},"concepts/sharing-reserved":{"id":"concepts/sharing-reserved","title":"Reserved Shares","description":"By default a public or private share is assigned a share token when you create a share using the zrok share command. The zrok share command is the bridge between your local environment and the users you are sharing with. When you terminate the zrok share, the bridge is eliminated and the share token is deleted. If you run zrok share again, you will be allocated a brand new share token.","sidebar":"tutorialSidebar"},"concepts/tunnels":{"id":"concepts/tunnels","title":"Sharing TCP and UDP Servers","description":"zrok includes support for sharing low-level TCP and UDP network resources using the tcpTunnel and udpTunnel backend modes.","sidebar":"tutorialSidebar"},"getting-started":{"id":"getting-started","title":"Getting Started with zrok","description":"What\'s a zrok?","sidebar":"tutorialSidebar"},"guides/docker-share/docker_private_share_guide":{"id":"guides/docker-share/docker_private_share_guide","title":"Docker Private Share","description":"With zrok, you can privately share a server app that\'s running in Docker, or any server that\'s reachable by the zrok container. Then, a zrok private access running somewhere else can use the private share. In this guide we\'ll cover both sides: the private share and the private access.","sidebar":"tutorialSidebar"},"guides/docker-share/docker_public_share_guide":{"id":"guides/docker-share/docker_public_share_guide","title":"Docker Public Share","description":"With zrok and Docker, you can publicly share a web server that\'s running in a local container or anywhere that\'s reachable by the zrok container. The share can be reached through a temporary public URL that expires when the container is stopped. If you\'re looking for a reserved subdomain for the share, check out zrok frontdoor.","sidebar":"tutorialSidebar"},"guides/drives/cli":{"id":"guides/drives/cli","title":"The Drives CLI","description":"The zrok drives CLI tools allow for simple, ergonomic management and synchronization of local and remote files.","sidebar":"tutorialSidebar"},"guides/frontdoor":{"id":"guides/frontdoor","title":"zrok frontdoor","description":"zrok frontdoor is the heavy-duty front door to your app or site. It makes your website or app available to your online audience through the shield of zrok.io\'s hardened, managed frontends.","sidebar":"tutorialSidebar"},"guides/install/index":{"id":"guides/install/index","title":"Install","description":"{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Getting Started","href":"/docs/getting-started","docId":"getting-started","unlisted":false},{"type":"category","label":"Concepts","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Private Shares","href":"/docs/concepts/sharing-private","docId":"concepts/sharing-private","unlisted":false},{"type":"link","label":"Public Shares","href":"/docs/concepts/sharing-public","docId":"concepts/sharing-public","unlisted":false},{"type":"link","label":"Reserved Shares","href":"/docs/concepts/sharing-reserved","docId":"concepts/sharing-reserved","unlisted":false},{"type":"link","label":"Sharing HTTP Servers","href":"/docs/concepts/http","docId":"concepts/http","unlisted":false},{"type":"link","label":"Sharing TCP and UDP Servers","href":"/docs/concepts/tunnels","docId":"concepts/tunnels","unlisted":false},{"type":"link","label":"Sharing Websites and Files","href":"/docs/concepts/files","docId":"concepts/files","unlisted":false},{"type":"link","label":"Open Source","href":"/docs/concepts/opensource","docId":"concepts/opensource","unlisted":false},{"type":"link","label":"Hosting","href":"/docs/concepts/hosting","docId":"concepts/hosting","unlisted":false}],"href":"/docs/concepts/"},{"type":"category","label":"Guides","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Install","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Linux","href":"/docs/guides/install/linux","docId":"guides/install/linux","unlisted":false},{"type":"link","label":"macOS","href":"/docs/guides/install/macos","docId":"guides/install/macos","unlisted":false},{"type":"link","label":"Windows","href":"/docs/guides/install/windows","docId":"guides/install/windows","unlisted":false}],"href":"/docs/guides/install/"},{"type":"link","label":"frontdoor","href":"/docs/guides/frontdoor","docId":"guides/frontdoor","unlisted":false},{"type":"link","label":"Permission Modes","href":"/docs/guides/permission-modes","docId":"guides/permission-modes","unlisted":false},{"type":"category","label":"Docker Share","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Public Share","href":"/docs/guides/docker-share/docker_public_share_guide","docId":"guides/docker-share/docker_public_share_guide","unlisted":false},{"type":"link","label":"Private Share","href":"/docs/guides/docker-share/docker_private_share_guide","docId":"guides/docker-share/docker_private_share_guide","unlisted":false}],"href":"/docs/guides/docker-share/"},{"type":"category","label":"Self Hosting","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Linux","href":"/docs/guides/self-hosting/linux","docId":"guides/self-hosting/linux","unlisted":false},{"type":"link","label":"NGINX TLS","href":"/docs/guides/self-hosting/nginx_tls_guide","docId":"guides/self-hosting/nginx_tls_guide","unlisted":false},{"type":"category","label":"Metrics and Limits","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Configuring Metrics","href":"/docs/guides/self-hosting/metrics-and-limits/configuring-metrics","docId":"guides/self-hosting/metrics-and-limits/configuring-metrics","unlisted":false},{"type":"link","label":"Configuring Limits","href":"/docs/guides/self-hosting/metrics-and-limits/configuring-limits","docId":"guides/self-hosting/metrics-and-limits/configuring-limits","unlisted":false}],"href":"/docs/category/metrics-and-limits"},{"type":"category","label":"OAuth","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"OAuth Public Frontend Configuration","href":"/docs/guides/self-hosting/oauth/configuring-oauth","docId":"guides/self-hosting/oauth/configuring-oauth","unlisted":false}],"href":"/docs/category/oauth"},{"type":"link","label":"Instance Config","href":"/docs/guides/self-hosting/instance-configuration","docId":"guides/self-hosting/instance-configuration","unlisted":false}],"href":"/docs/category/self-hosting"},{"type":"category","label":"drives","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"The Drives CLI","href":"/docs/guides/drives/cli","docId":"guides/drives/cli","unlisted":false}]},{"type":"link","label":"VPN","href":"/docs/guides/vpn/","docId":"guides/vpn/vpn","unlisted":false}],"href":"/docs/category/guides"}]},"docs":{"concepts/files":{"id":"concepts/files","title":"Sharing Websites and Files","description":"With zrok it is possible to share files quickly and easily as well. To share files using zrok use","sidebar":"tutorialSidebar"},"concepts/hosting":{"id":"concepts/hosting","title":"Hosting","description":"Self-Hosted","sidebar":"tutorialSidebar"},"concepts/http":{"id":"concepts/http","title":"Sharing HTTP Servers","description":"zrok can share HTTP and HTTPS resources natively. If you have an existing web server that you want to share with other users, you can use the zrok share command using the --backend-mode proxy flag.","sidebar":"tutorialSidebar"},"concepts/index":{"id":"concepts/index","title":"Concepts","description":"zrok was designed to make sharing local resources both secure and easy. In this section of the zrok documentation, we\'ll tour through all of the most important features.","sidebar":"tutorialSidebar"},"concepts/opensource":{"id":"concepts/opensource","title":"Open Source","description":"It\'s important to the zrok project that it remain free and open source software. The code is available on GitHub","sidebar":"tutorialSidebar"},"concepts/sharing-private":{"id":"concepts/sharing-private","title":"Private Shares","description":"zrok was built to share and access digital resources. A private share allows a resource to be","sidebar":"tutorialSidebar"},"concepts/sharing-public":{"id":"concepts/sharing-public","title":"Public Shares","description":"zrok supports public sharing for web-based (HTTP and HTTPS) resources. These resources are easily shared with the general internet through public access points.","sidebar":"tutorialSidebar"},"concepts/sharing-reserved":{"id":"concepts/sharing-reserved","title":"Reserved Shares","description":"By default a public or private share is assigned a share token when you create a share using the zrok share command. The zrok share command is the bridge between your local environment and the users you are sharing with. When you terminate the zrok share, the bridge is eliminated and the share token is deleted. If you run zrok share again, you will be allocated a brand new share token.","sidebar":"tutorialSidebar"},"concepts/tunnels":{"id":"concepts/tunnels","title":"Sharing TCP and UDP Servers","description":"zrok includes support for sharing low-level TCP and UDP network resources using the tcpTunnel and udpTunnel backend modes.","sidebar":"tutorialSidebar"},"getting-started":{"id":"getting-started","title":"Getting Started with zrok","description":"What\'s a zrok?","sidebar":"tutorialSidebar"},"guides/docker-share/docker_private_share_guide":{"id":"guides/docker-share/docker_private_share_guide","title":"Docker Private Share","description":"Goal","sidebar":"tutorialSidebar"},"guides/docker-share/docker_public_share_guide":{"id":"guides/docker-share/docker_public_share_guide","title":"Docker Compose Public Share","description":"Goal","sidebar":"tutorialSidebar"},"guides/docker-share/index":{"id":"guides/docker-share/index","title":"Getting Started with Docker","description":"Overview","sidebar":"tutorialSidebar"},"guides/drives/cli":{"id":"guides/drives/cli","title":"The Drives CLI","description":"The zrok drives CLI tools allow for simple, ergonomic management and synchronization of local and remote files.","sidebar":"tutorialSidebar"},"guides/frontdoor":{"id":"guides/frontdoor","title":"zrok frontdoor","description":"zrok frontdoor is the heavy-duty front door to your app or site. It makes your website or app available to your online audience through the shield of zrok.io\'s hardened, managed frontends.","sidebar":"tutorialSidebar"},"guides/install/index":{"id":"guides/install/index","title":"Install","description":"{n.r(r),n.d(r,{assets:()=>c,contentTitle:()=>t,default:()=>d,frontMatter:()=>s,metadata:()=>a,toc:()=>l});var i=n(5893),o=n(1151);const s={title:"Docker Private Share",sidebar_position:20,sidebar_label:"Private Share"},t=void 0,a={id:"guides/docker-share/docker_private_share_guide",title:"Docker Private Share",description:"Goal",source:"@site/../docs/guides/docker-share/docker_private_share_guide.md",sourceDirName:"guides/docker-share",slug:"/guides/docker-share/docker_private_share_guide",permalink:"/docs/guides/docker-share/docker_private_share_guide",draft:!1,unlisted:!1,editUrl:"https://github.com/openziti/zrok/blob/main/docs/../docs/guides/docker-share/docker_private_share_guide.md",tags:[],version:"current",sidebarPosition:20,frontMatter:{title:"Docker Private Share",sidebar_position:20,sidebar_label:"Private Share"},sidebar:"tutorialSidebar",previous:{title:"Public Share",permalink:"/docs/guides/docker-share/docker_public_share_guide"},next:{title:"Self Hosting",permalink:"/docs/category/self-hosting"}},c={},l=[{value:"Goal",id:"goal",level:2},{value:"Overview",id:"overview",level:2},{value:"Walkthrough Video",id:"walkthrough-video",level:2},{value:"How it Works",id:"how-it-works",level:2},{value:"Before You Begin",id:"before-you-begin",level:2},{value:"Begin Sharing Privately with zrok in Docker",id:"begin-sharing-privately-with-zrok-in-docker",level:2},{value:"Access the Private Share",id:"access-the-private-share",level:2},{value:"Going Further with Private Access",id:"going-further-with-private-access",level:2},{value:"Cleaning Up",id:"cleaning-up",level:2}];function h(e){const r={a:"a",code:"code",em:"em",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",...(0,o.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(r.h2,{id:"goal",children:"Goal"}),"\n",(0,i.jsx)(r.p,{children:"Privately share a Docker Compose service with a separate zrok environment and a permanent zrok share token."}),"\n",(0,i.jsx)(r.h2,{id:"overview",children:"Overview"}),"\n",(0,i.jsx)(r.p,{children:"With zrok, you can privately share a service that's running in Docker. You need a zrok private share running somewhere that it can reach the service you're sharing, and a zrok private access running somewhere else where you want to use the private share. Together, the private share and private access form a private point-to-point tunnel."}),"\n",(0,i.jsxs)(r.p,{children:["Here's a short article with an overview of ",(0,i.jsx)(r.a,{href:"/docs/concepts/sharing-private",children:"private sharing with zrok"}),"."]}),"\n",(0,i.jsx)(r.h2,{id:"walkthrough-video",children:"Walkthrough Video"}),"\n",(0,i.jsx)("iframe",{width:"100%",height:"315",src:"https://www.youtube.com/embed/HxyvtFAvwUE",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowfullscreen:!0}),"\n",(0,i.jsx)(r.h2,{id:"how-it-works",children:"How it Works"}),"\n",(0,i.jsx)(r.p,{children:"The Docker Compose project uses your zrok account token to reserve a private share token and keep sharing the backend target."}),"\n",(0,i.jsx)(r.p,{children:"When the project runs it will:"}),"\n",(0,i.jsxs)(r.ol,{children:["\n",(0,i.jsxs)(r.li,{children:["enable a zrok environment unless ",(0,i.jsx)(r.code,{children:"/mnt/.zrok/environment.json"})," exists in the ",(0,i.jsx)(r.code,{children:"zrok_env"})," volume"]}),"\n",(0,i.jsxs)(r.li,{children:["reserve a private share token for the service unless ",(0,i.jsx)(r.code,{children:"/mnt/.zrok/reserved.json"})," exists"]}),"\n",(0,i.jsxs)(r.li,{children:["start sharing the target specified in the ",(0,i.jsx)(r.code,{children:"ZROK_TARGET"})," environment variable"]}),"\n"]}),"\n",(0,i.jsx)(r.h2,{id:"before-you-begin",children:"Before You Begin"}),"\n",(0,i.jsxs)(r.p,{children:["To follow this guide you will need ",(0,i.jsx)(r.a,{href:"https://docs.docker.com/get-docker/",children:"Docker"})," and ",(0,i.jsx)(r.a,{href:"https://docs.docker.com/compose/install/",children:"the Docker Compose plugin"})," for running ",(0,i.jsx)(r.code,{children:"docker compose"})," commands in your terminal."]}),"\n",(0,i.jsx)(r.p,{children:"If you have installed Docker Desktop on macOS or Windows then you are all set."}),"\n",(0,i.jsx)(r.h2,{id:"begin-sharing-privately-with-zrok-in-docker",children:"Begin Sharing Privately with zrok in Docker"}),"\n",(0,i.jsx)(r.p,{children:"First, let's create the private share."}),"\n",(0,i.jsxs)(r.ol,{children:["\n",(0,i.jsxs)(r.li,{children:["\n",(0,i.jsx)(r.p,{children:"Make a folder on your computer to use as a Docker Compose project for your zrok private share."}),"\n"]}),"\n",(0,i.jsxs)(r.li,{children:["\n",(0,i.jsx)(r.p,{children:"In your terminal, change directory to your newly-created project folder."}),"\n"]}),"\n",(0,i.jsxs)(r.li,{children:["\n",(0,i.jsxs)(r.p,{children:["Download ",(0,i.jsx)(r.a,{href:"pathname:///zrok-private-share/compose.yml",children:"the zrok-private-share Docker Compose project file"})," into your new project folder and make sure it's named ",(0,i.jsx)(r.code,{children:"compose.yml"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(r.li,{children:["\n",(0,i.jsxs)(r.p,{children:["Copy your zrok environment token from the zrok web console to your clipboard and paste it in a file named ",(0,i.jsx)(r.code,{children:".env"})," in the same folder like this:"]}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:'# file name ".env"\nZROK_ENABLE_TOKEN="8UL9-48rN0ua"\n'})}),"\n"]}),"\n",(0,i.jsxs)(r.li,{children:["\n",(0,i.jsx)(r.p,{children:"If you are self-hosting zrok then it's important to set your API endpoint URL too. If you're using the hosted zrok service then you can skip this step."}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:'# file name ".env"\nZROK_API_ENDPOINT="https://zrok.example.com"\n'})}),"\n"]}),"\n",(0,i.jsxs)(r.li,{children:["\n",(0,i.jsx)(r.p,{children:"Run your Compose project to start sharing the built-in demo web server:"}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"docker compose up\n"})}),"\n"]}),"\n",(0,i.jsxs)(r.li,{children:["\n",(0,i.jsx)(r.p,{children:"Read the private share token from the output. One of the last lines is like this:"}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"zrok-private-share-1 | zrok access private wr3hpf2z5fiy\n"})}),"\n",(0,i.jsx)(r.p,{children:"Keep track of this token so you can use it in your zrok private access project."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(r.h2,{id:"access-the-private-share",children:"Access the Private Share"}),"\n",(0,i.jsx)(r.p,{children:"Now that we have a private share we can access it with the zrok command or by running a separate Docker Compose project."}),"\n",(0,i.jsxs)(r.ol,{children:["\n",(0,i.jsxs)(r.li,{children:["\n",(0,i.jsx)(r.p,{children:"Make a folder on your computer to use as a Docker Compose project for your zrok private access."}),"\n"]}),"\n",(0,i.jsxs)(r.li,{children:["\n",(0,i.jsx)(r.p,{children:"In your terminal, change directory to your newly-created project folder."}),"\n"]}),"\n",(0,i.jsxs)(r.li,{children:["\n",(0,i.jsxs)(r.p,{children:["Download ",(0,i.jsx)(r.a,{href:"pathname:///zrok-private-access/compose.yml",children:"the zrok-private-access Docker Compose project file"})," into your new project folder and make sure it's named ",(0,i.jsx)(r.code,{children:"compose.yml"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(r.li,{children:["\n",(0,i.jsxs)(r.p,{children:["Copy your zrok environment token from the zrok web console to your clipboard and paste it in a file named ",(0,i.jsx)(r.code,{children:".env"})," in the same folder like this:"]}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:'# file name ".env"\nZROK_ENABLE_TOKEN="8UL9-48rN0ua"\n'})}),"\n"]}),"\n",(0,i.jsxs)(r.li,{children:["\n",(0,i.jsxs)(r.p,{children:["Now copy the zrok private access token from the zrok private share project's output to your clipboard and paste it in the same file named ",(0,i.jsx)(r.code,{children:".env"})," here in your private share project folder like this:"]}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:'# file name ".env"\nZROK_ENABLE_TOKEN="8UL9-48rN0ua"\nZROK_ACCESS_TOKEN="wr3hpf2z5fiy"\n'})}),"\n"]}),"\n",(0,i.jsxs)(r.li,{children:["\n",(0,i.jsx)(r.p,{children:"Run your Compose project to start accessing the private share:"}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"docker compose up zrok-private-access\n"})}),"\n"]}),"\n",(0,i.jsxs)(r.li,{children:["\n",(0,i.jsxs)(r.p,{children:["Now your zrok private access proxy is ready on ",(0,i.jsx)(r.a,{href:"http://127.0.0.1:9191",children:"http://127.0.0.1:9191"}),". You can visit the demo web server in your browser."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(r.h2,{id:"going-further-with-private-access",children:"Going Further with Private Access"}),"\n",(0,i.jsxs)(r.ol,{children:["\n",(0,i.jsxs)(r.li,{children:["\n",(0,i.jsxs)(r.p,{children:["Try changing the demo web server used in the private share project. One alternative demo server is provided: ",(0,i.jsx)(r.code,{children:"httpbin"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(r.li,{children:["\n",(0,i.jsxs)(r.p,{children:["Try accessing the private share from ",(0,i.jsx)(r.em,{children:"inside"})," a container running in the private access project. One demo client is provided: ",(0,i.jsx)(r.code,{children:"demo-client"}),". You can run it like this."]}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"docker compose up demo-client\n"})}),"\n"]}),"\n",(0,i.jsxs)(r.li,{children:["\n",(0,i.jsxs)(r.p,{children:["You'll see in the terminal output that the demo-client container is getting a response from the private share indicating the source IP of the request from the perspective of the demo server: ",(0,i.jsx)(r.code,{children:"httpbin"})," that's running in the private share project."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(r.h2,{id:"cleaning-up",children:"Cleaning Up"}),"\n",(0,i.jsx)(r.p,{children:'Run the "down" command in both Compose projects to destroy them when you\'re all done. This will stop the running containers and delete zrok environments\' storage volumes. Then delete the selected zrok environment by clicking "Actions" in the web console.'}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"docker compose down --remove-orphans --volumes\n"})})]})}function d(e={}){const{wrapper:r}={...(0,o.a)(),...e.components};return r?(0,i.jsx)(r,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},1151:(e,r,n)=>{n.d(r,{Z:()=>a,a:()=>t});var i=n(7294);const o={},s=i.createContext(o);function t(e){const r=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),i.createElement(s.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bbbe662c.be555dc4.js b/assets/js/bbbe662c.be555dc4.js deleted file mode 100644 index 813e1fb5..00000000 --- a/assets/js/bbbe662c.be555dc4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4196],{8724:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>c,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var s=n(5893),i=n(1151);const o={sidebar_position:20,sidebar_label:"Private Share"},t="Docker Private Share",a={id:"guides/docker-share/docker_private_share_guide",title:"Docker Private Share",description:"With zrok, you can privately share a server app that's running in Docker, or any server that's reachable by the zrok container. Then, a zrok private access running somewhere else can use the private share. In this guide we'll cover both sides: the private share and the private access.",source:"@site/../docs/guides/docker-share/docker_private_share_guide.md",sourceDirName:"guides/docker-share",slug:"/guides/docker-share/docker_private_share_guide",permalink:"/docs/guides/docker-share/docker_private_share_guide",draft:!1,unlisted:!1,editUrl:"https://github.com/openziti/zrok/blob/main/docs/../docs/guides/docker-share/docker_private_share_guide.md",tags:[],version:"current",sidebarPosition:20,frontMatter:{sidebar_position:20,sidebar_label:"Private Share"},sidebar:"tutorialSidebar",previous:{title:"Public Share",permalink:"/docs/guides/docker-share/docker_public_share_guide"},next:{title:"Self Hosting",permalink:"/docs/category/self-hosting"}},c={},h=[{value:"Walkthrough Video",id:"walkthrough-video",level:2},{value:"Before You Begin",id:"before-you-begin",level:2},{value:"Begin Sharing Privately with zrok in Docker",id:"begin-sharing-privately-with-zrok-in-docker",level:2},{value:"Access the Private Share",id:"access-the-private-share",level:2},{value:"Going Further with Private Access",id:"going-further-with-private-access",level:2},{value:"Cleaning Up",id:"cleaning-up",level:2}];function l(e){const r={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(r.h1,{id:"docker-private-share",children:"Docker Private Share"}),"\n",(0,s.jsx)(r.p,{children:"With zrok, you can privately share a server app that's running in Docker, or any server that's reachable by the zrok container. Then, a zrok private access running somewhere else can use the private share. In this guide we'll cover both sides: the private share and the private access."}),"\n",(0,s.jsxs)(r.p,{children:["Here's a short article with an overview of ",(0,s.jsx)(r.a,{href:"/docs/concepts/sharing-private",children:"private sharing with zrok"}),"."]}),"\n",(0,s.jsx)(r.h2,{id:"walkthrough-video",children:"Walkthrough Video"}),"\n",(0,s.jsx)("iframe",{width:"100%",height:"315",src:"https://www.youtube.com/embed/HxyvtFAvwUE",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowfullscreen:!0}),"\n",(0,s.jsx)(r.h2,{id:"before-you-begin",children:"Before You Begin"}),"\n",(0,s.jsxs)(r.p,{children:["To follow this guide you will need ",(0,s.jsx)(r.a,{href:"https://docs.docker.com/get-docker/",children:"Docker"})," and ",(0,s.jsx)(r.a,{href:"https://docs.docker.com/compose/install/",children:"the Docker Compose plugin"})," for running ",(0,s.jsx)(r.code,{children:"docker compose"})," commands in your terminal."]}),"\n",(0,s.jsx)(r.p,{children:"If you have installed Docker Desktop on macOS or Windows then you are all set."}),"\n",(0,s.jsx)(r.h2,{id:"begin-sharing-privately-with-zrok-in-docker",children:"Begin Sharing Privately with zrok in Docker"}),"\n",(0,s.jsx)(r.p,{children:"First, let's create the private share."}),"\n",(0,s.jsxs)(r.ol,{children:["\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsx)(r.p,{children:"Make a folder on your computer to use as a Docker Compose project for your zrok private share."}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsx)(r.p,{children:"In your terminal, change directory to your newly-created project folder."}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsxs)(r.p,{children:["Download ",(0,s.jsx)(r.a,{href:"pathname:///zrok-private-share/compose.yml",children:"the zrok-private-share Docker Compose project file"})," into your new project folder and make sure it's named ",(0,s.jsx)(r.code,{children:"compose.yml"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsxs)(r.p,{children:["Copy your zrok environment token from the zrok web console to your clipboard and paste it in a file named ",(0,s.jsx)(r.code,{children:".env"})," in the same folder like this:"]}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",children:'# file name ".env"\nZROK_ENABLE_TOKEN="8UL9-48rN0ua"\n'})}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsx)(r.p,{children:"If you are self-hosting zrok then it's important to set your API endpoint URL too. If you're using the hosted zrok service then you can skip this step."}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",children:'# file name ".env"\nZROK_API_ENDPOINT="https://zrok.example.com"\n'})}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsx)(r.p,{children:"Run your Compose project to start sharing the built-in demo web server:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",children:"docker compose up\n"})}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsx)(r.p,{children:"Read the private share token from the output. One of the last lines is like this:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",children:"zrok-private-share-1 | zrok access private wr3hpf2z5fiy\n"})}),"\n",(0,s.jsx)(r.p,{children:"Keep track of this token so you can use it in your zrok private access project."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(r.h2,{id:"access-the-private-share",children:"Access the Private Share"}),"\n",(0,s.jsx)(r.p,{children:"Now that we have a private share we can access it with the zrok command or by running a separate Docker Compose project."}),"\n",(0,s.jsxs)(r.ol,{children:["\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsx)(r.p,{children:"Make a folder on your computer to use as a Docker Compose project for your zrok private access."}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsx)(r.p,{children:"In your terminal, change directory to your newly-created project folder."}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsxs)(r.p,{children:["Download ",(0,s.jsx)(r.a,{href:"pathname:///zrok-private-access/compose.yml",children:"the zrok-private-access Docker Compose project file"})," into your new project folder and make sure it's named ",(0,s.jsx)(r.code,{children:"compose.yml"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsxs)(r.p,{children:["Copy your zrok environment token from the zrok web console to your clipboard and paste it in a file named ",(0,s.jsx)(r.code,{children:".env"})," in the same folder like this:"]}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",children:'# file name ".env"\nZROK_ENABLE_TOKEN="8UL9-48rN0ua"\n'})}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsxs)(r.p,{children:["Now copy the zrok private access token from the zrok private share project's output to your clipboard and paste it in the same file named ",(0,s.jsx)(r.code,{children:".env"})," here in your private share project folder like this:"]}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",children:'# file name ".env"\nZROK_ENABLE_TOKEN="8UL9-48rN0ua"\nZROK_ACCESS_TOKEN="wr3hpf2z5fiy"\n'})}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsx)(r.p,{children:"Run your Compose project to start accessing the private share:"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",children:"docker compose up zrok-private-access\n"})}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsxs)(r.p,{children:["Now your zrok private access proxy is ready on ",(0,s.jsx)(r.a,{href:"http://127.0.0.1:9191",children:"http://127.0.0.1:9191"}),". You can visit the demo web server in your browser."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(r.h2,{id:"going-further-with-private-access",children:"Going Further with Private Access"}),"\n",(0,s.jsxs)(r.ol,{children:["\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsxs)(r.p,{children:["Try changing the demo web server used in the private share project. One alternative demo server is provided: ",(0,s.jsx)(r.code,{children:"httpbin"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsxs)(r.p,{children:["Try accessing the private share from ",(0,s.jsx)(r.em,{children:"inside"})," a container running in the private access project. One demo client is provided: ",(0,s.jsx)(r.code,{children:"demo-client"}),". You can run it like this."]}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",children:"docker compose up demo-client\n"})}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsxs)(r.p,{children:["You'll see in the terminal output that the demo-client container is getting a response from the private share indicating the source IP of the request from the perspective of the demo server: ",(0,s.jsx)(r.code,{children:"httpbin"})," that's running in the private share project."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(r.h2,{id:"cleaning-up",children:"Cleaning Up"}),"\n",(0,s.jsx)(r.p,{children:'Run the "down" command in both Compose projects to destroy them when you\'re all done. This will stop the running containers and delete zrok environments\' storage volumes. Then delete the selected zrok environment by clicking "Actions" in the web console.'}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",children:"docker compose down --remove-orphans --volumes\n"})})]})}function d(e={}){const{wrapper:r}={...(0,i.a)(),...e.components};return r?(0,s.jsx)(r,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},1151:(e,r,n)=>{n.d(r,{Z:()=>a,a:()=>t});var s=n(7294);const i={},o=s.createContext(i);function t(e){const r=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),s.createElement(o.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bc747cac.05d8fc83.js b/assets/js/bc747cac.d3154f01.js similarity index 78% rename from assets/js/bc747cac.05d8fc83.js rename to assets/js/bc747cac.d3154f01.js index 282e062d..1fd03b38 100644 --- a/assets/js/bc747cac.05d8fc83.js +++ b/assets/js/bc747cac.d3154f01.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8945],{3033:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>d});var s=n(5893),o=n(1151);const r={sidebar_title:"Core Features",sidebar_position:25},c="Concepts",i={id:"concepts/index",title:"Concepts",description:"zrok was designed to make sharing local resources both secure and easy. In this section of the zrok documentation, we'll tour through all of the most important features.",source:"@site/../docs/concepts/index.md",sourceDirName:"concepts",slug:"/concepts/",permalink:"/docs/concepts/",draft:!1,unlisted:!1,editUrl:"https://github.com/openziti/zrok/blob/main/docs/../docs/concepts/index.md",tags:[],version:"current",sidebarPosition:25,frontMatter:{sidebar_title:"Core Features",sidebar_position:25},sidebar:"tutorialSidebar",previous:{title:"Getting Started",permalink:"/docs/getting-started"},next:{title:"Private Shares",permalink:"/docs/concepts/sharing-private"}},a={},d=[];function l(e){const t={a:"a",code:"code",h1:"h1",p:"p",...(0,o.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"concepts",children:"Concepts"}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.code,{children:"zrok"})," was designed to make sharing local resources both secure and easy. In this section of the ",(0,s.jsx)(t.code,{children:"zrok"})," documentation, we'll tour through all of the most important features."]}),"\n",(0,s.jsxs)(t.p,{children:["Sharing with ",(0,s.jsx)(t.code,{children:"zrok"})," can be either ",(0,s.jsx)(t.a,{href:"/docs/concepts/sharing-public",children:(0,s.jsx)(t.code,{children:"public"})})," or ",(0,s.jsx)(t.a,{href:"/docs/concepts/sharing-private",children:(0,s.jsx)(t.code,{children:"private"})}),".\nNaturally, regular web-based resources can be shared but ",(0,s.jsx)(t.code,{children:"zrok"})," also includes support for sharing raw ",(0,s.jsx)(t.a,{href:"/docs/concepts/tunnels",children:"TCP"})," and ",(0,s.jsx)(t.a,{href:"/docs/concepts/tunnels",children:"UDP"})," network connections, and also includes a ",(0,s.jsx)(t.a,{href:"/docs/concepts/files",children:"website and file sharing"})," feature."]}),"\n",(0,s.jsxs)(t.p,{children:["Learn about ",(0,s.jsx)(t.code,{children:"zrok"})," ",(0,s.jsx)(t.a,{href:"/docs/concepts/hosting",children:"hosting here"}),", including instructions on how to ",(0,s.jsxs)(t.a,{href:"/docs/guides/self-hosting/self_hosting_guide",children:["install your own ",(0,s.jsx)(t.code,{children:"zrok"})," instance"]}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,o.a)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>i,a:()=>c});var s=n(7294);const o={},r=s.createContext(o);function c(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8945],{3033:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>d});var s=n(5893),o=n(1151);const r={sidebar_title:"Core Features",sidebar_position:25},c="Concepts",i={id:"concepts/index",title:"Concepts",description:"zrok was designed to make sharing local resources both secure and easy. In this section of the zrok documentation, we'll tour through all of the most important features.",source:"@site/../docs/concepts/index.md",sourceDirName:"concepts",slug:"/concepts/",permalink:"/docs/concepts/",draft:!1,unlisted:!1,editUrl:"https://github.com/openziti/zrok/blob/main/docs/../docs/concepts/index.md",tags:[],version:"current",sidebarPosition:25,frontMatter:{sidebar_title:"Core Features",sidebar_position:25},sidebar:"tutorialSidebar",previous:{title:"Getting Started",permalink:"/docs/getting-started"},next:{title:"Private Shares",permalink:"/docs/concepts/sharing-private"}},a={},d=[];function l(e){const t={a:"a",code:"code",h1:"h1",p:"p",...(0,o.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"concepts",children:"Concepts"}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.code,{children:"zrok"})," was designed to make sharing local resources both secure and easy. In this section of the ",(0,s.jsx)(t.code,{children:"zrok"})," documentation, we'll tour through all of the most important features."]}),"\n",(0,s.jsxs)(t.p,{children:["Sharing with ",(0,s.jsx)(t.code,{children:"zrok"})," can be either ",(0,s.jsx)(t.a,{href:"/docs/concepts/sharing-public",children:(0,s.jsx)(t.code,{children:"public"})})," or ",(0,s.jsx)(t.a,{href:"/docs/concepts/sharing-private",children:(0,s.jsx)(t.code,{children:"private"})}),".\nNaturally, regular web-based resources can be shared but ",(0,s.jsx)(t.code,{children:"zrok"})," also includes support for sharing raw ",(0,s.jsx)(t.a,{href:"/docs/concepts/tunnels",children:"TCP"})," and ",(0,s.jsx)(t.a,{href:"/docs/concepts/tunnels",children:"UDP"})," network connections, and also includes a ",(0,s.jsx)(t.a,{href:"/docs/concepts/files",children:"website and file sharing"})," feature."]}),"\n",(0,s.jsxs)(t.p,{children:["Learn about ",(0,s.jsx)(t.code,{children:"zrok"})," ",(0,s.jsx)(t.a,{href:"/docs/concepts/hosting",children:"hosting here"}),", including instructions on how to ",(0,s.jsxs)(t.a,{href:"/docs/guides/self-hosting/linux",children:["install your own ",(0,s.jsx)(t.code,{children:"zrok"})," instance"]}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,o.a)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>i,a:()=>c});var s=n(7294);const o={},r=s.createContext(o);function c(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cda0d2e5.3c74e878.js b/assets/js/cda0d2e5.3c74e878.js deleted file mode 100644 index bdcc0081..00000000 --- a/assets/js/cda0d2e5.3c74e878.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5889],{9836:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>v,contentTitle:()=>k,default:()=>z,frontMatter:()=>b,metadata:()=>f,toc:()=>y});var s=r(5893),i=r(1151),o=r(7294),t=r(4866),a=r(5518);const d=function(e){const[n,r]=(0,o.useState)(null);return(0,o.useEffect)((()=>{["Mac OS","Windows","Linux"].includes(a.BF)?r(a.BF):r("Linux")}),[]),(0,s.jsx)(s.Fragment,{children:(0,s.jsx)(t.Z,{...e,defaultValue:n,children:e.children})})};var c=r(5162),l=r(1326),h=r(2753);function p(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.a)(),...e.components},{Details:r}=n;return r||function(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"goal",children:"Goal"}),"\n",(0,s.jsx)(n.p,{children:"Proxy a reserved public subdomain to a backend target with an always-on Linux system service."}),"\n",(0,s.jsx)(n.h2,{id:"how-it-works",children:"How it Works"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"zrok-share"})," package creates a ",(0,s.jsx)(n.code,{children:"zrok-share.service"})," unit in systemd. The administrator edits the service's configuration file to specify the:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"zrok environment enable token"}),"\n",(0,s.jsxs)(n.li,{children:["target URL or files to be shared and backend mode, e.g. ",(0,s.jsx)(n.code,{children:"proxy"})]}),"\n",(0,s.jsx)(n.li,{children:"authentication options, if wanted"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"When the service starts it will:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["enable the zrok environment unless ",(0,s.jsx)(n.code,{children:"/var/lib/zrok-share/.zrok/environment.json"})," exists"]}),"\n",(0,s.jsxs)(n.li,{children:["reserve a public subdomain for the service unless ",(0,s.jsx)(n.code,{children:"/var/lib/zrok-share/.zrok/reserved.json"})," exists"]}),"\n",(0,s.jsxs)(n.li,{children:["start sharing the target specified as ",(0,s.jsx)(n.code,{children:"ZROK_TARGET"})," in the environment file"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Set up ",(0,s.jsx)(n.code,{children:"zrok"}),"'s Linux package repository by following ",(0,s.jsx)(n.a,{href:"/docs/guides/install/linux#install-zrok-from-the-repository",children:"the Linux install guide"}),", or run this one-liner to complete the repo setup and install packages."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl -sSLf https://get.openziti.io/install.bash \\\n| sudo bash -s zrok-share\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["If you set up the repository by following the guide, then also install the ",(0,s.jsx)(n.code,{children:"zrok-share"})," package. This package provides the systemd service."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="Ubuntu, Debian"',children:"sudo apt install zrok-share\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="Fedora, Rocky"',children:"sudo dnf install zrok-share\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(r,{children:[(0,s.jsx)("summary",{children:"Ansible Playbook"}),(0,s.jsxs)(h.Z,{title:"Set up package repository and install zrok-share",children:[l.Z,"\n- name: Install zrok-share package\n gather_facts: false\n hosts: all \n become: true\n tasks:\n - name: Install zrok-share\n ansible.builtin.package:\n name: zrok-share\n state: present\n\n - name: Copy env config from Ansible controller to target\n copy:\n dest: /opt/openziti/etc/zrok/zrok-share.env\n src: /opt/openziti/etc/zrok/zrok-share.env\n\n - name: Enable and restart service\n systemd:\n name: zrok-share\n enabled: yes\n state: restarted\n daemon_reload: yes\n\n - name: Wait for service\n systemd:\n name: zrok-share\n state: started\n register: service_status\n until: service_status.status.ActiveState == 'active'\n retries: 30\n delay: 1\n"]})]}),"\n",(0,s.jsx)(n.h2,{id:"enable",children:"Enable"}),"\n",(0,s.jsx)(n.p,{children:"Save the enable token from the zrok console in the configuration file."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_ENABLE_TOKEN="14cbfca9772f"\n'})}),"\n",(0,s.jsx)(n.h2,{id:"name-your-share",children:"Name your Share"}),"\n",(0,s.jsxs)(n.p,{children:["This unique name becomes part of the domain name of the share, e.g. ",(0,s.jsx)(n.code,{children:"https://my-prod-app.in.zrok.io"}),". A random name is generated if you don't specify one."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_UNIQUE_NAME="my-prod-app"\n'})}),"\n",(0,s.jsx)(n.h2,{id:"use-cases",children:"Use Cases"}),"\n",(0,s.jsxs)(n.p,{children:["You may change the target for the current backend mode, e.g. ",(0,s.jsx)(n.code,{children:"proxy"}),", by editing the configuration file and restarting the service. The reserved subdomain will remain the same."]}),"\n",(0,s.jsxs)(n.p,{children:["You may switch between backend modes or change authentication options by deleting ",(0,s.jsx)(n.code,{children:"/var/lib/zrok-share/.zrok/reserved.json"})," and restarting the service. A new subdomain will be reserved."]}),"\n",(0,s.jsx)(n.h3,{id:"proxy-a-web-server",children:"Proxy a Web Server"}),"\n",(0,s.jsx)(n.p,{children:"Proxy a reserved subdomain to an existing web server. The web server could be on a private network or on the same host as zrok."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_TARGET="http://127.0.0.1:3000"\nZROK_BACKEND_MODE="proxy"\n'})}),"\n",(0,s.jsxs)(n.p,{children:["If your HTTPS server has an unverifiable TLS server certificate then you must set ",(0,s.jsx)(n.code,{children:"--insecure"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_INSECURE="--insecure"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"serve-static-files",children:"Serve Static Files"}),"\n",(0,s.jsxs)(n.p,{children:["Run zrok's embedded web server to serve the files in a directory. If there's an ",(0,s.jsx)(n.code,{children:"index.html"})," file in the directory then visitors will see that web page in their browser, otherwise they'll see a generated index of the files. The directory must be readable by 'other', e.g. ",(0,s.jsx)(n.code,{children:"chmod -R o+rX /var/www/html"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_TARGET="/var/www/html"\nZROK_BACKEND_MODE="web"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"caddy-server",children:"Caddy Server"}),"\n",(0,s.jsx)(n.p,{children:"Use zrok's built-in Caddy server to serve static files or as a reverse proxy to multiple web servers with various HTTP routes or as a load-balanced set. A sample Caddyfile is available in the path shown."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_TARGET="/opt/openziti/etc/zrok/multiple_upstream.Caddyfile"\nZROK_BACKEND_MODE="caddy"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"network-drive",children:"Network Drive"}),"\n",(0,s.jsxs)(n.p,{children:["This uses zrok's ",(0,s.jsx)(n.code,{children:"drive"})," backend mode to serve a directory of static files as a virtual network drive. The directory must be readable by 'other', e.g. ",(0,s.jsx)(n.code,{children:"chmod -R o+rX /usr/share/doc"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_TARGET="/usr/share/doc"\nZROK_BACKEND_MODE="drive"\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://blog.openziti.io/zrok-drives-an-early-preview",children:"Learn more about this feature in this blog post"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"authentication",children:"Authentication"}),"\n",(0,s.jsx)(n.p,{children:"You can limit access to certain email addresses with OAuth or require a password."}),"\n",(0,s.jsx)(n.h3,{id:"oauth",children:"OAuth"}),"\n",(0,s.jsx)(n.p,{children:"You can require that visitors authenticate with an email address that matches at least one of the suffixes you specify. Add the following to the configuration file."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_OAUTH_PROVIDER="github" # or google\nZROK_OAUTH_EMAILS="alice@example.com *@acme.example.com"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"password",children:"Password"}),"\n",(0,s.jsx)(n.p,{children:"Enable HTTP basic authentication by adding the following to the configuration file."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_BASIC_AUTH="user:passwd"\n'})}),"\n",(0,s.jsx)(n.h2,{id:"start-the-service",children:"Start the Service"}),"\n",(0,s.jsx)(n.p,{children:"Start the service, and check the zrok console or the service log for the reserved subdomain."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="run now and at startup"',children:"sudo systemctl enable --now zrok-share.service\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title="run now"',children:"sudo systemctl restart zrok-share.service\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"journalctl -u zrok-share.service\n"})}),"\n",(0,s.jsx)(n.h2,{id:"compatibility",children:"Compatibility"}),"\n",(0,s.jsxs)(n.p,{children:["The Linux distribution must have a package manager that understands the ",(0,s.jsx)(n.code,{children:".deb"})," or ",(0,s.jsx)(n.code,{children:".rpm"})," format and be running systemd v232 or newer. The service was tested with:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Ubuntu 20.04, 22.04, 23.04"}),"\n",(0,s.jsx)(n.li,{children:"Debian 11 12"}),"\n",(0,s.jsx)(n.li,{children:"Rocky 8, 9"}),"\n",(0,s.jsx)(n.li,{children:"Fedora 37, 38"}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"package-contents",children:"Package Contents"}),"\n",(0,s.jsxs)(n.p,{children:["The files included in the ",(0,s.jsx)(n.code,{children:"zrok-share"})," package are sourced ",(0,s.jsx)(n.a,{href:"https://github.com/openziti/zrok/tree/main/nfpm",children:"here in GitHub"}),"."]})]})}function u(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(p,{...e})}):p(e)}function m(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"goal",children:"Goal"}),"\n",(0,s.jsx)(n.p,{children:"Proxy a reserved public subdomain to a backend target with an always-on Docker Compose service."}),"\n",(0,s.jsx)(n.h2,{id:"how-it-works",children:"How it Works"}),"\n",(0,s.jsx)(n.p,{children:"The Docker Compose project uses your zrok account token to reserve a public subdomain and keep sharing the backend\ntarget."}),"\n",(0,s.jsx)(n.p,{children:"When the project runs it will:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["enable a zrok environment unless ",(0,s.jsx)(n.code,{children:"/mnt/.zrok/environment.json"})," exists in the ",(0,s.jsx)(n.code,{children:"zrok_env"})," volume"]}),"\n",(0,s.jsxs)(n.li,{children:["reserve a public subdomain for the service unless ",(0,s.jsx)(n.code,{children:"/mnt/.zrok/reserved.json"})," exists"]}),"\n",(0,s.jsxs)(n.li,{children:["start sharing the target specified in the ",(0,s.jsx)(n.code,{children:"ZROK_TARGET"})," environment variable"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"create-the-docker-project",children:"Create the Docker Project"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Make a folder on your computer to use as a Docker Compose project for your zrok public share with a reserved subdomain and switch to the new directory in your terminal."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Download ",(0,s.jsxs)(n.a,{href:"pathname:///zrok-public-reserved/compose.yml",children:["the reserved public share ",(0,s.jsx)(n.code,{children:"compose.yml"})," project file"]})," into the same directory."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Copy your zrok account's enable token from the zrok web console to your clipboard and paste it in a file named ",(0,s.jsx)(n.code,{children:".env"})," in the same folder like this:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title=".env"',children:'ZROK_ENABLE_TOKEN="8UL9-48rN0ua"\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Name the Share"}),"\n",(0,s.jsxs)(n.p,{children:["This unique name becomes part of the domain name of the share, e.g. ",(0,s.jsx)(n.code,{children:"https://my-prod-app.in.zrok.io"}),". A random name is generated if you don't specify one."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title=".env"',children:'ZROK_UNIQUE_NAME="my-prod-app"\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Run the Compose project to start sharing the built-in demo web server. Be sure to ",(0,s.jsx)(n.code,{children:"--detach"})," so the project runs in the background if you want it to auto-restart when your computer reboots."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker compose up --detach\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Get the public share URL from the output of the ",(0,s.jsx)(n.code,{children:"zrok-share"})," service or by peeking in the zrok console where the share will appear in the graph."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker compose logs zrok-share\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-buttonless",metastring:'title="Output"',children:"zrok-public-share-1 | https://w6r1vesearkj.in.zrok.io/\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This concludes the minimum steps to begin sharing the demo web server. Read on to learn how to pivot to sharing any website or web service by leveraging additional zrok backend modes."}),"\n",(0,s.jsx)(n.h2,{id:"proxy-any-web-server",children:"Proxy Any Web Server"}),"\n",(0,s.jsxs)(n.p,{children:["The simplest way to share your existing HTTP server is to set ",(0,s.jsx)(n.code,{children:"ZROK_TARGET"})," (e.g. ",(0,s.jsx)(n.code,{children:"https://example.com"}),") in the environment of the ",(0,s.jsx)(n.code,{children:"docker compose up"})," command. When you restart the share will auto-configure for that URL."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title=".env"',children:'ZROK_TARGET="http://example.com:8080"\n'})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker compose down && docker compose up\n"})}),"\n",(0,s.jsx)(n.h2,{id:"require-authentication",children:"Require Authentication"}),"\n",(0,s.jsx)(n.p,{children:"You can require a password or an OAuth login with certain email addresses."}),"\n",(0,s.jsx)(n.h3,{id:"oauth-email",children:"OAuth Email"}),"\n",(0,s.jsxs)(n.p,{children:["You can allow specific email addresses or an email domain by setting ",(0,s.jsx)(n.code,{children:"ZROK_OAUTH_PROVIDER"})," to ",(0,s.jsx)(n.code,{children:"github"})," or ",(0,s.jsx)(n.code,{children:"google"})," and\n",(0,s.jsx)(n.code,{children:"ZROK_SHARE_OPTS"})," to specify additional command-line options to ",(0,s.jsx)(n.code,{children:"zrok reserve public"}),". Read more about the OAuth\nfeatures in ",(0,s.jsx)(n.a,{href:"https://blog.openziti.io/the-zrok-oauth-public-frontend",children:"this blog post"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:'title=".env"',children:'ZROK_OAUTH_PROVIDER="github"\nZROK_OAUTH_EMAILS="alice@example.com *@acme.example.com"\n'})}),"\n",(0,s.jsx)(n.h2,{id:"caddy-is-powerful",children:"Caddy is Powerful"}),"\n",(0,s.jsxs)(n.p,{children:["The reserved public share project uses zrok's default backend mode, ",(0,s.jsx)(n.code,{children:"proxy"}),". Another backend mode, ",(0,s.jsx)(n.code,{children:"caddy"}),", accepts a path to ",(0,s.jsx)(n.a,{href:"https://caddyserver.com/docs/caddyfile",children:"a Caddyfile"})," as the value of ",(0,s.jsx)(n.code,{children:"ZROK_TARGET"})," (",(0,s.jsx)(n.a,{href:"https://github.com/openziti/zrok/tree/main/etc/caddy",children:"zrok Caddyfile examples"}),")."]}),"\n",(0,s.jsxs)(n.p,{children:["Caddy is the most powerful and flexible backend mode in zrok. You must reserve a new public subdomain whenever you switch the backend mode, so using ",(0,s.jsx)(n.code,{children:"caddy"})," reduces the risk that you'll have to share a new frontend URL with your users."]}),"\n",(0,s.jsx)(n.p,{children:"With Caddy, you can balance the workload for websites or web services or share static sites and files or all of the above at the same time. You can update the Caddyfile and restart the Docker Compose project to start sharing the new configuration with the same reserved public subdomain."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Create a Caddyfile. This example demonstrates proxying two HTTP servers with a weighted round-robin load balancer."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-console",metastring:'title="Caddyfile"',children:"http:// {\n # zrok requires this bind address template\n bind {{ .ZrokBindAddress }}\n reverse_proxy /* {\n to http://httpbin1:8080 http://httpbin2:8080\n lb_policy weighted_round_robin 3 2\n }\n}\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Create a file ",(0,s.jsx)(n.code,{children:"compose.override.yml"}),". This example adds two ",(0,s.jsx)(n.code,{children:"httpbin"})," containers for load balancing, and mounts the Caddyfile into the container."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="compose.override.yml"',children:"services:\n httpbin1:\n image: mccutchen/go-httpbin # 8080/tcp\n httpbin2:\n image: mccutchen/go-httpbin # 8080/tcp\n zrok-share:\n volumes:\n - ./Caddyfile:/mnt/.zrok/Caddyfile\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Start a new Docker Compose project or delete the existing state volume."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker compose down --volumes\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["If you prefer to keep using the same zrok environment with the new share then delete ",(0,s.jsx)(n.code,{children:"/mnt/.zrok/reserved.json"})," instead of the entire volume."]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Run the project to load the new configuration."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker compose up --detach\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Note the new reserved share URL from the log."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docker compose logs zrok-share\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-buttonless",metastring:'title="Output"',children:"INFO: zrok public URL: https://88s803f2qvao.in.zrok.io/\n"})}),"\n"]}),"\n"]})]})}function x(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(m,{...e})}):m(e)}var j=r(9965),g=r(4996);const b={title:"zrok frontdoor",sidebar_label:"frontdoor",sidebar_position:20,hide_table_of_contents:!0},k=void 0,f={id:"guides/frontdoor",title:"zrok frontdoor",description:"zrok frontdoor is the heavy-duty front door to your app or site. It makes your website or app available to your online audience through the shield of zrok.io's hardened, managed frontends.",source:"@site/../docs/guides/frontdoor.mdx",sourceDirName:"guides",slug:"/guides/frontdoor",permalink:"/docs/guides/frontdoor",draft:!1,unlisted:!1,editUrl:"https://github.com/openziti/zrok/blob/main/docs/../docs/guides/frontdoor.mdx",tags:[],version:"current",sidebarPosition:20,frontMatter:{title:"zrok frontdoor",sidebar_label:"frontdoor",sidebar_position:20,hide_table_of_contents:!0},sidebar:"tutorialSidebar",previous:{title:"Windows",permalink:"/docs/guides/install/windows"},next:{title:"Permission Modes",permalink:"/docs/guides/permission-modes"}},v={},y=[{value:"Overview",id:"overview",level:2},{value:"Choose your OS",id:"choose-your-os",level:2},{value:"Concepts",id:"concepts",level:2}];function w(e){const n={a:"a",code:"code",h2:"h2",p:"p",strong:"strong",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"zrok frontdoor"})," is the heavy-duty front door to your app or site. It makes your website or app available to your online audience through the shield of zrok.io's hardened, managed frontends."]}),"\n",(0,s.jsx)("iframe",{width:"100%",height:"315",src:"https://www.youtube.com/embed/5Vi8GKuTi_I",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowfullscreen:!0}),"\n",(0,s.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,s.jsxs)(n.p,{children:["zrok frontends are the parts of zrok that proxy incoming public web traffic to zrok backend shares via OpenZiti. When you use zrok with a ",(0,s.jsx)(n.code,{children:"zrok.io"})," frontend, you're using ",(0,s.jsx)(n.strong,{children:"zrok frontdoor"}),". ",(0,s.jsx)(n.code,{children:"zrok.io"})," is zrok-as-a-service by NetFoundry, the team behind OpenZiti. You need a free account to use ",(0,s.jsx)(n.strong,{children:"zrok frontdoor"}),"."]}),"\n",(0,s.jsx)(j.Z,{alt:"frontdoor diagram",sources:{light:(0,g.Z)("/img/zrok-frontdoor-light-mode.svg"),dark:(0,g.Z)("/img/zrok-frontdoor-dark-mode.svg")}}),"\n",(0,s.jsx)(n.h2,{id:"choose-your-os",children:"Choose your OS"}),"\n",(0,s.jsx)(n.p,{children:"Choose between installing the Linux package or running zrok with Docker (Linux, macOS, or Windows)."}),"\n",(0,s.jsxs)(d,{queryString:"os",values:[{label:"Linux",value:"Linux"},{label:"macOS",value:"Mac OS"},{label:"Windows",value:"Windows"}],children:[(0,s.jsxs)(c.Z,{value:"Linux",children:[(0,s.jsxs)(n.p,{children:["On Linux, zrok frontdoor is implemented natively as a system service provided by the ",(0,s.jsx)(n.code,{children:"zrok-share"})," DEB or RPM package."]}),(0,s.jsxs)(n.p,{children:["If you'd prefer to run zrok in Docker instead of installing the package then you can follow the Docker instructions. With Docker, the steps are the same for Linux, ",(0,s.jsx)(n.a,{href:"./?os=Mac+OS",children:"macOS"}),", and ",(0,s.jsx)(n.a,{href:"./?os=Windows",children:"Windows"}),"."]}),(0,s.jsx)(u,{})]}),(0,s.jsxs)(c.Z,{value:"Mac OS",children:[(0,s.jsx)(n.p,{children:"On macOS, zrok frontdoor is implemented as a Docker Compose project which reserves a public subdomain for your website or service."}),(0,s.jsx)(x,{})]}),(0,s.jsxs)(c.Z,{value:"Windows",children:[(0,s.jsx)(n.p,{children:"On Windows, zrok frontdoor is implemented as a Docker Compose project which reserves a public subdomain for your website or service."}),(0,s.jsx)(x,{})]})]}),"\n",(0,s.jsx)(n.h2,{id:"concepts",children:"Concepts"}),"\n",(0,s.jsxs)(n.p,{children:["Overview of ",(0,s.jsx)(n.a,{href:"/docs/concepts/sharing-reserved",children:"zrok reserved shares"})]})]})}function z(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(w,{...e})}):w(e)}},2753:(e,n,r)=>{r.d(n,{Z:()=>t});r(7294);var s=r(1272),i=r(9286),o=r(5893);const t=e=>{let{title:n,children:r}=e;const t=r.map((e=>"string"==typeof e?e.trim():s.ZP.dump(e).trim())).join("\n\n");return(0,o.jsx)("div",{children:(0,o.jsx)(i.Z,{language:"yaml",title:n,children:t})})}},1326:(e,n,r)=>{r.d(n,{Z:()=>s});const s=[{name:"Set up zrok Package Repo",gather_facts:!0,hosts:"all",become:!0,tasks:[{name:"Set up apt repo",when:'ansible_os_family == "Debian"',block:[{name:"Install playbook dependencies","ansible.builtin.package":{name:["gnupg"],state:"present"}},{name:"Fetch armored pubkey","ansible.builtin.uri":{url:"https://get.openziti.io/tun/package-repos.gpg",return_content:"yes"},register:"armored_pubkey"},{name:"Dearmor pubkey","ansible.builtin.shell":'gpg --dearmor --output /usr/share/keyrings/openziti.gpg <<< "{{ armored_pubkey.content }}"\n',args:{creates:"/usr/share/keyrings/openziti.gpg",executable:"/bin/bash"}},{name:"Set pubkey filemode","ansible.builtin.file":{path:"/usr/share/keyrings/openziti.gpg",mode:"a+rX"}},{name:"Install OpenZiti repo deb source","ansible.builtin.copy":{dest:"/etc/apt/sources.list.d/openziti-release.list",content:"deb [signed-by=/usr/share/keyrings/openziti.gpg] https://packages.openziti.org/zitipax-openziti-deb-stable debian main\n"}},{name:"Refresh Repo Sources","ansible.builtin.apt":{update_cache:"yes",cache_valid_time:3600}}]},{name:"Set up yum repo",when:'ansible_os_family == "RedHat"',block:[{name:"Install OpenZiti repo rpm source","ansible.builtin.yum_repository":{name:"OpenZitiRelease",description:"OpenZiti Release",baseurl:"https://packages.openziti.org/zitipax-openziti-rpm-stable/redhat/$basearch",enabled:"yes",gpgkey:"https://packages.openziti.org/zitipax-openziti-rpm-stable/redhat/$basearch/repodata/repomd.xml.key",repo_gpgcheck:"yes",gpgcheck:"no"}}]}]}]}}]); \ No newline at end of file diff --git a/assets/js/cda0d2e5.a85a9a83.js b/assets/js/cda0d2e5.a85a9a83.js new file mode 100644 index 00000000..30982fd3 --- /dev/null +++ b/assets/js/cda0d2e5.a85a9a83.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5889],{8854:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>j,contentTitle:()=>x,default:()=>y,frontMatter:()=>b,metadata:()=>k,toc:()=>v});var s=n(5893),i=n(1151),t=n(7294),o=n(4866),a=n(5518);const l=function(e){const[r,n]=(0,t.useState)(null);return(0,t.useEffect)((()=>{["Mac OS","Windows","Linux"].includes(a.BF)?n(a.BF):n("Linux")}),[]),(0,s.jsx)(s.Fragment,{children:(0,s.jsx)(o.Z,{...e,defaultValue:r,children:e.children})})};var d=n(5162),c=n(1326),h=n(2753);function p(e){const r={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.a)(),...e.components},{Details:n}=r;return n||function(e,r){throw new Error("Expected "+(r?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(r.h2,{id:"goal",children:"Goal"}),"\n",(0,s.jsx)(r.p,{children:"Proxy a reserved public subdomain to a backend target with an always-on Linux system service."}),"\n",(0,s.jsx)(r.h2,{id:"how-it-works",children:"How it Works"}),"\n",(0,s.jsxs)(r.p,{children:["The ",(0,s.jsx)(r.code,{children:"zrok-share"})," package creates a ",(0,s.jsx)(r.code,{children:"zrok-share.service"})," unit in systemd. The administrator edits the service's configuration file to specify the:"]}),"\n",(0,s.jsxs)(r.ol,{children:["\n",(0,s.jsx)(r.li,{children:"zrok environment enable token"}),"\n",(0,s.jsxs)(r.li,{children:["target URL or files to be shared and backend mode, e.g. ",(0,s.jsx)(r.code,{children:"proxy"})]}),"\n",(0,s.jsx)(r.li,{children:"authentication options, if wanted"}),"\n"]}),"\n",(0,s.jsx)(r.p,{children:"When the service starts it will:"}),"\n",(0,s.jsxs)(r.ol,{children:["\n",(0,s.jsxs)(r.li,{children:["enable the zrok environment unless ",(0,s.jsx)(r.code,{children:"/var/lib/zrok-share/.zrok/environment.json"})," exists"]}),"\n",(0,s.jsxs)(r.li,{children:["reserve a public subdomain for the service unless ",(0,s.jsx)(r.code,{children:"/var/lib/zrok-share/.zrok/reserved.json"})," exists"]}),"\n",(0,s.jsxs)(r.li,{children:["start sharing the target specified as ",(0,s.jsx)(r.code,{children:"ZROK_TARGET"})," in the environment file"]}),"\n"]}),"\n",(0,s.jsx)(r.h2,{id:"installation",children:"Installation"}),"\n",(0,s.jsxs)(r.ol,{children:["\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsxs)(r.p,{children:["Set up ",(0,s.jsx)(r.code,{children:"zrok"}),"'s Linux package repository by following ",(0,s.jsx)(r.a,{href:"/docs/guides/install/linux#install-zrok-from-the-repository",children:"the Linux install guide"}),", or run this one-liner to complete the repo setup and install packages."]}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",children:"curl -sSLf https://get.openziti.io/install.bash \\\n| sudo bash -s zrok-share\n"})}),"\n"]}),"\n",(0,s.jsxs)(r.li,{children:["\n",(0,s.jsxs)(r.p,{children:["If you set up the repository by following the guide, then also install the ",(0,s.jsx)(r.code,{children:"zrok-share"})," package. This package provides the systemd service."]}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",metastring:'title="Ubuntu, Debian"',children:"sudo apt install zrok-share\n"})}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",metastring:'title="Fedora, Rocky"',children:"sudo dnf install zrok-share\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n,{children:[(0,s.jsx)("summary",{children:"Ansible Playbook"}),(0,s.jsxs)(h.Z,{title:"Set up package repository and install zrok-share",children:[c.Z,"\n- name: Install zrok-share package\n gather_facts: false\n hosts: all \n become: true\n tasks:\n - name: Install zrok-share\n ansible.builtin.package:\n name: zrok-share\n state: present\n\n - name: Copy env config from Ansible controller to target\n copy:\n dest: /opt/openziti/etc/zrok/zrok-share.env\n src: /opt/openziti/etc/zrok/zrok-share.env\n\n - name: Enable and restart service\n systemd:\n name: zrok-share\n enabled: yes\n state: restarted\n daemon_reload: yes\n\n - name: Wait for service\n systemd:\n name: zrok-share\n state: started\n register: service_status\n until: service_status.status.ActiveState == 'active'\n retries: 30\n delay: 1\n"]})]}),"\n",(0,s.jsx)(r.h2,{id:"enable",children:"Enable"}),"\n",(0,s.jsx)(r.p,{children:"Save the enable token from the zrok console in the configuration file."}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_ENABLE_TOKEN="14cbfca9772f"\n'})}),"\n",(0,s.jsx)(r.h2,{id:"name-your-share",children:"Name your Share"}),"\n",(0,s.jsxs)(r.p,{children:["This unique name becomes part of the domain name of the share, e.g. ",(0,s.jsx)(r.code,{children:"https://my-prod-app.in.zrok.io"}),". A random name is generated if you don't specify one."]}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_UNIQUE_NAME="my-prod-app"\n'})}),"\n",(0,s.jsx)(r.h2,{id:"use-cases",children:"Use Cases"}),"\n",(0,s.jsxs)(r.p,{children:["You may change the target for the current backend mode, e.g. ",(0,s.jsx)(r.code,{children:"proxy"}),", by editing the configuration file and restarting the service. The reserved subdomain will remain the same."]}),"\n",(0,s.jsxs)(r.p,{children:["You may switch between backend modes or change authentication options by deleting ",(0,s.jsx)(r.code,{children:"/var/lib/zrok-share/.zrok/reserved.json"})," and restarting the service. A new subdomain will be reserved."]}),"\n",(0,s.jsx)(r.h3,{id:"proxy-a-web-server",children:"Proxy a Web Server"}),"\n",(0,s.jsx)(r.p,{children:"Proxy a reserved subdomain to an existing web server. The web server could be on a private network or on the same host as zrok."}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_TARGET="http://127.0.0.1:3000"\nZROK_BACKEND_MODE="proxy"\n'})}),"\n",(0,s.jsxs)(r.p,{children:["If your HTTPS server has an unverifiable TLS server certificate then you must set ",(0,s.jsx)(r.code,{children:"--insecure"}),"."]}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_INSECURE="--insecure"\n'})}),"\n",(0,s.jsx)(r.h3,{id:"serve-static-files",children:"Serve Static Files"}),"\n",(0,s.jsxs)(r.p,{children:["Run zrok's embedded web server to serve the files in a directory. If there's an ",(0,s.jsx)(r.code,{children:"index.html"})," file in the directory then visitors will see that web page in their browser, otherwise they'll see a generated index of the files. The directory must be readable by 'other', e.g. ",(0,s.jsx)(r.code,{children:"chmod -R o+rX /var/www/html"}),"."]}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_TARGET="/var/www/html"\nZROK_BACKEND_MODE="web"\n'})}),"\n",(0,s.jsx)(r.h3,{id:"caddy-server",children:"Caddy Server"}),"\n",(0,s.jsx)(r.p,{children:"Use zrok's built-in Caddy server to serve static files or as a reverse proxy to multiple web servers with various HTTP routes or as a load-balanced set. A sample Caddyfile is available in the path shown."}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_TARGET="/opt/openziti/etc/zrok/multiple_upstream.Caddyfile"\nZROK_BACKEND_MODE="caddy"\n'})}),"\n",(0,s.jsx)(r.h3,{id:"network-drive",children:"Network Drive"}),"\n",(0,s.jsxs)(r.p,{children:["This uses zrok's ",(0,s.jsx)(r.code,{children:"drive"})," backend mode to serve a directory of static files as a virtual network drive. The directory must be readable by 'other', e.g. ",(0,s.jsx)(r.code,{children:"chmod -R o+rX /usr/share/doc"}),"."]}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_TARGET="/usr/share/doc"\nZROK_BACKEND_MODE="drive"\n'})}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)(r.a,{href:"https://blog.openziti.io/zrok-drives-an-early-preview",children:"Learn more about this feature in this blog post"}),"."]}),"\n",(0,s.jsx)(r.h2,{id:"authentication",children:"Authentication"}),"\n",(0,s.jsx)(r.p,{children:"You can limit access to certain email addresses with OAuth or require a password."}),"\n",(0,s.jsx)(r.h3,{id:"oauth",children:"OAuth"}),"\n",(0,s.jsx)(r.p,{children:"You can require that visitors authenticate with an email address that matches at least one of the suffixes you specify. Add the following to the configuration file."}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_OAUTH_PROVIDER="github" # or google\nZROK_OAUTH_EMAILS="alice@example.com *@acme.example.com"\n'})}),"\n",(0,s.jsx)(r.h3,{id:"password",children:"Password"}),"\n",(0,s.jsx)(r.p,{children:"Enable HTTP basic authentication by adding the following to the configuration file."}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",metastring:'title="/opt/openziti/etc/zrok/zrok-share.env"',children:'ZROK_BASIC_AUTH="user:passwd"\n'})}),"\n",(0,s.jsx)(r.h2,{id:"start-the-service",children:"Start the Service"}),"\n",(0,s.jsx)(r.p,{children:"Start the service, and check the zrok console or the service log for the reserved subdomain."}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",metastring:'title="run now and at startup"',children:"sudo systemctl enable --now zrok-share.service\n"})}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",metastring:'title="run now"',children:"sudo systemctl restart zrok-share.service\n"})}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-bash",children:"journalctl -u zrok-share.service\n"})}),"\n",(0,s.jsx)(r.h2,{id:"compatibility",children:"Compatibility"}),"\n",(0,s.jsxs)(r.p,{children:["The Linux distribution must have a package manager that understands the ",(0,s.jsx)(r.code,{children:".deb"})," or ",(0,s.jsx)(r.code,{children:".rpm"})," format and be running systemd v232 or newer. The service was tested with:"]}),"\n",(0,s.jsxs)(r.ul,{children:["\n",(0,s.jsx)(r.li,{children:"Ubuntu 20.04, 22.04, 23.04"}),"\n",(0,s.jsx)(r.li,{children:"Debian 11 12"}),"\n",(0,s.jsx)(r.li,{children:"Rocky 8, 9"}),"\n",(0,s.jsx)(r.li,{children:"Fedora 37, 38"}),"\n"]}),"\n",(0,s.jsx)(r.h2,{id:"package-contents",children:"Package Contents"}),"\n",(0,s.jsxs)(r.p,{children:["The files included in the ",(0,s.jsx)(r.code,{children:"zrok-share"})," package are sourced ",(0,s.jsx)(r.a,{href:"https://github.com/openziti/zrok/tree/main/nfpm",children:"here in GitHub"}),"."]})]})}function u(e={}){const{wrapper:r}={...(0,i.a)(),...e.components};return r?(0,s.jsx)(r,{...e,children:(0,s.jsx)(p,{...e})}):p(e)}var m=n(9965),g=n(4996);const b={title:"zrok frontdoor",sidebar_label:"frontdoor",sidebar_position:20,hide_table_of_contents:!0},x=void 0,k={id:"guides/frontdoor",title:"zrok frontdoor",description:"zrok frontdoor is the heavy-duty front door to your app or site. It makes your website or app available to your online audience through the shield of zrok.io's hardened, managed frontends.",source:"@site/../docs/guides/frontdoor.mdx",sourceDirName:"guides",slug:"/guides/frontdoor",permalink:"/docs/guides/frontdoor",draft:!1,unlisted:!1,editUrl:"https://github.com/openziti/zrok/blob/main/docs/../docs/guides/frontdoor.mdx",tags:[],version:"current",sidebarPosition:20,frontMatter:{title:"zrok frontdoor",sidebar_label:"frontdoor",sidebar_position:20,hide_table_of_contents:!0},sidebar:"tutorialSidebar",previous:{title:"Windows",permalink:"/docs/guides/install/windows"},next:{title:"Permission Modes",permalink:"/docs/guides/permission-modes"}},j={},v=[{value:"Overview",id:"overview",level:2},{value:"Choose your OS",id:"choose-your-os",level:2},{value:"Concepts",id:"concepts",level:2}];function f(e){const r={a:"a",code:"code",h2:"h2",p:"p",strong:"strong",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(r.p,{children:[(0,s.jsx)(r.strong,{children:"zrok frontdoor"})," is the heavy-duty front door to your app or site. It makes your website or app available to your online audience through the shield of zrok.io's hardened, managed frontends."]}),"\n",(0,s.jsx)("iframe",{width:"100%",height:"315",src:"https://www.youtube.com/embed/5Vi8GKuTi_I",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowfullscreen:!0}),"\n",(0,s.jsx)(r.h2,{id:"overview",children:"Overview"}),"\n",(0,s.jsxs)(r.p,{children:["zrok frontends are the parts of zrok that proxy incoming public web traffic to zrok backend shares via OpenZiti. When you use zrok with a ",(0,s.jsx)(r.code,{children:"zrok.io"})," frontend, you're using ",(0,s.jsx)(r.strong,{children:"zrok frontdoor"}),". ",(0,s.jsx)(r.code,{children:"zrok.io"})," is zrok-as-a-service by NetFoundry, the team behind OpenZiti. You need a free account to use ",(0,s.jsx)(r.strong,{children:"zrok frontdoor"}),"."]}),"\n",(0,s.jsx)(m.Z,{alt:"frontdoor diagram",sources:{light:(0,g.Z)("/img/zrok-frontdoor-light-mode.svg"),dark:(0,g.Z)("/img/zrok-frontdoor-dark-mode.svg")}}),"\n",(0,s.jsx)(r.h2,{id:"choose-your-os",children:"Choose your OS"}),"\n",(0,s.jsx)(r.p,{children:"Choose between installing the Linux package or running zrok with Docker (Linux, macOS, or Windows)."}),"\n",(0,s.jsxs)(l,{queryString:"os",values:[{label:"Linux",value:"Linux"},{label:"Docker",value:"Docker"}],children:[(0,s.jsxs)(d.Z,{value:"Linux",children:[(0,s.jsxs)(r.p,{children:["On Linux, zrok frontdoor is implemented natively as a system service provided by the ",(0,s.jsx)(r.code,{children:"zrok-share"})," DEB or RPM package."]}),(0,s.jsx)(u,{})]}),(0,s.jsx)(d.Z,{value:"Docker",children:(0,s.jsxs)(r.p,{children:["On macOS and Windows, zrok frontdoor is implemented as a Docker Compose project which reserves a public subdomain for your website or service and manages a zrok environment that's separate from the Docker host. ",(0,s.jsx)(r.a,{href:"/docs/guides/docker-share/docker_public_share_guide",children:"Link to the Docker Public Share Guide"})]})})]}),"\n",(0,s.jsx)(r.h2,{id:"concepts",children:"Concepts"}),"\n",(0,s.jsxs)(r.p,{children:["Overview of ",(0,s.jsx)(r.a,{href:"/docs/concepts/sharing-reserved",children:"zrok reserved shares"})]})]})}function y(e={}){const{wrapper:r}={...(0,i.a)(),...e.components};return r?(0,s.jsx)(r,{...e,children:(0,s.jsx)(f,{...e})}):f(e)}},2753:(e,r,n)=>{n.d(r,{Z:()=>o});n(7294);var s=n(1272),i=n(9286),t=n(5893);const o=e=>{let{title:r,children:n}=e;const o=n.map((e=>"string"==typeof e?e.trim():s.ZP.dump(e).trim())).join("\n\n");return(0,t.jsx)("div",{children:(0,t.jsx)(i.Z,{language:"yaml",title:r,children:o})})}},1326:(e,r,n)=>{n.d(r,{Z:()=>s});const s=[{name:"Set up zrok Package Repo",gather_facts:!0,hosts:"all",become:!0,tasks:[{name:"Set up apt repo",when:'ansible_os_family == "Debian"',block:[{name:"Install playbook dependencies","ansible.builtin.package":{name:["gnupg"],state:"present"}},{name:"Fetch armored pubkey","ansible.builtin.uri":{url:"https://get.openziti.io/tun/package-repos.gpg",return_content:"yes"},register:"armored_pubkey"},{name:"Dearmor pubkey","ansible.builtin.shell":'gpg --dearmor --output /usr/share/keyrings/openziti.gpg <<< "{{ armored_pubkey.content }}"\n',args:{creates:"/usr/share/keyrings/openziti.gpg",executable:"/bin/bash"}},{name:"Set pubkey filemode","ansible.builtin.file":{path:"/usr/share/keyrings/openziti.gpg",mode:"a+rX"}},{name:"Install OpenZiti repo deb source","ansible.builtin.copy":{dest:"/etc/apt/sources.list.d/openziti-release.list",content:"deb [signed-by=/usr/share/keyrings/openziti.gpg] https://packages.openziti.org/zitipax-openziti-deb-stable debian main\n"}},{name:"Refresh Repo Sources","ansible.builtin.apt":{update_cache:"yes",cache_valid_time:3600}}]},{name:"Set up yum repo",when:'ansible_os_family == "RedHat"',block:[{name:"Install OpenZiti repo rpm source","ansible.builtin.yum_repository":{name:"OpenZitiRelease",description:"OpenZiti Release",baseurl:"https://packages.openziti.org/zitipax-openziti-rpm-stable/redhat/$basearch",enabled:"yes",gpgkey:"https://packages.openziti.org/zitipax-openziti-rpm-stable/redhat/$basearch/repodata/repomd.xml.key",repo_gpgcheck:"yes",gpgcheck:"no"}}]}]}]}}]); \ No newline at end of file diff --git a/assets/js/e6ffb4b4.45c4cedd.js b/assets/js/e6ffb4b4.6ca3ea1c.js similarity index 75% rename from assets/js/e6ffb4b4.45c4cedd.js rename to assets/js/e6ffb4b4.6ca3ea1c.js index fbee70bd..c0702abe 100644 --- a/assets/js/e6ffb4b4.45c4cedd.js +++ b/assets/js/e6ffb4b4.6ca3ea1c.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[848],{1408:e=>{e.exports=JSON.parse('{"title":"Self Hosting","slug":"/category/self-hosting","permalink":"/docs/category/self-hosting","navigation":{"previous":{"title":"Private Share","permalink":"/docs/guides/docker-share/docker_private_share_guide"},"next":{"title":"Linux VPS","permalink":"/docs/guides/self-hosting/self_hosting_guide"}}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[848],{1408:e=>{e.exports=JSON.parse('{"title":"Self Hosting","slug":"/category/self-hosting","permalink":"/docs/category/self-hosting","navigation":{"previous":{"title":"Private Share","permalink":"/docs/guides/docker-share/docker_private_share_guide"},"next":{"title":"Linux","permalink":"/docs/guides/self-hosting/linux"}}}')}}]); \ No newline at end of file diff --git a/assets/js/f888b719.69c4f572.js b/assets/js/f888b719.74db6bc3.js similarity index 80% rename from assets/js/f888b719.69c4f572.js rename to assets/js/f888b719.74db6bc3.js index 5e498aef..24c57b6f 100644 --- a/assets/js/f888b719.69c4f572.js +++ b/assets/js/f888b719.74db6bc3.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8938],{2800:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>h,contentTitle:()=>d,default:()=>x,frontMatter:()=>c,metadata:()=>l,toc:()=>m});var r=s(5893),i=s(1151),o=s(4908),t=s(3298),a=s(7597);const c={title:"Getting Started with zrok",sidebar_label:"Getting Started",sidebar_position:10},d=void 0,l={id:"getting-started",title:"Getting Started with zrok",description:"What's a zrok?",source:"@site/../docs/getting-started.mdx",sourceDirName:".",slug:"/getting-started",permalink:"/docs/getting-started",draft:!1,unlisted:!1,editUrl:"https://github.com/openziti/zrok/blob/main/docs/../docs/getting-started.mdx",tags:[],version:"current",sidebarPosition:10,frontMatter:{title:"Getting Started with zrok",sidebar_label:"Getting Started",sidebar_position:10},sidebar:"tutorialSidebar",next:{title:"Concepts",permalink:"/docs/concepts/"}},h={},m=[{value:"What's a zrok?",id:"whats-a-zrok",level:2},{value:"Open Source",id:"open-source",level:2},{value:"Ziti native",id:"ziti-native",level:3},{value:"What's it for?",id:"whats-it-for",level:2},{value:"Installing the zrok Command",id:"installing-the-zrok-command",level:2},{value:"Generating an Invitation",id:"generating-an-invitation",level:2},{value:"Enabling Your zrok Environment",id:"enabling-your-zrok-environment",level:2},{value:"Sharing",id:"sharing",level:2},{value:"Ephemeral by Default",id:"ephemeral-by-default",level:3},{value:"Public Shares and Frontends",id:"public-shares-and-frontends",level:3},{value:"Private Shares",id:"private-shares",level:3},{value:"Proxy Backend Mode",id:"proxy-backend-mode",level:3},{value:"Web Backend Mode",id:"web-backend-mode",level:3},{value:"Reserved Shares",id:"reserved-shares",level:3},{value:"Concepts Review",id:"concepts-review",level:2},{value:"Instance and Account",id:"instance-and-account",level:3},{value:"Environment",id:"environment",level:3},{value:"Shares",id:"shares",level:3},{value:"Reserved Shares",id:"reserved-shares-1",level:3},{value:"Self-Hosting an Instance",id:"self-hosting-an-instance",level:2}];function u(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",h3:"h3",img:"img",p:"p",pre:"pre",...(0,i.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h2,{id:"whats-a-zrok",children:"What's a zrok?"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"zrok"})," (",(0,r.jsx)(n.em,{children:"/zi\u02d0\u0279\u0252k/ ZEE-rock"}),") is a secure, open-source, self-hostable sharing platform that simplifies shielding and sharing network services or files. There's a hardened zrok-as-a-service offering available at ",(0,r.jsx)(n.a,{href:"https://zrok.io",children:"zrok.io"})," with a generous free tier."]}),"\n",(0,r.jsx)(n.h2,{id:"open-source",children:"Open Source"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"zrok"})," is licensed under Apache 2.0."]}),"\n",(0,r.jsxs)(n.p,{children:["Check ",(0,r.jsx)(n.a,{href:"https://github.com/orgs/openziti/projects/16",children:"the roadmap"})," if you're thinking about the future. We would love to hear your ideas for ",(0,r.jsx)(n.code,{children:"zrok"}),"!"]}),"\n",(0,r.jsxs)(n.p,{children:["The best ways to engage are ",(0,r.jsx)(n.a,{href:"https://openziti.discourse.group/",children:"Discourse"})," for questions and ",(0,r.jsx)(n.a,{href:"https://github.com/openziti/zrok/issues",children:"GitHub Issues"})," for documenting problems."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/docs/concepts/opensource",children:"Read more about zrok open source"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"ziti-native",children:"Ziti native"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"zrok"})," is a ",(0,r.jsx)(n.em,{children:"Ziti Native Application"}),", built on the ",(0,r.jsx)(n.a,{href:"https://openziti.io",children:"OpenZiti"})," platform, and supported by the OpenZiti community and NetFoundry team."]}),"\n",(0,r.jsx)(n.h2,{id:"whats-it-for",children:"What's it for?"}),"\n",(0,r.jsxs)(n.p,{children:["Use ",(0,r.jsx)(n.code,{children:"zrok"})," to share a running service, like a web server or a network socket, or to share a directory of static files."]}),"\n",(0,r.jsxs)(n.p,{children:["If ",(0,r.jsx)(n.a,{href:"/docs/concepts/sharing-public",children:"sharing publicly"}),", you can reserve a subdomain, enable authentication options, or both. Public shares proxy HTTPS to your service or files."]}),"\n",(0,r.jsxs)(n.p,{children:["If ",(0,r.jsx)(n.a,{href:"/docs/concepts/sharing-private",children:"sharing privately"}),", only users with the share token can access your share. In addition to what you can share publicly, private shares can include TCP and UDP services."]}),"\n",(0,r.jsx)(n.h2,{id:"installing-the-zrok-command",children:"Installing the zrok Command"}),"\n",(0,r.jsx)(o.N,{children:(0,r.jsxs)("div",{className:a.Z.downloadContainer,children:[(0,r.jsx)(t.Z,{osName:"Windows",osLogo:"/img/logo-windows.svg",infoText:"Binary executable",guideLink:"/docs/guides/install/windows"}),(0,r.jsx)(t.Z,{osName:"macOS",osLogo:"/img/logo-apple.svg",infoText:"Binary executable",guideLink:"/docs/guides/install/macos"}),(0,r.jsx)(t.Z,{osName:"Linux",osLogo:"/img/logo-linux.svg",infoText:"DEB, RPM packages",guideLink:"/docs/guides/install/linux"})]})}),"\n",(0,r.jsx)(n.h2,{id:"generating-an-invitation",children:"Generating an Invitation"}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["If not using ",(0,r.jsx)(n.code,{children:"zrok.io"})," (zrok-as-a-service), you must configure the ",(0,r.jsx)(n.code,{children:"zrok"})," command to use your instance. See the ",(0,r.jsx)(n.a,{href:"/docs/guides/self-hosting/instance-configuration",children:"instance configuration guide"})," in the self-hosting section for details."]})}),"\n",(0,r.jsxs)(n.p,{children:["Invite yourself to ",(0,r.jsx)(n.code,{children:"zrok"})," by running the ",(0,r.jsx)(n.code,{children:"zrok invite"})," command:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-text",children:"zrok invite\n"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-buttonless",metastring:'title="Output"',children:"enter and confirm your email address...\n\n> user@domain.com\n> user@domain.com\n\n[ Submit ]\n\ninvitation sent to 'user@domain.com'!\n"})}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"zrok invite"})," command presents a small form that allows you to enter (and then confirm) your email address. Tabbing to the ",(0,r.jsx)(n.code,{children:"[ Submit ]"})," button will send the request to your configured ",(0,r.jsx)(n.code,{children:"zrok"})," service."]}),"\n",(0,r.jsxs)(n.p,{children:["Next, check the email where you sent the invite. You should receive a message asking you to click a link to create your ",(0,r.jsx)(n.code,{children:"zrok"})," account. When you click that link, you will be brought to a web page that will allow you to set a password for your new account:"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Enter a Password",src:s(9744).Z+"",width:"1791",height:"1362"})}),"\n",(0,r.jsxs)(n.p,{children:["Enter a password and its confirmation, and click the ",(0,r.jsx)(n.code,{children:"Register Account"})," button. You'll see the following:"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Successful Registration",src:s(242).Z+"",width:"1791",height:"1369"})}),"\n",(0,r.jsxs)(n.p,{children:['For now, we\'ll ignore the "enable your shell for zrok" section. Just click the ',(0,r.jsx)(n.code,{children:"zrok web portal"})," link:"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Web Login",src:s(9509).Z+"",width:"1791",height:"1362"})}),"\n",(0,r.jsxs)(n.p,{children:["After clicking the ",(0,r.jsx)(n.code,{children:"Log In"})," button, you'll be brought into the ",(0,r.jsx)(n.code,{children:"zrok"})," ",(0,r.jsx)(n.em,{children:"web console"}),":"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Web Console; Empty",src:s(2945).Z+"",width:"1791",height:"1362"})}),"\n",(0,r.jsxs)(n.p,{children:["Congratulations! Your ",(0,r.jsx)(n.code,{children:"zrok"})," account is ready to go!"]}),"\n",(0,r.jsx)(n.h2,{id:"enabling-your-zrok-environment",children:"Enabling Your zrok Environment"}),"\n",(0,r.jsxs)(n.p,{children:["When your ",(0,r.jsx)(n.code,{children:"zrok"})," account was created, the service generated a ",(0,r.jsx)(n.em,{children:"secret token"})," that identifies and authenticates in a single step. Protect your secret token as if it were a password, or an important account number; it's a ",(0,r.jsx)(n.em,{children:"secret"}),", protect it."]}),"\n",(0,r.jsxs)(n.p,{children:["When we left off you had downloaded, extracted, and configured your ",(0,r.jsx)(n.code,{children:"zrok"})," environment. In order to use that environment with your account, you'll need to ",(0,r.jsx)(n.code,{children:"enable"})," it. Enabling an environment generates a secure identity and the necessary underlying security policies with the OpenZiti network hosting the ",(0,r.jsx)(n.code,{children:"zrok"})," service."]}),"\n",(0,r.jsxs)(n.p,{children:["From the web console, click on your email address in the upper right corner of the header. That drop down menu contains an ",(0,r.jsx)(n.code,{children:"Enable Your Environment"})," link. Click that link and a modal dialog will be shown like this:"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Enable Modal Dialog",src:s(9042).Z+"",width:"1791",height:"1369"})}),"\n",(0,r.jsxs)(n.p,{children:["This dialog box shows you the ",(0,r.jsx)(n.code,{children:"zrok enable"})," command that you can use to enable any shell to work with your ",(0,r.jsx)(n.code,{children:"zrok"})," account with a single command."]}),"\n",(0,r.jsx)(n.p,{children:"Let's copy that command and paste it into your shell:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-buttonless",metastring:'title="Example"',children:"$ zrok enable klFEoIi0QAg7 \n\u28fb contacting the zrok service...\n"})}),"\n",(0,r.jsx)(n.p,{children:"After a few seconds, the message will change and indicate that the enable operation succeeded:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-buttonless",metastring:'title="Example"',children:"$ zrok enable klFEoIi0QAg7 \n\u28fb the zrok environment was successfully enabled...\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Now, if we run a ",(0,r.jsx)(n.code,{children:"zrok status"})," command, you will see the details of your environment:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-txt",children:"zrok status\n"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-buttonless",metastring:'title="Output"',children:"Config:\n\n CONFIG VALUE SOURCE\n apiEndpoint https://api.staging.zrok.io env\n\nEnvironment:\n\n PROPERTY VALUE\n Secret Token <>\n Ziti Identity <>\n"})}),"\n",(0,r.jsx)(n.p,{children:"Excellent... our environment is now fully enabled."}),"\n",(0,r.jsxs)(n.p,{children:["If we return to the ",(0,r.jsx)(n.em,{children:"web console"}),", we'll now see the new environment reflected in the explorer view:"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"New Environment in Web UI",src:s(5546).Z+"",width:"1791",height:"1369"})}),"\n",(0,r.jsxs)(n.p,{children:["In my case, the environment is named ",(0,r.jsx)(n.code,{children:"michael@ziti-lx"}),", which is the username of my shell and the hostname of the system the shell is running on."]}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["Should you want to use a non-default name for your environment, you can pass the ",(0,r.jsx)(n.code,{children:"-d"})," option to the ",(0,r.jsx)(n.code,{children:"zrok enable"})," command. See ",(0,r.jsx)(n.code,{children:"zrok enable --help"})," for details."]})}),"\n",(0,r.jsxs)(n.p,{children:["If you click on the environment node in the explorer in the ",(0,r.jsx)(n.em,{children:"web console"}),", the details panel shown at the bottom of the page will change:"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Empty Environment",src:s(3858).Z+"",width:"1791",height:"1369"})}),"\n",(0,r.jsxs)(n.p,{children:["The explorer supports clicking, dragging, mouse wheel zooming, and selecting the nodes in the graph for more information (and available actions) for the selected node. If you ever get lost in the explorer, click the ",(0,r.jsx)(n.img,{alt:"Zoom to Fit",src:s(3843).Z+"",width:"30",height:"25"})," ",(0,r.jsx)(n.em,{children:"zoom to fit"})," icon in the lower right corner of the explorer."]}),"\n",(0,r.jsxs)(n.p,{children:["If we click on the ",(0,r.jsx)(n.code,{children:"Detail"})," tab for our environment, we'll see something like:"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Environment Detail",src:s(2534).Z+"",width:"1791",height:"1369"})}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["With your ",(0,r.jsx)(n.code,{children:"zrok"})," account you can ",(0,r.jsx)(n.code,{children:"zrok enable"})," multiple environments. This will allow you to run ",(0,r.jsx)(n.code,{children:"zrok share"})," in one environment, and ",(0,r.jsx)(n.code,{children:"zrok access"})," in other environments."]})}),"\n",(0,r.jsx)(n.p,{children:"Your environment is fully ready to go. Now we can move on to the fun stuff..."}),"\n",(0,r.jsx)(n.h2,{id:"sharing",children:"Sharing"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"zrok"})," is designed to make sharing resources as effortless as possible, while providing a high degree of security and control."]}),"\n",(0,r.jsx)(n.h3,{id:"ephemeral-by-default",children:"Ephemeral by Default"}),"\n",(0,r.jsxs)(n.p,{children:["Shared resources are ",(0,r.jsx)(n.em,{children:"ephemeral"})," by default; as soon as you terminate the ",(0,r.jsx)(n.code,{children:"zrok share"})," command, the entire share is removed and is no longer available to any users. Identifiers for shared resources are randomly allocated when the share is created."]}),"\n",(0,r.jsx)(n.h3,{id:"public-shares-and-frontends",children:"Public Shares and Frontends"}),"\n",(0,r.jsxs)(n.p,{children:["Resources that are shared ",(0,r.jsx)(n.em,{children:"publicly"})," are exposed to any users on the internet who have access to the ",(0,r.jsx)(n.code,{children:"zrok"}),' instance\'s "frontend".']}),"\n",(0,r.jsx)(n.p,{children:"A frontend is an HTTPS listener exposed to the internet, that lets any user with your ephemeral share token access your publicly shared resources."}),"\n",(0,r.jsxs)(n.p,{children:["For example, I might create a public share using the ",(0,r.jsx)(n.code,{children:"zrok share public"})," command, which results in my ",(0,r.jsx)(n.code,{children:"zrok"})," instance exposing a URL like ",(0,r.jsx)(n.code,{children:"https://2ptgbr8tlfvk.share.zrok.io"})," to access my resources."]}),"\n",(0,r.jsxs)(n.p,{children:['In this case, my share was given the "share token" of ',(0,r.jsx)(n.code,{children:"2ptgbr8tlfvk"}),". That URL can be given to any user, allowing them to immediately access the shared resources directly from my local environment, all without exposing any access to my private, secure environment. The physical network location of my environment is not exposed to anonymous consumers of my resources."]}),"\n",(0,r.jsxs)(n.admonition,{type:"note",children:[(0,r.jsxs)(n.p,{children:["Here is the ",(0,r.jsx)(n.code,{children:"--help"})," output from ",(0,r.jsx)(n.code,{children:"zrok share public"}),":"]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-text",children:"zrok share public\n"})}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-buttonless",metastring:'title="Output"',children:'Error: accepts 1 arg(s), received 0\nUsage:\n zrok share public [flags]\n\nFlags:\n --backend-mode string The backend mode {proxy, web, caddy, drive} (default "proxy")\n --basic-auth stringArray Basic authentication users (,...)\n --frontends stringArray Selected frontends to use for the share (default [public])\n --headless Disable TUI and run headless\n -h, --help help for public\n --insecure Enable insecure TLS certificate validation for \n\nGlobal Flags:\n -p, --panic Panic instead of showing pretty errors\n -v, --verbose Enable verbose logging\n\n[ERROR]: an error occurred (accepts 1 arg(s), received 0)\n'})}),(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:""})," defines the path to the local resource that you intend to share. The form of ",(0,r.jsx)(n.code,{children:""})," depends on the ",(0,r.jsx)(n.code,{children:"--backend-mode"})," that you're using."]}),(0,r.jsxs)(n.p,{children:["In the case of ",(0,r.jsx)(n.code,{children:"--backend-mode proxy"}),", ",(0,r.jsx)(n.code,{children:""})," should be a URL to an HTTP endpoint."]}),(0,r.jsxs)(n.p,{children:["In the case of ",(0,r.jsx)(n.code,{children:"--backend-mode web"}),", ",(0,r.jsx)(n.code,{children:""}),' is the path to a file on disk that serves as the "root" of the file tree to be shared.']})]}),"\n",(0,r.jsx)(n.p,{children:"If we return to the web console, we see our share in the explorer:"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Web Console Share",src:s(6097).Z+"",width:"1791",height:"1369"})}),"\n",(0,r.jsxs)(n.p,{children:["If we click on our new share in the explorer, we can see the share details:\n",(0,r.jsx)(n.img,{alt:"Share Details",src:s(4647).Z+"",width:"1791",height:"1369"})]}),"\n",(0,r.jsxs)(n.p,{children:["If we click on the ",(0,r.jsx)(n.em,{children:"frontend endpoint"})," a new browser tab opens and we see the content of our share:\n",(0,r.jsx)(n.img,{alt:"Share Frontend",src:s(6254).Z+"",width:"1669",height:"1033"})]}),"\n",(0,r.jsx)(n.p,{children:"If we click on the environment in the explorer, we're shown all of the shares for that environment (including our new share), along with a spark line that shows the activity:"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Environment Spark Line",src:s(9737).Z+"",width:"1791",height:"1369"})}),"\n",(0,r.jsxs)(n.p,{children:["And as soon as I terminate the ",(0,r.jsx)(n.code,{children:"zrok share"})," client, the resources are removed from the ",(0,r.jsx)(n.code,{children:"zrok"})," environment."]}),"\n",(0,r.jsx)(n.p,{children:"If we try to reload the frontend endpoint in our web browser, we'll see:"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Not Found",src:s(5724).Z+"",width:"1556",height:"1229"})}),"\n",(0,r.jsx)(n.h3,{id:"private-shares",children:"Private Shares"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"zrok"})," also provides a powerful ",(0,r.jsx)(n.em,{children:"private"})," sharing model. If I execute the following command:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-buttonless",metastring:'title="Example"',children:"$ zrok share private http://localhost:8080\n"})}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"zrok"})," service will respond with the following:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-buttonless",metastring:'title="Output"',children:"access your share with: zrok access private wvszln4dyz9q\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Rather than allowing access to your service through a public frontend, a ",(0,r.jsx)(n.em,{children:"private"})," share is only exposed to the underlying OpenZiti network, and can only be accessed using the ",(0,r.jsx)(n.code,{children:"zrok access"})," command."]}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"zrok access private wvszln4dyz9q"})," command can be run by any ",(0,r.jsx)(n.code,{children:"zrok"})," user, allowing them to create and bind a local HTTP listener, that allows for private access to your shared resources."]}),"\n",(0,r.jsx)(n.h3,{id:"proxy-backend-mode",children:"Proxy Backend Mode"}),"\n",(0,r.jsxs)(n.p,{children:["Without specifying a ",(0,r.jsx)(n.em,{children:"backend mode"}),", the ",(0,r.jsx)(n.code,{children:"zrok share"})," command will assume that you're trying to share a ",(0,r.jsx)(n.code,{children:"proxy"})," resource. A ",(0,r.jsx)(n.code,{children:"proxy"})," resource is usually some private HTTP/HTTPS endpoint (like a development server, or a private application) running in your local environment. Usually such an endpoint would have no inbound connectivity except for however it is reachable from your local environment. It might be running on ",(0,r.jsx)(n.code,{children:"localhost"}),", or only listening on a private LAN segment behind a firewall."]}),"\n",(0,r.jsxs)(n.p,{children:["For these services a ",(0,r.jsx)(n.code,{children:"proxy"})," share will allow those endpoints to be reached, either ",(0,r.jsx)(n.em,{children:"publicly"})," or ",(0,r.jsx)(n.em,{children:"privately"})," through the ",(0,r.jsx)(n.code,{children:"zrok"})," service."]}),"\n",(0,r.jsx)(n.h3,{id:"web-backend-mode",children:"Web Backend Mode"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"zrok share"})," command accepts a ",(0,r.jsx)(n.code,{children:"--backend-mode"})," option. Besides ",(0,r.jsx)(n.code,{children:"proxy"}),", the current ",(0,r.jsx)(n.code,{children:"v0.3"})," release (as of this writing) also supports a ",(0,r.jsx)(n.code,{children:"web"})," mode. The ",(0,r.jsx)(n.code,{children:"web"})," mode allows you to specify a local folder on your filesystem, and instantly turns your ",(0,r.jsx)(n.code,{children:"zrok"})," client into a web server, exposing your web content either ",(0,r.jsx)(n.em,{children:"publicly"})," or ",(0,r.jsx)(n.em,{children:"privately"})," without having to a configure a web server."]}),"\n",(0,r.jsx)(n.h3,{id:"reserved-shares",children:"Reserved Shares"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"zrok"})," shares are ",(0,r.jsx)(n.em,{children:"ephemeral"}),' unless you specifically create a "reserved" share.']}),"\n",(0,r.jsxs)(n.p,{children:["A reserved share can be re-used multiple times; it will survive termination of the ",(0,r.jsx)(n.code,{children:"zrok share"})," command, allowing for longer-lasting semi-permanent access to shared resources."]}),"\n",(0,r.jsx)(n.p,{children:"The first step is to create the reserved share:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-txt",metastring:'title="Example"',children:"$ zrok reserve public --backend-mode web v0.3_getting_started\n[ 0.275] INFO main.(*reserveCommand).run: your reserved share token is 'mltwsinym1s2'\n[ 0.275] INFO main.(*reserveCommand).run: reserved frontend endpoint: https://mltwsinym1s2.share.zrok.io\n"})}),"\n",(0,r.jsxs)(n.p,{children:["I'm asking the ",(0,r.jsx)(n.code,{children:"zrok"})," service to reserve a share with a ",(0,r.jsx)(n.code,{children:"web"})," backend mode, pointing at my local ",(0,r.jsx)(n.code,{children:"docs"})," folder."]}),"\n",(0,r.jsxs)(n.p,{children:["You'll want to remember the share token (",(0,r.jsx)(n.code,{children:"mltwsinym1s2"})," in this case), and the frontend endpoint URL. If this were a ",(0,r.jsx)(n.em,{children:"private"})," reserved share, there would not be a frontend URL."]}),"\n",(0,r.jsx)(n.p,{children:"If we do nothing else, and then point a web browser at the frontend endpoint, we get:"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Not Found",src:s(7369).Z+"",width:"1556",height:"1229"})}),"\n",(0,r.jsxs)(n.p,{children:["This is the ",(0,r.jsx)(n.code,{children:"404"})," error message returned by the ",(0,r.jsx)(n.code,{children:"zrok"})," frontend. We're getting this because we haven't yet started up a ",(0,r.jsx)(n.code,{children:"zrok share"})," for the service. Let's do that:"]}),"\n",(0,r.jsx)(n.p,{children:"This command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-txt",metastring:'title="Example"',children:"$ zrok share reserved mltwsinym1s2\n"})}),"\n",(0,r.jsx)(n.p,{children:"...results in a new share backend starting up and connecting to the existing reserved share:"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"zrok share reserved",src:s(1577).Z+"",width:"951",height:"706"})}),"\n",(0,r.jsxs)(n.p,{children:["And now if we refresh the frontend endpoint URL in the web browser, we'll see an index of the ",(0,r.jsx)(n.code,{children:"docs"})," directory:"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"zrok docs share",src:s(6254).Z+"",width:"1669",height:"1033"})}),"\n",(0,r.jsxs)(n.p,{children:["With the reserved share, we're free to stop and restart the ",(0,r.jsx)(n.code,{children:"zrok share reserved"})," command as many times as we want, without losing the token for our share."]}),"\n",(0,r.jsxs)(n.p,{children:["When we're done with the reserved share, we can ",(0,r.jsx)(n.em,{children:"release"})," it using this command:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-txt",metastring:'title="Example"',children:"$ zrok release mltwsinym1s2\n[ 0.230] INFO main.(*releaseCommand).run: reserved share 'mltwsinym1s2' released\n"})}),"\n",(0,r.jsx)(n.h2,{id:"concepts-review",children:"Concepts Review"}),"\n",(0,r.jsxs)(n.p,{children:["In summary, ",(0,r.jsx)(n.code,{children:"zrok"})," lets you easily and securely share resources with both general internet users (through ",(0,r.jsx)(n.em,{children:"public"})," sharing) and also with other ",(0,r.jsx)(n.code,{children:"zrok"})," users (through ",(0,r.jsx)(n.em,{children:"private"})," sharing)."]}),"\n",(0,r.jsxs)(n.p,{children:["Here's a quick review of the ",(0,r.jsx)(n.code,{children:"zrok"})," mental model and the vocabulary."]}),"\n",(0,r.jsx)(n.h3,{id:"instance-and-account",children:"Instance and Account"}),"\n",(0,r.jsxs)(n.p,{children:["You create an ",(0,r.jsx)(n.em,{children:"account"})," with a ",(0,r.jsx)(n.code,{children:"zrok"})," ",(0,r.jsx)(n.em,{children:"instance"}),". Your account is identified by a username and a password, which you use to log into the ",(0,r.jsx)(n.em,{children:"web console"}),". Your account also has a ",(0,r.jsx)(n.em,{children:"secret token"}),", which you will use to authenticate from the ",(0,r.jsx)(n.code,{children:"zrok"})," command-line to interact with the ",(0,r.jsx)(n.em,{children:"instance"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["You create a new ",(0,r.jsx)(n.em,{children:"account"})," with a ",(0,r.jsx)(n.code,{children:"zrok"})," ",(0,r.jsx)(n.em,{children:"instance"})," through the ",(0,r.jsx)(n.code,{children:"zrok invite"})," command."]}),"\n",(0,r.jsx)(n.h3,{id:"environment",children:"Environment"}),"\n",(0,r.jsxs)(n.p,{children:["Using your ",(0,r.jsx)(n.em,{children:"secret token"})," you use the ",(0,r.jsx)(n.code,{children:"zrok"})," command-line interface to create an ",(0,r.jsx)(n.em,{children:"environment"}),". An ",(0,r.jsx)(n.em,{children:"environment"})," corresponds to a single command-line user on a specific ",(0,r.jsx)(n.em,{children:"host system"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["You create a new ",(0,r.jsx)(n.em,{children:"environment"})," by using the ",(0,r.jsx)(n.code,{children:"zrok enable"})," command."]}),"\n",(0,r.jsx)(n.h3,{id:"shares",children:"Shares"}),"\n",(0,r.jsxs)(n.p,{children:["Once you've enabled an ",(0,r.jsx)(n.em,{children:"environment"}),", you then create one or more ",(0,r.jsx)(n.em,{children:"shares"}),". Shares have either a ",(0,r.jsx)(n.em,{children:"public"})," or ",(0,r.jsx)(n.em,{children:"private"})," ",(0,r.jsx)(n.em,{children:"sharing mode"}),". ",(0,r.jsx)(n.em,{children:"Shares"})," share a specific type of resource using a ",(0,r.jsx)(n.em,{children:"backend mode"}),". As of this writing ",(0,r.jsx)(n.code,{children:"zrok"})," supports a ",(0,r.jsx)(n.code,{children:"proxy"})," ",(0,r.jsx)(n.em,{children:"backend mode"})," to share local HTTP resources as a ",(0,r.jsx)(n.em,{children:"reverse proxy"}),". ",(0,r.jsx)(n.code,{children:"zrok"})," also supports a ",(0,r.jsx)(n.code,{children:"web"})," ",(0,r.jsx)(n.em,{children:"backend mode"})," to share local file and HTML resources by enabling a basic HTTP server."]}),"\n",(0,r.jsxs)(n.p,{children:["Every ",(0,r.jsx)(n.em,{children:"share"})," is identified by a ",(0,r.jsx)(n.em,{children:"share token"}),". ",(0,r.jsx)(n.em,{children:"Public shares"})," can be accessed through either a ",(0,r.jsx)(n.em,{children:"frontend"})," instance offered through the ",(0,r.jsx)(n.code,{children:"zrok"})," ",(0,r.jsx)(n.em,{children:"instance"}),", or through the ",(0,r.jsx)(n.code,{children:"zrok access"})," command. ",(0,r.jsx)(n.em,{children:"Private shares"})," can only be accessed through the ",(0,r.jsx)(n.code,{children:"zrok access"})," command."]}),"\n",(0,r.jsxs)(n.p,{children:["You use the ",(0,r.jsx)(n.code,{children:"zrok share"})," command to create and enable ",(0,r.jsx)(n.em,{children:"ephemeral shares"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"reserved-shares-1",children:"Reserved Shares"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"zrok"})," supports creating ",(0,r.jsx)(n.em,{children:"shares"})," that have a consistent ",(0,r.jsx)(n.em,{children:"share token"})," that survives restarts of the ",(0,r.jsx)(n.code,{children:"zrok share"})," command. These are considered ",(0,r.jsx)(n.em,{children:"non-ephemeral"}),", and is callled a ",(0,r.jsx)(n.em,{children:"reserved share"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["You use the ",(0,r.jsx)(n.code,{children:"zrok reserve"})," command to create ",(0,r.jsx)(n.em,{children:"reserved shares"}),". Reserved shares last until you use the ",(0,r.jsx)(n.code,{children:"zrok release"})," command to delete them."]}),"\n",(0,r.jsx)(n.h2,{id:"self-hosting-an-instance",children:"Self-Hosting an Instance"}),"\n",(0,r.jsxs)(n.p,{children:["Interested in self-hosting your own ",(0,r.jsx)(n.code,{children:"zrok"})," instance? See the ",(0,r.jsx)(n.a,{href:"/docs/guides/self-hosting/self_hosting_guide",children:"self-hosting guide"})," for details."]})]})}function x(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},4908:(e,n,s)=>{s.d(n,{L:()=>t,N:()=>a});var r=s(7294),i=s(5893);const o=(0,r.createContext)([]),t=()=>(0,r.useContext)(o),a=e=>{let{children:n}=e;const[s,t]=(0,r.useState)([]);return(0,r.useEffect)((()=>{(async()=>{try{const e=await fetch("https://api.github.com/repos/openziti/zrok/releases/latest");if(!e.ok)throw new Error(`HTTP error! status: ${e.status}`);const n=(await e.json()).assets.map((e=>({name:e.name,url:e.browser_download_url,arch:e.name.replace(".tar.gz","").split("_")[3]})));console.log("Fetched assets:",n),t(n)}catch(e){console.error("Error fetching the release assets:",e)}})()}),[]),(0,i.jsx)(o.Provider,{value:s,children:n})}},3298:(e,n,s)=>{s.d(n,{Z:()=>c});s(7294);var r=s(4908),i=s(7597),o=s(2949),t=s(5893);const a=e=>{switch(e){case"amd64":return"x86_64";case"arm64":return"ARM64";case"armv7":return"ARM";default:return e.toUpperCase()}},c=e=>{let{osName:n,osLogo:s,infoText:c,guideLink:d}=e;const{colorMode:l}=(0,o.I)(),h=(0,r.L)();console.log("Assets in DownloadCard:",h);const m=(e=>{switch(e){case"Windows":return"windows";case"macOS":return"darwin";case"Linux":return"linux";default:return""}})(n),u=h.filter((e=>e.name.includes(m)));return console.log("Filtered assets for",n,"in DownloadCard:",u),(0,t.jsxs)("div",{className:i.Z.downloadCard,children:[(0,t.jsx)("div",{className:i.Z.imgContainer,children:(0,t.jsx)("img",{src:s,alt:`${n} logo`})}),(0,t.jsx)("h3",{children:n}),u.length>0&&(0,t.jsx)("ul",{children:u.map(((e,n)=>(0,t.jsx)("li",{className:i.Z.downloadButtons,children:(0,t.jsx)("a",{href:e.url,className:i.Z.downloadLinks,children:a(e.arch)})},n)))}),d&&(0,t.jsxs)("div",{className:i.Z.cardFooter,children:[(0,t.jsx)("p",{children:c}),(0,t.jsx)("a",{href:d,children:"GUIDE"}),(0,t.jsx)("p",{})]})]})}},7597:(e,n,s)=>{s.d(n,{Z:()=>r});const r={downloadContainer:"downloadContainer_nNgj",downloadCard:"downloadCard_D_EY",cardFooter:"cardFooter_Rhom",downloadButtons:"downloadButtons_NPAP",downloadLinks:"downloadLinks_thSu",imgContainer:"imgContainer_r0QA"}},9042:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_enable_modal-45da63a6907e930daaa4c798272ce5fa.png"},5724:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_not_found-fa3415937c341eb10e1eb98c9b063583.png"},242:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_registration_success-05e7e328284f6dc38cd993322698d38b.png"},7369:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_reserved_not_found-2519707e5cc3e635b7a6feb381c1d040.png"},1577:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_share_reserved-6bce67775ce2c41abb0ef13ee1fad972.png"},9744:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_verify-22a26d401b9a77a4278f3c0f54d2a981.png"},2945:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_web_console_empty-cce147eaf8e7bc83abe556336a4aea98.png"},9737:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_web_console_environment_spark-925c0709ed7a42f0a708ab0523cdeb5f.png"},6097:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_web_console_explorer_share-11236f68819da60014d5444e7429c189.png"},4647:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_web_console_share_detail-efeaa472d5e5c225a160f6d5647086b3.png"},6254:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_web_console_share_frontend-d7c0d6495493c00b94ae237339f2dc2d.png"},9509:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_web_login-a6161cc79e66932fab76994bdfb8f9c1.png"},2534:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_web_ui_empty_environment_detail-153c921ade86f924079947b0f734e3ff.png"},3858:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_web_ui_empty_shares-048c08c18477bcabb9fa8c1b58537012.png"},5546:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_web_ui_new_environment-414d8e8fc25b09f257cb40ba47d6acbb.png"},3843:(e,n,s)=>{s.d(n,{Z:()=>r});const r="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAZCAIAAACpVwlNAAAEr2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIKICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgdGlmZjpJbWFnZUxlbmd0aD0iMjUiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMzAiCiAgIHRpZmY6UmVzb2x1dGlvblVuaXQ9IjIiCiAgIHRpZmY6WFJlc29sdXRpb249Ijk2LzEiCiAgIHRpZmY6WVJlc29sdXRpb249Ijk2LzEiCiAgIGV4aWY6UGl4ZWxYRGltZW5zaW9uPSIzMCIKICAgZXhpZjpQaXhlbFlEaW1lbnNpb249IjI1IgogICBleGlmOkNvbG9yU3BhY2U9IjEiCiAgIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiCiAgIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIKICAgeG1wOk1vZGlmeURhdGU9IjIwMjMtMDEtMTlUMTA6NTY6NTYtMDU6MDAiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjMtMDEtMTlUMTA6NTY6NTYtMDU6MDAiPgogICA8eG1wTU06SGlzdG9yeT4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJwcm9kdWNlZCIKICAgICAgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWZmaW5pdHkgUGhvdG8gMi4wLjMiCiAgICAgIHN0RXZ0OndoZW49IjIwMjMtMDEtMTlUMTA6NTY6NTYtMDU6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KPD94cGFja2V0IGVuZD0iciI/Pq+HLHgAAAGBaUNDUHNSR0IgSUVDNjE5NjYtMi4xAAAokXWRy0tCQRSHP7UwemBQixYtJKyVRg8Q27RQyoJqYQZZbfTmI/BxuVcJaRu0FQqiNr0W9RfUNmgdBEURRNtaF7UpuZ2rghF5hjnzzW/OOcycAWs4rWT0piHIZPNaKOh3LkaWnPYXLHThwIclqujq7PxkmIb2eS/RYrces1bjuH+tbTWuK2BpER5XVC0vPCU8s55XTd4R7lZS0VXhM2G3JhcUvjP1WJVfTU5W+dtkLRwKgLVT2Jn8xbFfrKS0jLC8HFcmXVBq9zFf0h7PLszL2iezF50QQfw4mWaCAF6GGRPvxcMIg7KjQf5QJX+OnOQq4lWKaKyRJEUet6gFqR6XNSF6XEaaotn/v33VE6Mj1ertfmh+Noz3frBvQ7lkGF9HhlE+BtsTXGbr+blD8H2IXqprrgNwbML5VV2L7cLFFvQ8qlEtWpFsMq2JBLydQkcEum6gdbnas9o5Jw8Q3pCvuoa9fRiQeMfKD2DYZ+PDGzxnAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABZklEQVRIie2VvW7CMBDHr1UfwE5fII7lvahIWUEiQ7qxMLEwsVQMSB0YKsTExsDGxFs0QyqlYyMVld3k4wWw/QgMlqp+JXFQGZB649n3k+9/f9sX9w+PcJq4PBH3H/0zrkrWfK99jVF5/V6qIIzqod1m485rC6nK0S5GAPArvRDNHFtINZ0vviQp4Un2OTObjIs6q6G122yMhgPfaxvuN0VbGDHHBgDm2FbVAGqgLYyEVPFmCwDB84uQilHyB2i32ej3uoySvZDT+YInGaPE77QqlSkznz5vv9cFAEbJdL4QUlkYjYYDnYnf3o9HC6mewog5ttZBq7xcrf1OK95sy61ZgQaAIIx2lGgdRsPBcrXmSbYXstLyRmPkSWZh5HdaAODe3uipVlaZmk9IxdMcAHiam3DBRJCPCMJol+bfbuMxaJ7mjJLZZFxeb2Gku6mDTrJXjExeviILFqJF8WtpGOf5y5wn+gBcXI4F9z6rgwAAAABJRU5ErkJggg=="},1151:(e,n,s)=>{s.d(n,{Z:()=>a,a:()=>t});var r=s(7294);const i={},o=r.createContext(i);function t(e){const n=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),r.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8938],{2800:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>h,contentTitle:()=>d,default:()=>x,frontMatter:()=>c,metadata:()=>l,toc:()=>m});var r=s(5893),i=s(1151),o=s(4908),t=s(3298),a=s(7597);const c={title:"Getting Started with zrok",sidebar_label:"Getting Started",sidebar_position:10},d=void 0,l={id:"getting-started",title:"Getting Started with zrok",description:"What's a zrok?",source:"@site/../docs/getting-started.mdx",sourceDirName:".",slug:"/getting-started",permalink:"/docs/getting-started",draft:!1,unlisted:!1,editUrl:"https://github.com/openziti/zrok/blob/main/docs/../docs/getting-started.mdx",tags:[],version:"current",sidebarPosition:10,frontMatter:{title:"Getting Started with zrok",sidebar_label:"Getting Started",sidebar_position:10},sidebar:"tutorialSidebar",next:{title:"Concepts",permalink:"/docs/concepts/"}},h={},m=[{value:"What's a zrok?",id:"whats-a-zrok",level:2},{value:"Open Source",id:"open-source",level:2},{value:"Ziti native",id:"ziti-native",level:3},{value:"What's it for?",id:"whats-it-for",level:2},{value:"Installing the zrok Command",id:"installing-the-zrok-command",level:2},{value:"Generating an Invitation",id:"generating-an-invitation",level:2},{value:"Enabling Your zrok Environment",id:"enabling-your-zrok-environment",level:2},{value:"Sharing",id:"sharing",level:2},{value:"Ephemeral by Default",id:"ephemeral-by-default",level:3},{value:"Public Shares and Frontends",id:"public-shares-and-frontends",level:3},{value:"Private Shares",id:"private-shares",level:3},{value:"Proxy Backend Mode",id:"proxy-backend-mode",level:3},{value:"Web Backend Mode",id:"web-backend-mode",level:3},{value:"Reserved Shares",id:"reserved-shares",level:3},{value:"Concepts Review",id:"concepts-review",level:2},{value:"Instance and Account",id:"instance-and-account",level:3},{value:"Environment",id:"environment",level:3},{value:"Shares",id:"shares",level:3},{value:"Reserved Shares",id:"reserved-shares-1",level:3},{value:"Self-Hosting an Instance",id:"self-hosting-an-instance",level:2}];function u(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",h3:"h3",img:"img",p:"p",pre:"pre",...(0,i.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h2,{id:"whats-a-zrok",children:"What's a zrok?"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"zrok"})," (",(0,r.jsx)(n.em,{children:"/zi\u02d0\u0279\u0252k/ ZEE-rock"}),") is a secure, open-source, self-hostable sharing platform that simplifies shielding and sharing network services or files. There's a hardened zrok-as-a-service offering available at ",(0,r.jsx)(n.a,{href:"https://zrok.io",children:"zrok.io"})," with a generous free tier."]}),"\n",(0,r.jsx)(n.h2,{id:"open-source",children:"Open Source"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"zrok"})," is licensed under Apache 2.0."]}),"\n",(0,r.jsxs)(n.p,{children:["Check ",(0,r.jsx)(n.a,{href:"https://github.com/orgs/openziti/projects/16",children:"the roadmap"})," if you're thinking about the future. We would love to hear your ideas for ",(0,r.jsx)(n.code,{children:"zrok"}),"!"]}),"\n",(0,r.jsxs)(n.p,{children:["The best ways to engage are ",(0,r.jsx)(n.a,{href:"https://openziti.discourse.group/",children:"Discourse"})," for questions and ",(0,r.jsx)(n.a,{href:"https://github.com/openziti/zrok/issues",children:"GitHub Issues"})," for documenting problems."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/docs/concepts/opensource",children:"Read more about zrok open source"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"ziti-native",children:"Ziti native"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"zrok"})," is a ",(0,r.jsx)(n.em,{children:"Ziti Native Application"}),", built on the ",(0,r.jsx)(n.a,{href:"https://openziti.io",children:"OpenZiti"})," platform, and supported by the OpenZiti community and NetFoundry team."]}),"\n",(0,r.jsx)(n.h2,{id:"whats-it-for",children:"What's it for?"}),"\n",(0,r.jsxs)(n.p,{children:["Use ",(0,r.jsx)(n.code,{children:"zrok"})," to share a running service, like a web server or a network socket, or to share a directory of static files."]}),"\n",(0,r.jsxs)(n.p,{children:["If ",(0,r.jsx)(n.a,{href:"/docs/concepts/sharing-public",children:"sharing publicly"}),", you can reserve a subdomain, enable authentication options, or both. Public shares proxy HTTPS to your service or files."]}),"\n",(0,r.jsxs)(n.p,{children:["If ",(0,r.jsx)(n.a,{href:"/docs/concepts/sharing-private",children:"sharing privately"}),", only users with the share token can access your share. In addition to what you can share publicly, private shares can include TCP and UDP services."]}),"\n",(0,r.jsx)(n.h2,{id:"installing-the-zrok-command",children:"Installing the zrok Command"}),"\n",(0,r.jsx)(o.N,{children:(0,r.jsxs)("div",{className:a.Z.downloadContainer,children:[(0,r.jsx)(t.Z,{osName:"Windows",osLogo:"/img/logo-windows.svg",infoText:"Binary executable",guideLink:"/docs/guides/install/windows"}),(0,r.jsx)(t.Z,{osName:"macOS",osLogo:"/img/logo-apple.svg",infoText:"Binary executable",guideLink:"/docs/guides/install/macos"}),(0,r.jsx)(t.Z,{osName:"Linux",osLogo:"/img/logo-linux.svg",infoText:"DEB, RPM packages",guideLink:"/docs/guides/install/linux"})]})}),"\n",(0,r.jsx)(n.h2,{id:"generating-an-invitation",children:"Generating an Invitation"}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["If not using ",(0,r.jsx)(n.code,{children:"zrok.io"})," (zrok-as-a-service), you must configure the ",(0,r.jsx)(n.code,{children:"zrok"})," command to use your instance. See the ",(0,r.jsx)(n.a,{href:"/docs/guides/self-hosting/instance-configuration",children:"instance configuration guide"})," in the self-hosting section for details."]})}),"\n",(0,r.jsxs)(n.p,{children:["Invite yourself to ",(0,r.jsx)(n.code,{children:"zrok"})," by running the ",(0,r.jsx)(n.code,{children:"zrok invite"})," command:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-text",children:"zrok invite\n"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-buttonless",metastring:'title="Output"',children:"enter and confirm your email address...\n\n> user@domain.com\n> user@domain.com\n\n[ Submit ]\n\ninvitation sent to 'user@domain.com'!\n"})}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"zrok invite"})," command presents a small form that allows you to enter (and then confirm) your email address. Tabbing to the ",(0,r.jsx)(n.code,{children:"[ Submit ]"})," button will send the request to your configured ",(0,r.jsx)(n.code,{children:"zrok"})," service."]}),"\n",(0,r.jsxs)(n.p,{children:["Next, check the email where you sent the invite. You should receive a message asking you to click a link to create your ",(0,r.jsx)(n.code,{children:"zrok"})," account. When you click that link, you will be brought to a web page that will allow you to set a password for your new account:"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Enter a Password",src:s(9744).Z+"",width:"1791",height:"1362"})}),"\n",(0,r.jsxs)(n.p,{children:["Enter a password and its confirmation, and click the ",(0,r.jsx)(n.code,{children:"Register Account"})," button. You'll see the following:"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Successful Registration",src:s(242).Z+"",width:"1791",height:"1369"})}),"\n",(0,r.jsxs)(n.p,{children:['For now, we\'ll ignore the "enable your shell for zrok" section. Just click the ',(0,r.jsx)(n.code,{children:"zrok web portal"})," link:"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Web Login",src:s(9509).Z+"",width:"1791",height:"1362"})}),"\n",(0,r.jsxs)(n.p,{children:["After clicking the ",(0,r.jsx)(n.code,{children:"Log In"})," button, you'll be brought into the ",(0,r.jsx)(n.code,{children:"zrok"})," ",(0,r.jsx)(n.em,{children:"web console"}),":"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Web Console; Empty",src:s(2945).Z+"",width:"1791",height:"1362"})}),"\n",(0,r.jsxs)(n.p,{children:["Congratulations! Your ",(0,r.jsx)(n.code,{children:"zrok"})," account is ready to go!"]}),"\n",(0,r.jsx)(n.h2,{id:"enabling-your-zrok-environment",children:"Enabling Your zrok Environment"}),"\n",(0,r.jsxs)(n.p,{children:["When your ",(0,r.jsx)(n.code,{children:"zrok"})," account was created, the service generated a ",(0,r.jsx)(n.em,{children:"secret token"})," that identifies and authenticates in a single step. Protect your secret token as if it were a password, or an important account number; it's a ",(0,r.jsx)(n.em,{children:"secret"}),", protect it."]}),"\n",(0,r.jsxs)(n.p,{children:["When we left off you had downloaded, extracted, and configured your ",(0,r.jsx)(n.code,{children:"zrok"})," environment. In order to use that environment with your account, you'll need to ",(0,r.jsx)(n.code,{children:"enable"})," it. Enabling an environment generates a secure identity and the necessary underlying security policies with the OpenZiti network hosting the ",(0,r.jsx)(n.code,{children:"zrok"})," service."]}),"\n",(0,r.jsxs)(n.p,{children:["From the web console, click on your email address in the upper right corner of the header. That drop down menu contains an ",(0,r.jsx)(n.code,{children:"Enable Your Environment"})," link. Click that link and a modal dialog will be shown like this:"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Enable Modal Dialog",src:s(9042).Z+"",width:"1791",height:"1369"})}),"\n",(0,r.jsxs)(n.p,{children:["This dialog box shows you the ",(0,r.jsx)(n.code,{children:"zrok enable"})," command that you can use to enable any shell to work with your ",(0,r.jsx)(n.code,{children:"zrok"})," account with a single command."]}),"\n",(0,r.jsx)(n.p,{children:"Let's copy that command and paste it into your shell:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-buttonless",metastring:'title="Example"',children:"$ zrok enable klFEoIi0QAg7 \n\u28fb contacting the zrok service...\n"})}),"\n",(0,r.jsx)(n.p,{children:"After a few seconds, the message will change and indicate that the enable operation succeeded:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-buttonless",metastring:'title="Example"',children:"$ zrok enable klFEoIi0QAg7 \n\u28fb the zrok environment was successfully enabled...\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Now, if we run a ",(0,r.jsx)(n.code,{children:"zrok status"})," command, you will see the details of your environment:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-txt",children:"zrok status\n"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-buttonless",metastring:'title="Output"',children:"Config:\n\n CONFIG VALUE SOURCE\n apiEndpoint https://api.staging.zrok.io env\n\nEnvironment:\n\n PROPERTY VALUE\n Secret Token <>\n Ziti Identity <>\n"})}),"\n",(0,r.jsx)(n.p,{children:"Excellent... our environment is now fully enabled."}),"\n",(0,r.jsxs)(n.p,{children:["If we return to the ",(0,r.jsx)(n.em,{children:"web console"}),", we'll now see the new environment reflected in the explorer view:"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"New Environment in Web UI",src:s(5546).Z+"",width:"1791",height:"1369"})}),"\n",(0,r.jsxs)(n.p,{children:["In my case, the environment is named ",(0,r.jsx)(n.code,{children:"michael@ziti-lx"}),", which is the username of my shell and the hostname of the system the shell is running on."]}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["Should you want to use a non-default name for your environment, you can pass the ",(0,r.jsx)(n.code,{children:"-d"})," option to the ",(0,r.jsx)(n.code,{children:"zrok enable"})," command. See ",(0,r.jsx)(n.code,{children:"zrok enable --help"})," for details."]})}),"\n",(0,r.jsxs)(n.p,{children:["If you click on the environment node in the explorer in the ",(0,r.jsx)(n.em,{children:"web console"}),", the details panel shown at the bottom of the page will change:"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Empty Environment",src:s(3858).Z+"",width:"1791",height:"1369"})}),"\n",(0,r.jsxs)(n.p,{children:["The explorer supports clicking, dragging, mouse wheel zooming, and selecting the nodes in the graph for more information (and available actions) for the selected node. If you ever get lost in the explorer, click the ",(0,r.jsx)(n.img,{alt:"Zoom to Fit",src:s(3843).Z+"",width:"30",height:"25"})," ",(0,r.jsx)(n.em,{children:"zoom to fit"})," icon in the lower right corner of the explorer."]}),"\n",(0,r.jsxs)(n.p,{children:["If we click on the ",(0,r.jsx)(n.code,{children:"Detail"})," tab for our environment, we'll see something like:"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Environment Detail",src:s(2534).Z+"",width:"1791",height:"1369"})}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["With your ",(0,r.jsx)(n.code,{children:"zrok"})," account you can ",(0,r.jsx)(n.code,{children:"zrok enable"})," multiple environments. This will allow you to run ",(0,r.jsx)(n.code,{children:"zrok share"})," in one environment, and ",(0,r.jsx)(n.code,{children:"zrok access"})," in other environments."]})}),"\n",(0,r.jsx)(n.p,{children:"Your environment is fully ready to go. Now we can move on to the fun stuff..."}),"\n",(0,r.jsx)(n.h2,{id:"sharing",children:"Sharing"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"zrok"})," is designed to make sharing resources as effortless as possible, while providing a high degree of security and control."]}),"\n",(0,r.jsx)(n.h3,{id:"ephemeral-by-default",children:"Ephemeral by Default"}),"\n",(0,r.jsxs)(n.p,{children:["Shared resources are ",(0,r.jsx)(n.em,{children:"ephemeral"})," by default; as soon as you terminate the ",(0,r.jsx)(n.code,{children:"zrok share"})," command, the entire share is removed and is no longer available to any users. Identifiers for shared resources are randomly allocated when the share is created."]}),"\n",(0,r.jsx)(n.h3,{id:"public-shares-and-frontends",children:"Public Shares and Frontends"}),"\n",(0,r.jsxs)(n.p,{children:["Resources that are shared ",(0,r.jsx)(n.em,{children:"publicly"})," are exposed to any users on the internet who have access to the ",(0,r.jsx)(n.code,{children:"zrok"}),' instance\'s "frontend".']}),"\n",(0,r.jsx)(n.p,{children:"A frontend is an HTTPS listener exposed to the internet, that lets any user with your ephemeral share token access your publicly shared resources."}),"\n",(0,r.jsxs)(n.p,{children:["For example, I might create a public share using the ",(0,r.jsx)(n.code,{children:"zrok share public"})," command, which results in my ",(0,r.jsx)(n.code,{children:"zrok"})," instance exposing a URL like ",(0,r.jsx)(n.code,{children:"https://2ptgbr8tlfvk.share.zrok.io"})," to access my resources."]}),"\n",(0,r.jsxs)(n.p,{children:['In this case, my share was given the "share token" of ',(0,r.jsx)(n.code,{children:"2ptgbr8tlfvk"}),". That URL can be given to any user, allowing them to immediately access the shared resources directly from my local environment, all without exposing any access to my private, secure environment. The physical network location of my environment is not exposed to anonymous consumers of my resources."]}),"\n",(0,r.jsxs)(n.admonition,{type:"note",children:[(0,r.jsxs)(n.p,{children:["Here is the ",(0,r.jsx)(n.code,{children:"--help"})," output from ",(0,r.jsx)(n.code,{children:"zrok share public"}),":"]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-text",children:"zrok share public\n"})}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-buttonless",metastring:'title="Output"',children:'Error: accepts 1 arg(s), received 0\nUsage:\n zrok share public [flags]\n\nFlags:\n --backend-mode string The backend mode {proxy, web, caddy, drive} (default "proxy")\n --basic-auth stringArray Basic authentication users (,...)\n --frontends stringArray Selected frontends to use for the share (default [public])\n --headless Disable TUI and run headless\n -h, --help help for public\n --insecure Enable insecure TLS certificate validation for \n\nGlobal Flags:\n -p, --panic Panic instead of showing pretty errors\n -v, --verbose Enable verbose logging\n\n[ERROR]: an error occurred (accepts 1 arg(s), received 0)\n'})}),(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:""})," defines the path to the local resource that you intend to share. The form of ",(0,r.jsx)(n.code,{children:""})," depends on the ",(0,r.jsx)(n.code,{children:"--backend-mode"})," that you're using."]}),(0,r.jsxs)(n.p,{children:["In the case of ",(0,r.jsx)(n.code,{children:"--backend-mode proxy"}),", ",(0,r.jsx)(n.code,{children:""})," should be a URL to an HTTP endpoint."]}),(0,r.jsxs)(n.p,{children:["In the case of ",(0,r.jsx)(n.code,{children:"--backend-mode web"}),", ",(0,r.jsx)(n.code,{children:""}),' is the path to a file on disk that serves as the "root" of the file tree to be shared.']})]}),"\n",(0,r.jsx)(n.p,{children:"If we return to the web console, we see our share in the explorer:"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Web Console Share",src:s(6097).Z+"",width:"1791",height:"1369"})}),"\n",(0,r.jsxs)(n.p,{children:["If we click on our new share in the explorer, we can see the share details:\n",(0,r.jsx)(n.img,{alt:"Share Details",src:s(4647).Z+"",width:"1791",height:"1369"})]}),"\n",(0,r.jsxs)(n.p,{children:["If we click on the ",(0,r.jsx)(n.em,{children:"frontend endpoint"})," a new browser tab opens and we see the content of our share:\n",(0,r.jsx)(n.img,{alt:"Share Frontend",src:s(6254).Z+"",width:"1669",height:"1033"})]}),"\n",(0,r.jsx)(n.p,{children:"If we click on the environment in the explorer, we're shown all of the shares for that environment (including our new share), along with a spark line that shows the activity:"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Environment Spark Line",src:s(9737).Z+"",width:"1791",height:"1369"})}),"\n",(0,r.jsxs)(n.p,{children:["And as soon as I terminate the ",(0,r.jsx)(n.code,{children:"zrok share"})," client, the resources are removed from the ",(0,r.jsx)(n.code,{children:"zrok"})," environment."]}),"\n",(0,r.jsx)(n.p,{children:"If we try to reload the frontend endpoint in our web browser, we'll see:"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Not Found",src:s(5724).Z+"",width:"1556",height:"1229"})}),"\n",(0,r.jsx)(n.h3,{id:"private-shares",children:"Private Shares"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"zrok"})," also provides a powerful ",(0,r.jsx)(n.em,{children:"private"})," sharing model. If I execute the following command:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-buttonless",metastring:'title="Example"',children:"$ zrok share private http://localhost:8080\n"})}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"zrok"})," service will respond with the following:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-buttonless",metastring:'title="Output"',children:"access your share with: zrok access private wvszln4dyz9q\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Rather than allowing access to your service through a public frontend, a ",(0,r.jsx)(n.em,{children:"private"})," share is only exposed to the underlying OpenZiti network, and can only be accessed using the ",(0,r.jsx)(n.code,{children:"zrok access"})," command."]}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"zrok access private wvszln4dyz9q"})," command can be run by any ",(0,r.jsx)(n.code,{children:"zrok"})," user, allowing them to create and bind a local HTTP listener, that allows for private access to your shared resources."]}),"\n",(0,r.jsx)(n.h3,{id:"proxy-backend-mode",children:"Proxy Backend Mode"}),"\n",(0,r.jsxs)(n.p,{children:["Without specifying a ",(0,r.jsx)(n.em,{children:"backend mode"}),", the ",(0,r.jsx)(n.code,{children:"zrok share"})," command will assume that you're trying to share a ",(0,r.jsx)(n.code,{children:"proxy"})," resource. A ",(0,r.jsx)(n.code,{children:"proxy"})," resource is usually some private HTTP/HTTPS endpoint (like a development server, or a private application) running in your local environment. Usually such an endpoint would have no inbound connectivity except for however it is reachable from your local environment. It might be running on ",(0,r.jsx)(n.code,{children:"localhost"}),", or only listening on a private LAN segment behind a firewall."]}),"\n",(0,r.jsxs)(n.p,{children:["For these services a ",(0,r.jsx)(n.code,{children:"proxy"})," share will allow those endpoints to be reached, either ",(0,r.jsx)(n.em,{children:"publicly"})," or ",(0,r.jsx)(n.em,{children:"privately"})," through the ",(0,r.jsx)(n.code,{children:"zrok"})," service."]}),"\n",(0,r.jsx)(n.h3,{id:"web-backend-mode",children:"Web Backend Mode"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"zrok share"})," command accepts a ",(0,r.jsx)(n.code,{children:"--backend-mode"})," option. Besides ",(0,r.jsx)(n.code,{children:"proxy"}),", the current ",(0,r.jsx)(n.code,{children:"v0.3"})," release (as of this writing) also supports a ",(0,r.jsx)(n.code,{children:"web"})," mode. The ",(0,r.jsx)(n.code,{children:"web"})," mode allows you to specify a local folder on your filesystem, and instantly turns your ",(0,r.jsx)(n.code,{children:"zrok"})," client into a web server, exposing your web content either ",(0,r.jsx)(n.em,{children:"publicly"})," or ",(0,r.jsx)(n.em,{children:"privately"})," without having to a configure a web server."]}),"\n",(0,r.jsx)(n.h3,{id:"reserved-shares",children:"Reserved Shares"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"zrok"})," shares are ",(0,r.jsx)(n.em,{children:"ephemeral"}),' unless you specifically create a "reserved" share.']}),"\n",(0,r.jsxs)(n.p,{children:["A reserved share can be re-used multiple times; it will survive termination of the ",(0,r.jsx)(n.code,{children:"zrok share"})," command, allowing for longer-lasting semi-permanent access to shared resources."]}),"\n",(0,r.jsx)(n.p,{children:"The first step is to create the reserved share:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-txt",metastring:'title="Example"',children:"$ zrok reserve public --backend-mode web v0.3_getting_started\n[ 0.275] INFO main.(*reserveCommand).run: your reserved share token is 'mltwsinym1s2'\n[ 0.275] INFO main.(*reserveCommand).run: reserved frontend endpoint: https://mltwsinym1s2.share.zrok.io\n"})}),"\n",(0,r.jsxs)(n.p,{children:["I'm asking the ",(0,r.jsx)(n.code,{children:"zrok"})," service to reserve a share with a ",(0,r.jsx)(n.code,{children:"web"})," backend mode, pointing at my local ",(0,r.jsx)(n.code,{children:"docs"})," folder."]}),"\n",(0,r.jsxs)(n.p,{children:["You'll want to remember the share token (",(0,r.jsx)(n.code,{children:"mltwsinym1s2"})," in this case), and the frontend endpoint URL. If this were a ",(0,r.jsx)(n.em,{children:"private"})," reserved share, there would not be a frontend URL."]}),"\n",(0,r.jsx)(n.p,{children:"If we do nothing else, and then point a web browser at the frontend endpoint, we get:"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Not Found",src:s(7369).Z+"",width:"1556",height:"1229"})}),"\n",(0,r.jsxs)(n.p,{children:["This is the ",(0,r.jsx)(n.code,{children:"404"})," error message returned by the ",(0,r.jsx)(n.code,{children:"zrok"})," frontend. We're getting this because we haven't yet started up a ",(0,r.jsx)(n.code,{children:"zrok share"})," for the service. Let's do that:"]}),"\n",(0,r.jsx)(n.p,{children:"This command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-txt",metastring:'title="Example"',children:"$ zrok share reserved mltwsinym1s2\n"})}),"\n",(0,r.jsx)(n.p,{children:"...results in a new share backend starting up and connecting to the existing reserved share:"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"zrok share reserved",src:s(1577).Z+"",width:"951",height:"706"})}),"\n",(0,r.jsxs)(n.p,{children:["And now if we refresh the frontend endpoint URL in the web browser, we'll see an index of the ",(0,r.jsx)(n.code,{children:"docs"})," directory:"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"zrok docs share",src:s(6254).Z+"",width:"1669",height:"1033"})}),"\n",(0,r.jsxs)(n.p,{children:["With the reserved share, we're free to stop and restart the ",(0,r.jsx)(n.code,{children:"zrok share reserved"})," command as many times as we want, without losing the token for our share."]}),"\n",(0,r.jsxs)(n.p,{children:["When we're done with the reserved share, we can ",(0,r.jsx)(n.em,{children:"release"})," it using this command:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-txt",metastring:'title="Example"',children:"$ zrok release mltwsinym1s2\n[ 0.230] INFO main.(*releaseCommand).run: reserved share 'mltwsinym1s2' released\n"})}),"\n",(0,r.jsx)(n.h2,{id:"concepts-review",children:"Concepts Review"}),"\n",(0,r.jsxs)(n.p,{children:["In summary, ",(0,r.jsx)(n.code,{children:"zrok"})," lets you easily and securely share resources with both general internet users (through ",(0,r.jsx)(n.em,{children:"public"})," sharing) and also with other ",(0,r.jsx)(n.code,{children:"zrok"})," users (through ",(0,r.jsx)(n.em,{children:"private"})," sharing)."]}),"\n",(0,r.jsxs)(n.p,{children:["Here's a quick review of the ",(0,r.jsx)(n.code,{children:"zrok"})," mental model and the vocabulary."]}),"\n",(0,r.jsx)(n.h3,{id:"instance-and-account",children:"Instance and Account"}),"\n",(0,r.jsxs)(n.p,{children:["You create an ",(0,r.jsx)(n.em,{children:"account"})," with a ",(0,r.jsx)(n.code,{children:"zrok"})," ",(0,r.jsx)(n.em,{children:"instance"}),". Your account is identified by a username and a password, which you use to log into the ",(0,r.jsx)(n.em,{children:"web console"}),". Your account also has a ",(0,r.jsx)(n.em,{children:"secret token"}),", which you will use to authenticate from the ",(0,r.jsx)(n.code,{children:"zrok"})," command-line to interact with the ",(0,r.jsx)(n.em,{children:"instance"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["You create a new ",(0,r.jsx)(n.em,{children:"account"})," with a ",(0,r.jsx)(n.code,{children:"zrok"})," ",(0,r.jsx)(n.em,{children:"instance"})," through the ",(0,r.jsx)(n.code,{children:"zrok invite"})," command."]}),"\n",(0,r.jsx)(n.h3,{id:"environment",children:"Environment"}),"\n",(0,r.jsxs)(n.p,{children:["Using your ",(0,r.jsx)(n.em,{children:"secret token"})," you use the ",(0,r.jsx)(n.code,{children:"zrok"})," command-line interface to create an ",(0,r.jsx)(n.em,{children:"environment"}),". An ",(0,r.jsx)(n.em,{children:"environment"})," corresponds to a single command-line user on a specific ",(0,r.jsx)(n.em,{children:"host system"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["You create a new ",(0,r.jsx)(n.em,{children:"environment"})," by using the ",(0,r.jsx)(n.code,{children:"zrok enable"})," command."]}),"\n",(0,r.jsx)(n.h3,{id:"shares",children:"Shares"}),"\n",(0,r.jsxs)(n.p,{children:["Once you've enabled an ",(0,r.jsx)(n.em,{children:"environment"}),", you then create one or more ",(0,r.jsx)(n.em,{children:"shares"}),". Shares have either a ",(0,r.jsx)(n.em,{children:"public"})," or ",(0,r.jsx)(n.em,{children:"private"})," ",(0,r.jsx)(n.em,{children:"sharing mode"}),". ",(0,r.jsx)(n.em,{children:"Shares"})," share a specific type of resource using a ",(0,r.jsx)(n.em,{children:"backend mode"}),". As of this writing ",(0,r.jsx)(n.code,{children:"zrok"})," supports a ",(0,r.jsx)(n.code,{children:"proxy"})," ",(0,r.jsx)(n.em,{children:"backend mode"})," to share local HTTP resources as a ",(0,r.jsx)(n.em,{children:"reverse proxy"}),". ",(0,r.jsx)(n.code,{children:"zrok"})," also supports a ",(0,r.jsx)(n.code,{children:"web"})," ",(0,r.jsx)(n.em,{children:"backend mode"})," to share local file and HTML resources by enabling a basic HTTP server."]}),"\n",(0,r.jsxs)(n.p,{children:["Every ",(0,r.jsx)(n.em,{children:"share"})," is identified by a ",(0,r.jsx)(n.em,{children:"share token"}),". ",(0,r.jsx)(n.em,{children:"Public shares"})," can be accessed through either a ",(0,r.jsx)(n.em,{children:"frontend"})," instance offered through the ",(0,r.jsx)(n.code,{children:"zrok"})," ",(0,r.jsx)(n.em,{children:"instance"}),", or through the ",(0,r.jsx)(n.code,{children:"zrok access"})," command. ",(0,r.jsx)(n.em,{children:"Private shares"})," can only be accessed through the ",(0,r.jsx)(n.code,{children:"zrok access"})," command."]}),"\n",(0,r.jsxs)(n.p,{children:["You use the ",(0,r.jsx)(n.code,{children:"zrok share"})," command to create and enable ",(0,r.jsx)(n.em,{children:"ephemeral shares"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"reserved-shares-1",children:"Reserved Shares"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"zrok"})," supports creating ",(0,r.jsx)(n.em,{children:"shares"})," that have a consistent ",(0,r.jsx)(n.em,{children:"share token"})," that survives restarts of the ",(0,r.jsx)(n.code,{children:"zrok share"})," command. These are considered ",(0,r.jsx)(n.em,{children:"non-ephemeral"}),", and is callled a ",(0,r.jsx)(n.em,{children:"reserved share"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["You use the ",(0,r.jsx)(n.code,{children:"zrok reserve"})," command to create ",(0,r.jsx)(n.em,{children:"reserved shares"}),". Reserved shares last until you use the ",(0,r.jsx)(n.code,{children:"zrok release"})," command to delete them."]}),"\n",(0,r.jsx)(n.h2,{id:"self-hosting-an-instance",children:"Self-Hosting an Instance"}),"\n",(0,r.jsxs)(n.p,{children:["Interested in self-hosting your own ",(0,r.jsx)(n.code,{children:"zrok"})," instance? See the ",(0,r.jsx)(n.a,{href:"/docs/guides/self-hosting/linux",children:"self-hosting guide"})," for details."]})]})}function x(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},4908:(e,n,s)=>{s.d(n,{L:()=>t,N:()=>a});var r=s(7294),i=s(5893);const o=(0,r.createContext)([]),t=()=>(0,r.useContext)(o),a=e=>{let{children:n}=e;const[s,t]=(0,r.useState)([]);return(0,r.useEffect)((()=>{(async()=>{try{const e=await fetch("https://api.github.com/repos/openziti/zrok/releases/latest");if(!e.ok)throw new Error(`HTTP error! status: ${e.status}`);const n=(await e.json()).assets.map((e=>({name:e.name,url:e.browser_download_url,arch:e.name.replace(".tar.gz","").split("_")[3]})));console.log("Fetched assets:",n),t(n)}catch(e){console.error("Error fetching the release assets:",e)}})()}),[]),(0,i.jsx)(o.Provider,{value:s,children:n})}},3298:(e,n,s)=>{s.d(n,{Z:()=>c});s(7294);var r=s(4908),i=s(7597),o=s(2949),t=s(5893);const a=e=>{switch(e){case"amd64":return"x86_64";case"arm64":return"ARM64";case"armv7":return"ARM";default:return e.toUpperCase()}},c=e=>{let{osName:n,osLogo:s,infoText:c,guideLink:d}=e;const{colorMode:l}=(0,o.I)(),h=(0,r.L)();console.log("Assets in DownloadCard:",h);const m=(e=>{switch(e){case"Windows":return"windows";case"macOS":return"darwin";case"Linux":return"linux";default:return""}})(n),u=h.filter((e=>e.name.includes(m)));return console.log("Filtered assets for",n,"in DownloadCard:",u),(0,t.jsxs)("div",{className:i.Z.downloadCard,children:[(0,t.jsx)("div",{className:i.Z.imgContainer,children:(0,t.jsx)("img",{src:s,alt:`${n} logo`})}),(0,t.jsx)("h3",{children:n}),u.length>0&&(0,t.jsx)("ul",{children:u.map(((e,n)=>(0,t.jsx)("li",{className:i.Z.downloadButtons,children:(0,t.jsx)("a",{href:e.url,className:i.Z.downloadLinks,children:a(e.arch)})},n)))}),d&&(0,t.jsxs)("div",{className:i.Z.cardFooter,children:[(0,t.jsx)("p",{children:c}),(0,t.jsx)("a",{href:d,children:"GUIDE"}),(0,t.jsx)("p",{})]})]})}},7597:(e,n,s)=>{s.d(n,{Z:()=>r});const r={downloadContainer:"downloadContainer_nNgj",downloadCard:"downloadCard_D_EY",cardFooter:"cardFooter_Rhom",downloadButtons:"downloadButtons_NPAP",downloadLinks:"downloadLinks_thSu",imgContainer:"imgContainer_r0QA"}},9042:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_enable_modal-45da63a6907e930daaa4c798272ce5fa.png"},5724:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_not_found-fa3415937c341eb10e1eb98c9b063583.png"},242:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_registration_success-05e7e328284f6dc38cd993322698d38b.png"},7369:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_reserved_not_found-2519707e5cc3e635b7a6feb381c1d040.png"},1577:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_share_reserved-6bce67775ce2c41abb0ef13ee1fad972.png"},9744:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_verify-22a26d401b9a77a4278f3c0f54d2a981.png"},2945:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_web_console_empty-cce147eaf8e7bc83abe556336a4aea98.png"},9737:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_web_console_environment_spark-925c0709ed7a42f0a708ab0523cdeb5f.png"},6097:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_web_console_explorer_share-11236f68819da60014d5444e7429c189.png"},4647:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_web_console_share_detail-efeaa472d5e5c225a160f6d5647086b3.png"},6254:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_web_console_share_frontend-d7c0d6495493c00b94ae237339f2dc2d.png"},9509:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_web_login-a6161cc79e66932fab76994bdfb8f9c1.png"},2534:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_web_ui_empty_environment_detail-153c921ade86f924079947b0f734e3ff.png"},3858:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_web_ui_empty_shares-048c08c18477bcabb9fa8c1b58537012.png"},5546:(e,n,s)=>{s.d(n,{Z:()=>r});const r=s.p+"assets/images/zrok_web_ui_new_environment-414d8e8fc25b09f257cb40ba47d6acbb.png"},3843:(e,n,s)=>{s.d(n,{Z:()=>r});const r="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAZCAIAAACpVwlNAAAEr2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIKICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgdGlmZjpJbWFnZUxlbmd0aD0iMjUiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMzAiCiAgIHRpZmY6UmVzb2x1dGlvblVuaXQ9IjIiCiAgIHRpZmY6WFJlc29sdXRpb249Ijk2LzEiCiAgIHRpZmY6WVJlc29sdXRpb249Ijk2LzEiCiAgIGV4aWY6UGl4ZWxYRGltZW5zaW9uPSIzMCIKICAgZXhpZjpQaXhlbFlEaW1lbnNpb249IjI1IgogICBleGlmOkNvbG9yU3BhY2U9IjEiCiAgIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiCiAgIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIKICAgeG1wOk1vZGlmeURhdGU9IjIwMjMtMDEtMTlUMTA6NTY6NTYtMDU6MDAiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjMtMDEtMTlUMTA6NTY6NTYtMDU6MDAiPgogICA8eG1wTU06SGlzdG9yeT4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJwcm9kdWNlZCIKICAgICAgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWZmaW5pdHkgUGhvdG8gMi4wLjMiCiAgICAgIHN0RXZ0OndoZW49IjIwMjMtMDEtMTlUMTA6NTY6NTYtMDU6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KPD94cGFja2V0IGVuZD0iciI/Pq+HLHgAAAGBaUNDUHNSR0IgSUVDNjE5NjYtMi4xAAAokXWRy0tCQRSHP7UwemBQixYtJKyVRg8Q27RQyoJqYQZZbfTmI/BxuVcJaRu0FQqiNr0W9RfUNmgdBEURRNtaF7UpuZ2rghF5hjnzzW/OOcycAWs4rWT0piHIZPNaKOh3LkaWnPYXLHThwIclqujq7PxkmIb2eS/RYrces1bjuH+tbTWuK2BpER5XVC0vPCU8s55XTd4R7lZS0VXhM2G3JhcUvjP1WJVfTU5W+dtkLRwKgLVT2Jn8xbFfrKS0jLC8HFcmXVBq9zFf0h7PLszL2iezF50QQfw4mWaCAF6GGRPvxcMIg7KjQf5QJX+OnOQq4lWKaKyRJEUet6gFqR6XNSF6XEaaotn/v33VE6Mj1ertfmh+Noz3frBvQ7lkGF9HhlE+BtsTXGbr+blD8H2IXqprrgNwbML5VV2L7cLFFvQ8qlEtWpFsMq2JBLydQkcEum6gdbnas9o5Jw8Q3pCvuoa9fRiQeMfKD2DYZ+PDGzxnAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABZklEQVRIie2VvW7CMBDHr1UfwE5fII7lvahIWUEiQ7qxMLEwsVQMSB0YKsTExsDGxFs0QyqlYyMVld3k4wWw/QgMlqp+JXFQGZB649n3k+9/f9sX9w+PcJq4PBH3H/0zrkrWfK99jVF5/V6qIIzqod1m485rC6nK0S5GAPArvRDNHFtINZ0vviQp4Un2OTObjIs6q6G122yMhgPfaxvuN0VbGDHHBgDm2FbVAGqgLYyEVPFmCwDB84uQilHyB2i32ej3uoySvZDT+YInGaPE77QqlSkznz5vv9cFAEbJdL4QUlkYjYYDnYnf3o9HC6mewog5ttZBq7xcrf1OK95sy61ZgQaAIIx2lGgdRsPBcrXmSbYXstLyRmPkSWZh5HdaAODe3uipVlaZmk9IxdMcAHiam3DBRJCPCMJol+bfbuMxaJ7mjJLZZFxeb2Gku6mDTrJXjExeviILFqJF8WtpGOf5y5wn+gBcXI4F9z6rgwAAAABJRU5ErkJggg=="},1151:(e,n,s)=>{s.d(n,{Z:()=>a,a:()=>t});var r=s(7294);const i={},o=r.createContext(i);function t(e){const n=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),r.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/main.12d5b0be.js b/assets/js/main.12d5b0be.js deleted file mode 100644 index 02b14c69..00000000 --- a/assets/js/main.12d5b0be.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see main.12d5b0be.js.LICENSE.txt */ -(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[179],{830:(e,t,n)=>{"use strict";n.d(t,{W:()=>o});var r=n(7294);function o(){return r.createElement("svg",{width:"20",height:"20",className:"DocSearch-Search-Icon",viewBox:"0 0 20 20"},r.createElement("path",{d:"M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"}))}},723:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});n(7294);var r=n(8356),o=n.n(r),a=n(6887);const i={"0654c903":[()=>n.e(2022).then(n.bind(n,445)),"@site/../docs/guides/self-hosting/self_hosting_guide.md",445],"07d0b302":[()=>n.e(8905).then(n.bind(n,3103)),"@site/../docs/concepts/http.md",3103],"0c66edb9":[()=>n.e(58).then(n.bind(n,2732)),"@site/../docs/guides/permission-modes.md",2732],"14eb3368":[()=>Promise.all([n.e(532),n.e(9817)]).then(n.bind(n,4228)),"@theme/DocCategoryGeneratedIndexPage",4228],17896441:[()=>Promise.all([n.e(532),n.e(2312),n.e(7918)]).then(n.bind(n,1720)),"@theme/DocItem",1720],"1a4e3797":[()=>Promise.all([n.e(532),n.e(7920)]).then(n.bind(n,6434)),"@theme/SearchPage",6434],"1ba5bc99":[()=>Promise.all([n.e(532),n.e(7142)]).then(n.bind(n,1616)),"@site/../docs/guides/install/macos.mdx",1616],"21880a4d":[()=>n.e(8156).then(n.bind(n,8697)),"@site/../docs/guides/vpn/vpn.md",8697],"288b1075":[()=>n.e(2108).then(n.bind(n,8152)),"@site/../docs/guides/self-hosting/metrics-and-limits/configuring-metrics.md",8152],"2e812224":[()=>n.e(7076).then(n.bind(n,4695)),"@site/../docs/guides/docker-share/docker_public_share_guide.md",4695],"339d500a":[()=>n.e(1889).then(n.bind(n,6335)),"@site/../docs/concepts/tunnels.md",6335],"34e1d3b9":[()=>n.e(1360).then(n.bind(n,3901)),"@site/../docs/concepts/sharing-private.md",3901],"4555b262":[()=>n.e(1387).then(n.bind(n,2314)),"@site/../docs/guides/drives/cli.md",2314],"47881d5c":[()=>Promise.all([n.e(532),n.e(2312),n.e(1272),n.e(826)]).then(n.bind(n,6285)),"@site/../docs/guides/install/linux.mdx",6285],48230885:[()=>n.e(9828).then(n.bind(n,7569)),"@site/../docs/guides/self-hosting/nginx_tls_guide.md",7569],"50ef9c44":[()=>n.e(8198).then(n.bind(n,8413)),"@site/../docs/concepts/hosting.md",8413],"5b30ef33":[()=>n.e(1402).then(n.t.bind(n,5975,19)),"~docs/default/category-docs-tutorialsidebar-category-docker-share-495.json",5975],"5cd0a723":[()=>n.e(8993).then(n.bind(n,2121)),"@site/../docs/guides/self-hosting/instance-configuration.mdx",2121],"5e95c892":[()=>n.e(9661).then(n.bind(n,1892)),"@theme/DocsRoot",1892],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,6809)),"@generated/docusaurus.config",6809],"600b2345":[()=>n.e(4900).then(n.bind(n,169)),"@site/../docs/guides/self-hosting/metrics-and-limits/configuring-limits.md",169],"60d45520":[()=>n.e(1364).then(n.t.bind(n,7085,19)),"/home/runner/work/zrok/zrok/website/.docusaurus/docusaurus-theme-search-algolia/default/plugin-route-context-module-100.json",7085],"613b9d03":[()=>n.e(1055).then(n.t.bind(n,5745,19)),"/home/runner/work/zrok/zrok/website/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",5745],"6272ba0e":[()=>n.e(7176).then(n.bind(n,7806)),"@site/../docs/concepts/sharing-reserved.md",7806],"6e881e32":[()=>n.e(3182).then(n.bind(n,8214)),"@site/../docs/guides/self-hosting/oauth/configuring-oauth.md",8214],"75b20590":[()=>n.e(4838).then(n.bind(n,6162)),"@site/../docs/concepts/opensource.md",6162],"881eafa3":[()=>n.e(7209).then(n.t.bind(n,3047,19)),"~docs/default/category-docs-tutorialsidebar-category-oauth-2cf.json",3047],"8ae7f3b1":[()=>n.e(9212).then(n.t.bind(n,8429,19)),"~docs/default/category-docs-tutorialsidebar-category-guides-3fc.json",8429],"8ef4b25e":[()=>n.e(318).then(n.t.bind(n,2636,19)),"~docs/default/category-docs-tutorialsidebar-category-metrics-and-limits-42e.json",2636],"935f2afb":[()=>n.e(53).then(n.t.bind(n,1109,19)),"~docs/default/version-current-metadata-prop-751.json",1109],"9a9d4214":[()=>n.e(1711).then(n.t.bind(n,3769,19)),"/home/runner/work/zrok/zrok/website/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",3769],a7bd4aaa:[()=>n.e(8518).then(n.bind(n,8564)),"@theme/DocVersionRoot",8564],a94703ab:[()=>Promise.all([n.e(532),n.e(4368)]).then(n.bind(n,2674)),"@theme/DocRoot",2674],b6569025:[()=>Promise.all([n.e(532),n.e(6913)]).then(n.bind(n,9243)),"@site/../docs/guides/install/index.mdx",9243],bbbe662c:[()=>n.e(4196).then(n.bind(n,8724)),"@site/../docs/guides/docker-share/docker_private_share_guide.md",8724],bc747cac:[()=>n.e(8945).then(n.bind(n,3033)),"@site/../docs/concepts/index.md",3033],c015c796:[()=>n.e(2732).then(n.bind(n,2180)),"@site/../docs/concepts/files.md",2180],c304be44:[()=>Promise.all([n.e(532),n.e(5327)]).then(n.bind(n,6508)),"@site/../docs/guides/install/windows.mdx",6508],c4f5d8e4:[()=>n.e(4195).then(n.bind(n,2841)),"@site/src/pages/index.js",2841],cda0d2e5:[()=>Promise.all([n.e(532),n.e(2312),n.e(1272),n.e(174),n.e(5889)]).then(n.bind(n,9836)),"@site/../docs/guides/frontdoor.mdx",9836],e6ffb4b4:[()=>n.e(848).then(n.t.bind(n,1408,19)),"~docs/default/category-docs-tutorialsidebar-category-self-hosting-ed7.json",1408],f2348458:[()=>n.e(2992).then(n.bind(n,4732)),"@site/../docs/concepts/sharing-public.md",4732],f888b719:[()=>Promise.all([n.e(532),n.e(8938)]).then(n.bind(n,2800)),"@site/../docs/getting-started.mdx",2800]};var l=n(5893);function s(e){let{error:t,retry:n,pastDelay:r}=e;return t?(0,l.jsxs)("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"},children:[(0,l.jsx)("p",{children:String(t)}),(0,l.jsx)("div",{children:(0,l.jsx)("button",{type:"button",onClick:n,children:"Retry"})})]}):r?(0,l.jsx)("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:(0,l.jsx)("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb",children:(0,l.jsxs)("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2",children:[(0,l.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,l.jsx)("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,l.jsx)("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,l.jsx)("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,l.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,l.jsx)("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,l.jsx)("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,l.jsx)("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,l.jsx)("circle",{cx:"22",cy:"22",r:"8",children:(0,l.jsx)("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"})})]})})}):null}var c=n(9670),u=n(226);function d(e,t){if("*"===e)return o()({loading:s,loader:()=>n.e(1772).then(n.bind(n,1772)),modules:["@theme/NotFound"],webpack:()=>[1772],render(e,t){const n=e.default;return(0,l.jsx)(u.z,{value:{plugin:{name:"native",id:"default"}},children:(0,l.jsx)(n,{...t})})}});const r=a[`${e}-${t}`],d={},p=[],f=[],m=(0,c.Z)(r);return Object.entries(m).forEach((e=>{let[t,n]=e;const r=i[n];r&&(d[t]=r[0],p.push(r[1]),f.push(r[2]))})),o().Map({loading:s,loader:d,modules:p,webpack:()=>f,render(t,n){const o=JSON.parse(JSON.stringify(r));Object.entries(t).forEach((t=>{let[n,r]=t;const a=r.default;if(!a)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof a&&"function"!=typeof a||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{a[e]=r[e]}));let i=o;const l=n.split(".");l.slice(0,-1).forEach((e=>{i=i[e]})),i[l[l.length-1]]=a}));const a=o.__comp;delete o.__comp;const i=o.__context;return delete o.__context,(0,l.jsx)(u.z,{value:i,children:(0,l.jsx)(a,{...o,...n})})}})}const p=[{path:"/search/",component:d("/search/","a8e"),exact:!0},{path:"/docs/",component:d("/docs/","3e8"),routes:[{path:"/docs/",component:d("/docs/","e86"),routes:[{path:"/docs/",component:d("/docs/","28c"),routes:[{path:"/docs/category/docker-share/",component:d("/docs/category/docker-share/","246"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/category/guides/",component:d("/docs/category/guides/","319"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/category/metrics-and-limits/",component:d("/docs/category/metrics-and-limits/","16b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/category/oauth/",component:d("/docs/category/oauth/","089"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/category/self-hosting/",component:d("/docs/category/self-hosting/","607"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/concepts/",component:d("/docs/concepts/","fb7"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/concepts/files/",component:d("/docs/concepts/files/","18c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/concepts/hosting/",component:d("/docs/concepts/hosting/","e72"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/concepts/http/",component:d("/docs/concepts/http/","6d2"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/concepts/opensource/",component:d("/docs/concepts/opensource/","1e8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/concepts/sharing-private/",component:d("/docs/concepts/sharing-private/","355"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/concepts/sharing-public/",component:d("/docs/concepts/sharing-public/","de6"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/concepts/sharing-reserved/",component:d("/docs/concepts/sharing-reserved/","75a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/concepts/tunnels/",component:d("/docs/concepts/tunnels/","539"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/getting-started/",component:d("/docs/getting-started/","8ef"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/docker-share/docker_private_share_guide/",component:d("/docs/guides/docker-share/docker_private_share_guide/","037"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/docker-share/docker_public_share_guide/",component:d("/docs/guides/docker-share/docker_public_share_guide/","5f8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/drives/cli/",component:d("/docs/guides/drives/cli/","26a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/frontdoor/",component:d("/docs/guides/frontdoor/","7f7"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/install/",component:d("/docs/guides/install/","fdd"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/install/linux/",component:d("/docs/guides/install/linux/","e6c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/install/macos/",component:d("/docs/guides/install/macos/","8ec"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/install/windows/",component:d("/docs/guides/install/windows/","86f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/permission-modes/",component:d("/docs/guides/permission-modes/","d5b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/self-hosting/instance-configuration/",component:d("/docs/guides/self-hosting/instance-configuration/","737"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/self-hosting/metrics-and-limits/configuring-limits/",component:d("/docs/guides/self-hosting/metrics-and-limits/configuring-limits/","fb2"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/self-hosting/metrics-and-limits/configuring-metrics/",component:d("/docs/guides/self-hosting/metrics-and-limits/configuring-metrics/","4be"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/self-hosting/nginx_tls_guide/",component:d("/docs/guides/self-hosting/nginx_tls_guide/","df3"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/self-hosting/oauth/configuring-oauth/",component:d("/docs/guides/self-hosting/oauth/configuring-oauth/","a75"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/self-hosting/self_hosting_guide/",component:d("/docs/guides/self-hosting/self_hosting_guide/","ddb"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/guides/vpn/",component:d("/docs/guides/vpn/","155"),exact:!0,sidebar:"tutorialSidebar"}]}]}]},{path:"/",component:d("/","6c6"),exact:!0},{path:"*",component:d("*")}]},8934:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,t:()=>i});var r=n(7294),o=n(5893);const a=r.createContext(!1);function i(e){let{children:t}=e;const[n,i]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{i(!0)}),[]),(0,o.jsx)(a.Provider,{value:n,children:t})}},7221:(e,t,n)=>{"use strict";var r=n(7294),o=n(745),a=n(3727),i=n(405),l=n(412);const s=[n(2497),n(3310),n(8320),n(2295)];var c=n(723),u=n(6550),d=n(8790),p=n(5893);function f(e){let{children:t}=e;return(0,p.jsx)(p.Fragment,{children:t})}var m=n(5742),h=n(2263),g=n(4996),y=n(6668),b=n(833),v=n(4711),w=n(9727),k=n(3320),x=n(8780),S=n(197);function E(){const{i18n:{currentLocale:e,defaultLocale:t,localeConfigs:n}}=(0,h.Z)(),r=(0,v.l)(),o=n[e].htmlLang,a=e=>e.replace("-","_");return(0,p.jsxs)(m.Z,{children:[Object.entries(n).map((e=>{let[t,{htmlLang:n}]=e;return(0,p.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:n},t)})),(0,p.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}),(0,p.jsx)("meta",{property:"og:locale",content:a(o)}),Object.values(n).filter((e=>o!==e.htmlLang)).map((e=>(0,p.jsx)("meta",{property:"og:locale:alternate",content:a(e.htmlLang)},`meta-og-${e.htmlLang}`)))]})}function C(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,h.Z)(),r=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,h.Z)(),{pathname:r}=(0,u.TH)();return e+(0,x.applyTrailingSlash)((0,g.Z)(r),{trailingSlash:n,baseUrl:t})}(),o=t?`${n}${t}`:r;return(0,p.jsxs)(m.Z,{children:[(0,p.jsx)("meta",{property:"og:url",content:o}),(0,p.jsx)("link",{rel:"canonical",href:o})]})}function _(){const{i18n:{currentLocale:e}}=(0,h.Z)(),{metadata:t,image:n}=(0,y.L)();return(0,p.jsxs)(p.Fragment,{children:[(0,p.jsxs)(m.Z,{children:[(0,p.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,p.jsx)("body",{className:w.h})]}),n&&(0,p.jsx)(b.d,{image:n}),(0,p.jsx)(C,{}),(0,p.jsx)(E,{}),(0,p.jsx)(S.Z,{tag:k.HX,locale:e}),(0,p.jsx)(m.Z,{children:t.map(((e,t)=>(0,p.jsx)("meta",{...e},t)))})]})}const T=new Map;function j(e){if(T.has(e.pathname))return{...e,pathname:T.get(e.pathname)};if((0,d.f)(c.Z,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return T.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return T.set(e.pathname,t),{...e,pathname:t}}var A=n(8934),L=n(8940),R=n(469);function N(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>o.forEach((e=>e?.()))}const P=function(e){let{children:t,location:n,previousLocation:r}=e;return(0,R.Z)((()=>{r!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,o=t.hash===n.hash,a=t.search===n.search;if(r&&o&&!a)return;const{hash:i}=t;if(i){const e=decodeURIComponent(i.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:r}),N("onRouteDidUpdate",{previousLocation:r,location:n}))}),[r,n]),t};function O(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.f)(c.Z,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class I extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=l.Z.canUseDOM?N("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=N("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),O(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return(0,p.jsx)(P,{previousLocation:this.previousLocation,location:t,children:(0,p.jsx)(u.AW,{location:t,render:()=>e})})}}const D=I,M="__docusaurus-base-url-issue-banner-container",F="__docusaurus-base-url-issue-banner",z="__docusaurus-base-url-issue-banner-suggestion-container";function B(e){return`\ndocument.addEventListener('DOMContentLoaded', function maybeInsertBanner() {\n var shouldInsert = typeof window['docusaurus'] === 'undefined';\n shouldInsert && insertBanner();\n});\n\nfunction insertBanner() {\n var bannerContainer = document.createElement('div');\n bannerContainer.id = '${M}';\n var bannerHtml = ${JSON.stringify(function(e){return`\n
\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = ${e} ${"/"===e?" (default value)":""}

\n

We suggest trying baseUrl =

\n
\n`}(e)).replace(/{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const o=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;o?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var Q=n(9670);const Y=new Set,X=new Set,J=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,ee={prefetch(e){if(!(e=>!J()&&!X.has(e)&&!Y.has(e))(e))return!1;Y.add(e);const t=(0,d.f)(c.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(W).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,Q.Z)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?K(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!J()&&!X.has(e))(e)&&(X.add(e),O(e))},te=Object.freeze(ee),ne=Boolean(!0);if(l.Z.canUseDOM){window.docusaurus=te;const e=document.getElementById("__docusaurus"),t=(0,p.jsx)(i.B6,{children:(0,p.jsx)(a.VK,{children:(0,p.jsx)(V,{})})}),n=(e,t)=>{console.error("Docusaurus React Root onRecoverableError:",e,t)},l=()=>{if(ne)r.startTransition((()=>{o.hydrateRoot(e,t,{onRecoverableError:n})}));else{const a=o.createRoot(e,{onRecoverableError:n});r.startTransition((()=>{a.render(t)}))}};O(window.location.pathname).then(l)}},8940:(e,t,n)=>{"use strict";n.d(t,{_:()=>d,M:()=>p});var r=n(7294),o=n(6809);const a=JSON.parse('{"docusaurus-plugin-google-tag-manager":{"default":{"containerId":"GTM-MDFLZPK8","id":"default"}},"docusaurus-plugin-content-docs":{"default":{"path":"/docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/docs","mainDocId":"getting-started","docs":[{"id":"concepts/files","path":"/docs/concepts/files","sidebar":"tutorialSidebar"},{"id":"concepts/hosting","path":"/docs/concepts/hosting","sidebar":"tutorialSidebar"},{"id":"concepts/http","path":"/docs/concepts/http","sidebar":"tutorialSidebar"},{"id":"concepts/index","path":"/docs/concepts/","sidebar":"tutorialSidebar"},{"id":"concepts/opensource","path":"/docs/concepts/opensource","sidebar":"tutorialSidebar"},{"id":"concepts/sharing-private","path":"/docs/concepts/sharing-private","sidebar":"tutorialSidebar"},{"id":"concepts/sharing-public","path":"/docs/concepts/sharing-public","sidebar":"tutorialSidebar"},{"id":"concepts/sharing-reserved","path":"/docs/concepts/sharing-reserved","sidebar":"tutorialSidebar"},{"id":"concepts/tunnels","path":"/docs/concepts/tunnels","sidebar":"tutorialSidebar"},{"id":"getting-started","path":"/docs/getting-started","sidebar":"tutorialSidebar"},{"id":"guides/docker-share/docker_private_share_guide","path":"/docs/guides/docker-share/docker_private_share_guide","sidebar":"tutorialSidebar"},{"id":"guides/docker-share/docker_public_share_guide","path":"/docs/guides/docker-share/docker_public_share_guide","sidebar":"tutorialSidebar"},{"id":"guides/drives/cli","path":"/docs/guides/drives/cli","sidebar":"tutorialSidebar"},{"id":"guides/frontdoor","path":"/docs/guides/frontdoor","sidebar":"tutorialSidebar"},{"id":"guides/install/index","path":"/docs/guides/install/","sidebar":"tutorialSidebar"},{"id":"guides/install/linux","path":"/docs/guides/install/linux","sidebar":"tutorialSidebar"},{"id":"guides/install/macos","path":"/docs/guides/install/macos","sidebar":"tutorialSidebar"},{"id":"guides/install/windows","path":"/docs/guides/install/windows","sidebar":"tutorialSidebar"},{"id":"guides/permission-modes","path":"/docs/guides/permission-modes","sidebar":"tutorialSidebar"},{"id":"guides/self-hosting/instance-configuration","path":"/docs/guides/self-hosting/instance-configuration","sidebar":"tutorialSidebar"},{"id":"guides/self-hosting/metrics-and-limits/configuring-limits","path":"/docs/guides/self-hosting/metrics-and-limits/configuring-limits","sidebar":"tutorialSidebar"},{"id":"guides/self-hosting/metrics-and-limits/configuring-metrics","path":"/docs/guides/self-hosting/metrics-and-limits/configuring-metrics","sidebar":"tutorialSidebar"},{"id":"guides/self-hosting/nginx_tls_guide","path":"/docs/guides/self-hosting/nginx_tls_guide","sidebar":"tutorialSidebar"},{"id":"guides/self-hosting/oauth/configuring-oauth","path":"/docs/guides/self-hosting/oauth/configuring-oauth","sidebar":"tutorialSidebar"},{"id":"guides/self-hosting/self_hosting_guide","path":"/docs/guides/self-hosting/self_hosting_guide","sidebar":"tutorialSidebar"},{"id":"guides/vpn/vpn","path":"/docs/guides/vpn/","sidebar":"tutorialSidebar"},{"id":"/category/guides","path":"/docs/category/guides","sidebar":"tutorialSidebar"},{"id":"/category/docker-share","path":"/docs/category/docker-share","sidebar":"tutorialSidebar"},{"id":"/category/self-hosting","path":"/docs/category/self-hosting","sidebar":"tutorialSidebar"},{"id":"/category/metrics-and-limits","path":"/docs/category/metrics-and-limits","sidebar":"tutorialSidebar"},{"id":"/category/oauth","path":"/docs/category/oauth","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/docs/getting-started","label":"Getting Started"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var l=n(7529);const s=JSON.parse('{"docusaurusVersion":"3.1.0","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"3.1.0"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"3.1.0"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"3.1.0"},"docusaurus-plugin-google-tag-manager":{"type":"package","name":"@docusaurus/plugin-google-tag-manager","version":"3.1.0"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"3.1.0"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"3.1.0"},"docusaurus-theme-search-algolia":{"type":"package","name":"@docusaurus/theme-search-algolia","version":"3.1.0"},"docusaurus-plugin-client-redirects":{"type":"package","name":"@docusaurus/plugin-client-redirects","version":"3.1.0"},"custom-webpack-plugin":{"type":"local"}}}');var c=n(5893);const u={siteConfig:o.default,siteMetadata:s,globalData:a,i18n:i,codeTranslations:l},d=r.createContext(u);function p(e){let{children:t}=e;return(0,c.jsx)(d.Provider,{value:u,children:t})}},4763:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7294),o=n(412),a=n(5742),i=n(8780),l=n(7372),s=n(5893);function c(e){let{error:t,tryAgain:n}=e;return(0,s.jsxs)("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"},children:[(0,s.jsx)("h1",{style:{fontSize:"3rem"},children:"This page crashed"}),(0,s.jsx)("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"},children:"Try again"}),(0,s.jsx)(u,{error:t})]})}function u(e){let{error:t}=e;const n=(0,i.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,s.jsx)("p",{style:{whiteSpace:"pre-wrap"},children:n})}function d(e){let{error:t,tryAgain:n}=e;return(0,s.jsxs)(f,{fallback:()=>(0,s.jsx)(c,{error:t,tryAgain:n}),children:[(0,s.jsx)(a.Z,{children:(0,s.jsx)("title",{children:"Page Error"})}),(0,s.jsx)(l.Z,{children:(0,s.jsx)(c,{error:t,tryAgain:n})})]})}const p=e=>(0,s.jsx)(d,{...e});class f extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){o.Z.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??p)(e)}return e??null}}},412:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,o={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},5742:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});n(7294);var r=n(405),o=n(5893);function a(e){return(0,o.jsx)(r.ql,{...e})}},3692:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7294),o=n(3727),a=n(8780),i=n(2263),l=n(3919),s=n(412),c=n(8138),u=n(4996),d=n(5893);function p(e,t){let{isNavLink:n,to:p,href:f,activeClassName:m,isActive:h,"data-noBrokenLinkCheck":g,autoAddBaseUrl:y=!0,...b}=e;const{siteConfig:{trailingSlash:v,baseUrl:w}}=(0,i.Z)(),{withBaseUrl:k}=(0,u.C)(),x=(0,c.Z)(),S=(0,r.useRef)(null);(0,r.useImperativeHandle)(t,(()=>S.current));const E=p||f;const C=(0,l.Z)(E),_=E?.replace("pathname://","");let T=void 0!==_?(j=_,y&&(e=>e.startsWith("/"))(j)?k(j):j):void 0;var j;T&&C&&(T=(0,a.applyTrailingSlash)(T,{trailingSlash:v,baseUrl:w}));const A=(0,r.useRef)(!1),L=n?o.OL:o.rU,R=s.Z.canUseIntersectionObserver,N=(0,r.useRef)(),P=()=>{A.current||null==T||(window.docusaurus.preload(T),A.current=!0)};(0,r.useEffect)((()=>(!R&&C&&null!=T&&window.docusaurus.prefetch(T),()=>{R&&N.current&&N.current.disconnect()})),[N,T,R,C]);const O=T?.startsWith("#")??!1,I=!T||!C||O;return I||g||x.collectLink(T),I?(0,d.jsx)("a",{ref:S,href:T,...E&&!C&&{target:"_blank",rel:"noopener noreferrer"},...b}):(0,d.jsx)(L,{...b,onMouseEnter:P,onTouchStart:P,innerRef:e=>{S.current=e,R&&e&&C&&(N.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(N.current.unobserve(e),N.current.disconnect(),null!=T&&window.docusaurus.prefetch(T))}))})),N.current.observe(e))},to:T,...n&&{isActive:h,activeClassName:m}})}const f=r.forwardRef(p)},5999:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c,I:()=>s});var r=n(7294),o=n(5893);function a(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var i=n(7529);function l(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return i[t??n]??n??t}function s(e,t){let{message:n,id:r}=e;return a(l({message:n,id:r}),t)}function c(e){let{children:t,id:n,values:r}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");const i=l({message:t,id:n});return(0,o.jsx)(o.Fragment,{children:a(i,r)})}},9935:(e,t,n)=>{"use strict";n.d(t,{m:()=>r});const r="default"},3919:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function o(e){return void 0!==e&&!r(e)}n.d(t,{Z:()=>o,b:()=>r})},4996:(e,t,n)=>{"use strict";n.d(t,{C:()=>i,Z:()=>l});var r=n(7294),o=n(2263),a=n(3919);function i(){const{siteConfig:{baseUrl:e,url:t}}=(0,o.Z)(),n=(0,r.useCallback)(((n,r)=>function(e,t,n,r){let{forcePrependBaseUrl:o=!1,absolute:i=!1}=void 0===r?{}:r;if(!n||n.startsWith("#")||(0,a.b)(n))return n;if(o)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const l=n.startsWith(t)?n:t+n.replace(/^\//,"");return i?e+l:l}(t,e,n,r)),[t,e]);return{withBaseUrl:n}}function l(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},8138:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(7294);n(5893);const o=r.createContext({collectAnchor:()=>{},collectLink:()=>{}}),a=()=>(0,r.useContext)(o);function i(){return a()}},2263:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(7294),o=n(8940);function a(){return(0,r.useContext)(o._)}},2389:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(7294),o=n(8934);function a(){return(0,r.useContext)(o._)}},469:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294);const o=n(412).Z.canUseDOM?r.useLayoutEffect:r.useEffect},9670:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function o(e){const t={};return function e(n,o){Object.entries(n).forEach((n=>{let[a,i]=n;const l=o?`${o}.${a}`:a;r(i)?e(i,l):t[l]=i}))}(e),t}},226:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,z:()=>i});var r=n(7294),o=n(5893);const a=r.createContext(null);function i(e){let{children:t,value:n}=e;const i=r.useContext(a),l=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:i,value:n})),[i,n]);return(0,o.jsx)(a.Provider,{value:l,children:t})}},143:(e,t,n)=>{"use strict";n.d(t,{Iw:()=>y,gA:()=>f,WS:()=>m,_r:()=>d,Jo:()=>b,zh:()=>p,yW:()=>g,gB:()=>h});var r=n(6550),o=n(2263),a=n(9935);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,o.Z)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const l=e=>e.versions.find((e=>e.isLast));function s(e,t){const n=l(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,r.LX)(t,{path:e.path,exact:!1,strict:!1})))}function c(e,t){const n=s(e,t),o=n?.docs.find((e=>!!(0,r.LX)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:o,alternateDocVersions:o?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(o.id):{}}}const u={},d=()=>i("docusaurus-plugin-content-docs")??u,p=e=>function(e,t,n){void 0===t&&(t=a.m),void 0===n&&(n={});const r=i(e),o=r?.[t];if(!o&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return o}("docusaurus-plugin-content-docs",e,{failfast:!0});function f(e){void 0===e&&(e={});const t=d(),{pathname:n}=(0,r.TH)();return function(e,t,n){void 0===n&&(n={});const o=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.LX)(t,{path:n.path,exact:!1,strict:!1})})),a=o?{pluginId:o[0],pluginData:o[1]}:void 0;if(!a&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return a}(t,n,e)}function m(e){void 0===e&&(e={});const t=f(e),{pathname:n}=(0,r.TH)();if(!t)return;return{activePlugin:t,activeVersion:s(t.pluginData,n)}}function h(e){return p(e).versions}function g(e){const t=p(e);return l(t)}function y(e){const t=p(e),{pathname:n}=(0,r.TH)();return c(t,n)}function b(e){const t=p(e),{pathname:n}=(0,r.TH)();return function(e,t){const n=l(e);return{latestDocSuggestion:c(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},8320:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(4865),o=n.n(r);o().configure({showSpinner:!1});const a={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{o().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){o().done()}}},3310:(e,t,n)=>{"use strict";n.r(t);var r=n(4798),o=n(6809);!function(e){const{themeConfig:{prism:t}}=o.default,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{"php"===e&&n(6854),n(6726)(`./prism-${e}`)})),delete globalThis.Prism}(r.p1)},2503:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});n(7294);var r=n(6905),o=n(5999),a=n(6668),i=n(3692),l=n(8138);const s={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};var c=n(5893);function u(e){let{as:t,id:n,...u}=e;const d=(0,l.Z)(),{navbar:{hideOnScroll:p}}=(0,a.L)();if("h1"===t||!n)return(0,c.jsx)(t,{...u,id:void 0});d.collectAnchor(n);const f=(0,o.I)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof u.children?u.children:n});return(0,c.jsxs)(t,{...u,className:(0,r.Z)("anchor",p?s.anchorWithHideOnScrollNavbar:s.anchorWithStickyNavbar,u.className),id:n,children:[u.children,(0,c.jsx)(i.Z,{className:"hash-link",to:`#${n}`,"aria-label":f,title:f,children:"\u200b"})]})}},9471:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});n(7294);const r={iconExternalLink:"iconExternalLink_nPIU"};var o=n(5893);function a(e){let{width:t=13.5,height:n=13.5}=e;return(0,o.jsx)("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:r.iconExternalLink,children:(0,o.jsx)("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"})})}},7372:(e,t,n)=>{"use strict";n.d(t,{Z:()=>Nt});var r=n(7294),o=n(6905),a=n(4763),i=n(833),l=n(6550),s=n(5999),c=n(5936),u=n(5893);const d="__docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function f(){const e=(0,r.useRef)(null),{action:t}=(0,l.k6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&p(t)}),[]);return(0,c.S)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&p(e.current)})),{containerRef:e,onClick:n}}const m=(0,s.I)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function h(e){const t=e.children??m,{containerRef:n,onClick:r}=f();return(0,u.jsx)("div",{ref:n,role:"region","aria-label":m,children:(0,u.jsx)("a",{...e,href:`#${d}`,onClick:r,children:t})})}var g=n(5281),y=n(9727);const b={skipToContent:"skipToContent_fXgn"};function v(){return(0,u.jsx)(h,{className:b.skipToContent})}var w=n(6668),k=n(9689);function x(e){let{width:t=21,height:n=21,color:r="currentColor",strokeWidth:o=1.2,className:a,...i}=e;return(0,u.jsx)("svg",{viewBox:"0 0 15 15",width:t,height:n,...i,children:(0,u.jsx)("g",{stroke:r,strokeWidth:o,children:(0,u.jsx)("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})})})}const S={closeButton:"closeButton_CVFx"};function E(e){return(0,u.jsx)("button",{type:"button","aria-label":(0,s.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"}),...e,className:(0,o.Z)("clean-btn close",S.closeButton,e.className),children:(0,u.jsx)(x,{width:14,height:14,strokeWidth:3.1})})}const C={content:"content_knG7"};function _(e){const{announcementBar:t}=(0,w.L)(),{content:n}=t;return(0,u.jsx)("div",{...e,className:(0,o.Z)(C.content,e.className),dangerouslySetInnerHTML:{__html:n}})}const T={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function j(){const{announcementBar:e}=(0,w.L)(),{isActive:t,close:n}=(0,k.nT)();if(!t)return null;const{backgroundColor:r,textColor:o,isCloseable:a}=e;return(0,u.jsxs)("div",{className:T.announcementBar,style:{backgroundColor:r,color:o},role:"banner",children:[a&&(0,u.jsx)("div",{className:T.announcementBarPlaceholder}),(0,u.jsx)(_,{className:T.announcementBarContent}),a&&(0,u.jsx)(E,{onClick:n,className:T.announcementBarClose})]})}var A=n(3163),L=n(2466);var R=n(902),N=n(3102);const P=r.createContext(null);function O(e){let{children:t}=e;const n=function(){const e=(0,A.e)(),t=(0,N.HY)(),[n,o]=(0,r.useState)(!1),a=null!==t.component,i=(0,R.D9)(a);return(0,r.useEffect)((()=>{a&&!i&&o(!0)}),[a,i]),(0,r.useEffect)((()=>{a?e.shown||o(!0):o(!1)}),[e.shown,a]),(0,r.useMemo)((()=>[n,o]),[n])}();return(0,u.jsx)(P.Provider,{value:n,children:t})}function I(e){if(e.component){const t=e.component;return(0,u.jsx)(t,{...e.props})}}function D(){const e=(0,r.useContext)(P);if(!e)throw new R.i6("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,o=(0,r.useCallback)((()=>n(!1)),[n]),a=(0,N.HY)();return(0,r.useMemo)((()=>({shown:t,hide:o,content:I(a)})),[o,a,t])}function M(e){let{header:t,primaryMenu:n,secondaryMenu:r}=e;const{shown:a}=D();return(0,u.jsxs)("div",{className:"navbar-sidebar",children:[t,(0,u.jsxs)("div",{className:(0,o.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":a}),children:[(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:n}),(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:r})]})]})}var F=n(2949),z=n(2389);function B(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"})})}function U(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"})})}const $={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function q(e){let{className:t,buttonClassName:n,value:r,onChange:a}=e;const i=(0,z.Z)(),l=(0,s.I)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===r?(0,s.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,s.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return(0,u.jsx)("div",{className:(0,o.Z)($.toggle,t),children:(0,u.jsxs)("button",{className:(0,o.Z)("clean-btn",$.toggleButton,!i&&$.toggleButtonDisabled,n),type:"button",onClick:()=>a("dark"===r?"light":"dark"),disabled:!i,title:l,"aria-label":l,"aria-live":"polite",children:[(0,u.jsx)(B,{className:(0,o.Z)($.toggleIcon,$.lightToggleIcon)}),(0,u.jsx)(U,{className:(0,o.Z)($.toggleIcon,$.darkToggleIcon)})]})})}const Z=r.memo(q),H={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function G(e){let{className:t}=e;const n=(0,w.L)().navbar.style,r=(0,w.L)().colorMode.disableSwitch,{colorMode:o,setColorMode:a}=(0,F.I)();return r?null:(0,u.jsx)(Z,{className:t,buttonClassName:"dark"===n?H.darkNavbarColorModeToggle:void 0,value:o,onChange:a})}var V=n(1327);function W(){return(0,u.jsx)(V.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function K(){const e=(0,A.e)();return(0,u.jsx)("button",{type:"button","aria-label":(0,s.I)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle(),children:(0,u.jsx)(x,{color:"var(--ifm-color-emphasis-600)"})})}function Q(){return(0,u.jsxs)("div",{className:"navbar-sidebar__brand",children:[(0,u.jsx)(W,{}),(0,u.jsx)(G,{className:"margin-right--md"}),(0,u.jsx)(K,{})]})}var Y=n(3692),X=n(4996),J=n(3919),ee=n(8022),te=n(9471);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:r,href:o,label:a,html:i,isDropdownLink:l,prependBaseUrlToHref:s,...c}=e;const d=(0,X.Z)(r),p=(0,X.Z)(t),f=(0,X.Z)(o,{forcePrependBaseUrl:!0}),m=a&&o&&!(0,J.Z)(o),h=i?{dangerouslySetInnerHTML:{__html:i}}:{children:(0,u.jsxs)(u.Fragment,{children:[a,m&&(0,u.jsx)(te.Z,{...l&&{width:12,height:12}})]})};return o?(0,u.jsx)(Y.Z,{href:s?f:o,...c,...h}):(0,u.jsx)(Y.Z,{to:d,isNavLink:!0,...(t||n)&&{isActive:(e,t)=>n?(0,ee.F)(n,t.pathname):t.pathname.startsWith(p)},...c,...h})}function re(e){let{className:t,isDropdownItem:n=!1,...r}=e;const a=(0,u.jsx)(ne,{className:(0,o.Z)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n,...r});return n?(0,u.jsx)("li",{children:a}):a}function oe(e){let{className:t,isDropdownItem:n,...r}=e;return(0,u.jsx)("li",{className:"menu__list-item",children:(0,u.jsx)(ne,{className:(0,o.Z)("menu__link",t),...r})})}function ae(e){let{mobile:t=!1,position:n,...r}=e;const o=t?oe:re;return(0,u.jsx)(o,{...r,activeClassName:r.activeClassName??(t?"menu__link--active":"navbar__link--active")})}var ie=n(6043),le=n(8596),se=n(2263);const ce={dropdownNavbarItemMobile:"dropdownNavbarItemMobile_S0Fm"};function ue(e,t){return e.some((e=>function(e,t){return!!(0,le.Mg)(e.to,t)||!!(0,ee.F)(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function de(e){let{items:t,position:n,className:a,onClick:i,...l}=e;const s=(0,r.useRef)(null),[c,d]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{s.current&&!s.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[s]),(0,u.jsxs)("div",{ref:s,className:(0,o.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":c}),children:[(0,u.jsx)(ne,{"aria-haspopup":"true","aria-expanded":c,role:"button",href:l.to?void 0:"#",className:(0,o.Z)("navbar__link",a),...l,onClick:l.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!c))},children:l.children??l.label}),(0,u.jsx)("ul",{className:"dropdown__menu",children:t.map(((e,t)=>(0,r.createElement)(Ze,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t})))})]})}function pe(e){let{items:t,className:n,position:a,onClick:i,...s}=e;const c=function(){const{siteConfig:{baseUrl:e}}=(0,se.Z)(),{pathname:t}=(0,l.TH)();return t.replace(e,"/")}(),d=ue(t,c),{collapsed:p,toggleCollapsed:f,setCollapsed:m}=(0,ie.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&m(!d)}),[c,d,m]),(0,u.jsxs)("li",{className:(0,o.Z)("menu__list-item",{"menu__list-item--collapsed":p}),children:[(0,u.jsx)(ne,{role:"button",className:(0,o.Z)(ce.dropdownNavbarItemMobile,"menu__link menu__link--sublist menu__link--sublist-caret",n),...s,onClick:e=>{e.preventDefault(),f()},children:s.children??s.label}),(0,u.jsx)(ie.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:p,children:t.map(((e,t)=>(0,r.createElement)(Ze,{mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active",...e,key:t})))})]})}function fe(e){let{mobile:t=!1,...n}=e;const r=t?pe:de;return(0,u.jsx)(r,{...n})}var me=n(4711);function he(e){let{width:t=20,height:n=20,...r}=e;return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0,...r,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"})})}const ge="iconLanguage_nlXk";var ye=n(3935);function be(){return r.createElement("svg",{width:"15",height:"15",className:"DocSearch-Control-Key-Icon"},r.createElement("path",{d:"M4.505 4.496h2M5.505 5.496v5M8.216 4.496l.055 5.993M10 7.5c.333.333.5.667.5 1v2M12.326 4.5v5.996M8.384 4.496c1.674 0 2.116 0 2.116 1.5s-.442 1.5-2.116 1.5M3.205 9.303c-.09.448-.277 1.21-1.241 1.203C1 10.5.5 9.513.5 8V7c0-1.57.5-2.5 1.464-2.494.964.006 1.134.598 1.24 1.342M12.553 10.5h1.953",strokeWidth:"1.2",stroke:"currentColor",fill:"none",strokeLinecap:"square"}))}var ve=n(830),we=["translations"];function ke(){return ke=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var Ce="Ctrl";var _e=r.forwardRef((function(e,t){var n=e.translations,o=void 0===n?{}:n,a=Ee(e,we),i=o.buttonText,l=void 0===i?"Search":i,s=o.buttonAriaLabel,c=void 0===s?"Search":s,u=xe((0,r.useState)(null),2),d=u[0],p=u[1];return(0,r.useEffect)((function(){"undefined"!=typeof navigator&&(/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)?p("\u2318"):p(Ce))}),[]),r.createElement("button",ke({type:"button",className:"DocSearch DocSearch-Button","aria-label":c},a,{ref:t}),r.createElement("span",{className:"DocSearch-Button-Container"},r.createElement(ve.W,null),r.createElement("span",{className:"DocSearch-Button-Placeholder"},l)),r.createElement("span",{className:"DocSearch-Button-Keys"},null!==d&&r.createElement(r.Fragment,null,r.createElement("kbd",{className:"DocSearch-Button-Key"},d===Ce?r.createElement(be,null):d),r.createElement("kbd",{className:"DocSearch-Button-Key"},"K"))))})),Te=n(5742),je=n(6177),Ae=n(239),Le=n(3320);const Re={button:{buttonText:(0,s.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"}),buttonAriaLabel:(0,s.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"})},modal:{searchBox:{resetButtonTitle:(0,s.I)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),resetButtonAriaLabel:(0,s.I)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),cancelButtonText:(0,s.I)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"}),cancelButtonAriaLabel:(0,s.I)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"})},startScreen:{recentSearchesTitle:(0,s.I)({id:"theme.SearchModal.startScreen.recentSearchesTitle",message:"Recent",description:"The title for recent searches"}),noRecentSearchesText:(0,s.I)({id:"theme.SearchModal.startScreen.noRecentSearchesText",message:"No recent searches",description:"The text when no recent searches"}),saveRecentSearchButtonTitle:(0,s.I)({id:"theme.SearchModal.startScreen.saveRecentSearchButtonTitle",message:"Save this search",description:"The label for save recent search button"}),removeRecentSearchButtonTitle:(0,s.I)({id:"theme.SearchModal.startScreen.removeRecentSearchButtonTitle",message:"Remove this search from history",description:"The label for remove recent search button"}),favoriteSearchesTitle:(0,s.I)({id:"theme.SearchModal.startScreen.favoriteSearchesTitle",message:"Favorite",description:"The title for favorite searches"}),removeFavoriteSearchButtonTitle:(0,s.I)({id:"theme.SearchModal.startScreen.removeFavoriteSearchButtonTitle",message:"Remove this search from favorites",description:"The label for remove favorite search button"})},errorScreen:{titleText:(0,s.I)({id:"theme.SearchModal.errorScreen.titleText",message:"Unable to fetch results",description:"The title for error screen of search modal"}),helpText:(0,s.I)({id:"theme.SearchModal.errorScreen.helpText",message:"You might want to check your network connection.",description:"The help text for error screen of search modal"})},footer:{selectText:(0,s.I)({id:"theme.SearchModal.footer.selectText",message:"to select",description:"The explanatory text of the action for the enter key"}),selectKeyAriaLabel:(0,s.I)({id:"theme.SearchModal.footer.selectKeyAriaLabel",message:"Enter key",description:"The ARIA label for the Enter key button that makes the selection"}),navigateText:(0,s.I)({id:"theme.SearchModal.footer.navigateText",message:"to navigate",description:"The explanatory text of the action for the Arrow up and Arrow down key"}),navigateUpKeyAriaLabel:(0,s.I)({id:"theme.SearchModal.footer.navigateUpKeyAriaLabel",message:"Arrow up",description:"The ARIA label for the Arrow up key button that makes the navigation"}),navigateDownKeyAriaLabel:(0,s.I)({id:"theme.SearchModal.footer.navigateDownKeyAriaLabel",message:"Arrow down",description:"The ARIA label for the Arrow down key button that makes the navigation"}),closeText:(0,s.I)({id:"theme.SearchModal.footer.closeText",message:"to close",description:"The explanatory text of the action for Escape key"}),closeKeyAriaLabel:(0,s.I)({id:"theme.SearchModal.footer.closeKeyAriaLabel",message:"Escape key",description:"The ARIA label for the Escape key button that close the modal"}),searchByText:(0,s.I)({id:"theme.SearchModal.footer.searchByText",message:"Search by",description:"The text explain that the search is making by Algolia"})},noResultsScreen:{noResultsText:(0,s.I)({id:"theme.SearchModal.noResultsScreen.noResultsText",message:"No results for",description:"The text explains that there are no results for the following search"}),suggestedQueryText:(0,s.I)({id:"theme.SearchModal.noResultsScreen.suggestedQueryText",message:"Try searching for",description:"The text for the suggested query when no results are found for the following search"}),reportMissingResultsText:(0,s.I)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsText",message:"Believe this query should return results?",description:"The text for the question where the user thinks there are missing results"}),reportMissingResultsLinkText:(0,s.I)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsLinkText",message:"Let us know.",description:"The text for the link to report missing results"})}},placeholder:(0,s.I)({id:"theme.SearchModal.placeholder",message:"Search docs",description:"The placeholder of the input of the DocSearch pop-up modal"})};let Ne=null;function Pe(e){let{hit:t,children:n}=e;return(0,u.jsx)(Y.Z,{to:t.url,children:n})}function Oe(e){let{state:t,onClose:n}=e;const r=(0,je.M)();return(0,u.jsx)(Y.Z,{to:r(t.query),onClick:n,children:(0,u.jsx)(s.Z,{id:"theme.SearchBar.seeAll",values:{count:t.context.nbHits},children:"See all {count} results"})})}function Ie(e){let{contextualSearch:t,externalUrlRegex:o,...a}=e;const{siteMetadata:i}=(0,se.Z)(),s=(0,Ae.l)(),c=function(){const{locale:e,tags:t}=(0,Le._q)();return[`language:${e}`,t.map((e=>`docusaurus_tag:${e}`))]}(),d=a.searchParameters?.facetFilters??[],p=t?function(e,t){const n=e=>"string"==typeof e?[e]:e;return[...n(e),...n(t)]}(c,d):d,f={...a.searchParameters,facetFilters:p},m=(0,l.k6)(),h=(0,r.useRef)(null),g=(0,r.useRef)(null),[y,b]=(0,r.useState)(!1),[v,w]=(0,r.useState)(void 0),k=(0,r.useCallback)((()=>Ne?Promise.resolve():Promise.all([n.e(1426).then(n.bind(n,1426)),Promise.all([n.e(532),n.e(6945)]).then(n.bind(n,6945)),Promise.all([n.e(532),n.e(8894)]).then(n.bind(n,8894))]).then((e=>{let[{DocSearchModal:t}]=e;Ne=t}))),[]),x=(0,r.useCallback)((()=>{k().then((()=>{h.current=document.createElement("div"),document.body.insertBefore(h.current,document.body.firstChild),b(!0)}))}),[k,b]),S=(0,r.useCallback)((()=>{b(!1),h.current?.remove()}),[b]),E=(0,r.useCallback)((e=>{k().then((()=>{b(!0),w(e.key)}))}),[k,b,w]),C=(0,r.useRef)({navigate(e){let{itemUrl:t}=e;(0,ee.F)(o,t)?window.location.href=t:m.push(t)}}).current,_=(0,r.useRef)((e=>a.transformItems?a.transformItems(e):e.map((e=>({...e,url:s(e.url)}))))).current,T=(0,r.useMemo)((()=>e=>(0,u.jsx)(Oe,{...e,onClose:S})),[S]),j=(0,r.useCallback)((e=>(e.addAlgoliaAgent("docusaurus",i.docusaurusVersion),e)),[i.docusaurusVersion]);return function(e){var t=e.isOpen,n=e.onOpen,o=e.onClose,a=e.onInput,i=e.searchButtonRef;r.useEffect((function(){function e(e){var r;(27===e.keyCode&&t||"k"===(null===(r=e.key)||void 0===r?void 0:r.toLowerCase())&&(e.metaKey||e.ctrlKey)||!function(e){var t=e.target,n=t.tagName;return t.isContentEditable||"INPUT"===n||"SELECT"===n||"TEXTAREA"===n}(e)&&"/"===e.key&&!t)&&(e.preventDefault(),t?o():document.body.classList.contains("DocSearch--active")||document.body.classList.contains("DocSearch--active")||n()),i&&i.current===document.activeElement&&a&&/[a-zA-Z0-9]/.test(String.fromCharCode(e.keyCode))&&a(e)}return window.addEventListener("keydown",e),function(){window.removeEventListener("keydown",e)}}),[t,n,o,a,i])}({isOpen:y,onOpen:x,onClose:S,onInput:E,searchButtonRef:g}),(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(Te.Z,{children:(0,u.jsx)("link",{rel:"preconnect",href:`https://${a.appId}-dsn.algolia.net`,crossOrigin:"anonymous"})}),(0,u.jsx)(_e,{onTouchStart:k,onFocus:k,onMouseOver:k,onClick:x,ref:g,translations:Re.button}),y&&Ne&&h.current&&(0,ye.createPortal)((0,u.jsx)(Ne,{onClose:S,initialScrollY:window.scrollY,initialQuery:v,navigator:C,transformItems:_,hitComponent:Pe,transformSearchClient:j,...a.searchPagePath&&{resultsFooterComponent:T},...a,searchParameters:f,placeholder:Re.placeholder,translations:Re.modal}),h.current)]})}function De(){const{siteConfig:e}=(0,se.Z)();return(0,u.jsx)(Ie,{...e.themeConfig.algolia})}const Me={navbarSearchContainer:"navbarSearchContainer_Bca1"};function Fe(e){let{children:t,className:n}=e;return(0,u.jsx)("div",{className:(0,o.Z)(n,Me.navbarSearchContainer),children:t})}var ze=n(143),Be=n(3438);var Ue=n(373);const $e=e=>e.docs.find((t=>t.id===e.mainDocId));const qe={default:ae,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:r,queryString:o="",...a}=e;const{i18n:{currentLocale:i,locales:c,localeConfigs:d}}=(0,se.Z)(),p=(0,me.l)(),{search:f,hash:m}=(0,l.TH)(),h=[...n,...c.map((e=>{const n=`${`pathname://${p.createUrl({locale:e,fullyQualified:!1})}`}${f}${m}${o}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===i?t?"menu__link--active":"dropdown__link--active":""}})),...r],g=t?(0,s.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[i].label;return(0,u.jsx)(fe,{...a,mobile:t,label:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(he,{className:ge}),g]}),items:h})},search:function(e){let{mobile:t,className:n}=e;return t?null:(0,u.jsx)(Fe,{className:n,children:(0,u.jsx)(De,{})})},dropdown:fe,html:function(e){let{value:t,className:n,mobile:r=!1,isDropdownItem:a=!1}=e;const i=a?"li":"div";return(0,u.jsx)(i,{className:(0,o.Z)({navbar__item:!r&&!a,"menu__list-item":r},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:r,...o}=e;const{activeDoc:a}=(0,ze.Iw)(r),i=(0,Be.vY)(t,r),l=a?.path===i?.path;return null===i||i.unlisted&&!l?null:(0,u.jsx)(ae,{exact:!0,...o,isActive:()=>l||!!a?.sidebar&&a.sidebar===i.sidebar,label:n??i.id,to:i.path})},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:r,...o}=e;const{activeDoc:a}=(0,ze.Iw)(r),i=(0,Be.oz)(t,r).link;if(!i)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return(0,u.jsx)(ae,{exact:!0,...o,isActive:()=>a?.sidebar===t,label:n??i.label,to:i.path})},docsVersion:function(e){let{label:t,to:n,docsPluginId:r,...o}=e;const a=(0,Be.lO)(r)[0],i=t??a.label,l=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(a).path;return(0,u.jsx)(ae,{...o,label:i,to:l})},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:r,dropdownItemsBefore:o,dropdownItemsAfter:a,...i}=e;const{search:c,hash:d}=(0,l.TH)(),p=(0,ze.Iw)(n),f=(0,ze.gB)(n),{savePreferredVersionName:m}=(0,Ue.J)(n),h=[...o,...f.map((e=>{const t=p.alternateDocVersions[e.name]??$e(e);return{label:e.label,to:`${t.path}${c}${d}`,isActive:()=>e===p.activeVersion,onClick:()=>m(e.name)}})),...a],g=(0,Be.lO)(n)[0],y=t&&h.length>1?(0,s.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):g.label,b=t&&h.length>1?void 0:$e(g).path;return h.length<=1?(0,u.jsx)(ae,{...i,mobile:t,label:y,to:b,isActive:r?()=>!1:void 0}):(0,u.jsx)(fe,{...i,mobile:t,label:y,to:b,items:h,isActive:r?()=>!1:void 0})}};function Ze(e){let{type:t,...n}=e;const r=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=qe[r];if(!o)throw new Error(`No NavbarItem component found for type "${t}".`);return(0,u.jsx)(o,{...n})}function He(){const e=(0,A.e)(),t=(0,w.L)().navbar.items;return(0,u.jsx)("ul",{className:"menu__list",children:t.map(((t,n)=>(0,r.createElement)(Ze,{mobile:!0,...t,onClick:()=>e.toggle(),key:n})))})}function Ge(e){return(0,u.jsx)("button",{...e,type:"button",className:"clean-btn navbar-sidebar__back",children:(0,u.jsx)(s.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)",children:"\u2190 Back to main menu"})})}function Ve(){const e=0===(0,w.L)().navbar.items.length,t=D();return(0,u.jsxs)(u.Fragment,{children:[!e&&(0,u.jsx)(Ge,{onClick:()=>t.hide()}),t.content]})}function We(){const e=(0,A.e)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?(0,u.jsx)(M,{header:(0,u.jsx)(Q,{}),primaryMenu:(0,u.jsx)(He,{}),secondaryMenu:(0,u.jsx)(Ve,{})}):null}const Ke={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Qe(e){return(0,u.jsx)("div",{role:"presentation",...e,className:(0,o.Z)("navbar-sidebar__backdrop",e.className)})}function Ye(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:a}}=(0,w.L)(),i=(0,A.e)(),{navbarRef:l,isNavbarVisible:d}=function(e){const[t,n]=(0,r.useState)(e),o=(0,r.useRef)(!1),a=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(a.current=e.getBoundingClientRect().height)}),[]);return(0,L.RF)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i=l?n(!1):i+c{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return o.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return(0,u.jsxs)("nav",{ref:l,"aria-label":(0,s.I)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,o.Z)("navbar","navbar--fixed-top",n&&[Ke.navbarHideable,!d&&Ke.navbarHidden],{"navbar--dark":"dark"===a,"navbar--primary":"primary"===a,"navbar-sidebar--show":i.shown}),children:[t,(0,u.jsx)(Qe,{onClick:i.toggle}),(0,u.jsx)(We,{})]})}var Xe=n(8780);const Je={errorBoundaryError:"errorBoundaryError_a6uf",errorBoundaryFallback:"errorBoundaryFallback_VBag"};function et(e){return(0,u.jsx)("button",{type:"button",...e,children:(0,u.jsx)(s.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error",children:"Try again"})})}function tt(e){let{error:t}=e;const n=(0,Xe.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,u.jsx)("p",{className:Je.errorBoundaryError,children:n})}class nt extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}const rt="right";function ot(e){let{width:t=30,height:n=30,className:r,...o}=e;return(0,u.jsx)("svg",{className:r,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true",...o,children:(0,u.jsx)("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"})})}function at(){const{toggle:e,shown:t}=(0,A.e)();return(0,u.jsx)("button",{onClick:e,"aria-label":(0,s.I)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button",children:(0,u.jsx)(ot,{})})}const it={colorModeToggle:"colorModeToggle_DEke"};function lt(e){let{items:t}=e;return(0,u.jsx)(u.Fragment,{children:t.map(((e,t)=>(0,u.jsx)(nt,{onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t}),children:(0,u.jsx)(Ze,{...e})},t)))})}function st(e){let{left:t,right:n}=e;return(0,u.jsxs)("div",{className:"navbar__inner",children:[(0,u.jsx)("div",{className:"navbar__items",children:t}),(0,u.jsx)("div",{className:"navbar__items navbar__items--right",children:n})]})}function ct(){const e=(0,A.e)(),t=(0,w.L)().navbar.items,[n,r]=function(e){function t(e){return"left"===(e.position??rt)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),o=t.find((e=>"search"===e.type));return(0,u.jsx)(st,{left:(0,u.jsxs)(u.Fragment,{children:[!e.disabled&&(0,u.jsx)(at,{}),(0,u.jsx)(W,{}),(0,u.jsx)(lt,{items:n})]}),right:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(lt,{items:r}),(0,u.jsx)(G,{className:it.colorModeToggle}),!o&&(0,u.jsx)(Fe,{children:(0,u.jsx)(De,{})})]})})}function ut(){return(0,u.jsx)(Ye,{children:(0,u.jsx)(ct,{})})}function dt(e){let{item:t}=e;const{to:n,href:r,label:o,prependBaseUrlToHref:a,...i}=t,l=(0,X.Z)(n),s=(0,X.Z)(r,{forcePrependBaseUrl:!0});return(0,u.jsxs)(Y.Z,{className:"footer__link-item",...r?{href:a?s:r}:{to:l},...i,children:[o,r&&!(0,J.Z)(r)&&(0,u.jsx)(te.Z,{})]})}function pt(e){let{item:t}=e;return t.html?(0,u.jsx)("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)("li",{className:"footer__item",children:(0,u.jsx)(dt,{item:t})},t.href??t.to)}function ft(e){let{column:t}=e;return(0,u.jsxs)("div",{className:"col footer__col",children:[(0,u.jsx)("div",{className:"footer__title",children:t.title}),(0,u.jsx)("ul",{className:"footer__items clean-list",children:t.items.map(((e,t)=>(0,u.jsx)(pt,{item:e},t)))})]})}function mt(e){let{columns:t}=e;return(0,u.jsx)("div",{className:"row footer__links",children:t.map(((e,t)=>(0,u.jsx)(ft,{column:e},t)))})}function ht(){return(0,u.jsx)("span",{className:"footer__link-separator",children:"\xb7"})}function gt(e){let{item:t}=e;return t.html?(0,u.jsx)("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)(dt,{item:t})}function yt(e){let{links:t}=e;return(0,u.jsx)("div",{className:"footer__links text--center",children:(0,u.jsx)("div",{className:"footer__links",children:t.map(((e,n)=>(0,u.jsxs)(r.Fragment,{children:[(0,u.jsx)(gt,{item:e}),t.length!==n+1&&(0,u.jsx)(ht,{})]},n)))})})}function bt(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?(0,u.jsx)(mt,{columns:t}):(0,u.jsx)(yt,{links:t})}var vt=n(9965);const wt={footerLogoLink:"footerLogoLink_BH7S"};function kt(e){let{logo:t}=e;const{withBaseUrl:n}=(0,X.C)(),r={light:n(t.src),dark:n(t.srcDark??t.src)};return(0,u.jsx)(vt.Z,{className:(0,o.Z)("footer__logo",t.className),alt:t.alt,sources:r,width:t.width,height:t.height,style:t.style})}function xt(e){let{logo:t}=e;return t.href?(0,u.jsx)(Y.Z,{href:t.href,className:wt.footerLogoLink,target:t.target,children:(0,u.jsx)(kt,{logo:t})}):(0,u.jsx)(kt,{logo:t})}function St(e){let{copyright:t}=e;return(0,u.jsx)("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function Et(e){let{style:t,links:n,logo:r,copyright:a}=e;return(0,u.jsx)("footer",{className:(0,o.Z)("footer",{"footer--dark":"dark"===t}),children:(0,u.jsxs)("div",{className:"container container-fluid",children:[n,(r||a)&&(0,u.jsxs)("div",{className:"footer__bottom text--center",children:[r&&(0,u.jsx)("div",{className:"margin-bottom--sm",children:r}),a]})]})})}function Ct(){const{footer:e}=(0,w.L)();if(!e)return null;const{copyright:t,links:n,logo:r,style:o}=e;return(0,u.jsx)(Et,{style:o,links:n&&n.length>0&&(0,u.jsx)(bt,{links:n}),logo:r&&(0,u.jsx)(xt,{logo:r}),copyright:t&&(0,u.jsx)(St,{copyright:t})})}const _t=r.memo(Ct),Tt=(0,R.Qc)([F.S,k.pl,L.OC,Ue.L5,i.VC,function(e){let{children:t}=e;return(0,u.jsx)(N.n2,{children:(0,u.jsx)(A.M,{children:(0,u.jsx)(O,{children:t})})})}]);function jt(e){let{children:t}=e;return(0,u.jsx)(Tt,{children:t})}var At=n(2503);function Lt(e){let{error:t,tryAgain:n}=e;return(0,u.jsx)("main",{className:"container margin-vert--xl",children:(0,u.jsx)("div",{className:"row",children:(0,u.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,u.jsx)(At.Z,{as:"h1",className:"hero__title",children:(0,u.jsx)(s.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed",children:"This page crashed."})}),(0,u.jsx)("div",{className:"margin-vert--lg",children:(0,u.jsx)(et,{onClick:n,className:"button button--primary shadow--lw"})}),(0,u.jsx)("hr",{}),(0,u.jsx)("div",{className:"margin-vert--md",children:(0,u.jsx)(tt,{error:t})})]})})})}const Rt={mainWrapper:"mainWrapper_z2l0"};function Nt(e){const{children:t,noFooter:n,wrapperClassName:r,title:l,description:s}=e;return(0,y.t)(),(0,u.jsxs)(jt,{children:[(0,u.jsx)(i.d,{title:l,description:s}),(0,u.jsx)(v,{}),(0,u.jsx)(j,{}),(0,u.jsx)(ut,{}),(0,u.jsx)("div",{id:d,className:(0,o.Z)(g.k.wrapper.main,Rt.mainWrapper,r),children:(0,u.jsx)(a.Z,{fallback:e=>(0,u.jsx)(Lt,{...e}),children:t})}),!n&&(0,u.jsx)(_t,{})]})}},1327:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});n(7294);var r=n(3692),o=n(4996),a=n(2263),i=n(6668),l=n(9965),s=n(5893);function c(e){let{logo:t,alt:n,imageClassName:r}=e;const a={light:(0,o.Z)(t.src),dark:(0,o.Z)(t.srcDark||t.src)},i=(0,s.jsx)(l.Z,{className:t.className,sources:a,height:t.height,width:t.width,alt:n,style:t.style});return r?(0,s.jsx)("div",{className:r,children:i}):i}function u(e){const{siteConfig:{title:t}}=(0,a.Z)(),{navbar:{title:n,logo:l}}=(0,i.L)(),{imageClassName:u,titleClassName:d,...p}=e,f=(0,o.Z)(l?.href||"/"),m=n?"":t,h=l?.alt??m;return(0,s.jsxs)(r.Z,{to:f,...p,...l?.target&&{target:l.target},children:[l&&(0,s.jsx)(c,{logo:l,alt:h,imageClassName:u}),null!=n&&(0,s.jsx)("b",{className:d,children:n})]})}},197:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});n(7294);var r=n(5742),o=n(5893);function a(e){let{locale:t,version:n,tag:a}=e;const i=t;return(0,o.jsxs)(r.Z,{children:[t&&(0,o.jsx)("meta",{name:"docusaurus_locale",content:t}),n&&(0,o.jsx)("meta",{name:"docusaurus_version",content:n}),a&&(0,o.jsx)("meta",{name:"docusaurus_tag",content:a}),i&&(0,o.jsx)("meta",{name:"docsearch:language",content:i}),n&&(0,o.jsx)("meta",{name:"docsearch:version",content:n}),a&&(0,o.jsx)("meta",{name:"docsearch:docusaurus_tag",content:a})]})}},9965:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(7294),o=n(788),a=n(2389),i=n(2949);const l={themedComponent:"themedComponent_mlkZ","themedComponent--light":"themedComponent--light_NVdE","themedComponent--dark":"themedComponent--dark_xIcU"};var s=n(5893);function c(e){let{className:t,children:n}=e;const c=(0,a.Z)(),{colorMode:u}=(0,i.I)();return(0,s.jsx)(s.Fragment,{children:(c?"dark"===u?["dark"]:["light"]:["light","dark"]).map((e=>{const a=n({theme:e,className:(0,o.Z)(t,l.themedComponent,l[`themedComponent--${e}`])});return(0,s.jsx)(r.Fragment,{children:a},e)}))})}function u(e){const{sources:t,className:n,alt:r,...o}=e;return(0,s.jsx)(c,{className:n,children:e=>{let{theme:n,className:a}=e;return(0,s.jsx)("img",{src:t[n],alt:r,className:a,...o})}})}},6043:(e,t,n)=>{"use strict";n.d(t,{u:()=>c,z:()=>y});var r=n(7294),o=n(412),a=n(469),i=n(1442),l=n(5893);const s="ease-in-out";function c(e){let{initialState:t}=e;const[n,o]=(0,r.useState)(t??!1),a=(0,r.useCallback)((()=>{o((e=>!e))}),[]);return{collapsed:n,setCollapsed:o,toggleCollapsed:a}}const u={display:"none",overflow:"hidden",height:"0px"},d={display:"block",overflow:"visible",height:"auto"};function p(e,t){const n=t?u:d;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function f(e){let{collapsibleRef:t,collapsed:n,animation:o}=e;const a=(0,r.useRef)(!1);(0,r.useEffect)((()=>{const e=t.current;function r(){const t=e.scrollHeight,n=o?.duration??function(e){if((0,i.n)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${o?.easing??s}`,height:`${t}px`}}function l(){const t=r();e.style.transition=t.transition,e.style.height=t.height}if(!a.current)return p(e,n),void(a.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(l(),requestAnimationFrame((()=>{e.style.height=u.height,e.style.overflow=u.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{l()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,o])}function m(e){if(!o.Z.canUseDOM)return e?u:d}function h(e){let{as:t="div",collapsed:n,children:o,animation:a,onCollapseTransitionEnd:i,className:s,disableSSRStyle:c}=e;const u=(0,r.useRef)(null);return f({collapsibleRef:u,collapsed:n,animation:a}),(0,l.jsx)(t,{ref:u,style:c?void 0:m(n),onTransitionEnd:e=>{"height"===e.propertyName&&(p(u.current,n),i?.(n))},className:s,children:o})}function g(e){let{collapsed:t,...n}=e;const[o,i]=(0,r.useState)(!t),[s,c]=(0,r.useState)(t);return(0,a.Z)((()=>{t||i(!0)}),[t]),(0,a.Z)((()=>{o&&c(t)}),[o,t]),o?(0,l.jsx)(h,{...n,collapsed:s}):null}function y(e){let{lazy:t,...n}=e;const r=t?g:h;return(0,l.jsx)(r,{...n})}},9689:(e,t,n)=>{"use strict";n.d(t,{nT:()=>h,pl:()=>m});var r=n(7294),o=n(2389),a=n(12),i=n(902),l=n(6668),s=n(5893);const c=(0,a.WA)("docusaurus.announcement.dismiss"),u=(0,a.WA)("docusaurus.announcement.id"),d=()=>"true"===c.get(),p=e=>c.set(String(e)),f=r.createContext(null);function m(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,l.L)(),t=(0,o.Z)(),[n,a]=(0,r.useState)((()=>!!t&&d()));(0,r.useEffect)((()=>{a(d())}),[]);const i=(0,r.useCallback)((()=>{p(!0),a(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=u.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;u.set(t),r&&p(!1),!r&&d()||a(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return(0,s.jsx)(f.Provider,{value:n,children:t})}function h(){const e=(0,r.useContext)(f);if(!e)throw new i.i6("AnnouncementBarProvider");return e}},2949:(e,t,n)=>{"use strict";n.d(t,{I:()=>y,S:()=>g});var r=n(7294),o=n(412),a=n(902),i=n(12),l=n(6668),s=n(5893);const c=r.createContext(void 0),u="theme",d=(0,i.WA)(u),p={light:"light",dark:"dark"},f=e=>e===p.dark?p.dark:p.light,m=e=>o.Z.canUseDOM?f(document.documentElement.getAttribute("data-theme")):f(e),h=e=>{d.set(f(e))};function g(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,l.L)(),[o,a]=(0,r.useState)(m(e));(0,r.useEffect)((()=>{t&&d.del()}),[t]);const i=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:o=!0}=r;t?(a(t),o&&h(t)):(a(n?window.matchMedia("(prefers-color-scheme: dark)").matches?p.dark:p.light:e),d.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",f(o))}),[o]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==u)return;const t=d.get();null!==t&&i(f(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,i]);const s=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||s.current?s.current=window.matchMedia("print").matches:i(null)};return e.addListener(r),()=>e.removeListener(r)}),[i,t,n]),(0,r.useMemo)((()=>({colorMode:o,setColorMode:i,get isDarkTheme(){return o===p.dark},setLightTheme(){i(p.light)},setDarkTheme(){i(p.dark)}})),[o,i])}();return(0,s.jsx)(c.Provider,{value:n,children:t})}function y(){const e=(0,r.useContext)(c);if(null==e)throw new a.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},373:(e,t,n)=>{"use strict";n.d(t,{J:()=>v,L5:()=>y,Oh:()=>w});var r=n(7294),o=n(143),a=n(9935),i=n(6668),l=n(3438),s=n(902),c=n(12),u=n(5893);const d=e=>`docs-preferred-version-${e}`,p={save:(e,t,n)=>{(0,c.WA)(d(e),{persistence:t}).set(n)},read:(e,t)=>(0,c.WA)(d(e),{persistence:t}).get(),clear:(e,t)=>{(0,c.WA)(d(e),{persistence:t}).del()}},f=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const m=r.createContext(null);function h(){const e=(0,o._r)(),t=(0,i.L)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[a,l]=(0,r.useState)((()=>f(n)));(0,r.useEffect)((()=>{l(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function o(e){const t=p.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(p.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,o(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[a,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){p.save(e,t,n),l((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function g(e){let{children:t}=e;const n=h();return(0,u.jsx)(m.Provider,{value:n,children:t})}function y(e){let{children:t}=e;return l.cE?(0,u.jsx)(g,{children:t}):(0,u.jsx)(u.Fragment,{children:t})}function b(){const e=(0,r.useContext)(m);if(!e)throw new s.i6("DocsPreferredVersionContextProvider");return e}function v(e){void 0===e&&(e=a.m);const t=(0,o.zh)(e),[n,i]=b(),{preferredVersionName:l}=n[e];return{preferredVersion:t.versions.find((e=>e.name===l))??null,savePreferredVersionName:(0,r.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}function w(){const e=(0,o._r)(),[t]=b();function n(n){const r=e[n],{preferredVersionName:o}=t[n];return r.versions.find((e=>e.name===o))??null}const r=Object.keys(e);return Object.fromEntries(r.map((e=>[e,n(e)])))}},1116:(e,t,n)=>{"use strict";n.d(t,{V:()=>c,b:()=>s});var r=n(7294),o=n(902),a=n(5893);const i=Symbol("EmptyContext"),l=r.createContext(i);function s(e){let{children:t,name:n,items:o}=e;const i=(0,r.useMemo)((()=>n&&o?{name:n,items:o}:null),[n,o]);return(0,a.jsx)(l.Provider,{value:i,children:t})}function c(){const e=(0,r.useContext)(l);if(e===i)throw new o.i6("DocsSidebarProvider");return e}},4477:(e,t,n)=>{"use strict";n.d(t,{E:()=>s,q:()=>l});var r=n(7294),o=n(902),a=n(5893);const i=r.createContext(null);function l(e){let{children:t,version:n}=e;return(0,a.jsx)(i.Provider,{value:n,children:t})}function s(){const e=(0,r.useContext)(i);if(null===e)throw new o.i6("DocsVersionProvider");return e}},3163:(e,t,n)=>{"use strict";n.d(t,{M:()=>p,e:()=>f});var r=n(7294),o=n(3102),a=n(7524),i=n(1980),l=n(6668),s=n(902),c=n(5893);const u=r.createContext(void 0);function d(){const e=function(){const e=(0,o.HY)(),{items:t}=(0,l.L)().navbar;return 0===t.length&&!e.component}(),t=(0,a.i)(),n=!e&&"mobile"===t,[s,c]=(0,r.useState)(!1);(0,i.Rb)((()=>{if(s)return c(!1),!1}));const u=(0,r.useCallback)((()=>{c((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&c(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:u,shown:s})),[e,n,u,s])}function p(e){let{children:t}=e;const n=d();return(0,c.jsx)(u.Provider,{value:n,children:t})}function f(){const e=r.useContext(u);if(void 0===e)throw new s.i6("NavbarMobileSidebarProvider");return e}},3102:(e,t,n)=>{"use strict";n.d(t,{HY:()=>s,Zo:()=>c,n2:()=>l});var r=n(7294),o=n(902),a=n(5893);const i=r.createContext(null);function l(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return(0,a.jsx)(i.Provider,{value:n,children:t})}function s(){const e=(0,r.useContext)(i);if(!e)throw new o.i6("NavbarSecondaryMenuContentProvider");return e[0]}function c(e){let{component:t,props:n}=e;const a=(0,r.useContext)(i);if(!a)throw new o.i6("NavbarSecondaryMenuContentProvider");const[,l]=a,s=(0,o.Ql)(n);return(0,r.useEffect)((()=>{l({component:t,props:s})}),[l,t,s]),(0,r.useEffect)((()=>()=>l({component:null,props:null})),[l]),null}},9727:(e,t,n)=>{"use strict";n.d(t,{h:()=>o,t:()=>a});var r=n(7294);const o="navigation-with-keyboard";function a(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(o),"mousedown"===e.type&&document.body.classList.remove(o)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(o),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},6177:(e,t,n)=>{"use strict";n.d(t,{K:()=>l,M:()=>s});var r=n(7294),o=n(2263),a=n(1980);const i="q";function l(){return(0,a.Nc)(i)}function s(){const{siteConfig:{baseUrl:e,themeConfig:t}}=(0,o.Z)(),{algolia:{searchPagePath:n}}=t;return(0,r.useCallback)((t=>`${e}${n}?${i}=${encodeURIComponent(t)}`),[e,n])}},7524:(e,t,n)=>{"use strict";n.d(t,{i:()=>l});var r=n(7294),o=n(412);const a={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function l(e){let{desktopBreakpoint:t=i}=void 0===e?{}:e;const[n,l]=(0,r.useState)((()=>"ssr"));return(0,r.useEffect)((()=>{function e(){l(function(e){if(!o.Z.canUseDOM)throw new Error("getWindowSize() should only be called after React hydration");return window.innerWidth>e?a.desktop:a.mobile}(t))}return e(),window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e)}}),[t]),n}},5281:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",unlistedBanner:"theme-unlisted-banner",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{}}},1442:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{n:()=>r})},3438:(e,t,n)=>{"use strict";n.d(t,{LM:()=>m,MN:()=>T,SN:()=>_,_F:()=>b,cE:()=>p,f:()=>w,jA:()=>h,lO:()=>S,oz:()=>E,s1:()=>x,vY:()=>C,xz:()=>f});var r=n(7294),o=n(6550),a=n(8790),i=n(143),l=n(373),s=n(4477),c=n(1116),u=n(7392),d=n(8596);const p=!!i._r;function f(e){const t=(0,s.E)();if(!e)return;const n=t.docs[e];if(!n)throw new Error(`no version doc found by id=${e}`);return n}function m(e){return"link"!==e.type||e.unlisted?"category"===e.type?function(e){if(e.href&&!e.linkUnlisted)return e.href;for(const t of e.items){const e=m(t);if(e)return e}}(e):void 0:e.href}function h(){const{pathname:e}=(0,o.TH)(),t=(0,c.V)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");const n=k({sidebarItems:t.items,pathname:e,onlyCategories:!0}).slice(-1)[0];if(!n)throw new Error(`${e} is not associated with a category. useCurrentSidebarCategory() should only be used on category index pages.`);return n}const g=(e,t)=>void 0!==e&&(0,d.Mg)(e,t),y=(e,t)=>e.some((e=>b(e,t)));function b(e,t){return"link"===e.type?g(e.href,t):"category"===e.type&&(g(e.href,t)||y(e.items,t))}function v(e,t){switch(e.type){case"category":return b(e,t)||e.items.some((e=>v(e,t)));case"link":return!e.unlisted||b(e,t);default:return!0}}function w(e,t){return(0,r.useMemo)((()=>e.filter((e=>v(e,t)))),[e,t])}function k(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const o=[];return function e(t){for(const a of t)if("category"===a.type&&((0,d.Mg)(a.href,n)||e(a.items))||"link"===a.type&&(0,d.Mg)(a.href,n)){return r&&"category"!==a.type||o.unshift(a),!0}return!1}(t),o}function x(){const e=(0,c.V)(),{pathname:t}=(0,o.TH)(),n=(0,i.gA)()?.pluginData.breadcrumbs;return!1!==n&&e?k({sidebarItems:e.items,pathname:t}):null}function S(e){const{activeVersion:t}=(0,i.Iw)(e),{preferredVersion:n}=(0,l.J)(e),o=(0,i.yW)(e);return(0,r.useMemo)((()=>(0,u.j)([t,n,o].filter(Boolean))),[t,n,o])}function E(e,t){const n=S(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function C(e,t){const n=S(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${(0,u.j)(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function _(e){let{route:t}=e;const n=(0,o.TH)(),r=(0,s.E)(),i=t.routes,l=i.find((e=>(0,o.LX)(n.pathname,e)));if(!l)return null;const c=l.sidebar,u=c?r.docsSidebars[c]:void 0;return{docElement:(0,a.H)(i),sidebarName:c,sidebarItems:u}}function T(e){return e.filter((e=>!("category"===e.type||"link"===e.type)||!!m(e)))}},2128:(e,t,n)=>{"use strict";n.d(t,{p:()=>o});var r=n(2263);function o(e){const{siteConfig:t}=(0,r.Z)(),{title:n,titleDelimiter:o}=t;return e?.trim().length?`${e.trim()} ${o} ${n}`:n}},1980:(e,t,n)=>{"use strict";n.d(t,{Nc:()=>s,Rb:()=>i,_X:()=>l});var r=n(7294),o=n(6550),a=n(902);function i(e){!function(e){const t=(0,o.k6)(),n=(0,a.zX)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}function l(e){return function(e){const t=(0,o.k6)();return(0,r.useSyncExternalStore)(t.listen,(()=>e(t)),(()=>e(t)))}((t=>null===e?null:new URLSearchParams(t.location.search).get(e)))}function s(e){const t=l(e)??"",n=function(){const e=(0,o.k6)();return(0,r.useCallback)(((t,n,r)=>{const o=new URLSearchParams(e.location.search);n?o.set(t,n):o.delete(t),(r?.push?e.push:e.replace)({search:o.toString()})}),[e])}();return[t,(0,r.useCallback)(((t,r)=>{n(e,t,r)}),[n,e])]}},7392:(e,t,n)=>{"use strict";function r(e,t){return void 0===t&&(t=(e,t)=>e===t),e.filter(((n,r)=>e.findIndex((e=>t(e,n)))!==r))}function o(e){return Array.from(new Set(e))}n.d(t,{j:()=>o,l:()=>r})},833:(e,t,n)=>{"use strict";n.d(t,{FG:()=>f,d:()=>d,VC:()=>m});var r=n(7294),o=n(788),a=n(5742),i=n(226);function l(){const e=r.useContext(i._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var s=n(4996),c=n(2128),u=n(5893);function d(e){let{title:t,description:n,keywords:r,image:o,children:i}=e;const l=(0,c.p)(t),{withBaseUrl:d}=(0,s.C)(),p=o?d(o,{absolute:!0}):void 0;return(0,u.jsxs)(a.Z,{children:[t&&(0,u.jsx)("title",{children:l}),t&&(0,u.jsx)("meta",{property:"og:title",content:l}),n&&(0,u.jsx)("meta",{name:"description",content:n}),n&&(0,u.jsx)("meta",{property:"og:description",content:n}),r&&(0,u.jsx)("meta",{name:"keywords",content:Array.isArray(r)?r.join(","):r}),p&&(0,u.jsx)("meta",{property:"og:image",content:p}),p&&(0,u.jsx)("meta",{name:"twitter:image",content:p}),i]})}const p=r.createContext(void 0);function f(e){let{className:t,children:n}=e;const i=r.useContext(p),l=(0,o.Z)(i,t);return(0,u.jsxs)(p.Provider,{value:l,children:[(0,u.jsx)(a.Z,{children:(0,u.jsx)("html",{className:l})}),n]})}function m(e){let{children:t}=e;const n=l(),r=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const a=`plugin-id-${n.plugin.id}`;return(0,u.jsx)(f,{className:(0,o.Z)(r,a),children:t})}},902:(e,t,n)=>{"use strict";n.d(t,{D9:()=>l,Qc:()=>u,Ql:()=>c,i6:()=>s,zX:()=>i});var r=n(7294),o=n(469),a=n(5893);function i(e){const t=(0,r.useRef)(e);return(0,o.Z)((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function l(e){const t=(0,r.useRef)();return(0,o.Z)((()=>{t.current=e})),t.current}class s extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function c(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function u(e){return t=>{let{children:n}=t;return(0,a.jsx)(a.Fragment,{children:e.reduceRight(((e,t)=>(0,a.jsx)(t,{children:e})),n)})}}},8022:(e,t,n)=>{"use strict";function r(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}n.d(t,{F:()=>r})},8596:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>i,Ns:()=>l});var r=n(7294),o=n(723),a=n(2263);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function l(){const{baseUrl:e}=(0,a.Z)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function o(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(o).flatMap((e=>e.routes??[])))}(n)}({routes:o.Z,baseUrl:e})),[e])}},2466:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>h,OC:()=>u,RF:()=>f,o5:()=>m});var r=n(7294),o=n(412),a=n(2389),i=n(469),l=n(902),s=n(5893);const c=r.createContext(void 0);function u(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return(0,s.jsx)(c.Provider,{value:n,children:t})}function d(){const e=(0,r.useContext)(c);if(null==e)throw new l.i6("ScrollControllerProvider");return e}const p=()=>o.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function f(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=d(),o=(0,r.useRef)(p()),a=(0,l.zX)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=p();a(e,o.current),o.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[a,n,...t])}function m(){const e=d(),t=function(){const e=(0,r.useRef)({elem:null,top:0}),t=(0,r.useCallback)((t=>{e.current={elem:t,top:t.getBoundingClientRect().top}}),[]),n=(0,r.useCallback)((()=>{const{current:{elem:t,top:n}}=e;if(!t)return{restored:!1};const r=t.getBoundingClientRect().top-n;return r&&window.scrollBy({left:0,top:r}),e.current={elem:null,top:0},{restored:0!==r}}),[]);return(0,r.useMemo)((()=>({save:t,restore:n})),[n,t])}(),n=(0,r.useRef)(void 0),o=(0,r.useCallback)((r=>{t.save(r),e.disableScrollEvents(),n.current=()=>{const{restored:r}=t.restore();if(n.current=void 0,r){const t=()=>{e.enableScrollEvents(),window.removeEventListener("scroll",t)};window.addEventListener("scroll",t)}else e.enableScrollEvents()}}),[e,t]);return(0,i.Z)((()=>{queueMicrotask((()=>n.current?.()))})),{blockElementScrollPositionUntilNextRender:o}}function h(){const e=(0,r.useRef)(null),t=(0,a.Z)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const o=document.documentElement.scrollTop;(n&&o>e||!n&&ot&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},3320:(e,t,n)=>{"use strict";n.d(t,{HX:()=>i,_q:()=>s,os:()=>l});var r=n(143),o=n(2263),a=n(373);const i="default";function l(e,t){return`docs-${e}-${t}`}function s(){const{i18n:e}=(0,o.Z)(),t=(0,r._r)(),n=(0,r.WS)(),s=(0,a.Oh)();const c=[i,...Object.keys(t).map((function(e){const r=n?.activePlugin.pluginId===e?n.activeVersion:void 0,o=s[e],a=t[e].versions.find((e=>e.isLast));return l(e,(r??o??a).name)}))];return{locale:e.currentLocale,tags:c}}},12:(e,t,n)=>{"use strict";n.d(t,{Nk:()=>u,WA:()=>c});var r=n(7294);const o="localStorage";function a(e){let{key:t,oldValue:n,newValue:r,storage:o}=e;if(n===r)return;const a=document.createEvent("StorageEvent");a.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,o),window.dispatchEvent(a)}function i(e){if(void 0===e&&(e=o),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,l||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),l=!0),null}var t}let l=!1;const s={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function c(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(e);const n=i(t?.persistence);return null===n?s:{get:()=>{try{return n.getItem(e)}catch(t){return console.error(`Docusaurus storage error, can't get key=${e}`,t),null}},set:t=>{try{const r=n.getItem(e);n.setItem(e,t),a({key:e,oldValue:r,newValue:t,storage:n})}catch(r){console.error(`Docusaurus storage error, can't set ${e}=${t}`,r)}},del:()=>{try{const t=n.getItem(e);n.removeItem(e),a({key:e,oldValue:t,newValue:null,storage:n})}catch(t){console.error(`Docusaurus storage error, can't delete key=${e}`,t)}},listen:t=>{try{const r=r=>{r.storageArea===n&&r.key===e&&t(r)};return window.addEventListener("storage",r),()=>window.removeEventListener("storage",r)}catch(r){return console.error(`Docusaurus storage error, can't listen for changes of key=${e}`,r),()=>{}}}}}function u(e,t){const n=(0,r.useRef)((()=>null===e?s:c(e,t))).current(),o=(0,r.useCallback)((e=>"undefined"==typeof window?()=>{}:n.listen(e)),[n]);return[(0,r.useSyncExternalStore)(o,(()=>"undefined"==typeof window?null:n.get()),(()=>null)),n]}},4711:(e,t,n)=>{"use strict";n.d(t,{l:()=>i});var r=n(2263),o=n(6550),a=n(8780);function i(){const{siteConfig:{baseUrl:e,url:t,trailingSlash:n},i18n:{defaultLocale:i,currentLocale:l}}=(0,r.Z)(),{pathname:s}=(0,o.TH)(),c=(0,a.applyTrailingSlash)(s,{trailingSlash:n,baseUrl:e}),u=l===i?e:e.replace(`/${l}/`,"/"),d=c.replace(e,"");return{createUrl:function(e){let{locale:n,fullyQualified:r}=e;return`${r?t:""}${function(e){return e===i?`${u}`:`${u}${e}/`}(n)}${d}`}}}},5936:(e,t,n)=>{"use strict";n.d(t,{S:()=>i});var r=n(7294),o=n(6550),a=n(902);function i(e){const t=(0,o.TH)(),n=(0,a.D9)(t),i=(0,a.zX)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},6668:(e,t,n)=>{"use strict";n.d(t,{L:()=>o});var r=n(2263);function o(){return(0,r.Z)().siteConfig.themeConfig}},6278:(e,t,n)=>{"use strict";n.d(t,{L:()=>o});var r=n(2263);function o(){const{siteConfig:{themeConfig:e}}=(0,r.Z)();return e}},239:(e,t,n)=>{"use strict";n.d(t,{l:()=>l});var r=n(7294),o=n(8022),a=n(4996),i=n(6278);function l(){const{withBaseUrl:e}=(0,a.C)(),{algolia:{externalUrlRegex:t,replaceSearchResultPathname:n}}=(0,i.L)();return(0,r.useCallback)((r=>{const a=new URL(r);if((0,o.F)(t,a.href))return r;const i=`${a.pathname+a.hash}`;return e(function(e,t){return t?e.replaceAll(new RegExp(t.from,"g"),t.to):e}(i,n))}),[e,t,n])}},8802:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[o]=e.split(/[#?]/),a="/"===o||o===r?o:(i=o,n?function(e){return e.endsWith("/")?e:`${e}/`}(i):function(e){return e.endsWith("/")?e.slice(0,-1):e}(i));var i;return e.replace(o,a)}},4143:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=void 0,t.getErrorCausalChain=function e(t){return t.cause?[t,...e(t.cause)]:[t]}},8780:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="__blog-post-container";var o=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(o).default}});var a=n(4143);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return a.getErrorCausalChain}})},2358:(e,t,n)=>{"use strict";n.d(t,{lX:()=>S,q_:()=>A,ob:()=>h,PP:()=>R,Ep:()=>m,Hp:()=>g});var r=n(7462);function o(e){return"/"===e.charAt(0)}function a(e,t){for(var n=t,r=n+1,o=e.length;r=0;p--){var f=i[p];"."===f?a(i,p):".."===f?(a(i,p),d++):d&&(a(i,p),d--)}if(!c)for(;d--;d)i.unshift("..");!c||""===i[0]||i[0]&&o(i[0])||i.unshift("");var m=i.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};function l(e){return e.valueOf?e.valueOf():Object.prototype.valueOf.call(e)}const s=function e(t,n){if(t===n)return!0;if(null==t||null==n)return!1;if(Array.isArray(t))return Array.isArray(n)&&t.length===n.length&&t.every((function(t,r){return e(t,n[r])}));if("object"==typeof t||"object"==typeof n){var r=l(t),o=l(n);return r!==t||o!==n?e(r,o):Object.keys(Object.assign({},t,n)).every((function(r){return e(t[r],n[r])}))}return!1};var c=n(8776);function u(e){return"/"===e.charAt(0)?e:"/"+e}function d(e){return"/"===e.charAt(0)?e.substr(1):e}function p(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function f(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function m(e){var t=e.pathname,n=e.search,r=e.hash,o=t||"/";return n&&"?"!==n&&(o+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(o+="#"===r.charAt(0)?r:"#"+r),o}function h(e,t,n,o){var a;"string"==typeof e?(a=function(e){var t=e||"/",n="",r="",o=t.indexOf("#");-1!==o&&(r=t.substr(o),t=t.substr(0,o));var a=t.indexOf("?");return-1!==a&&(n=t.substr(a),t=t.substr(0,a)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),a.state=t):(void 0===(a=(0,r.Z)({},e)).pathname&&(a.pathname=""),a.search?"?"!==a.search.charAt(0)&&(a.search="?"+a.search):a.search="",a.hash?"#"!==a.hash.charAt(0)&&(a.hash="#"+a.hash):a.hash="",void 0!==t&&void 0===a.state&&(a.state=t));try{a.pathname=decodeURI(a.pathname)}catch(l){throw l instanceof URIError?new URIError('Pathname "'+a.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):l}return n&&(a.key=n),o?a.pathname?"/"!==a.pathname.charAt(0)&&(a.pathname=i(a.pathname,o.pathname)):a.pathname=o.pathname:a.pathname||(a.pathname="/"),a}function g(e,t){return e.pathname===t.pathname&&e.search===t.search&&e.hash===t.hash&&e.key===t.key&&s(e.state,t.state)}function y(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,o){if(null!=e){var a="function"==typeof e?e(t,n):e;"string"==typeof a?"function"==typeof r?r(a,o):o(!0):o(!1!==a)}else o(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,o):n.push(o),d({action:r,location:o,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",o=h(e,t,p(),w.location);u.confirmTransitionTo(o,r,n,(function(e){e&&(w.entries[w.index]=o,d({action:r,location:o}))}))},go:v,goBack:function(){v(-1)},goForward:function(){v(1)},canGo:function(e){var t=w.index+e;return t>=0&&t{"use strict";var r=n(9864),o={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},a={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},l={};function s(e){return r.isMemo(e)?i:l[e.$$typeof]||o}l[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},l[r.Memo]=i;var c=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(m){var o=f(n);o&&o!==m&&e(t,o,r)}var i=u(n);d&&(i=i.concat(d(n)));for(var l=s(t),h=s(n),g=0;g{"use strict";e.exports=function(e,t,n,r,o,a,i,l){if(!e){var s;if(void 0===t)s=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,o,a,i,l],u=0;(s=new Error(t.replace(/%s/g,(function(){return c[u++]})))).name="Invariant Violation"}throw s.framesToPop=1,s}}},5826:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},2497:(e,t,n)=>{"use strict";n.r(t)},2295:(e,t,n)=>{"use strict";n.r(t)},4865:function(e,t,n){var r,o;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
'};function o(e,t,n){return en?n:e}function a(e){return 100*(-1+e)}function i(e,t,n){var o;return(o="translate3d"===r.positionUsing?{transform:"translate3d("+a(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+a(e)+"%,0)"}:{"margin-left":a(e)+"%"}).transition="all "+t+"ms "+n,o}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=o(e,r.minimum,1),n.status=1===e?null:e;var a=n.render(!t),c=a.querySelector(r.barSelector),u=r.speed,d=r.easing;return a.offsetWidth,l((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),s(c,i(e,u,d)),1===e?(s(a,{transition:"none",opacity:1}),a.offsetWidth,setTimeout((function(){s(a,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*o(Math.random()*t,.1,.95)),t=o(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var o,i=t.querySelector(r.barSelector),l=e?"-100":a(n.status||0),c=document.querySelector(r.parent);return s(i,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),r.showSpinner||(o=t.querySelector(r.spinnerSelector))&&f(o),c!=document.body&&u(c,"nprogress-custom-parent"),c.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&f(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var l=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),s=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,o=e.length,a=t.charAt(0).toUpperCase()+t.slice(1);o--;)if((r=e[o]+a)in n)return r;return t}function o(e){return e=n(e),t[e]||(t[e]=r(e))}function a(e,t,n){t=o(t),e.style[t]=n}return function(e,t){var n,r,o=arguments;if(2==o.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&a(e,n,r);else a(e,o[1],o[2])}}();function c(e,t){return("string"==typeof e?e:p(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=p(e),r=n+t;c(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=p(e);c(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(o="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=o)},4779:(e,t,n)=>{var r=n(5826);e.exports=f,e.exports.parse=a,e.exports.compile=function(e,t){return l(a(e,t),t)},e.exports.tokensToFunction=l,e.exports.tokensToRegExp=p;var o=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function a(e,t){for(var n,r=[],a=0,i=0,l="",u=t&&t.delimiter||"/";null!=(n=o.exec(e));){var d=n[0],p=n[1],f=n.index;if(l+=e.slice(i,f),i=f+d.length,p)l+=p[1];else{var m=e[i],h=n[2],g=n[3],y=n[4],b=n[5],v=n[6],w=n[7];l&&(r.push(l),l="");var k=null!=h&&null!=m&&m!==h,x="+"===v||"*"===v,S="?"===v||"*"===v,E=n[2]||u,C=y||b;r.push({name:g||a++,prefix:h||"",delimiter:E,optional:S,repeat:x,partial:k,asterisk:!!w,pattern:C?c(C):w?".*":"[^"+s(E)+"]+?"})}}return i{e.exports&&(e.exports={core:{meta:{path:"components/prism-core.js",option:"mandatory"},core:"Core"},themes:{meta:{path:"themes/{id}.css",link:"index.html?theme={id}",exclusive:!0},prism:{title:"Default",option:"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{title:"Okaidia",owner:"ocodia"},"prism-twilight":{title:"Twilight",owner:"remybach"},"prism-coy":{title:"Coy",owner:"tshedor"},"prism-solarizedlight":{title:"Solarized Light",owner:"hectormatos2011 "},"prism-tomorrow":{title:"Tomorrow Night",owner:"Rosey"}},languages:{meta:{path:"components/prism-{id}",noCSS:!0,examplesPath:"examples/prism-{id}",addCheckAll:!0},markup:{title:"Markup",alias:["html","xml","svg","mathml","ssml","atom","rss"],aliasTitles:{html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",ssml:"SSML",atom:"Atom",rss:"RSS"},option:"default"},css:{title:"CSS",option:"default",modify:"markup"},clike:{title:"C-like",option:"default"},javascript:{title:"JavaScript",require:"clike",modify:"markup",optional:"regex",alias:"js",option:"default"},abap:{title:"ABAP",owner:"dellagustin"},abnf:{title:"ABNF",owner:"RunDevelopment"},actionscript:{title:"ActionScript",require:"javascript",modify:"markup",owner:"Golmote"},ada:{title:"Ada",owner:"Lucretia"},agda:{title:"Agda",owner:"xy-ren"},al:{title:"AL",owner:"RunDevelopment"},antlr4:{title:"ANTLR4",alias:"g4",owner:"RunDevelopment"},apacheconf:{title:"Apache Configuration",owner:"GuiTeK"},apex:{title:"Apex",require:["clike","sql"],owner:"RunDevelopment"},apl:{title:"APL",owner:"ngn"},applescript:{title:"AppleScript",owner:"Golmote"},aql:{title:"AQL",owner:"RunDevelopment"},arduino:{title:"Arduino",require:"cpp",alias:"ino",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},armasm:{title:"ARM Assembly",alias:"arm-asm",owner:"RunDevelopment"},arturo:{title:"Arturo",alias:"art",optional:["bash","css","javascript","markup","markdown","sql"],owner:"drkameleon"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},asmatmel:{title:"Atmel AVR Assembly",owner:"cerkit"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},avisynth:{title:"AviSynth",alias:"avs",owner:"Zinfidel"},"avro-idl":{title:"Avro IDL",alias:"avdl",owner:"RunDevelopment"},awk:{title:"AWK",alias:"gawk",aliasTitles:{gawk:"GAWK"},owner:"RunDevelopment"},bash:{title:"Bash",alias:["sh","shell"],aliasTitles:{sh:"Shell",shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bbj:{title:"BBj",owner:"hyyan"},bicep:{title:"Bicep",owner:"johnnyreilly"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},bqn:{title:"BQN",owner:"yewscion"},brainfuck:{title:"Brainfuck",owner:"Golmote"},brightscript:{title:"BrightScript",owner:"RunDevelopment"},bro:{title:"Bro",owner:"wayward710"},bsl:{title:"BSL (1C:Enterprise)",alias:"oscript",aliasTitles:{oscript:"OneScript"},owner:"Diversus23"},c:{title:"C",require:"clike",owner:"zeitgeist87"},csharp:{title:"C#",require:"clike",alias:["cs","dotnet"],owner:"mvalipour"},cpp:{title:"C++",require:"c",owner:"zeitgeist87"},cfscript:{title:"CFScript",require:"clike",alias:"cfc",owner:"mjclemente"},chaiscript:{title:"ChaiScript",require:["clike","cpp"],owner:"RunDevelopment"},cil:{title:"CIL",owner:"sbrl"},cilkc:{title:"Cilk/C",require:"c",alias:"cilk-c",owner:"OpenCilk"},cilkcpp:{title:"Cilk/C++",require:"cpp",alias:["cilk-cpp","cilk"],owner:"OpenCilk"},clojure:{title:"Clojure",owner:"troglotit"},cmake:{title:"CMake",owner:"mjrogozinski"},cobol:{title:"COBOL",owner:"RunDevelopment"},coffeescript:{title:"CoffeeScript",require:"javascript",alias:"coffee",owner:"R-osey"},concurnas:{title:"Concurnas",alias:"conc",owner:"jasontatton"},csp:{title:"Content-Security-Policy",owner:"ScottHelme"},cooklang:{title:"Cooklang",owner:"ahue"},coq:{title:"Coq",owner:"RunDevelopment"},crystal:{title:"Crystal",require:"ruby",owner:"MakeNowJust"},"css-extras":{title:"CSS Extras",require:"css",modify:"css",owner:"milesj"},csv:{title:"CSV",owner:"RunDevelopment"},cue:{title:"CUE",owner:"RunDevelopment"},cypher:{title:"Cypher",owner:"RunDevelopment"},d:{title:"D",require:"clike",owner:"Golmote"},dart:{title:"Dart",require:"clike",owner:"Golmote"},dataweave:{title:"DataWeave",owner:"machaval"},dax:{title:"DAX",owner:"peterbud"},dhall:{title:"Dhall",owner:"RunDevelopment"},diff:{title:"Diff",owner:"uranusjr"},django:{title:"Django/Jinja2",require:"markup-templating",alias:"jinja2",owner:"romanvm"},"dns-zone-file":{title:"DNS zone file",owner:"RunDevelopment",alias:"dns-zone"},docker:{title:"Docker",alias:"dockerfile",owner:"JustinBeckwith"},dot:{title:"DOT (Graphviz)",alias:"gv",optional:"markup",owner:"RunDevelopment"},ebnf:{title:"EBNF",owner:"RunDevelopment"},editorconfig:{title:"EditorConfig",owner:"osipxd"},eiffel:{title:"Eiffel",owner:"Conaclos"},ejs:{title:"EJS",require:["javascript","markup-templating"],owner:"RunDevelopment",alias:"eta",aliasTitles:{eta:"Eta"}},elixir:{title:"Elixir",owner:"Golmote"},elm:{title:"Elm",owner:"zwilias"},etlua:{title:"Embedded Lua templating",require:["lua","markup-templating"],owner:"RunDevelopment"},erb:{title:"ERB",require:["ruby","markup-templating"],owner:"Golmote"},erlang:{title:"Erlang",owner:"Golmote"},"excel-formula":{title:"Excel Formula",alias:["xlsx","xls"],owner:"RunDevelopment"},fsharp:{title:"F#",require:"clike",owner:"simonreynolds7"},factor:{title:"Factor",owner:"catb0t"},false:{title:"False",owner:"edukisto"},"firestore-security-rules":{title:"Firestore security rules",require:"clike",owner:"RunDevelopment"},flow:{title:"Flow",require:"javascript",owner:"Golmote"},fortran:{title:"Fortran",owner:"Golmote"},ftl:{title:"FreeMarker Template Language",require:"markup-templating",owner:"RunDevelopment"},gml:{title:"GameMaker Language",alias:"gamemakerlanguage",require:"clike",owner:"LiarOnce"},gap:{title:"GAP (CAS)",owner:"RunDevelopment"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gettext:{title:"gettext",alias:"po",owner:"RunDevelopment"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},"linker-script":{title:"GNU Linker Script",alias:"ld",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},gradle:{title:"Gradle",require:"clike",owner:"zeabdelkhalek-badido18"},graphql:{title:"GraphQL",optional:"markdown",owner:"Golmote"},groovy:{title:"Groovy",require:"clike",owner:"robfletcher"},haml:{title:"Haml",require:"ruby",optional:["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],owner:"Golmote"},handlebars:{title:"Handlebars",require:"markup-templating",alias:["hbs","mustache"],aliasTitles:{mustache:"Mustache"},owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",optional:"regex",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},hoon:{title:"Hoon",owner:"matildepark"},http:{title:"HTTP",optional:["csp","css","hpkp","hsts","javascript","json","markup","uri"],owner:"danielgtaylor"},hpkp:{title:"HTTP Public-Key-Pins",owner:"ScottHelme"},hsts:{title:"HTTP Strict-Transport-Security",owner:"ScottHelme"},ichigojam:{title:"IchigoJam",owner:"BlueCocoa"},icon:{title:"Icon",owner:"Golmote"},"icu-message-format":{title:"ICU Message Format",owner:"RunDevelopment"},idris:{title:"Idris",alias:"idr",owner:"KeenS",require:"haskell"},ignore:{title:".ignore",owner:"osipxd",alias:["gitignore","hgignore","npmignore"],aliasTitles:{gitignore:".gitignore",hgignore:".hgignore",npmignore:".npmignore"}},inform7:{title:"Inform 7",owner:"Golmote"},ini:{title:"Ini",owner:"aviaryan"},io:{title:"Io",owner:"AlesTsurko"},j:{title:"J",owner:"Golmote"},java:{title:"Java",require:"clike",owner:"sherblot"},javadoc:{title:"JavaDoc",require:["markup","java","javadoclike"],modify:"java",optional:"scala",owner:"RunDevelopment"},javadoclike:{title:"JavaDoc-like",modify:["java","javascript","php"],owner:"RunDevelopment"},javastacktrace:{title:"Java stack trace",owner:"RunDevelopment"},jexl:{title:"Jexl",owner:"czosel"},jolie:{title:"Jolie",require:"clike",owner:"thesave"},jq:{title:"JQ",owner:"RunDevelopment"},jsdoc:{title:"JSDoc",require:["javascript","javadoclike","typescript"],modify:"javascript",optional:["actionscript","coffeescript"],owner:"RunDevelopment"},"js-extras":{title:"JS Extras",require:"javascript",modify:"javascript",optional:["actionscript","coffeescript","flow","n4js","typescript"],owner:"RunDevelopment"},json:{title:"JSON",alias:"webmanifest",aliasTitles:{webmanifest:"Web App Manifest"},owner:"CupOfTea696"},json5:{title:"JSON5",require:"json",owner:"RunDevelopment"},jsonp:{title:"JSONP",require:"json",owner:"RunDevelopment"},jsstacktrace:{title:"JS stack trace",owner:"sbrl"},"js-templates":{title:"JS Templates",require:"javascript",modify:"javascript",optional:["css","css-extras","graphql","markdown","markup","sql"],owner:"RunDevelopment"},julia:{title:"Julia",owner:"cdagnino"},keepalived:{title:"Keepalived Configure",owner:"dev-itsheng"},keyman:{title:"Keyman",owner:"mcdurdin"},kotlin:{title:"Kotlin",alias:["kt","kts"],aliasTitles:{kts:"Kotlin Script"},require:"clike",owner:"Golmote"},kumir:{title:"KuMir (\u041a\u0443\u041c\u0438\u0440)",alias:"kum",owner:"edukisto"},kusto:{title:"Kusto",owner:"RunDevelopment"},latex:{title:"LaTeX",alias:["tex","context"],aliasTitles:{tex:"TeX",context:"ConTeXt"},owner:"japborst"},latte:{title:"Latte",require:["clike","markup-templating","php"],owner:"nette"},less:{title:"Less",require:"css",optional:"css-extras",owner:"Golmote"},lilypond:{title:"LilyPond",require:"scheme",alias:"ly",owner:"RunDevelopment"},liquid:{title:"Liquid",require:"markup-templating",owner:"cinhtau"},lisp:{title:"Lisp",alias:["emacs","elisp","emacs-lisp"],owner:"JuanCaicedo"},livescript:{title:"LiveScript",owner:"Golmote"},llvm:{title:"LLVM IR",owner:"porglezomp"},log:{title:"Log file",optional:"javastacktrace",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},magma:{title:"Magma (CAS)",owner:"RunDevelopment"},makefile:{title:"Makefile",owner:"Golmote"},markdown:{title:"Markdown",require:"markup",optional:"yaml",alias:"md",owner:"Golmote"},"markup-templating":{title:"Markup templating",require:"markup",owner:"Golmote"},mata:{title:"Mata",owner:"RunDevelopment"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},metafont:{title:"METAFONT",owner:"LaeriExNihilo"},mizar:{title:"Mizar",owner:"Golmote"},mongodb:{title:"MongoDB",owner:"airs0urce",require:"javascript"},monkey:{title:"Monkey",owner:"Golmote"},moonscript:{title:"MoonScript",alias:"moon",owner:"RunDevelopment"},n1ql:{title:"N1QL",owner:"TMWilds"},n4js:{title:"N4JS",require:"javascript",optional:"jsdoc",alias:"n4jsd",owner:"bsmith-n4"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",owner:"stephanmax"},naniscript:{title:"Naninovel Script",owner:"Elringus",alias:"nani"},nasm:{title:"NASM",owner:"rbmj"},neon:{title:"NEON",owner:"nette"},nevod:{title:"Nevod",owner:"nezaboodka"},nginx:{title:"nginx",owner:"volado"},nim:{title:"Nim",owner:"Golmote"},nix:{title:"Nix",owner:"Golmote"},nsis:{title:"NSIS",owner:"idleberg"},objectivec:{title:"Objective-C",require:"c",alias:"objc",owner:"uranusjr"},ocaml:{title:"OCaml",owner:"Golmote"},odin:{title:"Odin",owner:"edukisto"},opencl:{title:"OpenCL",require:"c",modify:["c","cpp"],owner:"Milania1"},openqasm:{title:"OpenQasm",alias:"qasm",owner:"RunDevelopment"},oz:{title:"Oz",owner:"Golmote"},parigp:{title:"PARI/GP",owner:"Golmote"},parser:{title:"Parser",require:"markup",owner:"Golmote"},pascal:{title:"Pascal",alias:"objectpascal",aliasTitles:{objectpascal:"Object Pascal"},owner:"Golmote"},pascaligo:{title:"Pascaligo",owner:"DefinitelyNotAGoat"},psl:{title:"PATROL Scripting Language",owner:"bertysentry"},pcaxis:{title:"PC-Axis",alias:"px",owner:"RunDevelopment"},peoplecode:{title:"PeopleCode",alias:"pcode",owner:"RunDevelopment"},perl:{title:"Perl",owner:"Golmote"},php:{title:"PHP",require:"markup-templating",owner:"milesj"},phpdoc:{title:"PHPDoc",require:["php","javadoclike"],modify:"php",owner:"RunDevelopment"},"php-extras":{title:"PHP Extras",require:"php",modify:"php",owner:"milesj"},"plant-uml":{title:"PlantUML",alias:"plantuml",owner:"RunDevelopment"},plsql:{title:"PL/SQL",require:"sql",owner:"Golmote"},powerquery:{title:"PowerQuery",alias:["pq","mscript"],owner:"peterbud"},powershell:{title:"PowerShell",owner:"nauzilus"},processing:{title:"Processing",require:"clike",owner:"Golmote"},prolog:{title:"Prolog",owner:"Golmote"},promql:{title:"PromQL",owner:"arendjr"},properties:{title:".properties",owner:"Golmote"},protobuf:{title:"Protocol Buffers",require:"clike",owner:"just-boris"},pug:{title:"Pug",require:["markup","javascript"],optional:["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],owner:"Golmote"},puppet:{title:"Puppet",owner:"Golmote"},pure:{title:"Pure",optional:["c","cpp","fortran"],owner:"Golmote"},purebasic:{title:"PureBasic",require:"clike",alias:"pbfasm",owner:"HeX0R101"},purescript:{title:"PureScript",require:"haskell",alias:"purs",owner:"sriharshachilakapati"},python:{title:"Python",alias:"py",owner:"multipetros"},qsharp:{title:"Q#",require:"clike",alias:"qs",owner:"fedonman"},q:{title:"Q (kdb+ database)",owner:"Golmote"},qml:{title:"QML",require:"javascript",owner:"RunDevelopment"},qore:{title:"Qore",require:"clike",owner:"temnroegg"},r:{title:"R",owner:"Golmote"},racket:{title:"Racket",require:"scheme",alias:"rkt",owner:"RunDevelopment"},cshtml:{title:"Razor C#",alias:"razor",require:["markup","csharp"],optional:["css","css-extras","javascript","js-extras"],owner:"RunDevelopment"},jsx:{title:"React JSX",require:["markup","javascript"],optional:["jsdoc","js-extras","js-templates"],owner:"vkbansal"},tsx:{title:"React TSX",require:["jsx","typescript"]},reason:{title:"Reason",require:"clike",owner:"Golmote"},regex:{title:"Regex",owner:"RunDevelopment"},rego:{title:"Rego",owner:"JordanSh"},renpy:{title:"Ren'py",alias:"rpy",owner:"HyuchiaDiego"},rescript:{title:"ReScript",alias:"res",owner:"vmarcosp"},rest:{title:"reST (reStructuredText)",owner:"Golmote"},rip:{title:"Rip",owner:"ravinggenius"},roboconf:{title:"Roboconf",owner:"Golmote"},robotframework:{title:"Robot Framework",alias:"robot",owner:"RunDevelopment"},ruby:{title:"Ruby",require:"clike",alias:"rb",owner:"samflores"},rust:{title:"Rust",owner:"Golmote"},sas:{title:"SAS",optional:["groovy","lua","sql"],owner:"Golmote"},sass:{title:"Sass (Sass)",require:"css",optional:"css-extras",owner:"Golmote"},scss:{title:"Sass (SCSS)",require:"css",optional:"css-extras",owner:"MoOx"},scala:{title:"Scala",require:"java",owner:"jozic"},scheme:{title:"Scheme",owner:"bacchus123"},"shell-session":{title:"Shell session",require:"bash",alias:["sh-session","shellsession"],owner:"RunDevelopment"},smali:{title:"Smali",owner:"RunDevelopment"},smalltalk:{title:"Smalltalk",owner:"Golmote"},smarty:{title:"Smarty",require:"markup-templating",optional:"php",owner:"Golmote"},sml:{title:"SML",alias:"smlnj",aliasTitles:{smlnj:"SML/NJ"},owner:"RunDevelopment"},solidity:{title:"Solidity (Ethereum)",alias:"sol",require:"clike",owner:"glachaud"},"solution-file":{title:"Solution file",alias:"sln",owner:"RunDevelopment"},soy:{title:"Soy (Closure Template)",require:"markup-templating",owner:"Golmote"},sparql:{title:"SPARQL",require:"turtle",owner:"Triply-Dev",alias:"rq"},"splunk-spl":{title:"Splunk SPL",owner:"RunDevelopment"},sqf:{title:"SQF: Status Quo Function (Arma 3)",require:"clike",owner:"RunDevelopment"},sql:{title:"SQL",owner:"multipetros"},squirrel:{title:"Squirrel",require:"clike",owner:"RunDevelopment"},stan:{title:"Stan",owner:"RunDevelopment"},stata:{title:"Stata Ado",require:["mata","java","python"],owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},supercollider:{title:"SuperCollider",alias:"sclang",owner:"RunDevelopment"},swift:{title:"Swift",owner:"chrischares"},systemd:{title:"Systemd configuration file",owner:"RunDevelopment"},"t4-templating":{title:"T4 templating",owner:"RunDevelopment"},"t4-cs":{title:"T4 Text Templates (C#)",require:["t4-templating","csharp"],alias:"t4",owner:"RunDevelopment"},"t4-vb":{title:"T4 Text Templates (VB)",require:["t4-templating","vbnet"],owner:"RunDevelopment"},tap:{title:"TAP",owner:"isaacs",require:"yaml"},tcl:{title:"Tcl",owner:"PeterChaplin"},tt2:{title:"Template Toolkit 2",require:["clike","markup-templating"],owner:"gflohr"},textile:{title:"Textile",require:"markup",optional:"css",owner:"Golmote"},toml:{title:"TOML",owner:"RunDevelopment"},tremor:{title:"Tremor",alias:["trickle","troy"],owner:"darach",aliasTitles:{trickle:"trickle",troy:"troy"}},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup-templating",owner:"brandonkelly"},typescript:{title:"TypeScript",require:"javascript",optional:"js-templates",alias:"ts",owner:"vkbansal"},typoscript:{title:"TypoScript",alias:"tsconfig",aliasTitles:{tsconfig:"TSConfig"},owner:"dkern"},unrealscript:{title:"UnrealScript",alias:["uscript","uc"],owner:"RunDevelopment"},uorazor:{title:"UO Razor Script",owner:"jaseowns"},uri:{title:"URI",alias:"url",aliasTitles:{url:"URL"},owner:"RunDevelopment"},v:{title:"V",require:"clike",owner:"taggon"},vala:{title:"Vala",require:"clike",optional:"regex",owner:"TemplarVolk"},vbnet:{title:"VB.Net",require:"basic",owner:"Bigsby"},velocity:{title:"Velocity",require:"markup",owner:"Golmote"},verilog:{title:"Verilog",owner:"a-rey"},vhdl:{title:"VHDL",owner:"a-rey"},vim:{title:"vim",owner:"westonganger"},"visual-basic":{title:"Visual Basic",alias:["vb","vba"],aliasTitles:{vba:"VBA"},owner:"Golmote"},warpscript:{title:"WarpScript",owner:"RunDevelopment"},wasm:{title:"WebAssembly",owner:"Golmote"},"web-idl":{title:"Web IDL",alias:"webidl",owner:"RunDevelopment"},wgsl:{title:"WGSL",owner:"Dr4gonthree"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},wren:{title:"Wren",owner:"clsource"},xeora:{title:"Xeora",require:"markup",alias:"xeoracube",aliasTitles:{xeoracube:"XeoraCube"},owner:"freakmaxi"},"xml-doc":{title:"XML doc (.net)",require:"markup",modify:["csharp","fsharp","vbnet"],owner:"RunDevelopment"},xojo:{title:"Xojo (REALbasic)",owner:"Golmote"},xquery:{title:"XQuery",require:"markup",owner:"Golmote"},yaml:{title:"YAML",alias:"yml",owner:"hason"},yang:{title:"YANG",owner:"RunDevelopment"},zig:{title:"Zig",owner:"RunDevelopment"}},plugins:{meta:{path:"plugins/{id}/prism-{id}",link:"plugins/{id}/"},"line-highlight":{title:"Line Highlight",description:"Highlights specific lines and/or line ranges."},"line-numbers":{title:"Line Numbers",description:"Line number at the beginning of code lines.",owner:"kuba-kubula"},"show-invisibles":{title:"Show Invisibles",description:"Show hidden characters such as tabs and line breaks.",optional:["autolinker","data-uri-highlight"]},autolinker:{title:"Autolinker",description:"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},wpd:{title:"WebPlatform Docs",description:'Makes tokens link to WebPlatform.org documentation. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (.comment can become .namespace--comment) or replace them with your defined ones (like .editor__comment). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the highlightAll and highlightAllUnder methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},2885:(e,t,n)=>{const r=n(9901),o=n(9642),a=new Set;function i(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...a,...Object.keys(Prism.languages)];o(r,e,t).load((e=>{if(!(e in r.languages))return void(i.silent||console.warn("Language does not exist: "+e));const t="./prism-"+e;delete n.c[n(6500).resolve(t)],delete Prism.languages[e],n(6500)(t),a.add(e)}))}i.silent=!1,e.exports=i},6854:()=>{!function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,o,a){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(o,(function(e){if("function"==typeof a&&!a(e))return e;for(var o,l=i.length;-1!==n.code.indexOf(o=t(r,l));)++l;return i[l]=e,o})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var o=0,a=Object.keys(n.tokenStack);!function i(l){for(var s=0;s=a.length);s++){var c=l[s];if("string"==typeof c||c.content&&"string"==typeof c.content){var u=a[o],d=n.tokenStack[u],p="string"==typeof c?c:c.content,f=t(r,u),m=p.indexOf(f);if(m>-1){++o;var h=p.substring(0,m),g=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),y=p.substring(m+f.length),b=[];h&&b.push.apply(b,i([h])),b.push(g),y&&b.push.apply(b,i([y])),"string"==typeof c?l.splice.apply(l,[s,1].concat(b)):c.content=b}}else c.content&&i(c.content)}return l}(n.tokens)}}}})}(Prism)},6726:(e,t,n)=>{var r={"./":2885};function o(e){var t=a(e);return n(t)}function a(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=a,e.exports=o,o.id=6726},6500:(e,t,n)=>{var r={"./":2885};function o(e){var t=a(e);return n(t)}function a(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=a,e.exports=o,o.id=6500},9642:e=>{"use strict";var t=function(){var e=function(){};function t(e,t){Array.isArray(e)?e.forEach(t):null!=e&&t(e,0)}function n(e){for(var t={},n=0,r=e.length;n "));var l={},s=e[r];if(s){function c(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in l))for(var i in o(t,a),l[t]=!0,n[t])l[i]=!0}t(s.require,c),t(s.optional,c),t(s.modify,c)}n[r]=l,a.pop()}}return function(e){var t=n[e];return t||(o(e,r),t=n[e]),t}}function o(e){for(var t in e)return!0;return!1}return function(a,i,l){var s=function(e){var t={};for(var n in e){var r=e[n];for(var o in r)if("meta"!=o){var a=r[o];t[o]="string"==typeof a?{title:a}:a}}return t}(a),c=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var o in n={},e){var a=e[o];t(a&&a.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+o+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+o+" because it is a component.");n[t]=o}))}return n[r]||r}}(s);i=i.map(c),l=(l||[]).map(c);var u=n(i),d=n(l);i.forEach((function e(n){var r=s[n];t(r&&r.require,(function(t){t in d||(u[t]=!0,e(t))}))}));for(var p,f=r(s),m=u;o(m);){for(var h in p={},m){var g=s[h];t(g&&g.modify,(function(e){e in d&&(p[e]=!0)}))}for(var y in d)if(!(y in u))for(var b in f(y))if(b in u){p[y]=!0;break}for(var v in m=p)u[v]=!0}var w={getIds:function(){var e=[];return w.load((function(t){e.push(t)})),e},load:function(t,n){return function(t,n,r,o){var a=o?o.series:void 0,i=o?o.parallel:e,l={},s={};function c(e){if(e in l)return l[e];s[e]=!0;var o,u=[];for(var d in t(e))d in n&&u.push(d);if(0===u.length)o=r(e);else{var p=i(u.map((function(e){var t=c(e);return delete s[e],t})));a?o=a(p,(function(){return r(e)})):r(e)}return l[e]=o}for(var u in n)c(u);var d=[];for(var p in s)d.push(l[p]);return i(d)}(f,u,t,n)}};return w}}();e.exports=t},2703:(e,t,n)=>{"use strict";var r=n(414);function o(){}function a(){}a.resetWarningCache=o,e.exports=function(){function e(e,t,n,o,a,i){if(i!==r){var l=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw l.name="Invariant Violation",l}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:a,resetWarningCache:o};return n.PropTypes=n,n}},5697:(e,t,n)=>{e.exports=n(2703)()},414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},4448:(e,t,n)=>{"use strict";var r=n(7294),o=n(3840);function a(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n