diff --git a/404.html b/404.html index ef498ac80..74607f107 100644 --- a/404.html +++ b/404.html @@ -4,10 +4,10 @@ Page Not Found | Komodo - - + + -
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

+
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

\ No newline at end of file diff --git a/CNAME b/CNAME deleted file mode 100644 index 87c35431d..000000000 --- a/CNAME +++ /dev/null @@ -1 +0,0 @@ -komo.do \ No newline at end of file diff --git a/assets/js/0e384e19.abcf3cdb.js b/assets/js/0e384e19.abcf3cdb.js deleted file mode 100644 index 11d47aaaf..000000000 --- a/assets/js/0e384e19.abcf3cdb.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[976],{619:(e,o,n)=>{n.r(o),n.d(o,{assets:()=>d,contentTitle:()=>t,default:()=>h,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var r=n(4848),i=n(8453);const s={slug:"/intro"},t="What is Komodo?",a={id:"intro",title:"What is Komodo?",description:"Komodo is a web app to provide structure for managing your servers, builds, deployments, and automated procedures.",source:"@site/docs/intro.md",sourceDirName:".",slug:"/intro",permalink:"/docs/intro",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/intro.md",tags:[],version:"current",frontMatter:{slug:"/intro"},sidebar:"docs",next:{title:"Resources",permalink:"/docs/resources"}},d={},c=[{value:"Docker",id:"docker",level:2},{value:"Architecture and Components",id:"architecture-and-components",level:2},{value:"Core",id:"core",level:3},{value:"Periphery",id:"periphery",level:3},{value:"Core API",id:"core-api",level:2},{value:"Permissioning",id:"permissioning",level:2}];function l(e){const o={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(o.header,{children:(0,r.jsx)(o.h1,{id:"what-is-komodo",children:"What is Komodo?"})}),"\n",(0,r.jsx)(o.p,{children:"Komodo is a web app to provide structure for managing your servers, builds, deployments, and automated procedures."}),"\n",(0,r.jsx)(o.p,{children:"With Komodo you can:"}),"\n",(0,r.jsxs)(o.ul,{children:["\n",(0,r.jsx)(o.li,{children:"Connect all of your servers, and alert on CPU usage, memory usage, and disk usage."}),"\n",(0,r.jsx)(o.li,{children:"Create, start, stop, and restart Docker containers on the connected servers, and view their status and logs."}),"\n",(0,r.jsx)(o.li,{children:"Deploy docker compose stacks. The file can be defined in UI, or in a git repo, with auto deploy on git push."}),"\n",(0,r.jsx)(o.li,{children:"Build application source into auto-versioned Docker images, auto built on webhook. Deploy single-use AWS instances for infinite capacity."}),"\n",(0,r.jsx)(o.li,{children:"Manage repositories on connected servers, which can perform automation via scripting / webhooks."}),"\n",(0,r.jsx)(o.li,{children:"Manage all your configuration / environment variables, with shared global variable and secret interpolation."}),"\n",(0,r.jsx)(o.li,{children:"Keep a record of all the actions that are performed and by whom."}),"\n"]}),"\n",(0,r.jsx)(o.p,{children:'There is no limit to the number of servers you can connect, and there will never be. There is no limit to what API you can use for automation, and there never will be. No "business edition" here.'}),"\n",(0,r.jsx)(o.h2,{id:"docker",children:"Docker"}),"\n",(0,r.jsxs)(o.p,{children:["Komodo is opinionated by design, and uses ",(0,r.jsx)(o.a,{href:"https://docs.docker.com/",children:"docker"})," as the container engine for building and deploying."]}),"\n",(0,r.jsx)(o.admonition,{type:"info",children:(0,r.jsxs)(o.p,{children:["Komodo also supports ",(0,r.jsx)(o.a,{href:"https://podman.io/",children:(0,r.jsx)(o.strong,{children:"podman"})})," instead of docker by utilizing the ",(0,r.jsx)(o.code,{children:"podman"})," -> ",(0,r.jsx)(o.code,{children:"docker"})," alias.\nFor Stack / docker compose support with podman, check out ",(0,r.jsx)(o.a,{href:"https://github.com/containers/podman-compose",children:(0,r.jsx)(o.strong,{children:"podman-compose"})}),". Thanks to ",(0,r.jsx)(o.code,{children:"u/pup_kit"})," for checking this."]})}),"\n",(0,r.jsx)(o.h2,{id:"architecture-and-components",children:"Architecture and Components"}),"\n",(0,r.jsx)(o.p,{children:"Komodo is composed of a single core and any amount of connected servers running the periphery application."}),"\n",(0,r.jsx)(o.h3,{id:"core",children:"Core"}),"\n",(0,r.jsx)(o.p,{children:"Komodo Core is a web server hosting the Core API and browser UI. All user interaction with the connected servers flow through the Core."}),"\n",(0,r.jsx)(o.h3,{id:"periphery",children:"Periphery"}),"\n",(0,r.jsx)(o.p,{children:"Komodo Periphery is a small stateless web server that runs on all connected servers. It exposes an API called by Komodo Core to perform actions on the server, get system usage, and container status / logs. It is only intended to be reached from the core, and has an address whitelist to limit the IPs allowed to call this API."}),"\n",(0,r.jsx)(o.h2,{id:"core-api",children:"Core API"}),"\n",(0,r.jsxs)(o.p,{children:["Komodo exposes powerful functionality over the Core's REST and Websocket API, enabling infrastructure engineers to manage their infrastructure programmatically. There is a ",(0,r.jsx)(o.a,{href:"https://crates.io/crates/komodo_client",children:"rust crate"})," to simplify programmatic interaction with the API, but in general this can be accomplished using any programming language that can make REST requests."]}),"\n",(0,r.jsx)(o.h2,{id:"permissioning",children:"Permissioning"}),"\n",(0,r.jsxs)(o.p,{children:["Komodo is a system designed to be used by many users, whether they are developers, operations personnel, or administrators. The ability to affect an applications state is very powerful, so Komodo has a granular permissioning system to only provide this functionality to the intended users. The permissioning system is explained in detail in the ",(0,r.jsx)(o.a,{href:"/docs/permissioning",children:"permissioning"})," section."]}),"\n",(0,r.jsxs)(o.p,{children:["User sign-on is possible using username / password, or with Oauth (Github and Google). See ",(0,r.jsx)(o.a,{href:"/docs/setup/",children:"Core Setup"}),"."]})]})}function h(e={}){const{wrapper:o}={...(0,i.R)(),...e.components};return o?(0,r.jsx)(o,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},8453:(e,o,n)=>{n.d(o,{R:()=>t,x:()=>a});var r=n(6540);const i={},s=r.createContext(i);function t(e){const o=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function a(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),r.createElement(s.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0e384e19.f2932478.js b/assets/js/0e384e19.f2932478.js new file mode 100644 index 000000000..6bf4d988b --- /dev/null +++ b/assets/js/0e384e19.f2932478.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[976],{619:(e,o,n)=>{n.r(o),n.d(o,{assets:()=>d,contentTitle:()=>t,default:()=>h,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var r=n(4848),i=n(8453);const s={slug:"/intro"},t="What is Komodo?",a={id:"intro",title:"What is Komodo?",description:"Komodo is a web app to provide structure for managing your servers, builds, deployments, and automated procedures.",source:"@site/docs/intro.md",sourceDirName:".",slug:"/intro",permalink:"/docs/intro",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/intro.md",tags:[],version:"current",frontMatter:{slug:"/intro"},sidebar:"docs",next:{title:"Resources",permalink:"/docs/resources"}},d={},c=[{value:"Docker",id:"docker",level:2},{value:"Architecture and Components",id:"architecture-and-components",level:2},{value:"Core",id:"core",level:3},{value:"Periphery",id:"periphery",level:3},{value:"Core API",id:"core-api",level:2},{value:"Permissioning",id:"permissioning",level:2}];function l(e){const o={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(o.header,{children:(0,r.jsx)(o.h1,{id:"what-is-komodo",children:"What is Komodo?"})}),"\n",(0,r.jsx)(o.p,{children:"Komodo is a web app to provide structure for managing your servers, builds, deployments, and automated procedures."}),"\n",(0,r.jsx)(o.p,{children:"With Komodo you can:"}),"\n",(0,r.jsxs)(o.ul,{children:["\n",(0,r.jsx)(o.li,{children:"Connect all of your servers, and alert on CPU usage, memory usage, and disk usage."}),"\n",(0,r.jsx)(o.li,{children:"Create, start, stop, and restart Docker containers on the connected servers, and view their status and logs."}),"\n",(0,r.jsx)(o.li,{children:"Deploy docker compose stacks. The file can be defined in UI, or in a git repo, with auto deploy on git push."}),"\n",(0,r.jsx)(o.li,{children:"Build application source into auto-versioned Docker images, auto built on webhook. Deploy single-use AWS instances for infinite capacity."}),"\n",(0,r.jsx)(o.li,{children:"Manage repositories on connected servers, which can perform automation via scripting / webhooks."}),"\n",(0,r.jsx)(o.li,{children:"Manage all your configuration / environment variables, with shared global variable and secret interpolation."}),"\n",(0,r.jsx)(o.li,{children:"Keep a record of all the actions that are performed and by whom."}),"\n"]}),"\n",(0,r.jsx)(o.p,{children:'There is no limit to the number of servers you can connect, and there will never be. There is no limit to what API you can use for automation, and there never will be. No "business edition" here.'}),"\n",(0,r.jsx)(o.h2,{id:"docker",children:"Docker"}),"\n",(0,r.jsxs)(o.p,{children:["Komodo is opinionated by design, and uses ",(0,r.jsx)(o.a,{href:"https://docs.docker.com/",children:"docker"})," as the container engine for building and deploying."]}),"\n",(0,r.jsx)(o.admonition,{type:"info",children:(0,r.jsxs)(o.p,{children:["Komodo also supports ",(0,r.jsx)(o.a,{href:"https://podman.io/",children:(0,r.jsx)(o.strong,{children:"podman"})})," instead of docker by utilizing the ",(0,r.jsx)(o.code,{children:"podman"})," -> ",(0,r.jsx)(o.code,{children:"docker"})," alias.\nFor Stack / docker compose support with podman, check out ",(0,r.jsx)(o.a,{href:"https://github.com/containers/podman-compose",children:(0,r.jsx)(o.strong,{children:"podman-compose"})}),". Thanks to ",(0,r.jsx)(o.code,{children:"u/pup_kit"})," for checking this."]})}),"\n",(0,r.jsx)(o.h2,{id:"architecture-and-components",children:"Architecture and Components"}),"\n",(0,r.jsx)(o.p,{children:"Komodo is composed of a single core and any amount of connected servers running the periphery application."}),"\n",(0,r.jsx)(o.h3,{id:"core",children:"Core"}),"\n",(0,r.jsx)(o.p,{children:"Komodo Core is a web server hosting the Core API and browser UI. All user interaction with the connected servers flow through the Core."}),"\n",(0,r.jsx)(o.h3,{id:"periphery",children:"Periphery"}),"\n",(0,r.jsx)(o.p,{children:"Komodo Periphery is a small stateless web server that runs on all connected servers. It exposes an API called by Komodo Core to perform actions on the server, get system usage, and container status / logs. It is only intended to be reached from the core, and has an address whitelist to limit the IPs allowed to call this API."}),"\n",(0,r.jsx)(o.h2,{id:"core-api",children:"Core API"}),"\n",(0,r.jsxs)(o.p,{children:["Komodo exposes powerful functionality over the Core's REST and Websocket API, enabling infrastructure engineers to manage their infrastructure programmatically. There is a ",(0,r.jsx)(o.a,{href:"https://crates.io/crates/komodo_client",children:"rust crate"})," to simplify programmatic interaction with the API, but in general this can be accomplished using any programming language that can make REST requests."]}),"\n",(0,r.jsx)(o.h2,{id:"permissioning",children:"Permissioning"}),"\n",(0,r.jsxs)(o.p,{children:["Komodo is a system designed to be used by many users, whether they are developers, operations personnel, or administrators. The ability to affect an applications state is very powerful, so Komodo has a granular permissioning system to only provide this functionality to the intended users. The permissioning system is explained in detail in the ",(0,r.jsx)(o.a,{href:"/docs/permissioning",children:"permissioning"})," section."]}),"\n",(0,r.jsxs)(o.p,{children:["User sign-on is possible using username / password, or with Oauth (Github and Google). See ",(0,r.jsx)(o.a,{href:"/docs/setup/",children:"Core Setup"}),"."]})]})}function h(e={}){const{wrapper:o}={...(0,i.R)(),...e.components};return o?(0,r.jsx)(o,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},8453:(e,o,n)=>{n.d(o,{R:()=>t,x:()=>a});var r=n(6540);const i={},s=r.createContext(i);function t(e){const o=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function a(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),r.createElement(s.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1bd19f0c.357d1dc4.js b/assets/js/1bd19f0c.357d1dc4.js deleted file mode 100644 index a354a5ae7..000000000 --- a/assets/js/1bd19f0c.357d1dc4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[469],{9723:(e,o,n)=>{n.r(o),n.d(o,{assets:()=>d,contentTitle:()=>a,default:()=>u,frontMatter:()=>s,metadata:()=>r,toc:()=>l});var t=n(4848),i=n(8453),c=n(6695);const s={},a="Advanced Configuration",r={id:"setup/advanced",title:"Advanced Configuration",description:"OIDC / Oauth2",source:"@site/docs/setup/advanced.mdx",sourceDirName:"setup",slug:"/setup/advanced",permalink:"/docs/setup/advanced",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/setup/advanced.mdx",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Sqlite",permalink:"/docs/setup/sqlite"},next:{title:"Connect More Servers",permalink:"/docs/connect-servers"}},d={},l=[{value:"OIDC / Oauth2",id:"oidc--oauth2",level:3},{value:"Mount a config file",id:"mount-a-config-file",level:3}];function h(e){const o={a:"a",admonition:"admonition",code:"code",h1:"h1",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(o.header,{children:(0,t.jsx)(o.h1,{id:"advanced-configuration",children:"Advanced Configuration"})}),"\n",(0,t.jsx)(o.h3,{id:"oidc--oauth2",children:"OIDC / Oauth2"}),"\n",(0,t.jsxs)(o.p,{children:["To enable OAuth2 login, you must create a client on the respective OAuth provider,\nfor example ",(0,t.jsx)(o.a,{href:"https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app",children:"Github"}),"\nor ",(0,t.jsx)(o.a,{href:"https://developers.google.com/identity/protocols/oauth2",children:"Google"}),"."]}),"\n",(0,t.jsxs)(o.p,{children:["Komodo also supports self hosted Oauth2 providers like ",(0,t.jsx)(o.a,{href:"https://docs.goauthentik.io/docs/providers/oauth2/",children:"Authentik"})," or ",(0,t.jsx)(o.a,{href:"https://docs.gitea.com/development/oauth2-provider",children:"Gitea"}),"."]}),"\n",(0,t.jsxs)(o.ul,{children:["\n",(0,t.jsxs)(o.li,{children:["Komodo uses the ",(0,t.jsx)(o.code,{children:"web application"})," login flow."]}),"\n",(0,t.jsxs)(o.li,{children:["The redirect uri is:","\n",(0,t.jsxs)(o.ul,{children:["\n",(0,t.jsxs)(o.li,{children:[(0,t.jsx)(o.code,{children:"/auth/github/callback"})," for Github."]}),"\n",(0,t.jsxs)(o.li,{children:[(0,t.jsx)(o.code,{children:"/auth/google/callback"})," for Google."]}),"\n",(0,t.jsxs)(o.li,{children:[(0,t.jsx)(o.code,{children:"/auth/oidc/callback"})," for OIDC."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(o.h3,{id:"mount-a-config-file",children:"Mount a config file"}),"\n",(0,t.jsxs)(o.p,{children:["If you prefer to keep sensitive information out of environment variables, you can optionally\nwrite a config file on your host, and mount it to ",(0,t.jsx)(o.code,{children:"/config/config.toml"})," in the Komodo core container."]}),"\n",(0,t.jsx)(o.admonition,{type:"info",children:(0,t.jsx)(o.p,{children:"Configuration can still be passed in environment variables, and will take precedent over what is passed in the file."})}),"\n",(0,t.jsxs)(o.p,{children:["Quick download to ",(0,t.jsx)(o.code,{children:"./komodo/core.config.toml"}),":"]}),"\n",(0,t.jsx)(o.pre,{children:(0,t.jsx)(o.code,{className:"language-bash",children:"wget -P komodo https://raw.githubusercontent.com/mbecker20/komodo/main/config/core.config.toml\n"})}),"\n","\n",(0,t.jsx)(c.A,{title:"https://github.com/mbecker20/komodo/blob/main/config/core.config.toml",url:"https://raw.githubusercontent.com/mbecker20/komodo/main/config/core.config.toml",language:"toml"})]})}function u(e={}){const{wrapper:o}={...(0,i.R)(),...e.components};return o?(0,t.jsx)(o,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},6695:(e,o,n)=>{n.d(o,{A:()=>s});var t=n(6540),i=n(1432),c=n(4848);function s(e){let{url:o,language:n,title:s}=e;const[a,r]=(0,t.useState)("");return(0,t.useEffect)((()=>{!async function(e,o){const n=await fetch(e);o(await n.text())}(o,r)}),[]),(0,c.jsx)(i.A,{title:s??o,language:n,showLineNumbers:!0,children:a})}}}]); \ No newline at end of file diff --git a/assets/js/1bd19f0c.3915991b.js b/assets/js/1bd19f0c.3915991b.js new file mode 100644 index 000000000..05c4b0a35 --- /dev/null +++ b/assets/js/1bd19f0c.3915991b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[469],{9723:(e,o,n)=>{n.r(o),n.d(o,{assets:()=>d,contentTitle:()=>a,default:()=>u,frontMatter:()=>s,metadata:()=>r,toc:()=>l});var t=n(4848),i=n(8453),c=n(6695);const s={},a="Advanced Configuration",r={id:"setup/advanced",title:"Advanced Configuration",description:"OIDC / Oauth2",source:"@site/docs/setup/advanced.mdx",sourceDirName:"setup",slug:"/setup/advanced",permalink:"/docs/setup/advanced",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/setup/advanced.mdx",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Sqlite",permalink:"/docs/setup/sqlite"},next:{title:"Connect More Servers",permalink:"/docs/connect-servers"}},d={},l=[{value:"OIDC / Oauth2",id:"oidc--oauth2",level:3},{value:"Mount a config file",id:"mount-a-config-file",level:3}];function h(e){const o={a:"a",admonition:"admonition",code:"code",h1:"h1",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(o.header,{children:(0,t.jsx)(o.h1,{id:"advanced-configuration",children:"Advanced Configuration"})}),"\n",(0,t.jsx)(o.h3,{id:"oidc--oauth2",children:"OIDC / Oauth2"}),"\n",(0,t.jsxs)(o.p,{children:["To enable OAuth2 login, you must create a client on the respective OAuth provider,\nfor example ",(0,t.jsx)(o.a,{href:"https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app",children:"Github"}),"\nor ",(0,t.jsx)(o.a,{href:"https://developers.google.com/identity/protocols/oauth2",children:"Google"}),"."]}),"\n",(0,t.jsxs)(o.p,{children:["Komodo also supports self hosted Oauth2 providers like ",(0,t.jsx)(o.a,{href:"https://docs.goauthentik.io/docs/providers/oauth2/",children:"Authentik"})," or ",(0,t.jsx)(o.a,{href:"https://docs.gitea.com/development/oauth2-provider",children:"Gitea"}),"."]}),"\n",(0,t.jsxs)(o.ul,{children:["\n",(0,t.jsxs)(o.li,{children:["Komodo uses the ",(0,t.jsx)(o.code,{children:"web application"})," login flow."]}),"\n",(0,t.jsxs)(o.li,{children:["The redirect uri is:","\n",(0,t.jsxs)(o.ul,{children:["\n",(0,t.jsxs)(o.li,{children:[(0,t.jsx)(o.code,{children:"/auth/github/callback"})," for Github."]}),"\n",(0,t.jsxs)(o.li,{children:[(0,t.jsx)(o.code,{children:"/auth/google/callback"})," for Google."]}),"\n",(0,t.jsxs)(o.li,{children:[(0,t.jsx)(o.code,{children:"/auth/oidc/callback"})," for OIDC."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(o.h3,{id:"mount-a-config-file",children:"Mount a config file"}),"\n",(0,t.jsxs)(o.p,{children:["If you prefer to keep sensitive information out of environment variables, you can optionally\nwrite a config file on your host, and mount it to ",(0,t.jsx)(o.code,{children:"/config/config.toml"})," in the Komodo core container."]}),"\n",(0,t.jsx)(o.admonition,{type:"info",children:(0,t.jsx)(o.p,{children:"Configuration can still be passed in environment variables, and will take precedent over what is passed in the file."})}),"\n",(0,t.jsxs)(o.p,{children:["Quick download to ",(0,t.jsx)(o.code,{children:"./komodo/core.config.toml"}),":"]}),"\n",(0,t.jsx)(o.pre,{children:(0,t.jsx)(o.code,{className:"language-bash",children:"wget -P komodo https://raw.githubusercontent.com/moghtech/komodo/main/config/core.config.toml\n"})}),"\n","\n",(0,t.jsx)(c.A,{title:"https://github.com/moghtech/komodo/blob/main/config/core.config.toml",url:"https://raw.githubusercontent.com/moghtech/komodo/main/config/core.config.toml",language:"toml"})]})}function u(e={}){const{wrapper:o}={...(0,i.R)(),...e.components};return o?(0,t.jsx)(o,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},6695:(e,o,n)=>{n.d(o,{A:()=>s});var t=n(6540),i=n(1432),c=n(4848);function s(e){let{url:o,language:n,title:s}=e;const[a,r]=(0,t.useState)("");return(0,t.useEffect)((()=>{!async function(e,o){const n=await fetch(e);o(await n.text())}(o,r)}),[]),(0,c.jsx)(i.A,{title:s??o,language:n,showLineNumbers:!0,children:a})}}}]); \ No newline at end of file diff --git a/assets/js/1df93b7f.e0f46f49.js b/assets/js/1df93b7f.7e9ef97e.js similarity index 72% rename from assets/js/1df93b7f.e0f46f49.js rename to assets/js/1df93b7f.7e9ef97e.js index c5c2d9aa3..3efb091fe 100644 --- a/assets/js/1df93b7f.e0f46f49.js +++ b/assets/js/1df93b7f.7e9ef97e.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[583],{7143:(e,t,s)=>{s.r(t),s.d(t,{default:()=>b});var n=s(4164),o=s(8774),r=s(4586),i=s(781),l=s(1107);const c={features:"features_t9lD",featureSvg:"featureSvg_GfXr"};var a=s(4848);const d=[{title:"Automated builds \ud83d\udee0\ufe0f",description:(0,a.jsx)(a.Fragment,{children:"Build auto versioned docker images from git repos, trigger builds on git push"})},{title:"Deploy docker containers \ud83d\ude80",description:(0,a.jsx)(a.Fragment,{children:"Deploy containers, deploy docker compose, see uptime and logs across all your servers"})},{title:"Powered by Rust \ud83e\udd80",description:(0,a.jsx)(a.Fragment,{children:"The core API and periphery agent are written in Rust"})}];function h(e){let{title:t,description:s}=e;return(0,a.jsx)("div",{className:(0,n.A)("col col--4"),children:(0,a.jsxs)("div",{className:"text--center padding-horiz--md",children:[(0,a.jsx)(l.A,{as:"h3",children:t}),(0,a.jsx)("p",{children:s})]})})}function u(){return(0,a.jsx)("section",{className:c.features,children:(0,a.jsx)("div",{className:"container",children:(0,a.jsx)("div",{className:"row",children:d.map(((e,t)=>(0,a.jsx)(h,{...e},t)))})})})}const m={heroBanner:"heroBanner_qdFl",buttons:"buttons_AeoN"};s(6540);function x(e){let{width:t="4rem"}=e;return(0,a.jsx)("img",{style:{width:t,height:"auto",opacity:.7},src:"img/monitor-lizard.png",alt:"monitor-lizard"})}function p(){const{siteConfig:e}=(0,r.A)();return(0,a.jsx)("header",{className:(0,n.A)("hero hero--primary",m.heroBanner),children:(0,a.jsxs)("div",{className:"container",children:[(0,a.jsx)("div",{style:{display:"flex",gap:"1rem",justifyContent:"center"},children:(0,a.jsxs)("div",{style:{position:"relative"},children:[(0,a.jsx)(x,{width:"600px"}),(0,a.jsx)("h1",{className:"hero__title",style:{margin:0,position:"absolute",top:"40%",left:"50%",transform:"translate(-50%, -50%)"},children:"Komodo"})]})}),(0,a.jsx)("p",{className:"hero__subtitle",children:e.tagline}),(0,a.jsx)("div",{style:{display:"flex",justifyContent:"center"},children:(0,a.jsxs)("div",{className:m.buttons,children:[(0,a.jsx)(o.A,{className:"button button--secondary button--lg",to:"/docs/intro",children:"Docs"}),(0,a.jsx)(o.A,{className:"button button--secondary button--lg",to:"https://github.com/mbecker20/komodo",children:"Github"}),(0,a.jsx)(o.A,{className:"button button--secondary button--lg",to:"https://github.com/mbecker20/komodo#screenshots",style:{width:"100%",boxSizing:"border-box",gridColumn:"span 2"},children:"Screenshots"}),(0,a.jsx)(o.A,{className:"button button--secondary button--lg",to:"https://demo.komo.do",style:{width:"100%",boxSizing:"border-box",gridColumn:"span 2"},children:"Demo"})]})})]})})}function b(){const{siteConfig:e}=(0,r.A)();return(0,a.jsxs)(i.A,{title:"Home",description:e.tagline,children:[(0,a.jsx)(p,{}),(0,a.jsx)("main",{children:(0,a.jsx)(u,{})})]})}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[583],{7143:(e,t,s)=>{s.r(t),s.d(t,{default:()=>g});var n=s(4164),o=s(8774),i=s(4586),r=s(781),l=s(1107);const c={features:"features_t9lD",featureSvg:"featureSvg_GfXr"};var a=s(4848);const d=[{title:"Automated builds \ud83d\udee0\ufe0f",description:(0,a.jsx)(a.Fragment,{children:"Build auto versioned docker images from git repos, trigger builds on git push"})},{title:"Deploy docker containers \ud83d\ude80",description:(0,a.jsx)(a.Fragment,{children:"Deploy containers, deploy docker compose, see uptime and logs across all your servers"})},{title:"Powered by Rust \ud83e\udd80",description:(0,a.jsx)(a.Fragment,{children:"The core API and periphery agent are written in Rust"})}];function h(e){let{title:t,description:s}=e;return(0,a.jsx)("div",{className:(0,n.A)("col col--4"),children:(0,a.jsxs)("div",{className:"text--center padding-horiz--md",children:[(0,a.jsx)(l.A,{as:"h3",children:t}),(0,a.jsx)("p",{children:s})]})})}function u(){return(0,a.jsx)("section",{className:c.features,children:(0,a.jsx)("div",{className:"container",children:(0,a.jsx)("div",{className:"row",children:d.map(((e,t)=>(0,a.jsx)(h,{...e},t)))})})})}const m={heroBanner:"heroBanner_qdFl",buttons:"buttons_AeoN"};s(6540);function x(e){let{width:t="4rem"}=e;return(0,a.jsx)("img",{style:{width:t,height:"auto",opacity:.7},src:"img/monitor-lizard.png",alt:"monitor-lizard"})}function p(){const{siteConfig:e}=(0,i.A)();return(0,a.jsx)("header",{className:(0,n.A)("hero hero--primary",m.heroBanner),children:(0,a.jsxs)("div",{className:"container",children:[(0,a.jsx)("div",{style:{display:"flex",gap:"1rem",justifyContent:"center"},children:(0,a.jsxs)("div",{style:{position:"relative"},children:[(0,a.jsx)(x,{width:"600px"}),(0,a.jsx)("h1",{className:"hero__title",style:{margin:0,position:"absolute",top:"40%",left:"50%",transform:"translate(-50%, -50%)"},children:"Komodo"})]})}),(0,a.jsx)("p",{className:"hero__subtitle",children:e.tagline}),(0,a.jsx)("div",{style:{display:"flex",justifyContent:"center"},children:(0,a.jsxs)("div",{className:m.buttons,children:[(0,a.jsx)(o.A,{className:"button button--secondary button--lg",to:"/docs/intro",children:"Docs"}),(0,a.jsx)(o.A,{className:"button button--secondary button--lg",to:"https://github.com/moghtech/komodo",children:"Github"}),(0,a.jsx)(o.A,{className:"button button--secondary button--lg",to:"https://github.com/moghtech/komodo#screenshots",style:{width:"100%",boxSizing:"border-box",gridColumn:"span 2"},children:"Screenshots"}),(0,a.jsx)(o.A,{className:"button button--secondary button--lg",to:"https://demo.komo.do",style:{width:"100%",boxSizing:"border-box",gridColumn:"span 2"},children:"Demo"})]})})]})})}function g(){const{siteConfig:e}=(0,i.A)();return(0,a.jsxs)(r.A,{title:"Home",description:e.tagline,children:[(0,a.jsx)(p,{}),(0,a.jsx)("main",{children:(0,a.jsx)(u,{})})]})}}}]); \ No newline at end of file diff --git a/assets/js/209736a1.256ac77d.js b/assets/js/209736a1.256ac77d.js deleted file mode 100644 index 8696055c0..000000000 --- a/assets/js/209736a1.256ac77d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[580],{8e3:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>t,metadata:()=>a,toc:()=>c});var o=s(4848),r=s(8453);const t={},i="Variables and Secrets",a={id:"variables",title:"Variables and Secrets",description:"A variable / secret in Komodo is just a key-value pair.",source:"@site/docs/variables.md",sourceDirName:".",slug:"/variables",permalink:"/docs/variables",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/variables.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Docker Compose",permalink:"/docs/docker-compose"},next:{title:"Procedures and Actions",permalink:"/docs/procedures"}},l={},c=[{value:"Defining Variables and Secrets",id:"defining-variables-and-secrets",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"variables-and-secrets",children:"Variables and Secrets"})}),"\n",(0,o.jsx)(n.p,{children:"A variable / secret in Komodo is just a key-value pair."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'KEY_1 = "value_1"\n'})}),"\n",(0,o.jsxs)(n.p,{children:["You can interpolate the value into any Environment (and most other user configurable inputs, such as Repo ",(0,o.jsx)(n.code,{children:"On Clone"})," and ",(0,o.jsx)(n.code,{children:"On Pull"}),", or Stack ",(0,o.jsx)(n.code,{children:"Extra Args"}),") using double brackets around the key to trigger interpolation:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-toml",children:"# Before interpolation\nSOME_ENV_VAR = [[KEY_1]] # <- wrap the key in double brackets '[[]]'\n\n# After iterpolation:\nSOME_ENV_VAR = value_1\n"})}),"\n",(0,o.jsx)(n.h2,{id:"defining-variables-and-secrets",children:"Defining Variables and Secrets"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"In the UI"}),", you can go to ",(0,o.jsx)(n.code,{children:"Settings"})," page, ",(0,o.jsx)(n.code,{children:"Variables"})," tab. Here, you can create some Variables to store in the Komodo database."]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:['There is a "secret" option you can check, this will ',(0,o.jsx)(n.strong,{children:"prevent the value from exposure in any updates / logs"}),", as well as prevent access to the value to any ",(0,o.jsx)(n.strong,{children:"non-admin"})," Komodo users."]}),"\n",(0,o.jsxs)(n.li,{children:["Variables can also be managed in ResourceSyncs (see ",(0,o.jsx)(n.a,{href:"/docs/sync-resources#deployments",children:"example"}),") but should only be done for non-secret variables, to avoid committing sensitive data. You should manage secrets using one of the following options."]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"Mount a config file to Core"}),": ",(0,o.jsx)(n.a,{href:"https://komo.do/docs/setup/advanced#mount-a-config-file",children:"https://komo.do/docs/setup/advanced#mount-a-config-file"})]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["In the Komodo Core config file, you can configure ",(0,o.jsx)(n.code,{children:"secrets"})," using a block like:","\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-toml",children:'# in core.config.toml\n[secrets]\nKEY_1 = "value_1"\nKEY_2 = "value_2"\n'})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"KEY_1"})," and ",(0,o.jsx)(n.code,{children:"KEY_2"})," will be available for interpolation on all your resources, as if they were Variables set up in the UI."]}),"\n",(0,o.jsxs)(n.li,{children:["They keys are queryable and show up on the variable page (so you know they are available for use),\nbut ",(0,o.jsx)(n.strong,{children:"the values are not exposed by API for ANY user"}),"."]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"Mount a config file to Periphery agent"}),":"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["In the Komodo Periphery config file, you can also configure ",(0,o.jsx)(n.code,{children:"secrets"})," using the same syntax as the Core config file."]}),"\n",(0,o.jsxs)(n.li,{children:["The variable ",(0,o.jsx)(n.strong,{children:"WILL NOT be available globally to all Komodo resources"}),", it will only be available to the resources on the associated Server resource on which that single Periphery agent is running."]}),"\n",(0,o.jsx)(n.li,{children:"This effectively distributes your secret locations, can be good or bad depending on your security requirements. It does avoid the need to send the secret over network from Core to Periphery, Periphery based secrets are never exposed to the network."}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"Use a dedicated secret management tool"})," such as Hashicorp Vault, alongside Komodo"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Ultimately Komodo variable / secret features ",(0,o.jsx)(n.strong,{children:"may not fill enterprise level secret management requirements"}),", organizations of this level should use still a dedicated secret management solution. At this point Komodo is not intended as an enterprise level secret management solution."]}),"\n",(0,o.jsxs)(n.li,{children:["These solutions do require application level integrations, your applications should only receive credentials to access the secret management API. ",(0,o.jsx)(n.strong,{children:"Your applications will pull the actual secret values from the dedicated secret management tool, they stay out of Komodo entirely"}),"."]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>a});var o=s(6540);const r={},t=o.createContext(r);function i(e){const n=o.useContext(t);return o.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(r):e.components||r:i(e.components),o.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/209736a1.47e2b879.js b/assets/js/209736a1.47e2b879.js new file mode 100644 index 000000000..5ab6f801f --- /dev/null +++ b/assets/js/209736a1.47e2b879.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[580],{8e3:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>t,metadata:()=>a,toc:()=>c});var o=s(4848),r=s(8453);const t={},i="Variables and Secrets",a={id:"variables",title:"Variables and Secrets",description:"A variable / secret in Komodo is just a key-value pair.",source:"@site/docs/variables.md",sourceDirName:".",slug:"/variables",permalink:"/docs/variables",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/variables.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Docker Compose",permalink:"/docs/docker-compose"},next:{title:"Procedures and Actions",permalink:"/docs/procedures"}},l={},c=[{value:"Defining Variables and Secrets",id:"defining-variables-and-secrets",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"variables-and-secrets",children:"Variables and Secrets"})}),"\n",(0,o.jsx)(n.p,{children:"A variable / secret in Komodo is just a key-value pair."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'KEY_1 = "value_1"\n'})}),"\n",(0,o.jsxs)(n.p,{children:["You can interpolate the value into any Environment (and most other user configurable inputs, such as Repo ",(0,o.jsx)(n.code,{children:"On Clone"})," and ",(0,o.jsx)(n.code,{children:"On Pull"}),", or Stack ",(0,o.jsx)(n.code,{children:"Extra Args"}),") using double brackets around the key to trigger interpolation:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-toml",children:"# Before interpolation\nSOME_ENV_VAR = [[KEY_1]] # <- wrap the key in double brackets '[[]]'\n\n# After iterpolation:\nSOME_ENV_VAR = value_1\n"})}),"\n",(0,o.jsx)(n.h2,{id:"defining-variables-and-secrets",children:"Defining Variables and Secrets"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"In the UI"}),", you can go to ",(0,o.jsx)(n.code,{children:"Settings"})," page, ",(0,o.jsx)(n.code,{children:"Variables"})," tab. Here, you can create some Variables to store in the Komodo database."]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:['There is a "secret" option you can check, this will ',(0,o.jsx)(n.strong,{children:"prevent the value from exposure in any updates / logs"}),", as well as prevent access to the value to any ",(0,o.jsx)(n.strong,{children:"non-admin"})," Komodo users."]}),"\n",(0,o.jsxs)(n.li,{children:["Variables can also be managed in ResourceSyncs (see ",(0,o.jsx)(n.a,{href:"/docs/sync-resources#deployments",children:"example"}),") but should only be done for non-secret variables, to avoid committing sensitive data. You should manage secrets using one of the following options."]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"Mount a config file to Core"}),": ",(0,o.jsx)(n.a,{href:"https://komo.do/docs/setup/advanced#mount-a-config-file",children:"https://komo.do/docs/setup/advanced#mount-a-config-file"})]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["In the Komodo Core config file, you can configure ",(0,o.jsx)(n.code,{children:"secrets"})," using a block like:","\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-toml",children:'# in core.config.toml\n[secrets]\nKEY_1 = "value_1"\nKEY_2 = "value_2"\n'})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"KEY_1"})," and ",(0,o.jsx)(n.code,{children:"KEY_2"})," will be available for interpolation on all your resources, as if they were Variables set up in the UI."]}),"\n",(0,o.jsxs)(n.li,{children:["They keys are queryable and show up on the variable page (so you know they are available for use),\nbut ",(0,o.jsx)(n.strong,{children:"the values are not exposed by API for ANY user"}),"."]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"Mount a config file to Periphery agent"}),":"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["In the Komodo Periphery config file, you can also configure ",(0,o.jsx)(n.code,{children:"secrets"})," using the same syntax as the Core config file."]}),"\n",(0,o.jsxs)(n.li,{children:["The variable ",(0,o.jsx)(n.strong,{children:"WILL NOT be available globally to all Komodo resources"}),", it will only be available to the resources on the associated Server resource on which that single Periphery agent is running."]}),"\n",(0,o.jsx)(n.li,{children:"This effectively distributes your secret locations, can be good or bad depending on your security requirements. It does avoid the need to send the secret over network from Core to Periphery, Periphery based secrets are never exposed to the network."}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"Use a dedicated secret management tool"})," such as Hashicorp Vault, alongside Komodo"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Ultimately Komodo variable / secret features ",(0,o.jsx)(n.strong,{children:"may not fill enterprise level secret management requirements"}),", organizations of this level should use still a dedicated secret management solution. At this point Komodo is not intended as an enterprise level secret management solution."]}),"\n",(0,o.jsxs)(n.li,{children:["These solutions do require application level integrations, your applications should only receive credentials to access the secret management API. ",(0,o.jsx)(n.strong,{children:"Your applications will pull the actual secret values from the dedicated secret management tool, they stay out of Komodo entirely"}),"."]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>a});var o=s(6540);const r={},t=o.createContext(r);function i(e){const n=o.useContext(t);return o.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(r):e.components||r:i(e.components),o.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2f7566f9.1ea46b68.js b/assets/js/2f7566f9.1ea46b68.js deleted file mode 100644 index 3e5b71aa5..000000000 --- a/assets/js/2f7566f9.1ea46b68.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[464],{8830:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>p,frontMatter:()=>t,metadata:()=>a,toc:()=>h});var r=i(4848),o=i(8453),s=i(6695);const t={},c="Connect More Servers",a={id:"connect-servers",title:"Connect More Servers",description:"Connecting a server to Komodo has 2 steps:",source:"@site/docs/connect-servers.mdx",sourceDirName:".",slug:"/connect-servers",permalink:"/docs/connect-servers",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/connect-servers.mdx",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Advanced Configuration",permalink:"/docs/setup/advanced"},next:{title:"Building Images",permalink:"/docs/build-images"}},l={},h=[{value:"Install Periphery",id:"install-periphery",level:2},{value:"Install the Periphery agent - systemd",id:"install-the-periphery-agent---systemd",level:3},{value:"Install the Periphery agent - container",id:"install-the-periphery-agent---container",level:3},{value:"Manual install steps - binaries",id:"manual-install-steps---binaries",level:3},{value:"Example periphery start command",id:"example-periphery-start-command",level:3},{value:"Passing config files",id:"passing-config-files",level:3},{value:"Configuration",id:"configuration",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"connect-more-servers",children:"Connect More Servers"})}),"\n",(0,r.jsx)(n.p,{children:"Connecting a server to Komodo has 2 steps:"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"Install the Periphery agent on the server (either binary or container)."}),"\n",(0,r.jsx)(n.li,{children:"Add the server to Komodo via the Core API / UI."}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"install-periphery",children:"Install Periphery"}),"\n",(0,r.jsxs)(n.p,{children:["You can install Periphery as a systemd managed process, run it as a ",(0,r.jsx)(n.a,{href:"https://github.com/mbecker20/komodo/pkgs/container/periphery",children:"docker container"}),", or do whatever you want with the binary."]}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsxs)(n.p,{children:["Allowing unintended access to the Periphery agent API is a security risk.\nEnsure to take appropriate measures to block access to the Periphery API, such as firewall rules on port ",(0,r.jsx)(n.code,{children:"8120"}),".\nAdditionally, you can whitelist your Komodo Core IP address in the ",(0,r.jsx)(n.a,{href:"https://github.com/mbecker20/komodo/blob/main/config/periphery.config.toml#L46",children:"Periphery config"}),",\nand configure it to ",(0,r.jsx)(n.a,{href:"https://github.com/mbecker20/komodo/blob/main/config/periphery.config.toml#L51",children:"only accept requests matching including your Core passkey"}),"."]})}),"\n",(0,r.jsx)(n.h3,{id:"install-the-periphery-agent---systemd",children:"Install the Periphery agent - systemd"}),"\n",(0,r.jsx)(n.p,{children:"As root user:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"curl -sSL https://raw.githubusercontent.com/mbecker20/komodo/main/scripts/setup-periphery.py | python3\n"})}),"\n",(0,r.jsx)(n.p,{children:"Periphery can also be installed to run as the calling user, just note this comes with some additional configuration."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"curl -sSL https://raw.githubusercontent.com/mbecker20/komodo/main/scripts/setup-periphery.py | python3 - --user\n"})}),"\n",(0,r.jsxs)(n.p,{children:["You can find more information (and view the script) in the ",(0,r.jsx)(n.a,{href:"https://github.com/mbecker20/komodo/tree/main/scripts",children:"readme"}),"."]}),"\n",(0,r.jsx)(n.admonition,{type:"info",children:(0,r.jsx)(n.p,{children:"This script can be run multiple times without issue, and it won't change existing config after the first run. Just run it again after a Komodo version release, and it will update the periphery version."})}),"\n",(0,r.jsx)(n.h3,{id:"install-the-periphery-agent---container",children:"Install the Periphery agent - container"}),"\n",(0,r.jsx)(n.p,{children:"You can use a docker compose file like this:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"services:\n periphery:\n image: ghcr.io/mbecker20/periphery:latest\n # image: ghcr.io/mbecker20/periphery:latest-aarch64 # use for arm support\n labels:\n komodo.skip: # Prevent Komodo from stopping with StopAllContainers\n logging:\n driver: local\n ports:\n - 8120:8120\n volumes:\n ## Mount external docker socket\n - /var/run/docker.sock:/var/run/docker.sock\n ## Allow Periphery to see processes outside of container\n - /proc:/proc\n ## use self signed certs in docker volume, \n ## or mount your own signed certs.\n - ssl-certs:/etc/komodo/ssl\n ## manage repos in a docker volume, \n ## or change it to an accessible host directory.\n - repos:/etc/komodo/repos\n ## manage stack files in a docker volume, \n ## or change it to an accessible host directory.\n - stacks:/etc/komodo/stacks\n ## Optionally mount a path to store compose files\n # - /path/to/compose:/host/compose\n environment:\n ## Full list: `https://github.com/mbecker20/komodo/blob/main/config/periphery.config.toml`\n ## Configure the same passkey given to Komodo Core (KOMODO_PASSKEY)\n PERIPHERY_PASSKEYS: your_core_passkey # Alt: PERIPHERY_PASSKEYS_FILE\n ## Adding IP here will ensure calling IP is in the list. (optional)\n PERIPHERY_ALLOWED_IPS:\n ## Enable HTTPS server\n PERIPHERY_SSL_ENABLED: true\n ## If the disk size is overreporting, can use one of these to \n ## whitelist / blacklist the disks to filter them, whichever is easier.\n ## Accepts comma separated list of paths.\n ## Usually whitelisting /etc/hostname gives correct size.\n PERIPHERY_INCLUDE_DISK_MOUNTS: /etc/hostname\n # PERIPHERY_EXCLUDE_DISK_MOUNTS: /snap,/etc/repos\n\nvolumes:\n ssl-certs:\n repos:\n stacks:\n"})}),"\n",(0,r.jsx)(n.h3,{id:"manual-install-steps---binaries",children:"Manual install steps - binaries"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Download the periphery binary from the latest ",(0,r.jsx)(n.a,{href:"https://github.com/mbecker20/komodo/releases",children:"release"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Create and edit your config files, following the ",(0,r.jsx)(n.a,{href:"https://github.com/mbecker20/komodo/blob/main/config/periphery.config.toml",children:"config example"}),"."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["See the ",(0,r.jsx)(n.a,{href:"https://docs.rs/komodo_client/latest/komodo_client/entities/config/periphery/index.html",children:"periphery config docs"}),"\nfor more information on configuring periphery."]})}),"\n",(0,r.jsxs)(n.ol,{start:"3",children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Ensure that inbound connectivity is allowed on the port specified in periphery.config.toml (default 8120)."}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Install docker. See the ",(0,r.jsx)(n.a,{href:"https://docs.docker.com/engine/install/",children:"docker install docs"}),"."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsx)(n.p,{children:"Ensure that the user which periphery is run as has access to the docker group without sudo."})}),"\n",(0,r.jsxs)(n.ol,{start:"5",children:["\n",(0,r.jsx)(n.li,{children:"Start the periphery binary with your preferred process manager, like systemd."}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"example-periphery-start-command",children:"Example periphery start command"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"periphery \\\n\t--config-path /path/to/periphery.config.base.toml \\\n\t--config-path /other_path/to/overide-periphery-config-directory \\\n\t--config-keyword periphery \\\n\t--config-keyword config \\\n\t--merge-nested-config true\n"})}),"\n",(0,r.jsx)(n.admonition,{type:"info",children:(0,r.jsxs)(n.p,{children:["You can run ",(0,r.jsx)(n.code,{children:"periphery --help"})," to see the manual."]})}),"\n",(0,r.jsx)(n.h3,{id:"passing-config-files",children:"Passing config files"}),"\n",(0,r.jsxs)(n.p,{children:["Either file paths or directory paths can be passed to ",(0,r.jsx)(n.code,{children:"--config-path"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["When using directories, the file entries can be filtered by name with the ",(0,r.jsx)(n.code,{children:"--config-keyword"})," argument, which can be passed multiple times to add more keywords. If passed, then only config files with file names that contain all keywords will be merged."]}),"\n",(0,r.jsxs)(n.p,{children:["When passing multiple config files, later --config-path given in the command will always overide previous ones. Directory config files are merged in alphabetical order by name, so ",(0,r.jsx)(n.code,{children:"config_b.toml"})," will overide ",(0,r.jsx)(n.code,{children:"config_a.toml"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["There are two ways to merge config files. The default behavior is to completely replace any base fields with whatever fields are present in the overide config. So if you pass ",(0,r.jsx)(n.code,{children:"allowed_ips = []"})," in your overide config, the final allowed_ips will be an empty list as well."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"--merge-nested-config true"})," will merge config fields recursively and extend config array fields."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, with ",(0,r.jsx)(n.code,{children:"--merge-nested-config true"})," you can specify an allowed ip in the base config, and another in the overide config, they will both be present in the final config."]}),"\n",(0,r.jsx)(n.p,{children:"Similarly, you can specify a base docker / github account pair, and extend them with additional accounts in the overide config."}),"\n",(0,r.jsx)(n.h2,{id:"configuration",children:"Configuration"}),"\n",(0,r.jsxs)(n.p,{children:["Quick download to ",(0,r.jsx)(n.code,{children:"./komodo/periphery.config.toml"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"wget -P komodo https://raw.githubusercontent.com/mbecker20/komodo/main/config/periphery.config.toml\n"})}),"\n","\n",(0,r.jsx)(s.A,{title:"https://github.com/mbecker20/komodo/blob/main/config/periphery.config.toml",url:"https://raw.githubusercontent.com/mbecker20/komodo/main/config/periphery.config.toml",language:"toml"})]})}function p(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},6695:(e,n,i)=>{i.d(n,{A:()=>t});var r=i(6540),o=i(1432),s=i(4848);function t(e){let{url:n,language:i,title:t}=e;const[c,a]=(0,r.useState)("");return(0,r.useEffect)((()=>{!async function(e,n){const i=await fetch(e);n(await i.text())}(n,a)}),[]),(0,s.jsx)(o.A,{title:t??n,language:i,showLineNumbers:!0,children:c})}}}]); \ No newline at end of file diff --git a/assets/js/2f7566f9.a498b7f6.js b/assets/js/2f7566f9.a498b7f6.js new file mode 100644 index 000000000..1198d7681 --- /dev/null +++ b/assets/js/2f7566f9.a498b7f6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[464],{8830:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>p,frontMatter:()=>s,metadata:()=>a,toc:()=>h});var o=i(4848),t=i(8453),r=i(6695);const s={},c="Connect More Servers",a={id:"connect-servers",title:"Connect More Servers",description:"Connecting a server to Komodo has 2 steps:",source:"@site/docs/connect-servers.mdx",sourceDirName:".",slug:"/connect-servers",permalink:"/docs/connect-servers",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/connect-servers.mdx",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Advanced Configuration",permalink:"/docs/setup/advanced"},next:{title:"Building Images",permalink:"/docs/build-images"}},l={},h=[{value:"Install Periphery",id:"install-periphery",level:2},{value:"Install the Periphery agent - systemd",id:"install-the-periphery-agent---systemd",level:3},{value:"Install the Periphery agent - container",id:"install-the-periphery-agent---container",level:3},{value:"Manual install steps - binaries",id:"manual-install-steps---binaries",level:3},{value:"Example periphery start command",id:"example-periphery-start-command",level:3},{value:"Passing config files",id:"passing-config-files",level:3},{value:"Configuration",id:"configuration",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,t.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"connect-more-servers",children:"Connect More Servers"})}),"\n",(0,o.jsx)(n.p,{children:"Connecting a server to Komodo has 2 steps:"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsx)(n.li,{children:"Install the Periphery agent on the server (either binary or container)."}),"\n",(0,o.jsx)(n.li,{children:"Add the server to Komodo via the Core API / UI."}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"install-periphery",children:"Install Periphery"}),"\n",(0,o.jsxs)(n.p,{children:["You can install Periphery as a systemd managed process, run it as a ",(0,o.jsx)(n.a,{href:"https://github.com/moghtech/komodo/pkgs/container/periphery",children:"docker container"}),", or do whatever you want with the binary."]}),"\n",(0,o.jsx)(n.admonition,{type:"warning",children:(0,o.jsxs)(n.p,{children:["Allowing unintended access to the Periphery agent API is a security risk.\nEnsure to take appropriate measures to block access to the Periphery API, such as firewall rules on port ",(0,o.jsx)(n.code,{children:"8120"}),".\nAdditionally, you can whitelist your Komodo Core IP address in the ",(0,o.jsx)(n.a,{href:"https://github.com/moghtech/komodo/blob/main/config/periphery.config.toml#L46",children:"Periphery config"}),",\nand configure it to ",(0,o.jsx)(n.a,{href:"https://github.com/moghtech/komodo/blob/main/config/periphery.config.toml#L51",children:"only accept requests matching including your Core passkey"}),"."]})}),"\n",(0,o.jsx)(n.h3,{id:"install-the-periphery-agent---systemd",children:"Install the Periphery agent - systemd"}),"\n",(0,o.jsx)(n.p,{children:"As root user:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"curl -sSL https://raw.githubusercontent.com/moghtech/komodo/main/scripts/setup-periphery.py | python3\n"})}),"\n",(0,o.jsx)(n.p,{children:"Periphery can also be installed to run as the calling user, just note this comes with some additional configuration."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"curl -sSL https://raw.githubusercontent.com/moghtech/komodo/main/scripts/setup-periphery.py | python3 - --user\n"})}),"\n",(0,o.jsxs)(n.p,{children:["You can find more information (and view the script) in the ",(0,o.jsx)(n.a,{href:"https://github.com/moghtech/komodo/tree/main/scripts",children:"readme"}),"."]}),"\n",(0,o.jsx)(n.admonition,{type:"info",children:(0,o.jsx)(n.p,{children:"This script can be run multiple times without issue, and it won't change existing config after the first run. Just run it again after a Komodo version release, and it will update the periphery version."})}),"\n",(0,o.jsx)(n.h3,{id:"install-the-periphery-agent---container",children:"Install the Periphery agent - container"}),"\n",(0,o.jsx)(n.p,{children:"You can use a docker compose file like this:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"services:\n periphery:\n image: ghcr.io/mbecker20/periphery:latest\n # image: ghcr.io/mbecker20/periphery:latest-aarch64 # use for arm support\n labels:\n komodo.skip: # Prevent Komodo from stopping with StopAllContainers\n logging:\n driver: local\n ports:\n - 8120:8120\n volumes:\n ## Mount external docker socket\n - /var/run/docker.sock:/var/run/docker.sock\n ## Allow Periphery to see processes outside of container\n - /proc:/proc\n ## use self signed certs in docker volume, \n ## or mount your own signed certs.\n - ssl-certs:/etc/komodo/ssl\n ## manage repos in a docker volume, \n ## or change it to an accessible host directory.\n - repos:/etc/komodo/repos\n ## manage stack files in a docker volume, \n ## or change it to an accessible host directory.\n - stacks:/etc/komodo/stacks\n ## Optionally mount a path to store compose files\n # - /path/to/compose:/host/compose\n environment:\n ## Full list: `https://github.com/moghtech/komodo/blob/main/config/periphery.config.toml`\n ## Configure the same passkey given to Komodo Core (KOMODO_PASSKEY)\n PERIPHERY_PASSKEYS: your_core_passkey # Alt: PERIPHERY_PASSKEYS_FILE\n ## Adding IP here will ensure calling IP is in the list. (optional)\n PERIPHERY_ALLOWED_IPS:\n ## Enable HTTPS server\n PERIPHERY_SSL_ENABLED: true\n ## If the disk size is overreporting, can use one of these to \n ## whitelist / blacklist the disks to filter them, whichever is easier.\n ## Accepts comma separated list of paths.\n ## Usually whitelisting /etc/hostname gives correct size.\n PERIPHERY_INCLUDE_DISK_MOUNTS: /etc/hostname\n # PERIPHERY_EXCLUDE_DISK_MOUNTS: /snap,/etc/repos\n\nvolumes:\n ssl-certs:\n repos:\n stacks:\n"})}),"\n",(0,o.jsx)(n.h3,{id:"manual-install-steps---binaries",children:"Manual install steps - binaries"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Download the periphery binary from the latest ",(0,o.jsx)(n.a,{href:"https://github.com/moghtech/komodo/releases",children:"release"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Create and edit your config files, following the ",(0,o.jsx)(n.a,{href:"https://github.com/moghtech/komodo/blob/main/config/periphery.config.toml",children:"config example"}),"."]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.admonition,{type:"note",children:(0,o.jsxs)(n.p,{children:["See the ",(0,o.jsx)(n.a,{href:"https://docs.rs/komodo_client/latest/komodo_client/entities/config/periphery/index.html",children:"periphery config docs"}),"\nfor more information on configuring periphery."]})}),"\n",(0,o.jsxs)(n.ol,{start:"3",children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Ensure that inbound connectivity is allowed on the port specified in periphery.config.toml (default 8120)."}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Install docker. See the ",(0,o.jsx)(n.a,{href:"https://docs.docker.com/engine/install/",children:"docker install docs"}),"."]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.admonition,{type:"note",children:(0,o.jsx)(n.p,{children:"Ensure that the user which periphery is run as has access to the docker group without sudo."})}),"\n",(0,o.jsxs)(n.ol,{start:"5",children:["\n",(0,o.jsx)(n.li,{children:"Start the periphery binary with your preferred process manager, like systemd."}),"\n"]}),"\n",(0,o.jsx)(n.h3,{id:"example-periphery-start-command",children:"Example periphery start command"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"periphery \\\n\t--config-path /path/to/periphery.config.base.toml \\\n\t--config-path /other_path/to/overide-periphery-config-directory \\\n\t--config-keyword periphery \\\n\t--config-keyword config \\\n\t--merge-nested-config true\n"})}),"\n",(0,o.jsx)(n.admonition,{type:"info",children:(0,o.jsxs)(n.p,{children:["You can run ",(0,o.jsx)(n.code,{children:"periphery --help"})," to see the manual."]})}),"\n",(0,o.jsx)(n.h3,{id:"passing-config-files",children:"Passing config files"}),"\n",(0,o.jsxs)(n.p,{children:["Either file paths or directory paths can be passed to ",(0,o.jsx)(n.code,{children:"--config-path"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["When using directories, the file entries can be filtered by name with the ",(0,o.jsx)(n.code,{children:"--config-keyword"})," argument, which can be passed multiple times to add more keywords. If passed, then only config files with file names that contain all keywords will be merged."]}),"\n",(0,o.jsxs)(n.p,{children:["When passing multiple config files, later --config-path given in the command will always overide previous ones. Directory config files are merged in alphabetical order by name, so ",(0,o.jsx)(n.code,{children:"config_b.toml"})," will overide ",(0,o.jsx)(n.code,{children:"config_a.toml"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["There are two ways to merge config files. The default behavior is to completely replace any base fields with whatever fields are present in the overide config. So if you pass ",(0,o.jsx)(n.code,{children:"allowed_ips = []"})," in your overide config, the final allowed_ips will be an empty list as well."]}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"--merge-nested-config true"})," will merge config fields recursively and extend config array fields."]}),"\n",(0,o.jsxs)(n.p,{children:["For example, with ",(0,o.jsx)(n.code,{children:"--merge-nested-config true"})," you can specify an allowed ip in the base config, and another in the overide config, they will both be present in the final config."]}),"\n",(0,o.jsx)(n.p,{children:"Similarly, you can specify a base docker / github account pair, and extend them with additional accounts in the overide config."}),"\n",(0,o.jsx)(n.h2,{id:"configuration",children:"Configuration"}),"\n",(0,o.jsxs)(n.p,{children:["Quick download to ",(0,o.jsx)(n.code,{children:"./komodo/periphery.config.toml"}),":"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"wget -P komodo https://raw.githubusercontent.com/moghtech/komodo/main/config/periphery.config.toml\n"})}),"\n","\n",(0,o.jsx)(r.A,{title:"https://github.com/moghtech/komodo/blob/main/config/periphery.config.toml",url:"https://raw.githubusercontent.com/moghtech/komodo/main/config/periphery.config.toml",language:"toml"})]})}function p(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},6695:(e,n,i)=>{i.d(n,{A:()=>s});var o=i(6540),t=i(1432),r=i(4848);function s(e){let{url:n,language:i,title:s}=e;const[c,a]=(0,o.useState)("");return(0,o.useEffect)((()=>{!async function(e,n){const i=await fetch(e);n(await i.text())}(n,a)}),[]),(0,r.jsx)(t.A,{title:s??n,language:i,showLineNumbers:!0,children:c})}}}]); \ No newline at end of file diff --git a/assets/js/3734296e.187b8a97.js b/assets/js/3734296e.187b8a97.js deleted file mode 100644 index 6ea64bf17..000000000 --- a/assets/js/3734296e.187b8a97.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[92],{5918:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>d,frontMatter:()=>i,metadata:()=>h,toc:()=>a});var n=s(4848),o=s(8453);const i={},r="File Paths",h={id:"file-paths",title:"File Paths",description:"When working with Komodo, you might have to configure file or directory paths.",source:"@site/docs/file-paths.md",sourceDirName:".",slug:"/file-paths",permalink:"/docs/file-paths",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/file-paths.md",tags:[],version:"current",frontMatter:{}},l={},a=[{value:"Relative Paths",id:"relative-paths",level:2},{value:"Implementation",id:"implementation",level:3},{value:"Docker Volume Paths",id:"docker-volume-paths",level:2}];function c(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"file-paths",children:"File Paths"})}),"\n",(0,n.jsx)(t.p,{children:"When working with Komodo, you might have to configure file or directory paths."}),"\n",(0,n.jsx)(t.h2,{id:"relative-paths",children:"Relative Paths"}),"\n",(0,n.jsx)(t.p,{children:"Where possible, it is better to use relative file paths. Using relative file paths removes the connection between the process being run and the particular server it runs on, making it easier to move things between servers."}),"\n",(0,n.jsx)(t.p,{children:"Where you see relative paths:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"setting the build directory and path of the Dockerfile"}),"\n",(0,n.jsx)(t.li,{children:"setting a pre build command path"}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"For all of the above, the path can be given relative to the root of the configured repo"}),"\n",(0,n.jsx)(t.p,{children:"The one exception is the Dockerfile path, which is given relative to the build directory (This is done by Docker itself, and this pattern matches usage of the Docker CLI)."}),"\n",(0,n.jsx)(t.p,{children:"There are 3 kinds of paths to pass:"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["to specify the root of the repo, use ",(0,n.jsx)(t.code,{children:"."})," as the path"]}),"\n",(0,n.jsxs)(t.li,{children:["to specify a folder in the repo, pass it with ",(0,n.jsx)(t.strong,{children:"no"})," preceding ",(0,n.jsx)(t.code,{children:"/"}),". For example, ",(0,n.jsx)(t.code,{children:"example_folder"})," or ",(0,n.jsx)(t.code,{children:"folder1/folder2"})]}),"\n",(0,n.jsxs)(t.li,{children:["to specify an absolute path on the servers filesystem, use a preceding slash, eg. ",(0,n.jsx)(t.code,{children:"/home/ubuntu/example"}),". This way should only be used if absolutely necessary, like when passing host paths when configuring docker volumes."]}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"implementation",children:"Implementation"}),"\n",(0,n.jsxs)(t.p,{children:["Relative file paths are joined with the path of the repo on the system using a Rust ",(0,n.jsx)(t.a,{href:"https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.push",children:"PathBuf"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"docker-volume-paths",children:"Docker Volume Paths"}),"\n",(0,n.jsxs)(t.p,{children:["These are passed directly to the Docker CLI using ",(0,n.jsx)(t.code,{children:"--volume /path/on/system:/path/in/container"}),". So for these, the same rules apply as when using Docker on the command line. Paths here should usually be given as absolute. It's also probably best to avoid usage of ",(0,n.jsx)(t.code,{children:"~"})," or environment variables like ",(0,n.jsx)(t.code,{children:"$HOME"}),", as this may lead to unexpected behavior."]})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},8453:(e,t,s)=>{s.d(t,{R:()=>r,x:()=>h});var n=s(6540);const o={},i=n.createContext(o);function r(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function h(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3734296e.a34e21bd.js b/assets/js/3734296e.a34e21bd.js new file mode 100644 index 000000000..f630c84e8 --- /dev/null +++ b/assets/js/3734296e.a34e21bd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[92],{5918:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>d,frontMatter:()=>i,metadata:()=>h,toc:()=>a});var n=s(4848),o=s(8453);const i={},r="File Paths",h={id:"file-paths",title:"File Paths",description:"When working with Komodo, you might have to configure file or directory paths.",source:"@site/docs/file-paths.md",sourceDirName:".",slug:"/file-paths",permalink:"/docs/file-paths",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/file-paths.md",tags:[],version:"current",frontMatter:{}},l={},a=[{value:"Relative Paths",id:"relative-paths",level:2},{value:"Implementation",id:"implementation",level:3},{value:"Docker Volume Paths",id:"docker-volume-paths",level:2}];function c(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"file-paths",children:"File Paths"})}),"\n",(0,n.jsx)(t.p,{children:"When working with Komodo, you might have to configure file or directory paths."}),"\n",(0,n.jsx)(t.h2,{id:"relative-paths",children:"Relative Paths"}),"\n",(0,n.jsx)(t.p,{children:"Where possible, it is better to use relative file paths. Using relative file paths removes the connection between the process being run and the particular server it runs on, making it easier to move things between servers."}),"\n",(0,n.jsx)(t.p,{children:"Where you see relative paths:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"setting the build directory and path of the Dockerfile"}),"\n",(0,n.jsx)(t.li,{children:"setting a pre build command path"}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"For all of the above, the path can be given relative to the root of the configured repo"}),"\n",(0,n.jsx)(t.p,{children:"The one exception is the Dockerfile path, which is given relative to the build directory (This is done by Docker itself, and this pattern matches usage of the Docker CLI)."}),"\n",(0,n.jsx)(t.p,{children:"There are 3 kinds of paths to pass:"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["to specify the root of the repo, use ",(0,n.jsx)(t.code,{children:"."})," as the path"]}),"\n",(0,n.jsxs)(t.li,{children:["to specify a folder in the repo, pass it with ",(0,n.jsx)(t.strong,{children:"no"})," preceding ",(0,n.jsx)(t.code,{children:"/"}),". For example, ",(0,n.jsx)(t.code,{children:"example_folder"})," or ",(0,n.jsx)(t.code,{children:"folder1/folder2"})]}),"\n",(0,n.jsxs)(t.li,{children:["to specify an absolute path on the servers filesystem, use a preceding slash, eg. ",(0,n.jsx)(t.code,{children:"/home/ubuntu/example"}),". This way should only be used if absolutely necessary, like when passing host paths when configuring docker volumes."]}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"implementation",children:"Implementation"}),"\n",(0,n.jsxs)(t.p,{children:["Relative file paths are joined with the path of the repo on the system using a Rust ",(0,n.jsx)(t.a,{href:"https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.push",children:"PathBuf"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"docker-volume-paths",children:"Docker Volume Paths"}),"\n",(0,n.jsxs)(t.p,{children:["These are passed directly to the Docker CLI using ",(0,n.jsx)(t.code,{children:"--volume /path/on/system:/path/in/container"}),". So for these, the same rules apply as when using Docker on the command line. Paths here should usually be given as absolute. It's also probably best to avoid usage of ",(0,n.jsx)(t.code,{children:"~"})," or environment variables like ",(0,n.jsx)(t.code,{children:"$HOME"}),", as this may lead to unexpected behavior."]})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},8453:(e,t,s)=>{s.d(t,{R:()=>r,x:()=>h});var n=s(6540);const o={},i=n.createContext(o);function r(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function h(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/39c35b2c.8d063d1f.js b/assets/js/39c35b2c.8d063d1f.js new file mode 100644 index 000000000..c16520189 --- /dev/null +++ b/assets/js/39c35b2c.8d063d1f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[782],{8327:(e,o,n)=>{n.r(o),n.d(o,{assets:()=>h,contentTitle:()=>s,default:()=>a,frontMatter:()=>t,metadata:()=>c,toc:()=>d});var i=n(4848),r=n(8453);const t={},s="Configuring Webhooks",c={id:"webhooks",title:"Configuring Webhooks",description:"Multiple Komodo resources can take advantage of webhooks from your git provider. Komodo supports incoming webhooks using either the Github or Gitlab webhook authentication type, which is also supported by other providers like Gitea.",source:"@site/docs/webhooks.md",sourceDirName:".",slug:"/webhooks",permalink:"/docs/webhooks",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/webhooks.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Sync Resources",permalink:"/docs/sync-resources"},next:{title:"Version Upgrades",permalink:"/docs/version-upgrades"}},h={},d=[{value:"Copy the Webhook URL",id:"copy-the-webhook-url",level:2},{value:"Create the webhook on the Git Provider",id:"create-the-webhook-on-the-git-provider",level:2},{value:"When does it trigger?",id:"when-does-it-trigger",level:2}];function l(e){const o={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(o.header,{children:(0,i.jsx)(o.h1,{id:"configuring-webhooks",children:"Configuring Webhooks"})}),"\n",(0,i.jsx)(o.p,{children:"Multiple Komodo resources can take advantage of webhooks from your git provider. Komodo supports incoming webhooks using either the Github or Gitlab webhook authentication type, which is also supported by other providers like Gitea."}),"\n",(0,i.jsx)(o.admonition,{type:"note",children:(0,i.jsx)(o.p,{children:'On Gitea, the default "Gitea" webhook type works with the Github authentication type \ud83d\udc4d'})}),"\n",(0,i.jsx)(o.h2,{id:"copy-the-webhook-url",children:"Copy the Webhook URL"}),"\n",(0,i.jsxs)(o.p,{children:["Find the resource in UI, like a ",(0,i.jsx)(o.code,{children:"Build"}),", ",(0,i.jsx)(o.code,{children:"Repo"}),", or ",(0,i.jsx)(o.code,{children:"Stack"}),".\nGo to the ",(0,i.jsx)(o.code,{children:"Config"}),' section, find "Webhooks", and copy the webhook for the action you want.']}),"\n",(0,i.jsx)(o.p,{children:"The webhook URL is constructed as follows:"}),"\n",(0,i.jsx)(o.pre,{children:(0,i.jsx)(o.code,{className:"language-shell",children:"https://${HOST}/listener/${AUTH_TYPE}/${RESOURCE_TYPE}/${ID_OR_NAME}/${EXECUTION}\n"})}),"\n",(0,i.jsxs)(o.ul,{children:["\n",(0,i.jsxs)(o.li,{children:[(0,i.jsx)(o.strong,{children:(0,i.jsx)(o.code,{children:"HOST"})}),": Your Komodo endpoint to recieve webhooks.","\n",(0,i.jsxs)(o.ul,{children:["\n",(0,i.jsxs)(o.li,{children:["If your Komodo sits in a private network,\nyou will need a public proxy setup to forward ",(0,i.jsx)(o.code,{children:"/listener"})," requests to Komodo."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(o.li,{children:[(0,i.jsx)(o.strong,{children:(0,i.jsx)(o.code,{children:"AUTH_TYPE"})}),":","\n",(0,i.jsxs)(o.ul,{children:["\n",(0,i.jsxs)(o.li,{children:["options: ",(0,i.jsx)(o.code,{children:"github"})," | ",(0,i.jsx)(o.code,{children:"gitlab"})]}),"\n",(0,i.jsxs)(o.li,{children:[(0,i.jsx)(o.code,{children:"github"}),": Validates the signature attached with ",(0,i.jsx)(o.code,{children:"X-Hub-Signature-256"}),". ",(0,i.jsx)(o.a,{href:"https://docs.github.com/en/webhooks/using-webhooks/validating-webhook-deliveries",children:"reference"})]}),"\n",(0,i.jsxs)(o.li,{children:[(0,i.jsx)(o.code,{children:"gitlab"}),": Checks that the secret attached to ",(0,i.jsx)(o.code,{children:"X-Gitlab-Token"})," is valid. ",(0,i.jsx)(o.a,{href:"https://docs.gitlab.com/ee/user/project/integrations/webhooks.html#create-a-webhook",children:"reference"})]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(o.li,{children:[(0,i.jsx)(o.strong,{children:(0,i.jsx)(o.code,{children:"RESOURCE_TYPE"})}),":","\n",(0,i.jsxs)(o.ul,{children:["\n",(0,i.jsxs)(o.li,{children:["options: ",(0,i.jsx)(o.code,{children:"build"})," | ",(0,i.jsx)(o.code,{children:"repo"})," | ",(0,i.jsx)(o.code,{children:"stack"})," | ",(0,i.jsx)(o.code,{children:"sync"})," | ",(0,i.jsx)(o.code,{children:"procedure"})," | ",(0,i.jsx)(o.code,{children:"action"})]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(o.li,{children:[(0,i.jsx)(o.strong,{children:(0,i.jsx)(o.code,{children:"ID_OR_NAME"})}),":","\n",(0,i.jsxs)(o.ul,{children:["\n",(0,i.jsx)(o.li,{children:"Reference the specific resource by id or name. If the name may change, it is better to use id."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(o.li,{children:[(0,i.jsx)(o.strong,{children:(0,i.jsx)(o.code,{children:"EXECUTION"})}),":","\n",(0,i.jsxs)(o.ul,{children:["\n",(0,i.jsxs)(o.li,{children:["Which executions are available depends on the ",(0,i.jsx)(o.code,{children:"RESOURCE_TYPE"}),". Builds only have the ",(0,i.jsx)(o.code,{children:"/build"})," action.\nRepos can select between ",(0,i.jsx)(o.code,{children:"/pull"}),", ",(0,i.jsx)(o.code,{children:"/clone"}),", or ",(0,i.jsx)(o.code,{children:"/build"}),". Stacks have ",(0,i.jsx)(o.code,{children:"/deploy"})," and ",(0,i.jsx)(o.code,{children:"/refresh"}),", and Resource Syncs have ",(0,i.jsx)(o.code,{children:"/sync"})," and ",(0,i.jsx)(o.code,{children:"/refresh"}),"."]}),"\n",(0,i.jsxs)(o.li,{children:["For ",(0,i.jsx)(o.strong,{children:"Procedures and Actions"}),", this will be the ",(0,i.jsx)(o.strong,{children:"branch to listen to for pushes"}),", or ",(0,i.jsx)(o.code,{children:"__ANY__"})," to trigger\non pushes to any branch."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(o.h2,{id:"create-the-webhook-on-the-git-provider",children:"Create the webhook on the Git Provider"}),"\n",(0,i.jsx)(o.p,{children:"Navigate to the repo page on your git provider, and go to the settings for the Repo.\nFind Webhook settings, and click to create a new webhook."}),"\n",(0,i.jsx)(o.p,{children:"You will have to input some information."}),"\n",(0,i.jsxs)(o.ol,{children:["\n",(0,i.jsxs)(o.li,{children:["The ",(0,i.jsx)(o.code,{children:"Payload URL"})," is the link that you copied in the step above, ",(0,i.jsx)(o.code,{children:"Copy the Resource Payload URL"}),"."]}),"\n",(0,i.jsxs)(o.li,{children:["For Content-type, choose ",(0,i.jsx)(o.code,{children:"application/json"})]}),"\n",(0,i.jsxs)(o.li,{children:["For Secret, input the secret you configured in the Komodo Core config (",(0,i.jsx)(o.code,{children:"KOMODO_WEBHOOK_SECRET"}),")."]}),"\n",(0,i.jsx)(o.li,{children:"Enable SSL Verification, if you have proper TLS setup to your git provider (recommended)."}),"\n",(0,i.jsx)(o.li,{children:'For "events that trigger the webhook", just the push request is what post people want.'}),"\n",(0,i.jsx)(o.li,{children:'Of course, make sure the webhook is "Active" and hit create.'}),"\n"]}),"\n",(0,i.jsx)(o.h2,{id:"when-does-it-trigger",children:"When does it trigger?"}),"\n",(0,i.jsxs)(o.p,{children:["Your git provider will now push this webhook to Komodo on ",(0,i.jsx)(o.em,{children:"every"})," push to ",(0,i.jsx)(o.em,{children:"any"})," branch. However, your ",(0,i.jsx)(o.code,{children:"Build"}),", ",(0,i.jsx)(o.code,{children:"Repo"}),",\netc. only cares about a specific branch of the repo."]}),"\n",(0,i.jsxs)(o.p,{children:["Because of this, the webhook will trigger the action ",(0,i.jsx)(o.strong,{children:"only on pushes to the branch configured on the resource"}),"."]}),"\n",(0,i.jsxs)(o.p,{children:["For example, if I make a build, I may point the build to the ",(0,i.jsx)(o.code,{children:"release"})," branch of a particular repo. If I set up a webhook, and push to the ",(0,i.jsx)(o.code,{children:"main"})," branch, the action will ",(0,i.jsx)(o.em,{children:"not trigger"}),". It will only trigger when the push is to the ",(0,i.jsx)(o.code,{children:"release"})," branch."]})]})}function a(e={}){const{wrapper:o}={...(0,r.R)(),...e.components};return o?(0,i.jsx)(o,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},8453:(e,o,n)=>{n.d(o,{R:()=>s,x:()=>c});var i=n(6540);const r={},t=i.createContext(r);function s(e){const o=i.useContext(t);return i.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(r):e.components||r:s(e.components),i.createElement(t.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/39c35b2c.d65ac76d.js b/assets/js/39c35b2c.d65ac76d.js deleted file mode 100644 index c45405f68..000000000 --- a/assets/js/39c35b2c.d65ac76d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[782],{8327:(e,o,n)=>{n.r(o),n.d(o,{assets:()=>h,contentTitle:()=>s,default:()=>a,frontMatter:()=>t,metadata:()=>c,toc:()=>d});var i=n(4848),r=n(8453);const t={},s="Configuring Webhooks",c={id:"webhooks",title:"Configuring Webhooks",description:"Multiple Komodo resources can take advantage of webhooks from your git provider. Komodo supports incoming webhooks using either the Github or Gitlab webhook authentication type, which is also supported by other providers like Gitea.",source:"@site/docs/webhooks.md",sourceDirName:".",slug:"/webhooks",permalink:"/docs/webhooks",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/webhooks.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Sync Resources",permalink:"/docs/sync-resources"},next:{title:"Version Upgrades",permalink:"/docs/version-upgrades"}},h={},d=[{value:"Copy the Webhook URL",id:"copy-the-webhook-url",level:2},{value:"Create the webhook on the Git Provider",id:"create-the-webhook-on-the-git-provider",level:2},{value:"When does it trigger?",id:"when-does-it-trigger",level:2}];function l(e){const o={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(o.header,{children:(0,i.jsx)(o.h1,{id:"configuring-webhooks",children:"Configuring Webhooks"})}),"\n",(0,i.jsx)(o.p,{children:"Multiple Komodo resources can take advantage of webhooks from your git provider. Komodo supports incoming webhooks using either the Github or Gitlab webhook authentication type, which is also supported by other providers like Gitea."}),"\n",(0,i.jsx)(o.admonition,{type:"note",children:(0,i.jsx)(o.p,{children:'On Gitea, the default "Gitea" webhook type works with the Github authentication type \ud83d\udc4d'})}),"\n",(0,i.jsx)(o.h2,{id:"copy-the-webhook-url",children:"Copy the Webhook URL"}),"\n",(0,i.jsxs)(o.p,{children:["Find the resource in UI, like a ",(0,i.jsx)(o.code,{children:"Build"}),", ",(0,i.jsx)(o.code,{children:"Repo"}),", or ",(0,i.jsx)(o.code,{children:"Stack"}),".\nGo to the ",(0,i.jsx)(o.code,{children:"Config"}),' section, find "Webhooks", and copy the webhook for the action you want.']}),"\n",(0,i.jsx)(o.p,{children:"The webhook URL is constructed as follows:"}),"\n",(0,i.jsx)(o.pre,{children:(0,i.jsx)(o.code,{className:"language-shell",children:"https://${HOST}/listener/${AUTH_TYPE}/${RESOURCE_TYPE}/${ID_OR_NAME}/${EXECUTION}\n"})}),"\n",(0,i.jsxs)(o.ul,{children:["\n",(0,i.jsxs)(o.li,{children:[(0,i.jsx)(o.strong,{children:(0,i.jsx)(o.code,{children:"HOST"})}),": Your Komodo endpoint to recieve webhooks.","\n",(0,i.jsxs)(o.ul,{children:["\n",(0,i.jsxs)(o.li,{children:["If your Komodo sits in a private network,\nyou will need a public proxy setup to forward ",(0,i.jsx)(o.code,{children:"/listener"})," requests to Komodo."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(o.li,{children:[(0,i.jsx)(o.strong,{children:(0,i.jsx)(o.code,{children:"AUTH_TYPE"})}),":","\n",(0,i.jsxs)(o.ul,{children:["\n",(0,i.jsxs)(o.li,{children:["options: ",(0,i.jsx)(o.code,{children:"github"})," | ",(0,i.jsx)(o.code,{children:"gitlab"})]}),"\n",(0,i.jsxs)(o.li,{children:[(0,i.jsx)(o.code,{children:"github"}),": Validates the signature attached with ",(0,i.jsx)(o.code,{children:"X-Hub-Signature-256"}),". ",(0,i.jsx)(o.a,{href:"https://docs.github.com/en/webhooks/using-webhooks/validating-webhook-deliveries",children:"reference"})]}),"\n",(0,i.jsxs)(o.li,{children:[(0,i.jsx)(o.code,{children:"gitlab"}),": Checks that the secret attached to ",(0,i.jsx)(o.code,{children:"X-Gitlab-Token"})," is valid. ",(0,i.jsx)(o.a,{href:"https://docs.gitlab.com/ee/user/project/integrations/webhooks.html#create-a-webhook",children:"reference"})]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(o.li,{children:[(0,i.jsx)(o.strong,{children:(0,i.jsx)(o.code,{children:"RESOURCE_TYPE"})}),":","\n",(0,i.jsxs)(o.ul,{children:["\n",(0,i.jsxs)(o.li,{children:["options: ",(0,i.jsx)(o.code,{children:"build"})," | ",(0,i.jsx)(o.code,{children:"repo"})," | ",(0,i.jsx)(o.code,{children:"stack"})," | ",(0,i.jsx)(o.code,{children:"sync"})," | ",(0,i.jsx)(o.code,{children:"procedure"})," | ",(0,i.jsx)(o.code,{children:"action"})]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(o.li,{children:[(0,i.jsx)(o.strong,{children:(0,i.jsx)(o.code,{children:"ID_OR_NAME"})}),":","\n",(0,i.jsxs)(o.ul,{children:["\n",(0,i.jsx)(o.li,{children:"Reference the specific resource by id or name. If the name may change, it is better to use id."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(o.li,{children:[(0,i.jsx)(o.strong,{children:(0,i.jsx)(o.code,{children:"EXECUTION"})}),":","\n",(0,i.jsxs)(o.ul,{children:["\n",(0,i.jsxs)(o.li,{children:["Which executions are available depends on the ",(0,i.jsx)(o.code,{children:"RESOURCE_TYPE"}),". Builds only have the ",(0,i.jsx)(o.code,{children:"/build"})," action.\nRepos can select between ",(0,i.jsx)(o.code,{children:"/pull"}),", ",(0,i.jsx)(o.code,{children:"/clone"}),", or ",(0,i.jsx)(o.code,{children:"/build"}),". Stacks have ",(0,i.jsx)(o.code,{children:"/deploy"})," and ",(0,i.jsx)(o.code,{children:"/refresh"}),", and Resource Syncs have ",(0,i.jsx)(o.code,{children:"/sync"})," and ",(0,i.jsx)(o.code,{children:"/refresh"}),"."]}),"\n",(0,i.jsxs)(o.li,{children:["For ",(0,i.jsx)(o.strong,{children:"Procedures and Actions"}),", this will be the ",(0,i.jsx)(o.strong,{children:"branch to listen to for pushes"}),", or ",(0,i.jsx)(o.code,{children:"__ANY__"})," to trigger\non pushes to any branch."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(o.h2,{id:"create-the-webhook-on-the-git-provider",children:"Create the webhook on the Git Provider"}),"\n",(0,i.jsx)(o.p,{children:"Navigate to the repo page on your git provider, and go to the settings for the Repo.\nFind Webhook settings, and click to create a new webhook."}),"\n",(0,i.jsx)(o.p,{children:"You will have to input some information."}),"\n",(0,i.jsxs)(o.ol,{children:["\n",(0,i.jsxs)(o.li,{children:["The ",(0,i.jsx)(o.code,{children:"Payload URL"})," is the link that you copied in the step above, ",(0,i.jsx)(o.code,{children:"Copy the Resource Payload URL"}),"."]}),"\n",(0,i.jsxs)(o.li,{children:["For Content-type, choose ",(0,i.jsx)(o.code,{children:"application/json"})]}),"\n",(0,i.jsxs)(o.li,{children:["For Secret, input the secret you configured in the Komodo Core config (",(0,i.jsx)(o.code,{children:"KOMODO_WEBHOOK_SECRET"}),")."]}),"\n",(0,i.jsx)(o.li,{children:"Enable SSL Verification, if you have proper TLS setup to your git provider (recommended)."}),"\n",(0,i.jsx)(o.li,{children:'For "events that trigger the webhook", just the push request is what post people want.'}),"\n",(0,i.jsx)(o.li,{children:'Of course, make sure the webhook is "Active" and hit create.'}),"\n"]}),"\n",(0,i.jsx)(o.h2,{id:"when-does-it-trigger",children:"When does it trigger?"}),"\n",(0,i.jsxs)(o.p,{children:["Your git provider will now push this webhook to Komodo on ",(0,i.jsx)(o.em,{children:"every"})," push to ",(0,i.jsx)(o.em,{children:"any"})," branch. However, your ",(0,i.jsx)(o.code,{children:"Build"}),", ",(0,i.jsx)(o.code,{children:"Repo"}),",\netc. only cares about a specific branch of the repo."]}),"\n",(0,i.jsxs)(o.p,{children:["Because of this, the webhook will trigger the action ",(0,i.jsx)(o.strong,{children:"only on pushes to the branch configured on the resource"}),"."]}),"\n",(0,i.jsxs)(o.p,{children:["For example, if I make a build, I may point the build to the ",(0,i.jsx)(o.code,{children:"release"})," branch of a particular repo. If I set up a webhook, and push to the ",(0,i.jsx)(o.code,{children:"main"})," branch, the action will ",(0,i.jsx)(o.em,{children:"not trigger"}),". It will only trigger when the push is to the ",(0,i.jsx)(o.code,{children:"release"})," branch."]})]})}function a(e={}){const{wrapper:o}={...(0,r.R)(),...e.components};return o?(0,i.jsx)(o,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},8453:(e,o,n)=>{n.d(o,{R:()=>s,x:()=>c});var i=n(6540);const r={},t=i.createContext(r);function s(e){const o=i.useContext(t);return i.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(r):e.components||r:s(e.components),i.createElement(t.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5ea303bc.a72ba471.js b/assets/js/5ea303bc.a72ba471.js new file mode 100644 index 000000000..de5fd326d --- /dev/null +++ b/assets/js/5ea303bc.a72ba471.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[535],{2320:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>m,frontMatter:()=>a,metadata:()=>u,toc:()=>i});var r=o(4848),n=o(8453),s=o(5627);const a={},l="Postgres",u={id:"setup/postgres",title:"Postgres",description:"1. Copy komodo/postgres.compose.yaml and komodo/compose.env to your host:",source:"@site/docs/setup/postgres.mdx",sourceDirName:"setup",slug:"/setup/postgres",permalink:"/docs/setup/postgres",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/setup/postgres.mdx",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"MongoDB",permalink:"/docs/setup/mongo"},next:{title:"Sqlite",permalink:"/docs/setup/sqlite"}},c={},i=[];function d(e){const t={code:"code",h1:"h1",header:"header",li:"li",ol:"ol",pre:"pre",...(0,n.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"postgres",children:"Postgres"})}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["Copy ",(0,r.jsx)(t.code,{children:"komodo/postgres.compose.yaml"})," and ",(0,r.jsx)(t.code,{children:"komodo/compose.env"})," to your host:"]}),"\n"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"wget -P komodo https://raw.githubusercontent.com/moghtech/komodo/main/compose/postgres.compose.yaml && \\\n wget -P komodo https://raw.githubusercontent.com/moghtech/komodo/main/compose/compose.env\n"})}),"\n",(0,r.jsxs)(t.ol,{start:"2",children:["\n",(0,r.jsxs)(t.li,{children:["Edit the variables in ",(0,r.jsx)(t.code,{children:"komodo/compose.env"}),"."]}),"\n",(0,r.jsx)(t.li,{children:"Deploy:"}),"\n"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"docker compose -p komodo -f komodo/postgres.compose.yaml --env-file komodo/compose.env up -d\n"})}),"\n","\n",(0,r.jsx)(s.A,{file_name:"postgres.compose.yaml"})]})}function m(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},5627:(e,t,o)=>{o.d(t,{A:()=>A});var r=o(6540),n=o(6695),s=o(4164),a=o(3104),l=o(6347),u=o(205),c=o(7485),i=o(1682),d=o(679);function m(e){return r.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function p(e){const{values:t,children:o}=e;return(0,r.useMemo)((()=>{const e=t??function(e){return m(e).map((e=>{let{props:{value:t,label:o,attributes:r,default:n}}=e;return{value:t,label:o,attributes:r,default:n}}))}(o);return function(e){const t=(0,i.XI)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,o])}function h(e){let{value:t,tabValues:o}=e;return o.some((e=>e.value===t))}function b(e){let{queryString:t=!1,groupId:o}=e;const n=(0,l.W6)(),s=function(e){let{queryString:t=!1,groupId:o}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!o)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return o??null}({queryString:t,groupId:o});return[(0,c.aZ)(s),(0,r.useCallback)((e=>{if(!s)return;const t=new URLSearchParams(n.location.search);t.set(s,e),n.replace({...n.location,search:t.toString()})}),[s,n])]}function g(e){const{defaultValue:t,queryString:o=!1,groupId:n}=e,s=p(e),[a,l]=(0,r.useState)((()=>function(e){let{defaultValue:t,tabValues:o}=e;if(0===o.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!h({value:t,tabValues:o}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${o.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const r=o.find((e=>e.default))??o[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:s}))),[c,i]=b({queryString:o,groupId:n}),[m,g]=function(e){let{groupId:t}=e;const o=function(e){return e?`docusaurus.tab.${e}`:null}(t),[n,s]=(0,d.Dv)(o);return[n,(0,r.useCallback)((e=>{o&&s.set(e)}),[o,s])]}({groupId:n}),f=(()=>{const e=c??m;return h({value:e,tabValues:s})?e:null})();(0,u.A)((()=>{f&&l(f)}),[f]);return{selectedValue:a,selectValue:(0,r.useCallback)((e=>{if(!h({value:e,tabValues:s}))throw new Error(`Can't select invalid tab value=${e}`);l(e),i(e),g(e)}),[i,g,s]),tabValues:s}}var f=o(2303);const v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var x=o(4848);function k(e){let{className:t,block:o,selectedValue:r,selectValue:n,tabValues:l}=e;const u=[],{blockElementScrollPositionUntilNextRender:c}=(0,a.a_)(),i=e=>{const t=e.currentTarget,o=u.indexOf(t),s=l[o].value;s!==r&&(c(t),n(s))},d=e=>{let t=null;switch(e.key){case"Enter":i(e);break;case"ArrowRight":{const o=u.indexOf(e.currentTarget)+1;t=u[o]??u[0];break}case"ArrowLeft":{const o=u.indexOf(e.currentTarget)-1;t=u[o]??u[u.length-1];break}}t?.focus()};return(0,x.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.A)("tabs",{"tabs--block":o},t),children:l.map((e=>{let{value:t,label:o,attributes:n}=e;return(0,x.jsx)("li",{role:"tab",tabIndex:r===t?0:-1,"aria-selected":r===t,ref:e=>u.push(e),onKeyDown:d,onClick:i,...n,className:(0,s.A)("tabs__item",v.tabItem,n?.className,{"tabs__item--active":r===t}),children:o??t},t)}))})}function y(e){let{lazy:t,children:o,selectedValue:n}=e;const a=(Array.isArray(o)?o:[o]).filter(Boolean);if(t){const e=a.find((e=>e.props.value===n));return e?(0,r.cloneElement)(e,{className:(0,s.A)("margin-top--md",e.props.className)}):null}return(0,x.jsx)("div",{className:"margin-top--md",children:a.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==n})))})}function j(e){const t=g(e);return(0,x.jsxs)("div",{className:(0,s.A)("tabs-container",v.tabList),children:[(0,x.jsx)(k,{...t,...e}),(0,x.jsx)(y,{...t,...e})]})}function w(e){const t=(0,f.A)();return(0,x.jsx)(j,{...e,children:m(e.children)},String(t))}const I={tabItem:"tabItem_Ymn6"};function V(e){let{children:t,hidden:o,className:r}=e;return(0,x.jsx)("div",{role:"tabpanel",className:(0,s.A)(I.tabItem,r),hidden:o,children:t})}function A(e){let{file_name:t}=e;return(0,x.jsxs)(w,{children:[(0,x.jsx)(V,{value:t,children:(0,x.jsx)(n.A,{title:`https://github.com/moghtech/komodo/blob/main/compose/${t}`,url:`https://raw.githubusercontent.com/moghtech/komodo/main/compose/${t}`,language:"yaml"})}),(0,x.jsx)(V,{value:"compose.env",children:(0,x.jsx)(n.A,{title:"https://github.com/moghtech/komodo/blob/main/compose/compose.env",url:"https://raw.githubusercontent.com/moghtech/komodo/main/compose/compose.env",language:"bash"})})]})}},6695:(e,t,o)=>{o.d(t,{A:()=>a});var r=o(6540),n=o(1432),s=o(4848);function a(e){let{url:t,language:o,title:a}=e;const[l,u]=(0,r.useState)("");return(0,r.useEffect)((()=>{!async function(e,t){const o=await fetch(e);t(await o.text())}(t,u)}),[]),(0,s.jsx)(n.A,{title:a??t,language:o,showLineNumbers:!0,children:l})}}}]); \ No newline at end of file diff --git a/assets/js/5ea303bc.e6ad1265.js b/assets/js/5ea303bc.e6ad1265.js deleted file mode 100644 index a2848a955..000000000 --- a/assets/js/5ea303bc.e6ad1265.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[535],{2320:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>m,frontMatter:()=>a,metadata:()=>u,toc:()=>i});var r=o(4848),n=o(8453),s=o(5627);const a={},l="Postgres",u={id:"setup/postgres",title:"Postgres",description:"1. Copy komodo/postgres.compose.yaml and komodo/compose.env to your host:",source:"@site/docs/setup/postgres.mdx",sourceDirName:"setup",slug:"/setup/postgres",permalink:"/docs/setup/postgres",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/setup/postgres.mdx",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"MongoDB",permalink:"/docs/setup/mongo"},next:{title:"Sqlite",permalink:"/docs/setup/sqlite"}},c={},i=[];function d(e){const t={code:"code",h1:"h1",header:"header",li:"li",ol:"ol",pre:"pre",...(0,n.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"postgres",children:"Postgres"})}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["Copy ",(0,r.jsx)(t.code,{children:"komodo/postgres.compose.yaml"})," and ",(0,r.jsx)(t.code,{children:"komodo/compose.env"})," to your host:"]}),"\n"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"wget -P komodo https://raw.githubusercontent.com/mbecker20/komodo/main/compose/postgres.compose.yaml && \\\n wget -P komodo https://raw.githubusercontent.com/mbecker20/komodo/main/compose/compose.env\n"})}),"\n",(0,r.jsxs)(t.ol,{start:"2",children:["\n",(0,r.jsxs)(t.li,{children:["Edit the variables in ",(0,r.jsx)(t.code,{children:"komodo/compose.env"}),"."]}),"\n",(0,r.jsx)(t.li,{children:"Deploy:"}),"\n"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"docker compose -p komodo -f komodo/postgres.compose.yaml --env-file komodo/compose.env up -d\n"})}),"\n","\n",(0,r.jsx)(s.A,{file_name:"postgres.compose.yaml"})]})}function m(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},5627:(e,t,o)=>{o.d(t,{A:()=>A});var r=o(6540),n=o(6695),s=o(4164),a=o(3104),l=o(6347),u=o(205),c=o(7485),i=o(1682),d=o(679);function m(e){return r.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function p(e){const{values:t,children:o}=e;return(0,r.useMemo)((()=>{const e=t??function(e){return m(e).map((e=>{let{props:{value:t,label:o,attributes:r,default:n}}=e;return{value:t,label:o,attributes:r,default:n}}))}(o);return function(e){const t=(0,i.XI)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,o])}function h(e){let{value:t,tabValues:o}=e;return o.some((e=>e.value===t))}function b(e){let{queryString:t=!1,groupId:o}=e;const n=(0,l.W6)(),s=function(e){let{queryString:t=!1,groupId:o}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!o)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return o??null}({queryString:t,groupId:o});return[(0,c.aZ)(s),(0,r.useCallback)((e=>{if(!s)return;const t=new URLSearchParams(n.location.search);t.set(s,e),n.replace({...n.location,search:t.toString()})}),[s,n])]}function f(e){const{defaultValue:t,queryString:o=!1,groupId:n}=e,s=p(e),[a,l]=(0,r.useState)((()=>function(e){let{defaultValue:t,tabValues:o}=e;if(0===o.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!h({value:t,tabValues:o}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${o.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const r=o.find((e=>e.default))??o[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:s}))),[c,i]=b({queryString:o,groupId:n}),[m,f]=function(e){let{groupId:t}=e;const o=function(e){return e?`docusaurus.tab.${e}`:null}(t),[n,s]=(0,d.Dv)(o);return[n,(0,r.useCallback)((e=>{o&&s.set(e)}),[o,s])]}({groupId:n}),g=(()=>{const e=c??m;return h({value:e,tabValues:s})?e:null})();(0,u.A)((()=>{g&&l(g)}),[g]);return{selectedValue:a,selectValue:(0,r.useCallback)((e=>{if(!h({value:e,tabValues:s}))throw new Error(`Can't select invalid tab value=${e}`);l(e),i(e),f(e)}),[i,f,s]),tabValues:s}}var g=o(2303);const v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var k=o(4848);function x(e){let{className:t,block:o,selectedValue:r,selectValue:n,tabValues:l}=e;const u=[],{blockElementScrollPositionUntilNextRender:c}=(0,a.a_)(),i=e=>{const t=e.currentTarget,o=u.indexOf(t),s=l[o].value;s!==r&&(c(t),n(s))},d=e=>{let t=null;switch(e.key){case"Enter":i(e);break;case"ArrowRight":{const o=u.indexOf(e.currentTarget)+1;t=u[o]??u[0];break}case"ArrowLeft":{const o=u.indexOf(e.currentTarget)-1;t=u[o]??u[u.length-1];break}}t?.focus()};return(0,k.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.A)("tabs",{"tabs--block":o},t),children:l.map((e=>{let{value:t,label:o,attributes:n}=e;return(0,k.jsx)("li",{role:"tab",tabIndex:r===t?0:-1,"aria-selected":r===t,ref:e=>u.push(e),onKeyDown:d,onClick:i,...n,className:(0,s.A)("tabs__item",v.tabItem,n?.className,{"tabs__item--active":r===t}),children:o??t},t)}))})}function y(e){let{lazy:t,children:o,selectedValue:n}=e;const a=(Array.isArray(o)?o:[o]).filter(Boolean);if(t){const e=a.find((e=>e.props.value===n));return e?(0,r.cloneElement)(e,{className:(0,s.A)("margin-top--md",e.props.className)}):null}return(0,k.jsx)("div",{className:"margin-top--md",children:a.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==n})))})}function j(e){const t=f(e);return(0,k.jsxs)("div",{className:(0,s.A)("tabs-container",v.tabList),children:[(0,k.jsx)(x,{...t,...e}),(0,k.jsx)(y,{...t,...e})]})}function w(e){const t=(0,g.A)();return(0,k.jsx)(j,{...e,children:m(e.children)},String(t))}const I={tabItem:"tabItem_Ymn6"};function V(e){let{children:t,hidden:o,className:r}=e;return(0,k.jsx)("div",{role:"tabpanel",className:(0,s.A)(I.tabItem,r),hidden:o,children:t})}function A(e){let{file_name:t}=e;return(0,k.jsxs)(w,{children:[(0,k.jsx)(V,{value:t,children:(0,k.jsx)(n.A,{title:`https://github.com/mbecker20/komodo/blob/main/compose/${t}`,url:`https://raw.githubusercontent.com/mbecker20/komodo/main/compose/${t}`,language:"yaml"})}),(0,k.jsx)(V,{value:"compose.env",children:(0,k.jsx)(n.A,{title:"https://github.com/mbecker20/komodo/blob/main/compose/compose.env",url:"https://raw.githubusercontent.com/mbecker20/komodo/main/compose/compose.env",language:"bash"})})]})}},6695:(e,t,o)=>{o.d(t,{A:()=>a});var r=o(6540),n=o(1432),s=o(4848);function a(e){let{url:t,language:o,title:a}=e;const[l,u]=(0,r.useState)("");return(0,r.useEffect)((()=>{!async function(e,t){const o=await fetch(e);t(await o.text())}(t,u)}),[]),(0,s.jsx)(n.A,{title:a??t,language:o,showLineNumbers:!0,children:l})}}}]); \ No newline at end of file diff --git a/assets/js/5fbc5cf1.7b981e55.js b/assets/js/5fbc5cf1.7b981e55.js new file mode 100644 index 000000000..864be2673 --- /dev/null +++ b/assets/js/5fbc5cf1.7b981e55.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[624],{6933:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>r,contentTitle:()=>c,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>d});var o=n(4848),s=n(8453);const i={},c="API and Clients",a={id:"api",title:"API and Clients",description:"Komodo Core exposes an RPC-like HTTP API to read data, write configuration, and execute actions.",source:"@site/docs/api.md",sourceDirName:".",slug:"/api",permalink:"/docs/api",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/api.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Version Upgrades",permalink:"/docs/version-upgrades"},next:{title:"Development",permalink:"/docs/development"}},r={},d=[{value:"Rust Client",id:"rust-client",level:2},{value:"Typescript Client",id:"typescript-client",level:2}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",strong:"strong",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"api-and-clients",children:"API and Clients"})}),"\n",(0,o.jsxs)(t.p,{children:["Komodo Core exposes an RPC-like HTTP API to read data, write configuration, and execute actions.\nThere are typesafe clients available in\n",(0,o.jsx)(t.a,{href:"/docs/api#rust-client",children:(0,o.jsx)(t.strong,{children:"Rust"})})," and ",(0,o.jsx)(t.a,{href:"/docs/api#typescript-client",children:(0,o.jsx)(t.strong,{children:"Typescript"})}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["The full API documentation is ",(0,o.jsx)(t.a,{href:"https://docs.rs/komodo_client/latest/komodo_client/api/index.html",children:(0,o.jsx)(t.strong,{children:"available here"})}),"."]}),"\n",(0,o.jsx)(t.h2,{id:"rust-client",children:"Rust Client"}),"\n",(0,o.jsxs)(t.p,{children:["The Rust client is published to crates.io at ",(0,o.jsx)(t.a,{href:"https://crates.io/crates/komodo_client",children:"komodo_client"}),"."]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-rust",children:'let komodo = KomodoClient::new("https://demo.komo.do", "your_key", "your_secret")\n .with_healthcheck()\n .await?;\n\nlet stacks = komodo.read(ListStacks::default()).await?;\n\nlet update = komodo\n .execute(DeployStack {\n stack: stacks[0].name.clone(),\n stop_time: None\n })\n .await?;\n'})}),"\n",(0,o.jsx)(t.h2,{id:"typescript-client",children:"Typescript Client"}),"\n",(0,o.jsxs)(t.p,{children:["The Typescript client is published to NPM at ",(0,o.jsx)(t.a,{href:"https://www.npmjs.com/package/komodo_client",children:"komodo_client"}),"."]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-ts",children:'import { KomodoClient, Types } from "komodo_client";\n\nconst komodo = KomodoClient("https://demo.komo.do", {\n type: "api-key",\n params: {\n api_key: "your_key",\n secret: "your secret",\n },\n});\n\n// Inferred as Types.StackListItem[]\nconst stacks = await komodo.read("ListStacks", {});\n\n// Inferred as Types.Update\nconst update = await komodo.execute("DeployStack", {\n stack: stacks[0].name,\n});\n'})})]})}function p(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>a});var o=n(6540);const s={},i=o.createContext(s);function c(e){const t=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),o.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5fbc5cf1.af350864.js b/assets/js/5fbc5cf1.af350864.js deleted file mode 100644 index 260003169..000000000 --- a/assets/js/5fbc5cf1.af350864.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[624],{6933:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>r,contentTitle:()=>c,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>d});var o=n(4848),s=n(8453);const i={},c="API and Clients",a={id:"api",title:"API and Clients",description:"Komodo Core exposes an RPC-like HTTP API to read data, write configuration, and execute actions.",source:"@site/docs/api.md",sourceDirName:".",slug:"/api",permalink:"/docs/api",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/api.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Version Upgrades",permalink:"/docs/version-upgrades"},next:{title:"Development",permalink:"/docs/development"}},r={},d=[{value:"Rust Client",id:"rust-client",level:2},{value:"Typescript Client",id:"typescript-client",level:2}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",strong:"strong",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"api-and-clients",children:"API and Clients"})}),"\n",(0,o.jsxs)(t.p,{children:["Komodo Core exposes an RPC-like HTTP API to read data, write configuration, and execute actions.\nThere are typesafe clients available in\n",(0,o.jsx)(t.a,{href:"/docs/api#rust-client",children:(0,o.jsx)(t.strong,{children:"Rust"})})," and ",(0,o.jsx)(t.a,{href:"/docs/api#typescript-client",children:(0,o.jsx)(t.strong,{children:"Typescript"})}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["The full API documentation is ",(0,o.jsx)(t.a,{href:"https://docs.rs/komodo_client/latest/komodo_client/api/index.html",children:(0,o.jsx)(t.strong,{children:"available here"})}),"."]}),"\n",(0,o.jsx)(t.h2,{id:"rust-client",children:"Rust Client"}),"\n",(0,o.jsxs)(t.p,{children:["The Rust client is published to crates.io at ",(0,o.jsx)(t.a,{href:"https://crates.io/crates/komodo_client",children:"komodo_client"}),"."]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-rust",children:'let komodo = KomodoClient::new("https://demo.komo.do", "your_key", "your_secret")\n .with_healthcheck()\n .await?;\n\nlet stacks = komodo.read(ListStacks::default()).await?;\n\nlet update = komodo\n .execute(DeployStack {\n stack: stacks[0].name.clone(),\n stop_time: None\n })\n .await?;\n'})}),"\n",(0,o.jsx)(t.h2,{id:"typescript-client",children:"Typescript Client"}),"\n",(0,o.jsxs)(t.p,{children:["The Typescript client is published to NPM at ",(0,o.jsx)(t.a,{href:"https://www.npmjs.com/package/komodo_client",children:"komodo_client"}),"."]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-ts",children:'import { KomodoClient, Types } from "komodo_client";\n\nconst komodo = KomodoClient("https://demo.komo.do", {\n type: "api-key",\n params: {\n api_key: "your_key",\n secret: "your secret",\n },\n});\n\n// Inferred as Types.StackListItem[]\nconst stacks = await komodo.read("ListStacks", {});\n\n// Inferred as Types.Update\nconst update = await komodo.execute("DeployStack", {\n stack: stacks[0].name,\n});\n'})})]})}function p(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>a});var o=n(6540);const s={},i=o.createContext(s);function c(e){const t=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),o.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/669fcf45.3c7598e9.js b/assets/js/669fcf45.3c7598e9.js new file mode 100644 index 000000000..3d85d63a7 --- /dev/null +++ b/assets/js/669fcf45.3c7598e9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[552],{7478:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>l,toc:()=>a});var o=t(4848),s=t(8453);const r={},i="Sync Resources",l={id:"sync-resources",title:"Sync Resources",description:"Komodo is able to create, update, delete, and deploy resources declared in TOML files by diffing them against the existing resources,",source:"@site/docs/sync-resources.md",sourceDirName:".",slug:"/sync-resources",permalink:"/docs/sync-resources",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/sync-resources.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Permissioning",permalink:"/docs/permissioning"},next:{title:"Configuring Webhooks",permalink:"/docs/webhooks"}},c={},a=[{value:"Example Declarations",id:"example-declarations",level:2},{value:"Server",id:"server",level:3},{value:"Builder and build",id:"builder-and-build",level:3},{value:"Deployments",id:"deployments",level:3},{value:"Stack",id:"stack",level:3},{value:"Procedure",id:"procedure",level:3},{value:"Repo",id:"repo",level:3},{value:"Resource sync",id:"resource-sync",level:3},{value:"User Group:",id:"user-group",level:3}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"sync-resources",children:"Sync Resources"})}),"\n",(0,o.jsxs)(n.p,{children:["Komodo is able to create, update, delete, and deploy resources declared in TOML files by diffing them against the existing resources,\nand apply updates based on the diffs. Push the files to a remote git repo and create a ",(0,o.jsx)(n.code,{children:"ResourceSync"})," pointing to the repo,\nand the core backend will poll for any updates (you can also manually trigger an update poll / execution in the UI)."]}),"\n",(0,o.jsxs)(n.p,{children:["File detection is additive and recursive, so you can spread out your resource declarations across any number of files\nand use any nesting of folders to organize resources inside a root folder. Additionally, you can create multiple ",(0,o.jsx)(n.code,{children:"ResourceSyncs"}),'\nand each sync will be handled independently. This allows different syncs to manage resources on a "per-project" basis.']}),"\n",(0,o.jsx)(n.p,{children:"The UI will display the computed sync actions and only execute them upon manual confirmation.\nOr the sync execution git webhook may be configured on the git repo to\nautomatically execute syncs upon pushes to the configured branch."}),"\n",(0,o.jsx)(n.h2,{id:"example-declarations",children:"Example Declarations"}),"\n",(0,o.jsx)(n.h3,{id:"server",children:"Server"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://docs.rs/komodo_client/latest/komodo_client/entities/server/struct.ServerConfig.html",children:"Server config schema"})}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-toml",children:'[[server]] # Declare a new server\nname = "server-prod"\ndescription = "the prod server"\ntags = ["prod"]\n[server.config]\naddress = "http://localhost:8120"\nregion = "AshburnDc1"\nenabled = true # default: false\n'})}),"\n",(0,o.jsx)(n.h3,{id:"builder-and-build",children:"Builder and build"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://docs.rs/komodo_client/latest/komodo_client/entities/builder/enum.BuilderConfig.html",children:"Builder config schema"})}),"\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://docs.rs/komodo_client/latest/komodo_client/entities/build/struct.BuildConfig.html",children:"Build config schema"})}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-toml",children:'[[builder]] # Declare a builder\nname = "builder-01"\ntags = []\nconfig.type = "Aws"\n[builder.config.params]\nregion = "us-east-2"\nami_id = "ami-0e9bd154667944680"\n# These things come from your specific setup\nsubnet_id = "subnet-xxxxxxxxxxxxxxxxxx"\nkey_pair_name = "xxxxxxxx"\nassign_public_ip = true\nuse_public_ip = true\nsecurity_group_ids = [\n "sg-xxxxxxxxxxxxxxxxxx",\n "sg-xxxxxxxxxxxxxxxxxx"\n]\n\n##\n\n[[build]]\nname = "test_logger"\ndescription = "Logs randomly at INFO, WARN, ERROR levels to test logging setups"\ntags = ["test"]\n[build.config]\nbuilder_id = "builder-01"\nrepo = "mbecker20/test_logger"\nbranch = "master"\ngit_account = "mbecker20"\nimage_registry.type = "Standard"\nimage_registry.params.domain = "github.com" # or your custom domain\nimage_registry.params.account = "your_username"\nimage_registry.params.organization = "your_organization" # optinoal\n# Set docker labels\nlabels = """\norg.opencontainers.image.source = https://github.com/mbecker20/test_logger\norg.opencontainers.image.description = Logs randomly at INFO, WARN, ERROR levels to test logging setups\norg.opencontainers.image.licenses = GPL-3.0\n"""\n'})}),"\n",(0,o.jsx)(n.h3,{id:"deployments",children:"Deployments"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://docs.rs/komodo_client/latest/komodo_client/entities/deployment/struct.DeploymentConfig.html",children:"Deployment config schema"})}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-toml",children:'# Declare variables\n[[variable]]\nname = "OTLP_ENDPOINT"\nvalue = "http://localhost:4317"\n\n##\n\n[[deployment]] # Declare a deployment\nname = "test-logger-01"\ndescription = "test logger deployment 1"\ntags = ["test"]\n# sync will deploy the container: \n# - if it is not running.\n# - has relevant config updates.\n# - the attached build has new version.\ndeploy = true\n[deployment.config]\nserver_id = "server-01"\nimage.type = "Build"\nimage.params.build = "test_logger"\n# set the volumes / bind mounts\nvolumes = """\n# Supports comments\n/data/logs = /etc/logs\n# And other formats (eg yaml list)\n- "/data/config:/etc/config"\n"""\n# Set the environment variables\nenvironment = """\n# Comments supported\nOTLP_ENDPOINT = [[OTLP_ENDPOINT]] # interpolate variables into the envs.\nVARIABLE_1 = value_1\nVARIABLE_2 = value_2\n"""\n# Set Docker labels\nlabels = "deployment.type = logger"\n\n##\n\n[[deployment]]\nname = "test-logger-02"\ndescription = "test logger deployment 2"\ntags = ["test"]\ndeploy = true\n# Create a dependency on test-logger-01. This deployment will only be deployed after test-logger-01 is deployed.\n# Additionally, any sync deploy of test-logger-01 will also trigger sync deploy of this deployment.\nafter = ["test-logger-01"]\n[deployment.config]\nserver_id = "server-01"\nimage.type = "Build"\nimage.params.build = "test_logger"\nvolumes = """\n/data/logs = /etc/logs\n/data/config = /etc/config"""\nenvironment = """\nVARIABLE_1 = value_1\nVARIABLE_2 = value_2\n"""\n# Set Docker labels\nlabels = "deployment.type = logger"\n'})}),"\n",(0,o.jsx)(n.h3,{id:"stack",children:"Stack"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://docs.rs/komodo_client/latest/komodo_client/entities/stack/struct.StackConfig.html",children:"Stack config schema"})}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-toml",children:'[[stack]]\nname = "test-stack"\ndescription = "stack test"\ndeploy = true\nafter = ["test-logger-01"] # Stacks can depend on deployments, and vice versa.\ntags = ["test"]\n[stack.config]\nserver_id = "server-prod"\nfile_paths = ["mongo.yaml", "redis.yaml"]\ngit_provider = "git.mogh.tech"\ngit_account = "mbecker20" # clone private repo by specifying account\nrepo = "mbecker20/stack_test"\n'})}),"\n",(0,o.jsx)(n.h3,{id:"procedure",children:"Procedure"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://docs.rs/komodo_client/latest/komodo_client/entities/procedure/struct.ProcedureConfig.html",children:"Procedure config schema"})}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-toml",children:'[[procedure]]\nname = "test-procedure"\ndescription = "Do some things in a specific order"\ntags = ["test"]\n\n[[procedure.config.stage]]\nname = "Build stuff"\nexecutions = [\n { execution.type = "RunBuild", execution.params.build = "test_logger" },\n # Uses the Batch version, witch matches many builds by pattern\n # This one matches all builds prefixed with `foo-` (wildcard) and `bar-` (regex).\n { execution.type = "BatchRunBuild", execution.params.pattern = "foo-* , \\\\^bar-.*$\\\\" },\n { execution.type = "PullRepo", execution.params.repo = "komodo-periphery" },\n]\n\n[[procedure.config.stage]]\nname = "Deploy test logger 1"\nexecutions = [\n { execution.type = "Deploy", execution.params.deployment = "test-logger-01" },\n { execution.type = "Deploy", execution.params.deployment = "test-logger-03", enabled = false },\n]\n\n[[procedure.config.stage]]\nname = "Deploy test logger 2"\nenabled = false\nexecutions = [\n { execution.type = "Deploy", execution.params.deployment = "test-logger-02" }\n]\n'})}),"\n",(0,o.jsx)(n.h3,{id:"repo",children:"Repo"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://docs.rs/komodo_client/latest/komodo_client/entities/repo/struct.RepoConfig.html",children:"Repo config schema"})}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-toml",children:'[[repo]]\nname = "komodo-periphery"\ndescription = "Builds new versions of the periphery binary. Requires Rust installed on the host."\ntags = ["komodo"]\n[repo.config]\nserver_id = "server-01"\ngit_provider = "git.mogh.tech" # use an alternate git provider (default is github.com)\ngit_account = "mbecker20"\nrepo = "moghtech/komodo"\n# Run an action after the repo is pulled\non_pull.path = "."\non_pull.command = """\n# Supports comments\n/root/.cargo/bin/cargo build -p komodo_periphery --release\n# Multiple lines will be combined together using \'&&\'\ncp ./target/release/periphery /root/periphery\n"""\n'})}),"\n",(0,o.jsx)(n.h3,{id:"resource-sync",children:"Resource sync"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://docs.rs/komodo_client/latest/komodo_client/entities/sync/type.ResourceSync.html",children:"Resource sync config schema"})}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-toml",children:'[[resource_sync]]\nname = "resource-sync"\n[resource_sync.config]\ngit_provider = "git.mogh.tech" # use an alternate git provider (default is github.com)\ngit_account = "mbecker20"\nrepo = "moghtech/komodo"\nresource_path = ["stacks.toml", "repos.toml"]\n'})}),"\n",(0,o.jsx)(n.h3,{id:"user-group",children:"User Group:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://docs.rs/komodo_client/latest/komodo_client/entities/toml/struct.UserGroupToml.html",children:"UserGroup schema"})}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-toml",children:'[[user_group]]\nname = "groupo"\nusers = ["mbecker20", "karamvirsingh98"]\n# Attach base level of Execute on all builds\nall.Build = "Execute"\nall.Alerter = "Write"\npermissions = [\n # Attach permissions to specific resources by name\n { target.type = "Repo", target.id = "komodo-periphery", level = "Execute" },\n # Attach permissions to many resources with name matching regex (this uses \'^(.+)-(.+)$\' as regex expression)\n { target.type = "Server", target.id = "\\\\^(.+)-(.+)$\\\\", level = "Read" },\n { target.type = "Deployment", target.id = "\\\\^immich\\\\", level = "Execute" },\n]\n'})})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>l});var o=t(6540);const s={},r=o.createContext(s);function i(e){const n=o.useContext(r);return o.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(s):e.components||s:i(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/669fcf45.9ce9f393.js b/assets/js/669fcf45.9ce9f393.js deleted file mode 100644 index fdb5a936a..000000000 --- a/assets/js/669fcf45.9ce9f393.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[552],{7478:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>l,toc:()=>a});var o=t(4848),s=t(8453);const r={},i="Sync Resources",l={id:"sync-resources",title:"Sync Resources",description:"Komodo is able to create, update, delete, and deploy resources declared in TOML files by diffing them against the existing resources,",source:"@site/docs/sync-resources.md",sourceDirName:".",slug:"/sync-resources",permalink:"/docs/sync-resources",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/sync-resources.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Permissioning",permalink:"/docs/permissioning"},next:{title:"Configuring Webhooks",permalink:"/docs/webhooks"}},c={},a=[{value:"Example Declarations",id:"example-declarations",level:2},{value:"Server",id:"server",level:3},{value:"Builder and build",id:"builder-and-build",level:3},{value:"Deployments",id:"deployments",level:3},{value:"Stack",id:"stack",level:3},{value:"Procedure",id:"procedure",level:3},{value:"Repo",id:"repo",level:3},{value:"Resource sync",id:"resource-sync",level:3},{value:"User Group:",id:"user-group",level:3}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"sync-resources",children:"Sync Resources"})}),"\n",(0,o.jsxs)(n.p,{children:["Komodo is able to create, update, delete, and deploy resources declared in TOML files by diffing them against the existing resources,\nand apply updates based on the diffs. Push the files to a remote git repo and create a ",(0,o.jsx)(n.code,{children:"ResourceSync"})," pointing to the repo,\nand the core backend will poll for any updates (you can also manually trigger an update poll / execution in the UI)."]}),"\n",(0,o.jsxs)(n.p,{children:["File detection is additive and recursive, so you can spread out your resource declarations across any number of files\nand use any nesting of folders to organize resources inside a root folder. Additionally, you can create multiple ",(0,o.jsx)(n.code,{children:"ResourceSyncs"}),'\nand each sync will be handled independently. This allows different syncs to manage resources on a "per-project" basis.']}),"\n",(0,o.jsx)(n.p,{children:"The UI will display the computed sync actions and only execute them upon manual confirmation.\nOr the sync execution git webhook may be configured on the git repo to\nautomatically execute syncs upon pushes to the configured branch."}),"\n",(0,o.jsx)(n.h2,{id:"example-declarations",children:"Example Declarations"}),"\n",(0,o.jsx)(n.h3,{id:"server",children:"Server"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://docs.rs/komodo_client/latest/komodo_client/entities/server/struct.ServerConfig.html",children:"Server config schema"})}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-toml",children:'[[server]] # Declare a new server\nname = "server-prod"\ndescription = "the prod server"\ntags = ["prod"]\n[server.config]\naddress = "http://localhost:8120"\nregion = "AshburnDc1"\nenabled = true # default: false\n'})}),"\n",(0,o.jsx)(n.h3,{id:"builder-and-build",children:"Builder and build"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://docs.rs/komodo_client/latest/komodo_client/entities/builder/enum.BuilderConfig.html",children:"Builder config schema"})}),"\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://docs.rs/komodo_client/latest/komodo_client/entities/build/struct.BuildConfig.html",children:"Build config schema"})}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-toml",children:'[[builder]] # Declare a builder\nname = "builder-01"\ntags = []\nconfig.type = "Aws"\n[builder.config.params]\nregion = "us-east-2"\nami_id = "ami-0e9bd154667944680"\n# These things come from your specific setup\nsubnet_id = "subnet-xxxxxxxxxxxxxxxxxx"\nkey_pair_name = "xxxxxxxx"\nassign_public_ip = true\nuse_public_ip = true\nsecurity_group_ids = [\n "sg-xxxxxxxxxxxxxxxxxx",\n "sg-xxxxxxxxxxxxxxxxxx"\n]\n\n##\n\n[[build]]\nname = "test_logger"\ndescription = "Logs randomly at INFO, WARN, ERROR levels to test logging setups"\ntags = ["test"]\n[build.config]\nbuilder_id = "builder-01"\nrepo = "mbecker20/test_logger"\nbranch = "master"\ngit_account = "mbecker20"\nimage_registry.type = "Standard"\nimage_registry.params.domain = "github.com" # or your custom domain\nimage_registry.params.account = "your_username"\nimage_registry.params.organization = "your_organization" # optinoal\n# Set docker labels\nlabels = """\norg.opencontainers.image.source = https://github.com/mbecker20/test_logger\norg.opencontainers.image.description = Logs randomly at INFO, WARN, ERROR levels to test logging setups\norg.opencontainers.image.licenses = GPL-3.0\n"""\n'})}),"\n",(0,o.jsx)(n.h3,{id:"deployments",children:"Deployments"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://docs.rs/komodo_client/latest/komodo_client/entities/deployment/struct.DeploymentConfig.html",children:"Deployment config schema"})}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-toml",children:'# Declare variables\n[[variable]]\nname = "OTLP_ENDPOINT"\nvalue = "http://localhost:4317"\n\n##\n\n[[deployment]] # Declare a deployment\nname = "test-logger-01"\ndescription = "test logger deployment 1"\ntags = ["test"]\n# sync will deploy the container: \n# - if it is not running.\n# - has relevant config updates.\n# - the attached build has new version.\ndeploy = true\n[deployment.config]\nserver_id = "server-01"\nimage.type = "Build"\nimage.params.build = "test_logger"\n# set the volumes / bind mounts\nvolumes = """\n# Supports comments\n/data/logs = /etc/logs\n# And other formats (eg yaml list)\n- "/data/config:/etc/config"\n"""\n# Set the environment variables\nenvironment = """\n# Comments supported\nOTLP_ENDPOINT = [[OTLP_ENDPOINT]] # interpolate variables into the envs.\nVARIABLE_1 = value_1\nVARIABLE_2 = value_2\n"""\n# Set Docker labels\nlabels = "deployment.type = logger"\n\n##\n\n[[deployment]]\nname = "test-logger-02"\ndescription = "test logger deployment 2"\ntags = ["test"]\ndeploy = true\n# Create a dependency on test-logger-01. This deployment will only be deployed after test-logger-01 is deployed.\n# Additionally, any sync deploy of test-logger-01 will also trigger sync deploy of this deployment.\nafter = ["test-logger-01"]\n[deployment.config]\nserver_id = "server-01"\nimage.type = "Build"\nimage.params.build = "test_logger"\nvolumes = """\n/data/logs = /etc/logs\n/data/config = /etc/config"""\nenvironment = """\nVARIABLE_1 = value_1\nVARIABLE_2 = value_2\n"""\n# Set Docker labels\nlabels = "deployment.type = logger"\n'})}),"\n",(0,o.jsx)(n.h3,{id:"stack",children:"Stack"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://docs.rs/komodo_client/latest/komodo_client/entities/stack/struct.StackConfig.html",children:"Stack config schema"})}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-toml",children:'[[stack]]\nname = "test-stack"\ndescription = "stack test"\ndeploy = true\nafter = ["test-logger-01"] # Stacks can depend on deployments, and vice versa.\ntags = ["test"]\n[stack.config]\nserver_id = "server-prod"\nfile_paths = ["mongo.yaml", "redis.yaml"]\ngit_provider = "git.mogh.tech"\ngit_account = "mbecker20" # clone private repo by specifying account\nrepo = "mbecker20/stack_test"\n'})}),"\n",(0,o.jsx)(n.h3,{id:"procedure",children:"Procedure"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://docs.rs/komodo_client/latest/komodo_client/entities/procedure/struct.ProcedureConfig.html",children:"Procedure config schema"})}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-toml",children:'[[procedure]]\nname = "test-procedure"\ndescription = "Do some things in a specific order"\ntags = ["test"]\n\n[[procedure.config.stage]]\nname = "Build stuff"\nexecutions = [\n { execution.type = "RunBuild", execution.params.build = "test_logger" },\n # Uses the Batch version, witch matches many builds by pattern\n # This one matches all builds prefixed with `foo-` (wildcard) and `bar-` (regex).\n { execution.type = "BatchRunBuild", execution.params.pattern = "foo-* , \\\\^bar-.*$\\\\" },\n { execution.type = "PullRepo", execution.params.repo = "komodo-periphery" },\n]\n\n[[procedure.config.stage]]\nname = "Deploy test logger 1"\nexecutions = [\n { execution.type = "Deploy", execution.params.deployment = "test-logger-01" },\n { execution.type = "Deploy", execution.params.deployment = "test-logger-03", enabled = false },\n]\n\n[[procedure.config.stage]]\nname = "Deploy test logger 2"\nenabled = false\nexecutions = [\n { execution.type = "Deploy", execution.params.deployment = "test-logger-02" }\n]\n'})}),"\n",(0,o.jsx)(n.h3,{id:"repo",children:"Repo"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://docs.rs/komodo_client/latest/komodo_client/entities/repo/struct.RepoConfig.html",children:"Repo config schema"})}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-toml",children:'[[repo]]\nname = "komodo-periphery"\ndescription = "Builds new versions of the periphery binary. Requires Rust installed on the host."\ntags = ["komodo"]\n[repo.config]\nserver_id = "server-01"\ngit_provider = "git.mogh.tech" # use an alternate git provider (default is github.com)\ngit_account = "mbecker20"\nrepo = "mbecker20/komodo"\n# Run an action after the repo is pulled\non_pull.path = "."\non_pull.command = """\n# Supports comments\n/root/.cargo/bin/cargo build -p komodo_periphery --release\n# Multiple lines will be combined together using \'&&\'\ncp ./target/release/periphery /root/periphery\n"""\n'})}),"\n",(0,o.jsx)(n.h3,{id:"resource-sync",children:"Resource sync"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://docs.rs/komodo_client/latest/komodo_client/entities/sync/type.ResourceSync.html",children:"Resource sync config schema"})}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-toml",children:'[[resource_sync]]\nname = "resource-sync"\n[resource_sync.config]\ngit_provider = "git.mogh.tech" # use an alternate git provider (default is github.com)\ngit_account = "mbecker20"\nrepo = "mbecker20/komodo"\nresource_path = ["stacks.toml", "repos.toml"]\n'})}),"\n",(0,o.jsx)(n.h3,{id:"user-group",children:"User Group:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://docs.rs/komodo_client/latest/komodo_client/entities/toml/struct.UserGroupToml.html",children:"UserGroup schema"})}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-toml",children:'[[user_group]]\nname = "groupo"\nusers = ["mbecker20", "karamvirsingh98"]\n# Attach base level of Execute on all builds\nall.Build = "Execute"\nall.Alerter = "Write"\npermissions = [\n # Attach permissions to specific resources by name\n { target.type = "Repo", target.id = "komodo-periphery", level = "Execute" },\n # Attach permissions to many resources with name matching regex (this uses \'^(.+)-(.+)$\' as regex expression)\n { target.type = "Server", target.id = "\\\\^(.+)-(.+)$\\\\", level = "Read" },\n { target.type = "Deployment", target.id = "\\\\^immich\\\\", level = "Execute" },\n]\n'})})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>l});var o=t(6540);const s={},r=o.createContext(s);function i(e){const n=o.useContext(r);return o.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(s):e.components||s:i(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6aab5236.28427783.js b/assets/js/6aab5236.28427783.js new file mode 100644 index 000000000..b76487192 --- /dev/null +++ b/assets/js/6aab5236.28427783.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[663],{487:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>s,metadata:()=>a,toc:()=>d});var r=t(4848),o=t(8453);const s={},i="Version Upgrades",a={id:"version-upgrades",title:"Version Upgrades",description:"Most version upgrades only require a redeployment of the Core container after pulling the latest version, and are fully backward compatible with the periphery clients, which may be updated later on as convenient. This is the default, and will be the case unless specifically mentioned in the version release notes.",source:"@site/docs/version-upgrades.md",sourceDirName:".",slug:"/version-upgrades",permalink:"/docs/version-upgrades",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/version-upgrades.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Configuring Webhooks",permalink:"/docs/webhooks"},next:{title:"API and Clients",permalink:"/docs/api"}},c={},d=[];function l(e){const n={a:"a",h1:"h1",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"version-upgrades",children:"Version Upgrades"})}),"\n",(0,r.jsxs)(n.p,{children:["Most version upgrades only require a redeployment of the Core container after pulling the latest version, and are fully backward compatible with the periphery clients, which may be updated later on as convenient. This is the default, and will be the case unless specifically mentioned in the ",(0,r.jsx)(n.a,{href:"https://github.com/moghtech/komodo/releases",children:"version release notes"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"Some Core API upgrades may change behavior such as building / cloning, and require updating the Periphery binaries to match the Core version before this functionality can be restored. This will be specifically mentioned in the release notes."}),"\n",(0,r.jsxs)(n.p,{children:["Additionally, some Core API upgrades may include database schema changes, and require a database migration. This can be accomplished by using the ",(0,r.jsx)(n.a,{href:"https://github.com/moghtech/komodo/blob/main/bin/migrator/README.md",children:"komodo migrator"})," for the particular version upgrade before upgrading the Core API container."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var r=t(6540);const o={},s=r.createContext(o);function i(e){const n=r.useContext(s);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(o):e.components||o:i(e.components),r.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6aab5236.4f2a084e.js b/assets/js/6aab5236.4f2a084e.js deleted file mode 100644 index af3fc8637..000000000 --- a/assets/js/6aab5236.4f2a084e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[663],{487:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>d});var r=t(4848),s=t(8453);const i={},o="Version Upgrades",a={id:"version-upgrades",title:"Version Upgrades",description:"Most version upgrades only require a redeployment of the Core container after pulling the latest version, and are fully backward compatible with the periphery clients, which may be updated later on as convenient. This is the default, and will be the case unless specifically mentioned in the version release notes.",source:"@site/docs/version-upgrades.md",sourceDirName:".",slug:"/version-upgrades",permalink:"/docs/version-upgrades",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/version-upgrades.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Configuring Webhooks",permalink:"/docs/webhooks"},next:{title:"API and Clients",permalink:"/docs/api"}},c={},d=[];function l(e){const n={a:"a",h1:"h1",header:"header",p:"p",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"version-upgrades",children:"Version Upgrades"})}),"\n",(0,r.jsxs)(n.p,{children:["Most version upgrades only require a redeployment of the Core container after pulling the latest version, and are fully backward compatible with the periphery clients, which may be updated later on as convenient. This is the default, and will be the case unless specifically mentioned in the ",(0,r.jsx)(n.a,{href:"https://github.com/mbecker20/komodo/releases",children:"version release notes"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"Some Core API upgrades may change behavior such as building / cloning, and require updating the Periphery binaries to match the Core version before this functionality can be restored. This will be specifically mentioned in the release notes."}),"\n",(0,r.jsxs)(n.p,{children:["Additionally, some Core API upgrades may include database schema changes, and require a database migration. This can be accomplished by using the ",(0,r.jsx)(n.a,{href:"https://github.com/mbecker20/komodo/blob/main/bin/migrator/README.md",children:"komodo migrator"})," for the particular version upgrade before upgrading the Core API container."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var r=t(6540);const s={},i=r.createContext(s);function o(e){const n=r.useContext(i);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(s):e.components||s:o(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/75245258.323ab3b0.js b/assets/js/75245258.323ab3b0.js deleted file mode 100644 index c1d95dea5..000000000 --- a/assets/js/75245258.323ab3b0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[531],{4016:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>m,frontMatter:()=>c,metadata:()=>a,toc:()=>d});var o=n(4848),r=n(8453),s=n(5871);const c={},i="Deploy Containers",a={id:"deploy-containers/index",title:"Deploy Containers",description:"Komodo can deploy any docker images that it can access with the configured docker accounts.",source:"@site/docs/deploy-containers/index.mdx",sourceDirName:"deploy-containers",slug:"/deploy-containers/",permalink:"/docs/deploy-containers/",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/deploy-containers/index.mdx",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Image Versioning",permalink:"/docs/build-images/versioning"},next:{title:"Configuration",permalink:"/docs/deploy-containers/configuration"}},l={},d=[];function u(e){const t={code:"code",h1:"h1",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"deploy-containers",children:"Deploy Containers"})}),"\n",(0,o.jsxs)(t.p,{children:["Komodo can deploy any docker images that it can access with the configured docker accounts.\nIt works by parsing the deployment configuration into a ",(0,o.jsx)(t.code,{children:"docker run"})," command, which is then run on the target system.\nThe configuration is stored on MongoDB, and records of all actions (update config, deploy, stop, etc.) are stored as well."]}),"\n","\n",(0,o.jsx)(s.A,{})]})}function m(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(u,{...e})}):u(e)}},5871:(e,t,n)=>{n.d(t,{A:()=>v});var o=n(6540),r=n(4164),s=n(6972),c=n(8774),i=n(4586);const a=["zero","one","two","few","many","other"];function l(e){return a.filter((t=>e.includes(t)))}const d={locale:"en",pluralForms:l(["one","other"]),select:e=>1===e?"one":"other"};function u(){const{i18n:{currentLocale:e}}=(0,i.A)();return(0,o.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:l(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),d}}),[e])}function m(){const e=u();return{selectMessage:(t,n)=>function(e,t,n){const o=e.split("|");if(1===o.length)return o[0];o.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${o.length}: ${e}`);const r=n.select(t),s=n.pluralForms.indexOf(r);return o[Math.min(s,o.length-1)]}(n,t,e)}}var p=n(6654),h=n(1312),f=n(1107);const g={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var x=n(4848);function y(e){let{href:t,children:n}=e;return(0,x.jsx)(c.A,{href:t,className:(0,r.A)("card padding--lg",g.cardContainer),children:n})}function j(e){let{href:t,icon:n,title:o,description:s}=e;return(0,x.jsxs)(y,{href:t,children:[(0,x.jsxs)(f.A,{as:"h2",className:(0,r.A)("text--truncate",g.cardTitle),title:o,children:[n," ",o]}),s&&(0,x.jsx)("p",{className:(0,r.A)("text--truncate",g.cardDescription),title:s,children:s})]})}function k(e){let{item:t}=e;const n=(0,s.Nr)(t),o=function(){const{selectMessage:e}=m();return t=>e(t,(0,h.T)({message:"1 item|{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t}))}();return n?(0,x.jsx)(j,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??o(t.items.length)}):null}function w(e){let{item:t}=e;const n=(0,p.A)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",o=(0,s.cC)(t.docId??void 0);return(0,x.jsx)(j,{href:t.href,icon:n,title:t.label,description:t.description??o?.description})}function C(e){let{item:t}=e;switch(t.type){case"link":return(0,x.jsx)(w,{item:t});case"category":return(0,x.jsx)(k,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function b(e){let{className:t}=e;const n=(0,s.$S)();return(0,x.jsx)(v,{items:n.items,className:t})}function v(e){const{items:t,className:n}=e;if(!t)return(0,x.jsx)(b,{...e});const o=(0,s.d1)(t);return(0,x.jsx)("section",{className:(0,r.A)("row",n),children:o.map(((e,t)=>(0,x.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,x.jsx)(C,{item:e})},t)))})}},8453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>i});var o=n(6540);const r={},s=o.createContext(r);function c(e){const t=o.useContext(s);return o.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(r):e.components||r:c(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/75245258.e5f63ae6.js b/assets/js/75245258.e5f63ae6.js new file mode 100644 index 000000000..dac170530 --- /dev/null +++ b/assets/js/75245258.e5f63ae6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[531],{4016:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>m,frontMatter:()=>c,metadata:()=>a,toc:()=>d});var o=n(4848),r=n(8453),s=n(5871);const c={},i="Deploy Containers",a={id:"deploy-containers/index",title:"Deploy Containers",description:"Komodo can deploy any docker images that it can access with the configured docker accounts.",source:"@site/docs/deploy-containers/index.mdx",sourceDirName:"deploy-containers",slug:"/deploy-containers/",permalink:"/docs/deploy-containers/",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/deploy-containers/index.mdx",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Image Versioning",permalink:"/docs/build-images/versioning"},next:{title:"Configuration",permalink:"/docs/deploy-containers/configuration"}},l={},d=[];function u(e){const t={code:"code",h1:"h1",header:"header",p:"p",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"deploy-containers",children:"Deploy Containers"})}),"\n",(0,o.jsxs)(t.p,{children:["Komodo can deploy any docker images that it can access with the configured docker accounts.\nIt works by parsing the deployment configuration into a ",(0,o.jsx)(t.code,{children:"docker run"})," command, which is then run on the target system.\nThe configuration is stored on MongoDB, and records of all actions (update config, deploy, stop, etc.) are stored as well."]}),"\n","\n",(0,o.jsx)(s.A,{})]})}function m(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(u,{...e})}):u(e)}},5871:(e,t,n)=>{n.d(t,{A:()=>v});var o=n(6540),r=n(4164),s=n(6972),c=n(8774),i=n(4586);const a=["zero","one","two","few","many","other"];function l(e){return a.filter((t=>e.includes(t)))}const d={locale:"en",pluralForms:l(["one","other"]),select:e=>1===e?"one":"other"};function u(){const{i18n:{currentLocale:e}}=(0,i.A)();return(0,o.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:l(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),d}}),[e])}function m(){const e=u();return{selectMessage:(t,n)=>function(e,t,n){const o=e.split("|");if(1===o.length)return o[0];o.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${o.length}: ${e}`);const r=n.select(t),s=n.pluralForms.indexOf(r);return o[Math.min(s,o.length-1)]}(n,t,e)}}var h=n(6654),p=n(1312),f=n(1107);const g={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var x=n(4848);function y(e){let{href:t,children:n}=e;return(0,x.jsx)(c.A,{href:t,className:(0,r.A)("card padding--lg",g.cardContainer),children:n})}function j(e){let{href:t,icon:n,title:o,description:s}=e;return(0,x.jsxs)(y,{href:t,children:[(0,x.jsxs)(f.A,{as:"h2",className:(0,r.A)("text--truncate",g.cardTitle),title:o,children:[n," ",o]}),s&&(0,x.jsx)("p",{className:(0,r.A)("text--truncate",g.cardDescription),title:s,children:s})]})}function k(e){let{item:t}=e;const n=(0,s.Nr)(t),o=function(){const{selectMessage:e}=m();return t=>e(t,(0,p.T)({message:"1 item|{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t}))}();return n?(0,x.jsx)(j,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??o(t.items.length)}):null}function w(e){let{item:t}=e;const n=(0,h.A)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",o=(0,s.cC)(t.docId??void 0);return(0,x.jsx)(j,{href:t.href,icon:n,title:t.label,description:t.description??o?.description})}function C(e){let{item:t}=e;switch(t.type){case"link":return(0,x.jsx)(w,{item:t});case"category":return(0,x.jsx)(k,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function b(e){let{className:t}=e;const n=(0,s.$S)();return(0,x.jsx)(v,{items:n.items,className:t})}function v(e){const{items:t,className:n}=e;if(!t)return(0,x.jsx)(b,{...e});const o=(0,s.d1)(t);return(0,x.jsx)("section",{className:(0,r.A)("row",n),children:o.map(((e,t)=>(0,x.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,x.jsx)(C,{item:e})},t)))})}},8453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>i});var o=n(6540);const r={},s=o.createContext(r);function c(e){const t=o.useContext(s);return o.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(r):e.components||r:c(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/79c522c5.273ac0b5.js b/assets/js/79c522c5.273ac0b5.js new file mode 100644 index 000000000..850fd3ba1 --- /dev/null +++ b/assets/js/79c522c5.273ac0b5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[943],{3827:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>i,contentTitle:()=>r,default:()=>h,frontMatter:()=>c,metadata:()=>a,toc:()=>d});var s=o(4848),t=o(8453);const c={},r="Procedures and Actions",a={id:"procedures",title:"Procedures and Actions",description:"For orchestrations involving multiple Resources, Komodo offers the Procedure and Action resource types.",source:"@site/docs/procedures.md",sourceDirName:".",slug:"/procedures",permalink:"/docs/procedures",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/procedures.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Variables and Secrets",permalink:"/docs/variables"},next:{title:"Permissioning",permalink:"/docs/permissioning"}},i={},d=[{value:"Procedures",id:"procedures",level:2},{value:"Batch Executions",id:"batch-executions",level:3},{value:"TOML Example",id:"toml-example",level:3},{value:"Actions",id:"actions",level:2}];function l(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",strong:"strong",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"procedures-and-actions",children:"Procedures and Actions"})}),"\n",(0,s.jsxs)(n.p,{children:["For orchestrations involving multiple Resources, Komodo offers the ",(0,s.jsx)(n.code,{children:"Procedure"})," and ",(0,s.jsx)(n.code,{children:"Action"})," resource types."]}),"\n",(0,s.jsx)(n.h2,{id:"procedures",children:"Procedures"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Procedures"})," are compositions of many executions, such as ",(0,s.jsx)(n.code,{children:"RunBuild"})," and ",(0,s.jsx)(n.code,{children:"DeployStack"}),".\nThe executions are grouped into a series of ",(0,s.jsx)(n.code,{children:"Stages"}),", where each ",(0,s.jsx)(n.code,{children:"Stage"})," contains one or more executions\nto run ",(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.em,{children:"all at once"})}),". The Procedure will wait until all of the executions in a ",(0,s.jsx)(n.code,{children:"Stage"})," are complete before moving\non to the next stage. In short, the executions in a ",(0,s.jsx)(n.code,{children:"Stage"})," are run ",(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.em,{children:"in parallel"})}),", and the stages themselves are\nexecuted ",(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.em,{children:"sequentially"})}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"batch-executions",children:"Batch Executions"}),"\n",(0,s.jsxs)(n.p,{children:["Many executions have a ",(0,s.jsx)(n.code,{children:"Batch"})," version you can select, for example ",(0,s.jsx)(n.a,{href:"https://docs.rs/komodo_client/latest/komodo_client/api/execute/struct.BatchDeployStackIfChanged.html",children:(0,s.jsx)(n.strong,{children:"BatchDeployStackIfChanged"})}),". With this, you can match multiple Stacks by name\nusing ",(0,s.jsx)(n.a,{href:"https://docs.rs/wildcard/latest/wildcard",children:(0,s.jsx)(n.strong,{children:"wildcard syntax"})})," and ",(0,s.jsx)(n.a,{href:"https://docs.rs/regex/latest/regex",children:(0,s.jsx)(n.strong,{children:"regex"})}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"toml-example",children:"TOML Example"}),"\n",(0,s.jsxs)(n.p,{children:["Like all Resources, ",(0,s.jsx)(n.code,{children:"Procedures"})," have a TOML representation, and can be managed in ",(0,s.jsx)(n.code,{children:"ResourceSyncs"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-toml",children:'[[procedure]]\nname = "pull-deploy"\ndescription = "Pulls stack-repo, deploys stacks"\n\n[[procedure.config.stage]]\nname = "Pull Repo"\nexecutions = [\n { execution.type = "PullRepo", execution.params.pattern = "stack-repo" },\n]\n\n[[procedure.config.stage]]\nname = "Deploy if changed"\nexecutions = [\n # Uses the Batch version, witch matches many stacks by pattern\n # This one matches all stacks prefixed with `foo-` (wildcard) and `bar-` (regex).\n { execution.type = "BatchDeployStackIfChanged", execution.params.pattern = "foo-* , \\\\^bar-.*$\\\\" },\n]\n'})}),"\n",(0,s.jsx)(n.h2,{id:"actions",children:"Actions"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Actions"})," give users the power of Typescript to write calls to the Komodo API."]}),"\n",(0,s.jsxs)(n.p,{children:["For example, an ",(0,s.jsx)(n.code,{children:"Action"})," script like this will align the versions and branches of many ",(0,s.jsx)(n.code,{children:"Builds"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:'const VERSION = "1.16.5";\nconst BRANCH = "dev/" + VERSION;\nconst APPS = ["core", "periphery"];\nconst ARCHS = ["x86", "aarch64"];\n\nawait komodo.write("UpdateVariableValue", {\n name: "KOMODO_DEV_VERSION",\n value: VERSION,\n});\nconsole.log("Updated KOMODO_DEV_VERSION to " + VERSION);\n\nfor (const app of APPS) {\n for (const arch of ARCHS) {\n const name = `komodo-${app}-${arch}-dev`;\n await komodo.write("UpdateBuild", {\n id: name,\n config: {\n version: VERSION as any,\n branch: BRANCH,\n },\n });\n console.log(\n `Updated Build ${name} to version ${VERSION} and branch ${BRANCH}`,\n );\n }\n}\n\nfor (const arch of ARCHS) {\n const name = `periphery-bin-${arch}-dev`;\n await komodo.write("UpdateRepo", {\n id: name,\n config: {\n branch: BRANCH,\n },\n });\n console.log(`Updated Repo ${name} to branch ${BRANCH}`);\n}\n'})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},8453:(e,n,o)=>{o.d(n,{R:()=>r,x:()=>a});var s=o(6540);const t={},c=s.createContext(t);function r(e){const n=s.useContext(c);return s.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(t):e.components||t:r(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/79c522c5.28aca0dd.js b/assets/js/79c522c5.28aca0dd.js deleted file mode 100644 index e723859c2..000000000 --- a/assets/js/79c522c5.28aca0dd.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[943],{3827:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>i,contentTitle:()=>t,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var s=o(4848),c=o(8453);const r={},t="Procedures and Actions",a={id:"procedures",title:"Procedures and Actions",description:"For orchestrations involving multiple Resources, Komodo offers the Procedure and Action resource types.",source:"@site/docs/procedures.md",sourceDirName:".",slug:"/procedures",permalink:"/docs/procedures",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/procedures.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Variables and Secrets",permalink:"/docs/variables"},next:{title:"Permissioning",permalink:"/docs/permissioning"}},i={},d=[{value:"Procedures",id:"procedures",level:2},{value:"Batch Executions",id:"batch-executions",level:3},{value:"TOML Example",id:"toml-example",level:3},{value:"Actions",id:"actions",level:2}];function l(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",strong:"strong",...(0,c.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"procedures-and-actions",children:"Procedures and Actions"})}),"\n",(0,s.jsxs)(n.p,{children:["For orchestrations involving multiple Resources, Komodo offers the ",(0,s.jsx)(n.code,{children:"Procedure"})," and ",(0,s.jsx)(n.code,{children:"Action"})," resource types."]}),"\n",(0,s.jsx)(n.h2,{id:"procedures",children:"Procedures"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Procedures"})," are compositions of many executions, such as ",(0,s.jsx)(n.code,{children:"RunBuild"})," and ",(0,s.jsx)(n.code,{children:"DeployStack"}),".\nThe executions are grouped into a series of ",(0,s.jsx)(n.code,{children:"Stages"}),", where each ",(0,s.jsx)(n.code,{children:"Stage"})," contains one or more executions\nto run ",(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.em,{children:"all at once"})}),". The Procedure will wait until all of the executions in a ",(0,s.jsx)(n.code,{children:"Stage"})," are complete before moving\non to the next stage. In short, the executions in a ",(0,s.jsx)(n.code,{children:"Stage"})," are run ",(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.em,{children:"in parallel"})}),", and the stages themselves are\nexecuted ",(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.em,{children:"sequentially"})}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"batch-executions",children:"Batch Executions"}),"\n",(0,s.jsxs)(n.p,{children:["Many executions have a ",(0,s.jsx)(n.code,{children:"Batch"})," version you can select, for example ",(0,s.jsx)(n.a,{href:"https://docs.rs/komodo_client/latest/komodo_client/api/execute/struct.BatchDeployStackIfChanged.html",children:(0,s.jsx)(n.strong,{children:"BatchDeployStackIfChanged"})}),". With this, you can match multiple Stacks by name\nusing ",(0,s.jsx)(n.a,{href:"https://docs.rs/wildcard/latest/wildcard",children:(0,s.jsx)(n.strong,{children:"wildcard syntax"})})," and ",(0,s.jsx)(n.a,{href:"https://docs.rs/regex/latest/regex",children:(0,s.jsx)(n.strong,{children:"regex"})}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"toml-example",children:"TOML Example"}),"\n",(0,s.jsxs)(n.p,{children:["Like all Resources, ",(0,s.jsx)(n.code,{children:"Procedures"})," have a TOML representation, and can be managed in ",(0,s.jsx)(n.code,{children:"ResourceSyncs"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-toml",children:'[[procedure]]\nname = "pull-deploy"\ndescription = "Pulls stack-repo, deploys stacks"\n\n[[procedure.config.stage]]\nname = "Pull Repo"\nexecutions = [\n { execution.type = "PullRepo", execution.params.pattern = "stack-repo" },\n]\n\n[[procedure.config.stage]]\nname = "Deploy if changed"\nexecutions = [\n # Uses the Batch version, witch matches many stacks by pattern\n # This one matches all stacks prefixed with `foo-` (wildcard) and `bar-` (regex).\n { execution.type = "BatchDeployStackIfChanged", execution.params.pattern = "foo-* , \\\\^bar-.*$\\\\" },\n]\n'})}),"\n",(0,s.jsx)(n.h2,{id:"actions",children:"Actions"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Actions"})," give users the power of Typescript to write calls to the Komodo API."]}),"\n",(0,s.jsxs)(n.p,{children:["For example, an ",(0,s.jsx)(n.code,{children:"Action"})," script like this will align the versions and branches of many ",(0,s.jsx)(n.code,{children:"Builds"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:'const VERSION = "1.16.5";\nconst BRANCH = "dev/" + VERSION;\nconst APPS = ["core", "periphery"];\nconst ARCHS = ["x86", "aarch64"];\n\nawait komodo.write("UpdateVariableValue", {\n name: "KOMODO_DEV_VERSION",\n value: VERSION,\n});\nconsole.log("Updated KOMODO_DEV_VERSION to " + VERSION);\n\nfor (const app of APPS) {\n for (const arch of ARCHS) {\n const name = `komodo-${app}-${arch}-dev`;\n await komodo.write("UpdateBuild", {\n id: name,\n config: {\n version: VERSION as any,\n branch: BRANCH,\n },\n });\n console.log(\n `Updated Build ${name} to version ${VERSION} and branch ${BRANCH}`,\n );\n }\n}\n\nfor (const arch of ARCHS) {\n const name = `periphery-bin-${arch}-dev`;\n await komodo.write("UpdateRepo", {\n id: name,\n config: {\n branch: BRANCH,\n },\n });\n console.log(`Updated Repo ${name} to branch ${BRANCH}`);\n}\n'})})]})}function h(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},8453:(e,n,o)=>{o.d(n,{R:()=>t,x:()=>a});var s=o(6540);const c={},r=s.createContext(c);function t(e){const n=s.useContext(r);return s.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(c):e.components||c:t(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8b13a4b4.4b7a52d3.js b/assets/js/8b13a4b4.4b7a52d3.js new file mode 100644 index 000000000..5a4c2f405 --- /dev/null +++ b/assets/js/8b13a4b4.4b7a52d3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[848],{5846:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>m,frontMatter:()=>s,metadata:()=>l,toc:()=>u});var r=n(4848),i=n(8453),o=n(5871);const s={slug:"/build-images"},c="Building Images",l={id:"build-images/index",title:"Building Images",description:"Komodo builds docker images by cloning the source repository from the configured git provider, running docker build,",source:"@site/docs/build-images/index.mdx",sourceDirName:"build-images",slug:"/build-images",permalink:"/docs/build-images",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/build-images/index.mdx",tags:[],version:"current",frontMatter:{slug:"/build-images"},sidebar:"docs",previous:{title:"Connect More Servers",permalink:"/docs/connect-servers"},next:{title:"Configuration",permalink:"/docs/build-images/configuration"}},a={},u=[];function d(e){const t={code:"code",h1:"h1",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"building-images",children:"Building Images"})}),"\n",(0,r.jsxs)(t.p,{children:["Komodo builds docker images by cloning the source repository from the configured git provider, running ",(0,r.jsx)(t.code,{children:"docker build"}),",\nand pushing the resulting image to the configured docker registry. Any repo containing a ",(0,r.jsx)(t.code,{children:"Dockerfile"})," is buildable using this method."]}),"\n","\n",(0,r.jsx)(o.A,{})]})}function m(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},5871:(e,t,n)=>{n.d(t,{A:()=>C});var r=n(6540),i=n(4164),o=n(6972),s=n(8774),c=n(4586);const l=["zero","one","two","few","many","other"];function a(e){return l.filter((t=>e.includes(t)))}const u={locale:"en",pluralForms:a(["one","other"]),select:e=>1===e?"one":"other"};function d(){const{i18n:{currentLocale:e}}=(0,c.A)();return(0,r.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:a(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),u}}),[e])}function m(){const e=d();return{selectMessage:(t,n)=>function(e,t,n){const r=e.split("|");if(1===r.length)return r[0];r.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${r.length}: ${e}`);const i=n.select(t),o=n.pluralForms.indexOf(i);return r[Math.min(o,r.length-1)]}(n,t,e)}}var h=n(6654),g=n(1312),f=n(1107);const p={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var x=n(4848);function b(e){let{href:t,children:n}=e;return(0,x.jsx)(s.A,{href:t,className:(0,i.A)("card padding--lg",p.cardContainer),children:n})}function j(e){let{href:t,icon:n,title:r,description:o}=e;return(0,x.jsxs)(b,{href:t,children:[(0,x.jsxs)(f.A,{as:"h2",className:(0,i.A)("text--truncate",p.cardTitle),title:r,children:[n," ",r]}),o&&(0,x.jsx)("p",{className:(0,i.A)("text--truncate",p.cardDescription),title:o,children:o})]})}function k(e){let{item:t}=e;const n=(0,o.Nr)(t),r=function(){const{selectMessage:e}=m();return t=>e(t,(0,g.T)({message:"1 item|{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t}))}();return n?(0,x.jsx)(j,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??r(t.items.length)}):null}function y(e){let{item:t}=e;const n=(0,h.A)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",r=(0,o.cC)(t.docId??void 0);return(0,x.jsx)(j,{href:t.href,icon:n,title:t.label,description:t.description??r?.description})}function v(e){let{item:t}=e;switch(t.type){case"link":return(0,x.jsx)(y,{item:t});case"category":return(0,x.jsx)(k,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function w(e){let{className:t}=e;const n=(0,o.$S)();return(0,x.jsx)(C,{items:n.items,className:t})}function C(e){const{items:t,className:n}=e;if(!t)return(0,x.jsx)(w,{...e});const r=(0,o.d1)(t);return(0,x.jsx)("section",{className:(0,i.A)("row",n),children:r.map(((e,t)=>(0,x.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,x.jsx)(v,{item:e})},t)))})}},8453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>c});var r=n(6540);const i={},o=r.createContext(i);function s(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8b13a4b4.9bad5394.js b/assets/js/8b13a4b4.9bad5394.js deleted file mode 100644 index a4587a766..000000000 --- a/assets/js/8b13a4b4.9bad5394.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[848],{5846:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>m,frontMatter:()=>s,metadata:()=>l,toc:()=>u});var r=n(4848),i=n(8453),o=n(5871);const s={slug:"/build-images"},c="Building Images",l={id:"build-images/index",title:"Building Images",description:"Komodo builds docker images by cloning the source repository from the configured git provider, running docker build,",source:"@site/docs/build-images/index.mdx",sourceDirName:"build-images",slug:"/build-images",permalink:"/docs/build-images",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/build-images/index.mdx",tags:[],version:"current",frontMatter:{slug:"/build-images"},sidebar:"docs",previous:{title:"Connect More Servers",permalink:"/docs/connect-servers"},next:{title:"Configuration",permalink:"/docs/build-images/configuration"}},a={},u=[];function d(e){const t={code:"code",h1:"h1",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"building-images",children:"Building Images"})}),"\n",(0,r.jsxs)(t.p,{children:["Komodo builds docker images by cloning the source repository from the configured git provider, running ",(0,r.jsx)(t.code,{children:"docker build"}),",\nand pushing the resulting image to the configured docker registry. Any repo containing a ",(0,r.jsx)(t.code,{children:"Dockerfile"})," is buildable using this method."]}),"\n","\n",(0,r.jsx)(o.A,{})]})}function m(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},5871:(e,t,n)=>{n.d(t,{A:()=>C});var r=n(6540),i=n(4164),o=n(6972),s=n(8774),c=n(4586);const l=["zero","one","two","few","many","other"];function a(e){return l.filter((t=>e.includes(t)))}const u={locale:"en",pluralForms:a(["one","other"]),select:e=>1===e?"one":"other"};function d(){const{i18n:{currentLocale:e}}=(0,c.A)();return(0,r.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:a(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),u}}),[e])}function m(){const e=d();return{selectMessage:(t,n)=>function(e,t,n){const r=e.split("|");if(1===r.length)return r[0];r.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${r.length}: ${e}`);const i=n.select(t),o=n.pluralForms.indexOf(i);return r[Math.min(o,r.length-1)]}(n,t,e)}}var g=n(6654),h=n(1312),f=n(1107);const p={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var x=n(4848);function b(e){let{href:t,children:n}=e;return(0,x.jsx)(s.A,{href:t,className:(0,i.A)("card padding--lg",p.cardContainer),children:n})}function j(e){let{href:t,icon:n,title:r,description:o}=e;return(0,x.jsxs)(b,{href:t,children:[(0,x.jsxs)(f.A,{as:"h2",className:(0,i.A)("text--truncate",p.cardTitle),title:r,children:[n," ",r]}),o&&(0,x.jsx)("p",{className:(0,i.A)("text--truncate",p.cardDescription),title:o,children:o})]})}function k(e){let{item:t}=e;const n=(0,o.Nr)(t),r=function(){const{selectMessage:e}=m();return t=>e(t,(0,h.T)({message:"1 item|{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t}))}();return n?(0,x.jsx)(j,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??r(t.items.length)}):null}function y(e){let{item:t}=e;const n=(0,g.A)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",r=(0,o.cC)(t.docId??void 0);return(0,x.jsx)(j,{href:t.href,icon:n,title:t.label,description:t.description??r?.description})}function v(e){let{item:t}=e;switch(t.type){case"link":return(0,x.jsx)(y,{item:t});case"category":return(0,x.jsx)(k,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function w(e){let{className:t}=e;const n=(0,o.$S)();return(0,x.jsx)(C,{items:n.items,className:t})}function C(e){const{items:t,className:n}=e;if(!t)return(0,x.jsx)(w,{...e});const r=(0,o.d1)(t);return(0,x.jsx)("section",{className:(0,i.A)("row",n),children:r.map(((e,t)=>(0,x.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,x.jsx)(v,{item:e})},t)))})}},8453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>c});var r=n(6540);const i={},o=r.createContext(i);function s(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8f030830.94a0df8d.js b/assets/js/8f030830.94a0df8d.js new file mode 100644 index 000000000..9c53ba52c --- /dev/null +++ b/assets/js/8f030830.94a0df8d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[423],{1792:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>t,default:()=>a,frontMatter:()=>i,metadata:()=>d,toc:()=>l});var r=s(4848),o=s(8453);const i={},t="Development",d={id:"development",title:"Development",description:"If you are looking to contribute to Komodo, this page is a launching point for setting up your Komodo development environment.",source:"@site/docs/development.md",sourceDirName:".",slug:"/development",permalink:"/docs/development",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/development.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"API and Clients",permalink:"/docs/api"}},c={},l=[{value:"Dependencies",id:"dependencies",level:2},{value:"runnables-cli",id:"runnables-cli",level:3},{value:"Docker",id:"docker",level:2},{value:"Devcontainer",id:"devcontainer",level:2},{value:"Local",id:"local",level:2},{value:"Docsite Development",id:"docsite-development",level:2}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"development",children:"Development"})}),"\n",(0,r.jsx)(n.p,{children:"If you are looking to contribute to Komodo, this page is a launching point for setting up your Komodo development environment."}),"\n",(0,r.jsx)(n.h2,{id:"dependencies",children:"Dependencies"}),"\n",(0,r.jsxs)(n.p,{children:["Running Komodo from ",(0,r.jsx)(n.a,{href:"https://github.com/moghtech/komodo",children:"source"})," requires either ",(0,r.jsx)(n.a,{href:"https://www.docker.com/",children:"Docker"})," (and can use the included ",(0,r.jsx)(n.a,{href:"https://code.visualstudio.com/docs/devcontainers/containers",children:"devcontainer"}),"), or can have the development dependencies installed locally:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Backend (Core / Periphery APIs)","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.a,{href:"https://www.rust-lang.org/",children:"Rust"})," stable via ",(0,r.jsx)(n.a,{href:"https://rustup.rs/",children:"rustup installer"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.a,{href:"https://www.mongodb.com/",children:"MongoDB"})," or ",(0,r.jsx)(n.a,{href:"https://www.ferretdb.com/",children:"FerretDB"})," available locally."]}),"\n",(0,r.jsxs)(n.li,{children:["On Debian/Ubuntu: ",(0,r.jsx)(n.code,{children:"apt install build-essential pkg-config libssl-dev"})," required to build the rust source."]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["Frontend (Web UI)","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.a,{href:"https://nodejs.org/en",children:"Node"})," >= 18.18 + NPM","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.a,{href:"https://yarnpkg.com/",children:"Yarn"})," - (Tip: use ",(0,r.jsx)(n.code,{children:"corepack enable"})," after installing ",(0,r.jsx)(n.code,{children:"node"})," to use ",(0,r.jsx)(n.code,{children:"yarn"}),")"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://github.com/1password/typeshare",children:"typeshare"})}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.a,{href:"https://deno.com/",children:"Deno"})," >= 2.0.2"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"runnables-cli",children:"runnables-cli"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://github.com/mbecker20/runnables-cli",children:"mbecker20/runnables-cli"})," can be used as a convience CLI for running common project tasks found in ",(0,r.jsx)(n.code,{children:"runfile.toml"}),". Otherwise, you can create your own project tasks by references the ",(0,r.jsx)(n.code,{children:"cmd"}),"s found in ",(0,r.jsx)(n.code,{children:"runfile.toml"}),". All instructions below will use runnables-cli v1.3.7+."]}),"\n",(0,r.jsx)(n.h2,{id:"docker",children:"Docker"}),"\n",(0,r.jsxs)(n.p,{children:["After making changes to the project, run ",(0,r.jsx)(n.code,{children:"run -r test-compose-build"})," to rebuild Komodo and then ",(0,r.jsx)(n.code,{children:"run -r test-compose-exposed"})," to start a Komodo container with the UI accessible at ",(0,r.jsx)(n.code,{children:"localhost:9120"}),". Any changes made to source files will require re-running the ",(0,r.jsx)(n.code,{children:"test-compose-build"})," and ",(0,r.jsx)(n.code,{children:"test-compose-exposed"})," commands."]}),"\n",(0,r.jsx)(n.h2,{id:"devcontainer",children:"Devcontainer"}),"\n",(0,r.jsxs)(n.p,{children:["Use the included ",(0,r.jsx)(n.code,{children:".devcontainer.json"})," with VSCode or other compatible IDE to stand-up a full environment, including database, with one click."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://code.visualstudio.com/Docs/editor/tasks",children:"VSCode Tasks"})," are provided for building and running Komodo."]}),"\n",(0,r.jsxs)(n.p,{children:["After opening the repository with the devcontainer run the task ",(0,r.jsx)(n.code,{children:"Init"})," to build the frontend/backend. Then, the task ",(0,r.jsx)(n.code,{children:"Run Komodo"})," can be used to run frontend/backend. Other tasks for rebuilding/running just one component of the stack (Core API, Periphery API, Frontend) are also provided."]}),"\n",(0,r.jsx)(n.h2,{id:"local",children:"Local"}),"\n",(0,r.jsx)(n.p,{children:"To run a full Komodo instance from a non-container environment run commands in this order:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Ensure dependencies are up to date","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"rustup update"})," -- ensure rust toolchain is up to date"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["Build and Run backend","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"run -r test-core"})," -- Build and run Core API"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"run -r test-periphery"})," -- Build and run Periphery API"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["Build Frontend","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Install ",(0,r.jsx)(n.strong,{children:"typeshare-cli"}),": ",(0,r.jsx)(n.code,{children:"cargo install typeshare-cli"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Run this once"})," -- ",(0,r.jsx)(n.code,{children:"run -r link-client"})," -- generates TS client and links to the frontend"]}),"\n",(0,r.jsxs)(n.li,{children:["After running the above once:","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"run -r gen-client"})," -- Rebuild client"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"run -r start-frontend"})," -- Start in dev (watch) mode"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"run -r build-frontend"})," -- Typecheck and build"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"docsite-development",children:"Docsite Development"}),"\n",(0,r.jsxs)(n.p,{children:["Use ",(0,r.jsx)(n.code,{children:"run -r docsite-start"})," to start the ",(0,r.jsx)(n.a,{href:"https://docusaurus.io/",children:"Docusaurus"})," Komodo docs site in development mode. Changes made to files in ",(0,r.jsx)(n.code,{children:"./docsite"})," will be automatically reloaded by the server."]})]})}function a(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>t,x:()=>d});var r=s(6540);const o={},i=r.createContext(o);function t(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8f030830.9c0bc802.js b/assets/js/8f030830.9c0bc802.js deleted file mode 100644 index f6d24608c..000000000 --- a/assets/js/8f030830.9c0bc802.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[423],{1792:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>t,default:()=>a,frontMatter:()=>i,metadata:()=>d,toc:()=>l});var s=r(4848),o=r(8453);const i={},t="Development",d={id:"development",title:"Development",description:"If you are looking to contribute to Komodo, this page is a launching point for setting up your Komodo development environment.",source:"@site/docs/development.md",sourceDirName:".",slug:"/development",permalink:"/docs/development",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/development.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"API and Clients",permalink:"/docs/api"}},c={},l=[{value:"Dependencies",id:"dependencies",level:2},{value:"runnables-cli",id:"runnables-cli",level:3},{value:"Docker",id:"docker",level:2},{value:"Devcontainer",id:"devcontainer",level:2},{value:"Local",id:"local",level:2},{value:"Docsite Development",id:"docsite-development",level:2}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"development",children:"Development"})}),"\n",(0,s.jsx)(n.p,{children:"If you are looking to contribute to Komodo, this page is a launching point for setting up your Komodo development environment."}),"\n",(0,s.jsx)(n.h2,{id:"dependencies",children:"Dependencies"}),"\n",(0,s.jsxs)(n.p,{children:["Running Komodo from ",(0,s.jsx)(n.a,{href:"https://github.com/mbecker20/komodo",children:"source"})," requires either ",(0,s.jsx)(n.a,{href:"https://www.docker.com/",children:"Docker"})," (and can use the included ",(0,s.jsx)(n.a,{href:"https://code.visualstudio.com/docs/devcontainers/containers",children:"devcontainer"}),"), or can have the development dependencies installed locally:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Backend (Core / Periphery APIs)","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://www.rust-lang.org/",children:"Rust"})," stable via ",(0,s.jsx)(n.a,{href:"https://rustup.rs/",children:"rustup installer"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://www.mongodb.com/",children:"MongoDB"})," or ",(0,s.jsx)(n.a,{href:"https://www.ferretdb.com/",children:"FerretDB"})," available locally."]}),"\n",(0,s.jsxs)(n.li,{children:["On Debian/Ubuntu: ",(0,s.jsx)(n.code,{children:"apt install build-essential pkg-config libssl-dev"})," required to build the rust source."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Frontend (Web UI)","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://nodejs.org/en",children:"Node"})," >= 18.18 + NPM","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://yarnpkg.com/",children:"Yarn"})," - (Tip: use ",(0,s.jsx)(n.code,{children:"corepack enable"})," after installing ",(0,s.jsx)(n.code,{children:"node"})," to use ",(0,s.jsx)(n.code,{children:"yarn"}),")"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/1password/typeshare",children:"typeshare"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://deno.com/",children:"Deno"})," >= 2.0.2"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"runnables-cli",children:"runnables-cli"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://github.com/mbecker20/runnables-cli",children:"mbecker20/runnables-cli"})," can be used as a convience CLI for running common project tasks found in ",(0,s.jsx)(n.code,{children:"runfile.toml"}),". Otherwise, you can create your own project tasks by references the ",(0,s.jsx)(n.code,{children:"cmd"}),"s found in ",(0,s.jsx)(n.code,{children:"runfile.toml"}),". All instructions below will use runnables-cli v1.3.7+."]}),"\n",(0,s.jsx)(n.h2,{id:"docker",children:"Docker"}),"\n",(0,s.jsxs)(n.p,{children:["After making changes to the project, run ",(0,s.jsx)(n.code,{children:"run -r test-compose-build"})," to rebuild Komodo and then ",(0,s.jsx)(n.code,{children:"run -r test-compose-exposed"})," to start a Komodo container with the UI accessible at ",(0,s.jsx)(n.code,{children:"localhost:9120"}),". Any changes made to source files will require re-running the ",(0,s.jsx)(n.code,{children:"test-compose-build"})," and ",(0,s.jsx)(n.code,{children:"test-compose-exposed"})," commands."]}),"\n",(0,s.jsx)(n.h2,{id:"devcontainer",children:"Devcontainer"}),"\n",(0,s.jsxs)(n.p,{children:["Use the included ",(0,s.jsx)(n.code,{children:".devcontainer.json"})," with VSCode or other compatible IDE to stand-up a full environment, including database, with one click."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://code.visualstudio.com/Docs/editor/tasks",children:"VSCode Tasks"})," are provided for building and running Komodo."]}),"\n",(0,s.jsxs)(n.p,{children:["After opening the repository with the devcontainer run the task ",(0,s.jsx)(n.code,{children:"Init"})," to build the frontend/backend. Then, the task ",(0,s.jsx)(n.code,{children:"Run Komodo"})," can be used to run frontend/backend. Other tasks for rebuilding/running just one component of the stack (Core API, Periphery API, Frontend) are also provided."]}),"\n",(0,s.jsx)(n.h2,{id:"local",children:"Local"}),"\n",(0,s.jsx)(n.p,{children:"To run a full Komodo instance from a non-container environment run commands in this order:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Ensure dependencies are up to date","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"rustup update"})," -- ensure rust toolchain is up to date"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Build and Run backend","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"run -r test-core"})," -- Build and run Core API"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"run -r test-periphery"})," -- Build and run Periphery API"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Build Frontend","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Install ",(0,s.jsx)(n.strong,{children:"typeshare-cli"}),": ",(0,s.jsx)(n.code,{children:"cargo install typeshare-cli"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Run this once"})," -- ",(0,s.jsx)(n.code,{children:"run -r link-client"})," -- generates TS client and links to the frontend"]}),"\n",(0,s.jsxs)(n.li,{children:["After running the above once:","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"run -r gen-client"})," -- Rebuild client"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"run -r start-frontend"})," -- Start in dev (watch) mode"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"run -r build-frontend"})," -- Typecheck and build"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"docsite-development",children:"Docsite Development"}),"\n",(0,s.jsxs)(n.p,{children:["Use ",(0,s.jsx)(n.code,{children:"run -r docsite-start"})," to start the ",(0,s.jsx)(n.a,{href:"https://docusaurus.io/",children:"Docusaurus"})," Komodo docs site in development mode. Changes made to files in ",(0,s.jsx)(n.code,{children:"./docsite"})," will be automatically reloaded by the server."]})]})}function a(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},8453:(e,n,r)=>{r.d(n,{R:()=>t,x:()=>d});var s=r(6540);const o={},i=s.createContext(o);function t(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a5a01e01.60457fec.js b/assets/js/a5a01e01.60457fec.js new file mode 100644 index 000000000..2c5cf5d8e --- /dev/null +++ b/assets/js/a5a01e01.60457fec.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[549],{6175:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>s,metadata:()=>r,toc:()=>d});var i=n(4848),o=n(8453);const s={},a="Image Versioning",r={id:"build-images/versioning",title:"Image Versioning",description:"Komodo uses a major.minor.patch versioning scheme to Build versioning. By default, every RunBuild will auto increment the Build's version patch number, and push the image to docker hub with the version tag, as well as the latest tag. A tag containing the latest short commit hash at the time the repo was cloned will also be created.",source:"@site/docs/build-images/versioning.md",sourceDirName:"build-images",slug:"/build-images/versioning",permalink:"/docs/build-images/versioning",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/build-images/versioning.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Builders",permalink:"/docs/build-images/builders"},next:{title:"Deploy Containers",permalink:"/docs/deploy-containers/"}},c={},d=[];function l(e){const t={code:"code",h1:"h1",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"image-versioning",children:"Image Versioning"})}),"\n",(0,i.jsxs)(t.p,{children:["Komodo uses a major.minor.patch versioning scheme to Build versioning. By default, every RunBuild will auto increment the Build's version patch number, and push the image to docker hub with the version tag, as well as the ",(0,i.jsx)(t.code,{children:"latest"})," tag. A tag containing the latest short commit hash at the time the repo was cloned will also be created."]}),"\n",(0,i.jsxs)(t.p,{children:['You can also turn off the auto incrementing feature, and manage the version yourself. In addition, you can configure a "version tag" on the build. This will postfix the version tag / commit hash tag with a custom label. For example, an image tag of ',(0,i.jsx)(t.code,{children:"dev"})," will produce tags like ",(0,i.jsx)(t.code,{children:"image_name:1.1.1-dev"})," and ",(0,i.jsx)(t.code,{children:"image_name:h3c87c-dev"}),"."]})]})}function u(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var i=n(6540);const o={},s=i.createContext(o);function a(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a5a01e01.cfd37f67.js b/assets/js/a5a01e01.cfd37f67.js deleted file mode 100644 index 57f494c3e..000000000 --- a/assets/js/a5a01e01.cfd37f67.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[549],{6175:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>s,metadata:()=>r,toc:()=>d});var i=n(4848),o=n(8453);const s={},a="Image Versioning",r={id:"build-images/versioning",title:"Image Versioning",description:"Komodo uses a major.minor.patch versioning scheme to Build versioning. By default, every RunBuild will auto increment the Build's version patch number, and push the image to docker hub with the version tag, as well as the latest tag. A tag containing the latest short commit hash at the time the repo was cloned will also be created.",source:"@site/docs/build-images/versioning.md",sourceDirName:"build-images",slug:"/build-images/versioning",permalink:"/docs/build-images/versioning",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/build-images/versioning.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Builders",permalink:"/docs/build-images/builders"},next:{title:"Deploy Containers",permalink:"/docs/deploy-containers/"}},c={},d=[];function l(e){const t={code:"code",h1:"h1",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"image-versioning",children:"Image Versioning"})}),"\n",(0,i.jsxs)(t.p,{children:["Komodo uses a major.minor.patch versioning scheme to Build versioning. By default, every RunBuild will auto increment the Build's version patch number, and push the image to docker hub with the version tag, as well as the ",(0,i.jsx)(t.code,{children:"latest"})," tag. A tag containing the latest short commit hash at the time the repo was cloned will also be created."]}),"\n",(0,i.jsxs)(t.p,{children:['You can also turn off the auto incrementing feature, and manage the version yourself. In addition, you can configure a "version tag" on the build. This will postfix the version tag / commit hash tag with a custom label. For example, an image tag of ',(0,i.jsx)(t.code,{children:"dev"})," will produce tags like ",(0,i.jsx)(t.code,{children:"image_name:1.1.1-dev"})," and ",(0,i.jsx)(t.code,{children:"image_name:h3c87c-dev"}),"."]})]})}function u(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var i=n(6540);const o={},s=i.createContext(o);function a(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a5c9d4c4.24d158b1.js b/assets/js/a5c9d4c4.24d158b1.js deleted file mode 100644 index 099130b50..000000000 --- a/assets/js/a5c9d4c4.24d158b1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[636],{2612:(e,o,n)=>{n.r(o),n.d(o,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var s=n(4848),t=n(8453);const i={},r="Docker Compose",c={id:"docker-compose",title:"Docker Compose",description:"Komodo can deploy docker compose projects through the Stack resource.",source:"@site/docs/docker-compose.md",sourceDirName:".",slug:"/docker-compose",permalink:"/docs/docker-compose",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/docker-compose.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Container Management",permalink:"/docs/deploy-containers/lifetime-management"},next:{title:"Variables and Secrets",permalink:"/docs/variables"}},a={},l=[{value:"Define the compose file/s",id:"define-the-compose-files",level:2},{value:"Importing Existing Compose projects",id:"importing-existing-compose-projects",level:2},{value:"Pass Environment Variables",id:"pass-environment-variables",level:2}];function d(e){const o={admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(o.header,{children:(0,s.jsx)(o.h1,{id:"docker-compose",children:"Docker Compose"})}),"\n",(0,s.jsxs)(o.p,{children:["Komodo can deploy docker compose projects through the ",(0,s.jsx)(o.code,{children:"Stack"})," resource."]}),"\n",(0,s.jsx)(o.h2,{id:"define-the-compose-files",children:"Define the compose file/s"}),"\n",(0,s.jsx)(o.p,{children:"Komodo supports 3 ways of defining the compose files:"}),"\n",(0,s.jsxs)(o.ol,{children:["\n",(0,s.jsxs)(o.li,{children:[(0,s.jsx)(o.strong,{children:"Write them in the UI"}),", and Komodo will write them to your host at deploy-time."]}),"\n",(0,s.jsxs)(o.li,{children:[(0,s.jsx)(o.strong,{children:"Store the files anywhere on the host"}),", and Komodo will just run the compose commands on the existing files."]}),"\n",(0,s.jsxs)(o.li,{children:[(0,s.jsx)(o.strong,{children:"Store them in a git repo"}),", and have Komodo clone it on the host to deploy."]}),"\n"]}),"\n",(0,s.jsx)(o.p,{children:"If you manage your compose files in git repos:"}),"\n",(0,s.jsxs)(o.ul,{children:["\n",(0,s.jsx)(o.li,{children:"All your files, across all servers, are available locally to edit in your favorite text editor."}),"\n",(0,s.jsx)(o.li,{children:"All of your changes are tracked, and can be reverted."}),"\n",(0,s.jsxs)(o.li,{children:["You can use the git webhooks to do other automations when you change the compose file contents. Redeploying will be as easy as ",(0,s.jsx)(o.code,{children:"git push"}),"."]}),"\n"]}),"\n",(0,s.jsx)(o.admonition,{type:"info",children:(0,s.jsx)(o.p,{children:"Many Komodo resources need access to git repos. There is an in-built token management system (managed in UI or in config file) to give resources access to credentials.\nAll resources which depend on git repos are able to use these credentials to access private repos."})}),"\n",(0,s.jsx)(o.h2,{id:"importing-existing-compose-projects",children:"Importing Existing Compose projects"}),"\n",(0,s.jsx)(o.p,{children:"First create the Stack in Komodo, and ensure it has access to the compose files using one\nof the three methods above. Make sure to attach the server you wish to deploy on."}),"\n",(0,s.jsxs)(o.p,{children:['In order for Komodo to pick up a running project, it has to know the compose "project name".\nYou can find the project name by running ',(0,s.jsx)(o.code,{children:"docker compose ls"})," on the host."]}),"\n",(0,s.jsx)(o.p,{children:'By default, Komodo will assume the Stack name is the compose project name.\nIf this is different than the project name on the host, you can configure a custom "Project Name" in the config.'}),"\n",(0,s.jsx)(o.h2,{id:"pass-environment-variables",children:"Pass Environment Variables"}),"\n",(0,s.jsx)(o.p,{children:"Komodo is able to pass custom environment variables to the docker compose process.\nThis works by:"}),"\n",(0,s.jsxs)(o.ol,{children:["\n",(0,s.jsx)(o.li,{children:'Write the variables to a ".env" file on the host at deploy-time.'}),"\n",(0,s.jsxs)(o.li,{children:["Pass the file to docker compose using the ",(0,s.jsx)(o.code,{children:"--env-file"})," flag."]}),"\n"]}),"\n",(0,s.jsx)(o.admonition,{type:"info",children:(0,s.jsxs)(o.p,{children:["Just like all other resources with Environments (Deployments, Repos, Builds),\nStack Environments support ",(0,s.jsx)(o.strong,{children:"Variable and Secret interpolation"}),". Define global variables\nin the UI and share the values across environments."]})})]})}function h(e={}){const{wrapper:o}={...(0,t.R)(),...e.components};return o?(0,s.jsx)(o,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},8453:(e,o,n)=>{n.d(o,{R:()=>r,x:()=>c});var s=n(6540);const t={},i=s.createContext(t);function r(e){const o=s.useContext(i);return s.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(t):e.components||t:r(e.components),s.createElement(i.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a5c9d4c4.c19c99ec.js b/assets/js/a5c9d4c4.c19c99ec.js new file mode 100644 index 000000000..6a078a8a5 --- /dev/null +++ b/assets/js/a5c9d4c4.c19c99ec.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[636],{2612:(e,o,n)=>{n.r(o),n.d(o,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var s=n(4848),t=n(8453);const i={},r="Docker Compose",c={id:"docker-compose",title:"Docker Compose",description:"Komodo can deploy docker compose projects through the Stack resource.",source:"@site/docs/docker-compose.md",sourceDirName:".",slug:"/docker-compose",permalink:"/docs/docker-compose",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/docker-compose.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Container Management",permalink:"/docs/deploy-containers/lifetime-management"},next:{title:"Variables and Secrets",permalink:"/docs/variables"}},a={},l=[{value:"Define the compose file/s",id:"define-the-compose-files",level:2},{value:"Importing Existing Compose projects",id:"importing-existing-compose-projects",level:2},{value:"Pass Environment Variables",id:"pass-environment-variables",level:2}];function d(e){const o={admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(o.header,{children:(0,s.jsx)(o.h1,{id:"docker-compose",children:"Docker Compose"})}),"\n",(0,s.jsxs)(o.p,{children:["Komodo can deploy docker compose projects through the ",(0,s.jsx)(o.code,{children:"Stack"})," resource."]}),"\n",(0,s.jsx)(o.h2,{id:"define-the-compose-files",children:"Define the compose file/s"}),"\n",(0,s.jsx)(o.p,{children:"Komodo supports 3 ways of defining the compose files:"}),"\n",(0,s.jsxs)(o.ol,{children:["\n",(0,s.jsxs)(o.li,{children:[(0,s.jsx)(o.strong,{children:"Write them in the UI"}),", and Komodo will write them to your host at deploy-time."]}),"\n",(0,s.jsxs)(o.li,{children:[(0,s.jsx)(o.strong,{children:"Store the files anywhere on the host"}),", and Komodo will just run the compose commands on the existing files."]}),"\n",(0,s.jsxs)(o.li,{children:[(0,s.jsx)(o.strong,{children:"Store them in a git repo"}),", and have Komodo clone it on the host to deploy."]}),"\n"]}),"\n",(0,s.jsx)(o.p,{children:"If you manage your compose files in git repos:"}),"\n",(0,s.jsxs)(o.ul,{children:["\n",(0,s.jsx)(o.li,{children:"All your files, across all servers, are available locally to edit in your favorite text editor."}),"\n",(0,s.jsx)(o.li,{children:"All of your changes are tracked, and can be reverted."}),"\n",(0,s.jsxs)(o.li,{children:["You can use the git webhooks to do other automations when you change the compose file contents. Redeploying will be as easy as ",(0,s.jsx)(o.code,{children:"git push"}),"."]}),"\n"]}),"\n",(0,s.jsx)(o.admonition,{type:"info",children:(0,s.jsx)(o.p,{children:"Many Komodo resources need access to git repos. There is an in-built token management system (managed in UI or in config file) to give resources access to credentials.\nAll resources which depend on git repos are able to use these credentials to access private repos."})}),"\n",(0,s.jsx)(o.h2,{id:"importing-existing-compose-projects",children:"Importing Existing Compose projects"}),"\n",(0,s.jsx)(o.p,{children:"First create the Stack in Komodo, and ensure it has access to the compose files using one\nof the three methods above. Make sure to attach the server you wish to deploy on."}),"\n",(0,s.jsxs)(o.p,{children:['In order for Komodo to pick up a running project, it has to know the compose "project name".\nYou can find the project name by running ',(0,s.jsx)(o.code,{children:"docker compose ls"})," on the host."]}),"\n",(0,s.jsx)(o.p,{children:'By default, Komodo will assume the Stack name is the compose project name.\nIf this is different than the project name on the host, you can configure a custom "Project Name" in the config.'}),"\n",(0,s.jsx)(o.h2,{id:"pass-environment-variables",children:"Pass Environment Variables"}),"\n",(0,s.jsx)(o.p,{children:"Komodo is able to pass custom environment variables to the docker compose process.\nThis works by:"}),"\n",(0,s.jsxs)(o.ol,{children:["\n",(0,s.jsx)(o.li,{children:'Write the variables to a ".env" file on the host at deploy-time.'}),"\n",(0,s.jsxs)(o.li,{children:["Pass the file to docker compose using the ",(0,s.jsx)(o.code,{children:"--env-file"})," flag."]}),"\n"]}),"\n",(0,s.jsx)(o.admonition,{type:"info",children:(0,s.jsxs)(o.p,{children:["Just like all other resources with Environments (Deployments, Repos, Builds),\nStack Environments support ",(0,s.jsx)(o.strong,{children:"Variable and Secret interpolation"}),". Define global variables\nin the UI and share the values across environments."]})})]})}function h(e={}){const{wrapper:o}={...(0,t.R)(),...e.components};return o?(0,s.jsx)(o,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},8453:(e,o,n)=>{n.d(o,{R:()=>r,x:()=>c});var s=n(6540);const t={},i=s.createContext(t);function r(e){const o=s.useContext(i);return s.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(t):e.components||t:r(e.components),s.createElement(i.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a9cd8699.6e3b5eeb.js b/assets/js/a9cd8699.6e3b5eeb.js new file mode 100644 index 000000000..71e0e9b96 --- /dev/null +++ b/assets/js/a9cd8699.6e3b5eeb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[648],{593:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>r,metadata:()=>d,toc:()=>a});var o=n(4848),t=n(8453);const r={},s="Configuration",d={id:"build-images/configuration",title:"Configuration",description:"Komodo just needs a bit of information in order to build your image.",source:"@site/docs/build-images/configuration.md",sourceDirName:"build-images",slug:"/build-images/configuration",permalink:"/docs/build-images/configuration",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/build-images/configuration.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Building Images",permalink:"/docs/build-images"},next:{title:"Pre-build command",permalink:"/docs/build-images/pre-build"}},c={},a=[{value:"Provider configuration",id:"provider-configuration",level:3},{value:"Repo configuration",id:"repo-configuration",level:3},{value:"Docker build configuration",id:"docker-build-configuration",level:3},{value:"Image registry",id:"image-registry",level:3},{value:"Adding build args",id:"adding-build-args",level:3},{value:"Adding build secrets",id:"adding-build-secrets",level:3}];function l(e){const i={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h3:"h3",header:"header",p:"p",pre:"pre",...(0,t.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(i.header,{children:(0,o.jsx)(i.h1,{id:"configuration",children:"Configuration"})}),"\n",(0,o.jsx)(i.p,{children:"Komodo just needs a bit of information in order to build your image."}),"\n",(0,o.jsx)(i.h3,{id:"provider-configuration",children:"Provider configuration"}),"\n",(0,o.jsxs)(i.p,{children:["Komodo supports cloning repos over http/s, from any provider that supports cloning private repos using ",(0,o.jsx)(i.code,{children:"git clone https://@git-provider.net//"}),"."]}),"\n",(0,o.jsxs)(i.p,{children:["Accounts / access tokens can be configured in either the ",(0,o.jsx)(i.a,{href:"/docs/setup/advanced#mount-a-config-file",children:"core config"}),"\nor in the ",(0,o.jsx)(i.a,{href:"/docs/connect-servers#manual-install-steps---binaries",children:"periphery config"}),"."]}),"\n",(0,o.jsx)(i.h3,{id:"repo-configuration",children:"Repo configuration"}),"\n",(0,o.jsxs)(i.p,{children:["To specify the git repo to build, just give it the name of the repo and the branch under ",(0,o.jsx)(i.em,{children:"repo config"}),". The name is given like ",(0,o.jsx)(i.code,{children:"moghtech/komodo"}),", it includes the username / organization that owns the repo."]}),"\n",(0,o.jsx)(i.p,{children:"Many repos are private, in this case an access token is needed by the building server.\nIt can either come from a provider defined in the core configuration,\nor in the periphery configuration of the building server."}),"\n",(0,o.jsx)(i.h3,{id:"docker-build-configuration",children:"Docker build configuration"}),"\n",(0,o.jsxs)(i.p,{children:["In order to docker build, Komodo just needs to know the build directory and the path of the Dockerfile relative to the repo, you can configure these in the ",(0,o.jsx)(i.em,{children:"build config"})," section."]}),"\n",(0,o.jsxs)(i.p,{children:["If the build directory is the root of the repository, you pass the build path as ",(0,o.jsx)(i.code,{children:"."}),'. If the build directory is some folder of the repo, just pass the name of the the folder. Do not pass the preceding "/". for example ',(0,o.jsx)(i.code,{children:"build/directory"})]}),"\n",(0,o.jsxs)(i.p,{children:["The dockerfile's path is given relative to the build directory. So if your build directory is ",(0,o.jsx)(i.code,{children:"build/directory"})," and the dockerfile is in ",(0,o.jsx)(i.code,{children:"build/directory/Dockerfile.example"}),", you give the dockerfile path simply as ",(0,o.jsx)(i.code,{children:"Dockerfile.example"}),"."]}),"\n",(0,o.jsx)(i.h3,{id:"image-registry",children:"Image registry"}),"\n",(0,o.jsx)(i.p,{children:"Komodo supports pushing to any docker registry.\nAny of the accounts that are specified in config for the specific registry, between the core config and builder, will be available to use for authentication against the registry.\nAdditionally, allowed organizations on the docker registry can be specified on the core config and attached to builds.\nDoing so will cause the images to be published under the organization's namespace rather than the account's."}),"\n",(0,o.jsx)(i.p,{children:"When connecting a build to a deployments, the default behavior is for the deployment to inherit the registry configuration from the build.\nIn cases where that account isn't available to the deployment, another account can be chosen in the deployment config."}),"\n",(0,o.jsx)(i.admonition,{type:"note",children:(0,o.jsxs)(i.p,{children:["In order to publish to the Github Container Registry, your Github access token must be given the ",(0,o.jsx)(i.code,{children:"write:packages"})," permission.\nSee the Github docs ",(0,o.jsx)(i.a,{href:"https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry#authenticating-with-a-personal-access-token-classic",children:"here"}),"."]})}),"\n",(0,o.jsx)(i.h3,{id:"adding-build-args",children:"Adding build args"}),"\n",(0,o.jsxs)(i.p,{children:["The Dockerfile may make use of ",(0,o.jsx)(i.a,{href:"https://docs.docker.com/engine/reference/builder/#arg",children:"build args"}),". Build args can be passed using the gui by navigating to the ",(0,o.jsx)(i.code,{children:"Build Args"})," tab in the config. They are passed in the menu just like in the would in a .env file:"]}),"\n",(0,o.jsx)(i.pre,{children:(0,o.jsx)(i.code,{children:"BUILD_ARG1=some_value\nBUILD_ARG2=some_other_value\n"})}),"\n",(0,o.jsxs)(i.p,{children:["Note that these values are visible in the final image using ",(0,o.jsx)(i.code,{children:"docker history"}),", so shouldn't be used to pass build time secrets. Use ",(0,o.jsx)(i.a,{href:"https://docs.docker.com/engine/reference/builder/#run---mounttypesecret",children:"secret mounts"})," for this instead."]}),"\n",(0,o.jsx)(i.h3,{id:"adding-build-secrets",children:"Adding build secrets"}),"\n",(0,o.jsxs)(i.p,{children:["The Dockerfile may also make use of ",(0,o.jsx)(i.a,{href:"https://docs.docker.com/build/building/secrets",children:"build secrets"}),"."]}),"\n",(0,o.jsx)(i.p,{children:"They are configured in the GUI the same way as build args. The values passed here can be used in RUN commands in the Dockerfile:"}),"\n",(0,o.jsx)(i.pre,{children:(0,o.jsx)(i.code,{children:"RUN --mount=type=secret,id=SECRET_KEY \\\n SECRET_KEY=$(cat /run/secrets/SECRET_KEY) ...\n"})}),"\n",(0,o.jsxs)(i.p,{children:["These values will not be visible with ",(0,o.jsx)(i.code,{children:"docker history"})," command."]})]})}function h(e={}){const{wrapper:i}={...(0,t.R)(),...e.components};return i?(0,o.jsx)(i,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},8453:(e,i,n)=>{n.d(i,{R:()=>s,x:()=>d});var o=n(6540);const t={},r=o.createContext(t);function s(e){const i=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function d(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:s(e.components),o.createElement(r.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a9cd8699.e624c656.js b/assets/js/a9cd8699.e624c656.js deleted file mode 100644 index c4f60e623..000000000 --- a/assets/js/a9cd8699.e624c656.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[648],{593:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>r,metadata:()=>d,toc:()=>a});var o=n(4848),t=n(8453);const r={},s="Configuration",d={id:"build-images/configuration",title:"Configuration",description:"Komodo just needs a bit of information in order to build your image.",source:"@site/docs/build-images/configuration.md",sourceDirName:"build-images",slug:"/build-images/configuration",permalink:"/docs/build-images/configuration",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/build-images/configuration.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Building Images",permalink:"/docs/build-images"},next:{title:"Pre-build command",permalink:"/docs/build-images/pre-build"}},c={},a=[{value:"Provider configuration",id:"provider-configuration",level:3},{value:"Repo configuration",id:"repo-configuration",level:3},{value:"Docker build configuration",id:"docker-build-configuration",level:3},{value:"Image registry",id:"image-registry",level:3},{value:"Adding build args",id:"adding-build-args",level:3},{value:"Adding build secrets",id:"adding-build-secrets",level:3}];function l(e){const i={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h3:"h3",header:"header",p:"p",pre:"pre",...(0,t.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(i.header,{children:(0,o.jsx)(i.h1,{id:"configuration",children:"Configuration"})}),"\n",(0,o.jsx)(i.p,{children:"Komodo just needs a bit of information in order to build your image."}),"\n",(0,o.jsx)(i.h3,{id:"provider-configuration",children:"Provider configuration"}),"\n",(0,o.jsxs)(i.p,{children:["Komodo supports cloning repos over http/s, from any provider that supports cloning private repos using ",(0,o.jsx)(i.code,{children:"git clone https://@git-provider.net//"}),"."]}),"\n",(0,o.jsxs)(i.p,{children:["Accounts / access tokens can be configured in either the ",(0,o.jsx)(i.a,{href:"/docs/setup/advanced#mount-a-config-file",children:"core config"}),"\nor in the ",(0,o.jsx)(i.a,{href:"/docs/connect-servers#manual-install-steps---binaries",children:"periphery config"}),"."]}),"\n",(0,o.jsx)(i.h3,{id:"repo-configuration",children:"Repo configuration"}),"\n",(0,o.jsxs)(i.p,{children:["To specify the git repo to build, just give it the name of the repo and the branch under ",(0,o.jsx)(i.em,{children:"repo config"}),". The name is given like ",(0,o.jsx)(i.code,{children:"mbecker20/komodo"}),", it includes the username / organization that owns the repo."]}),"\n",(0,o.jsx)(i.p,{children:"Many repos are private, in this case an access token is needed by the building server.\nIt can either come from a provider defined in the core configuration,\nor in the periphery configuration of the building server."}),"\n",(0,o.jsx)(i.h3,{id:"docker-build-configuration",children:"Docker build configuration"}),"\n",(0,o.jsxs)(i.p,{children:["In order to docker build, Komodo just needs to know the build directory and the path of the Dockerfile relative to the repo, you can configure these in the ",(0,o.jsx)(i.em,{children:"build config"})," section."]}),"\n",(0,o.jsxs)(i.p,{children:["If the build directory is the root of the repository, you pass the build path as ",(0,o.jsx)(i.code,{children:"."}),'. If the build directory is some folder of the repo, just pass the name of the the folder. Do not pass the preceding "/". for example ',(0,o.jsx)(i.code,{children:"build/directory"})]}),"\n",(0,o.jsxs)(i.p,{children:["The dockerfile's path is given relative to the build directory. So if your build directory is ",(0,o.jsx)(i.code,{children:"build/directory"})," and the dockerfile is in ",(0,o.jsx)(i.code,{children:"build/directory/Dockerfile.example"}),", you give the dockerfile path simply as ",(0,o.jsx)(i.code,{children:"Dockerfile.example"}),"."]}),"\n",(0,o.jsx)(i.h3,{id:"image-registry",children:"Image registry"}),"\n",(0,o.jsx)(i.p,{children:"Komodo supports pushing to any docker registry.\nAny of the accounts that are specified in config for the specific registry, between the core config and builder, will be available to use for authentication against the registry.\nAdditionally, allowed organizations on the docker registry can be specified on the core config and attached to builds.\nDoing so will cause the images to be published under the organization's namespace rather than the account's."}),"\n",(0,o.jsx)(i.p,{children:"When connecting a build to a deployments, the default behavior is for the deployment to inherit the registry configuration from the build.\nIn cases where that account isn't available to the deployment, another account can be chosen in the deployment config."}),"\n",(0,o.jsx)(i.admonition,{type:"note",children:(0,o.jsxs)(i.p,{children:["In order to publish to the Github Container Registry, your Github access token must be given the ",(0,o.jsx)(i.code,{children:"write:packages"})," permission.\nSee the Github docs ",(0,o.jsx)(i.a,{href:"https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry#authenticating-with-a-personal-access-token-classic",children:"here"}),"."]})}),"\n",(0,o.jsx)(i.h3,{id:"adding-build-args",children:"Adding build args"}),"\n",(0,o.jsxs)(i.p,{children:["The Dockerfile may make use of ",(0,o.jsx)(i.a,{href:"https://docs.docker.com/engine/reference/builder/#arg",children:"build args"}),". Build args can be passed using the gui by navigating to the ",(0,o.jsx)(i.code,{children:"Build Args"})," tab in the config. They are passed in the menu just like in the would in a .env file:"]}),"\n",(0,o.jsx)(i.pre,{children:(0,o.jsx)(i.code,{children:"BUILD_ARG1=some_value\nBUILD_ARG2=some_other_value\n"})}),"\n",(0,o.jsxs)(i.p,{children:["Note that these values are visible in the final image using ",(0,o.jsx)(i.code,{children:"docker history"}),", so shouldn't be used to pass build time secrets. Use ",(0,o.jsx)(i.a,{href:"https://docs.docker.com/engine/reference/builder/#run---mounttypesecret",children:"secret mounts"})," for this instead."]}),"\n",(0,o.jsx)(i.h3,{id:"adding-build-secrets",children:"Adding build secrets"}),"\n",(0,o.jsxs)(i.p,{children:["The Dockerfile may also make use of ",(0,o.jsx)(i.a,{href:"https://docs.docker.com/build/building/secrets",children:"build secrets"}),"."]}),"\n",(0,o.jsx)(i.p,{children:"They are configured in the GUI the same way as build args. The values passed here can be used in RUN commands in the Dockerfile:"}),"\n",(0,o.jsx)(i.pre,{children:(0,o.jsx)(i.code,{children:"RUN --mount=type=secret,id=SECRET_KEY \\\n SECRET_KEY=$(cat /run/secrets/SECRET_KEY) ...\n"})}),"\n",(0,o.jsxs)(i.p,{children:["These values will not be visible with ",(0,o.jsx)(i.code,{children:"docker history"})," command."]})]})}function h(e={}){const{wrapper:i}={...(0,t.R)(),...e.components};return i?(0,o.jsx)(i,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},8453:(e,i,n)=>{n.d(i,{R:()=>s,x:()=>d});var o=n(6540);const t={},r=o.createContext(t);function s(e){const i=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function d(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:s(e.components),o.createElement(r.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b19e82df.ae0cec3c.js b/assets/js/b19e82df.ae0cec3c.js new file mode 100644 index 000000000..4693ad819 --- /dev/null +++ b/assets/js/b19e82df.ae0cec3c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[842],{8929:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>m,frontMatter:()=>s,metadata:()=>u,toc:()=>i});var n=o(4848),r=o(8453),a=o(5627);const s={},l="MongoDB",u={id:"setup/mongo",title:"MongoDB",description:"1. Copy komodo/mongo.compose.yaml and komodo/compose.env to your host:",source:"@site/docs/setup/mongo.mdx",sourceDirName:"setup",slug:"/setup/mongo",permalink:"/docs/setup/mongo",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/setup/mongo.mdx",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Setup Komodo",permalink:"/docs/setup/"},next:{title:"Postgres",permalink:"/docs/setup/postgres"}},c={},i=[];function d(e){const t={code:"code",h1:"h1",header:"header",li:"li",ol:"ol",pre:"pre",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"mongodb",children:"MongoDB"})}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["Copy ",(0,n.jsx)(t.code,{children:"komodo/mongo.compose.yaml"})," and ",(0,n.jsx)(t.code,{children:"komodo/compose.env"})," to your host:"]}),"\n"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"wget -P komodo https://raw.githubusercontent.com/moghtech/komodo/main/compose/mongo.compose.yaml && \\\n wget -P komodo https://raw.githubusercontent.com/moghtech/komodo/main/compose/compose.env\n"})}),"\n",(0,n.jsxs)(t.ol,{start:"2",children:["\n",(0,n.jsxs)(t.li,{children:["Edit the variables in ",(0,n.jsx)(t.code,{children:"komodo/compose.env"}),"."]}),"\n",(0,n.jsx)(t.li,{children:"Deploy:"}),"\n"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"docker compose -p komodo -f komodo/mongo.compose.yaml --env-file komodo/compose.env up -d\n"})}),"\n","\n",(0,n.jsx)(a.A,{file_name:"mongo.compose.yaml"})]})}function m(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},5627:(e,t,o)=>{o.d(t,{A:()=>A});var n=o(6540),r=o(6695),a=o(4164),s=o(3104),l=o(6347),u=o(205),c=o(7485),i=o(1682),d=o(679);function m(e){return n.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,n.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function h(e){const{values:t,children:o}=e;return(0,n.useMemo)((()=>{const e=t??function(e){return m(e).map((e=>{let{props:{value:t,label:o,attributes:n,default:r}}=e;return{value:t,label:o,attributes:n,default:r}}))}(o);return function(e){const t=(0,i.XI)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,o])}function p(e){let{value:t,tabValues:o}=e;return o.some((e=>e.value===t))}function b(e){let{queryString:t=!1,groupId:o}=e;const r=(0,l.W6)(),a=function(e){let{queryString:t=!1,groupId:o}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!o)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return o??null}({queryString:t,groupId:o});return[(0,c.aZ)(a),(0,n.useCallback)((e=>{if(!a)return;const t=new URLSearchParams(r.location.search);t.set(a,e),r.replace({...r.location,search:t.toString()})}),[a,r])]}function g(e){const{defaultValue:t,queryString:o=!1,groupId:r}=e,a=h(e),[s,l]=(0,n.useState)((()=>function(e){let{defaultValue:t,tabValues:o}=e;if(0===o.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!p({value:t,tabValues:o}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${o.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const n=o.find((e=>e.default))??o[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:a}))),[c,i]=b({queryString:o,groupId:r}),[m,g]=function(e){let{groupId:t}=e;const o=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,a]=(0,d.Dv)(o);return[r,(0,n.useCallback)((e=>{o&&a.set(e)}),[o,a])]}({groupId:r}),f=(()=>{const e=c??m;return p({value:e,tabValues:a})?e:null})();(0,u.A)((()=>{f&&l(f)}),[f]);return{selectedValue:s,selectValue:(0,n.useCallback)((e=>{if(!p({value:e,tabValues:a}))throw new Error(`Can't select invalid tab value=${e}`);l(e),i(e),g(e)}),[i,g,a]),tabValues:a}}var f=o(2303);const v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var x=o(4848);function k(e){let{className:t,block:o,selectedValue:n,selectValue:r,tabValues:l}=e;const u=[],{blockElementScrollPositionUntilNextRender:c}=(0,s.a_)(),i=e=>{const t=e.currentTarget,o=u.indexOf(t),a=l[o].value;a!==n&&(c(t),r(a))},d=e=>{let t=null;switch(e.key){case"Enter":i(e);break;case"ArrowRight":{const o=u.indexOf(e.currentTarget)+1;t=u[o]??u[0];break}case"ArrowLeft":{const o=u.indexOf(e.currentTarget)-1;t=u[o]??u[u.length-1];break}}t?.focus()};return(0,x.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,a.A)("tabs",{"tabs--block":o},t),children:l.map((e=>{let{value:t,label:o,attributes:r}=e;return(0,x.jsx)("li",{role:"tab",tabIndex:n===t?0:-1,"aria-selected":n===t,ref:e=>u.push(e),onKeyDown:d,onClick:i,...r,className:(0,a.A)("tabs__item",v.tabItem,r?.className,{"tabs__item--active":n===t}),children:o??t},t)}))})}function y(e){let{lazy:t,children:o,selectedValue:r}=e;const s=(Array.isArray(o)?o:[o]).filter(Boolean);if(t){const e=s.find((e=>e.props.value===r));return e?(0,n.cloneElement)(e,{className:(0,a.A)("margin-top--md",e.props.className)}):null}return(0,x.jsx)("div",{className:"margin-top--md",children:s.map(((e,t)=>(0,n.cloneElement)(e,{key:t,hidden:e.props.value!==r})))})}function j(e){const t=g(e);return(0,x.jsxs)("div",{className:(0,a.A)("tabs-container",v.tabList),children:[(0,x.jsx)(k,{...t,...e}),(0,x.jsx)(y,{...t,...e})]})}function w(e){const t=(0,f.A)();return(0,x.jsx)(j,{...e,children:m(e.children)},String(t))}const I={tabItem:"tabItem_Ymn6"};function V(e){let{children:t,hidden:o,className:n}=e;return(0,x.jsx)("div",{role:"tabpanel",className:(0,a.A)(I.tabItem,n),hidden:o,children:t})}function A(e){let{file_name:t}=e;return(0,x.jsxs)(w,{children:[(0,x.jsx)(V,{value:t,children:(0,x.jsx)(r.A,{title:`https://github.com/moghtech/komodo/blob/main/compose/${t}`,url:`https://raw.githubusercontent.com/moghtech/komodo/main/compose/${t}`,language:"yaml"})}),(0,x.jsx)(V,{value:"compose.env",children:(0,x.jsx)(r.A,{title:"https://github.com/moghtech/komodo/blob/main/compose/compose.env",url:"https://raw.githubusercontent.com/moghtech/komodo/main/compose/compose.env",language:"bash"})})]})}},6695:(e,t,o)=>{o.d(t,{A:()=>s});var n=o(6540),r=o(1432),a=o(4848);function s(e){let{url:t,language:o,title:s}=e;const[l,u]=(0,n.useState)("");return(0,n.useEffect)((()=>{!async function(e,t){const o=await fetch(e);t(await o.text())}(t,u)}),[]),(0,a.jsx)(r.A,{title:s??t,language:o,showLineNumbers:!0,children:l})}}}]); \ No newline at end of file diff --git a/assets/js/b19e82df.b470a8ff.js b/assets/js/b19e82df.b470a8ff.js deleted file mode 100644 index d6f0f05ef..000000000 --- a/assets/js/b19e82df.b470a8ff.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[842],{8929:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>m,frontMatter:()=>s,metadata:()=>u,toc:()=>i});var n=o(4848),r=o(8453),a=o(5627);const s={},l="MongoDB",u={id:"setup/mongo",title:"MongoDB",description:"1. Copy komodo/mongo.compose.yaml and komodo/compose.env to your host:",source:"@site/docs/setup/mongo.mdx",sourceDirName:"setup",slug:"/setup/mongo",permalink:"/docs/setup/mongo",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/setup/mongo.mdx",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Setup Komodo",permalink:"/docs/setup/"},next:{title:"Postgres",permalink:"/docs/setup/postgres"}},c={},i=[];function d(e){const t={code:"code",h1:"h1",header:"header",li:"li",ol:"ol",pre:"pre",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"mongodb",children:"MongoDB"})}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["Copy ",(0,n.jsx)(t.code,{children:"komodo/mongo.compose.yaml"})," and ",(0,n.jsx)(t.code,{children:"komodo/compose.env"})," to your host:"]}),"\n"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"wget -P komodo https://raw.githubusercontent.com/mbecker20/komodo/main/compose/mongo.compose.yaml && \\\n wget -P komodo https://raw.githubusercontent.com/mbecker20/komodo/main/compose/compose.env\n"})}),"\n",(0,n.jsxs)(t.ol,{start:"2",children:["\n",(0,n.jsxs)(t.li,{children:["Edit the variables in ",(0,n.jsx)(t.code,{children:"komodo/compose.env"}),"."]}),"\n",(0,n.jsx)(t.li,{children:"Deploy:"}),"\n"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"docker compose -p komodo -f komodo/mongo.compose.yaml --env-file komodo/compose.env up -d\n"})}),"\n","\n",(0,n.jsx)(a.A,{file_name:"mongo.compose.yaml"})]})}function m(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},5627:(e,t,o)=>{o.d(t,{A:()=>A});var n=o(6540),r=o(6695),a=o(4164),s=o(3104),l=o(6347),u=o(205),c=o(7485),i=o(1682),d=o(679);function m(e){return n.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,n.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function p(e){const{values:t,children:o}=e;return(0,n.useMemo)((()=>{const e=t??function(e){return m(e).map((e=>{let{props:{value:t,label:o,attributes:n,default:r}}=e;return{value:t,label:o,attributes:n,default:r}}))}(o);return function(e){const t=(0,i.XI)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,o])}function h(e){let{value:t,tabValues:o}=e;return o.some((e=>e.value===t))}function b(e){let{queryString:t=!1,groupId:o}=e;const r=(0,l.W6)(),a=function(e){let{queryString:t=!1,groupId:o}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!o)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return o??null}({queryString:t,groupId:o});return[(0,c.aZ)(a),(0,n.useCallback)((e=>{if(!a)return;const t=new URLSearchParams(r.location.search);t.set(a,e),r.replace({...r.location,search:t.toString()})}),[a,r])]}function f(e){const{defaultValue:t,queryString:o=!1,groupId:r}=e,a=p(e),[s,l]=(0,n.useState)((()=>function(e){let{defaultValue:t,tabValues:o}=e;if(0===o.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!h({value:t,tabValues:o}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${o.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const n=o.find((e=>e.default))??o[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:a}))),[c,i]=b({queryString:o,groupId:r}),[m,f]=function(e){let{groupId:t}=e;const o=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,a]=(0,d.Dv)(o);return[r,(0,n.useCallback)((e=>{o&&a.set(e)}),[o,a])]}({groupId:r}),g=(()=>{const e=c??m;return h({value:e,tabValues:a})?e:null})();(0,u.A)((()=>{g&&l(g)}),[g]);return{selectedValue:s,selectValue:(0,n.useCallback)((e=>{if(!h({value:e,tabValues:a}))throw new Error(`Can't select invalid tab value=${e}`);l(e),i(e),f(e)}),[i,f,a]),tabValues:a}}var g=o(2303);const v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var k=o(4848);function x(e){let{className:t,block:o,selectedValue:n,selectValue:r,tabValues:l}=e;const u=[],{blockElementScrollPositionUntilNextRender:c}=(0,s.a_)(),i=e=>{const t=e.currentTarget,o=u.indexOf(t),a=l[o].value;a!==n&&(c(t),r(a))},d=e=>{let t=null;switch(e.key){case"Enter":i(e);break;case"ArrowRight":{const o=u.indexOf(e.currentTarget)+1;t=u[o]??u[0];break}case"ArrowLeft":{const o=u.indexOf(e.currentTarget)-1;t=u[o]??u[u.length-1];break}}t?.focus()};return(0,k.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,a.A)("tabs",{"tabs--block":o},t),children:l.map((e=>{let{value:t,label:o,attributes:r}=e;return(0,k.jsx)("li",{role:"tab",tabIndex:n===t?0:-1,"aria-selected":n===t,ref:e=>u.push(e),onKeyDown:d,onClick:i,...r,className:(0,a.A)("tabs__item",v.tabItem,r?.className,{"tabs__item--active":n===t}),children:o??t},t)}))})}function y(e){let{lazy:t,children:o,selectedValue:r}=e;const s=(Array.isArray(o)?o:[o]).filter(Boolean);if(t){const e=s.find((e=>e.props.value===r));return e?(0,n.cloneElement)(e,{className:(0,a.A)("margin-top--md",e.props.className)}):null}return(0,k.jsx)("div",{className:"margin-top--md",children:s.map(((e,t)=>(0,n.cloneElement)(e,{key:t,hidden:e.props.value!==r})))})}function j(e){const t=f(e);return(0,k.jsxs)("div",{className:(0,a.A)("tabs-container",v.tabList),children:[(0,k.jsx)(x,{...t,...e}),(0,k.jsx)(y,{...t,...e})]})}function w(e){const t=(0,g.A)();return(0,k.jsx)(j,{...e,children:m(e.children)},String(t))}const I={tabItem:"tabItem_Ymn6"};function V(e){let{children:t,hidden:o,className:n}=e;return(0,k.jsx)("div",{role:"tabpanel",className:(0,a.A)(I.tabItem,n),hidden:o,children:t})}function A(e){let{file_name:t}=e;return(0,k.jsxs)(w,{children:[(0,k.jsx)(V,{value:t,children:(0,k.jsx)(r.A,{title:`https://github.com/mbecker20/komodo/blob/main/compose/${t}`,url:`https://raw.githubusercontent.com/mbecker20/komodo/main/compose/${t}`,language:"yaml"})}),(0,k.jsx)(V,{value:"compose.env",children:(0,k.jsx)(r.A,{title:"https://github.com/mbecker20/komodo/blob/main/compose/compose.env",url:"https://raw.githubusercontent.com/mbecker20/komodo/main/compose/compose.env",language:"bash"})})]})}},6695:(e,t,o)=>{o.d(t,{A:()=>s});var n=o(6540),r=o(1432),a=o(4848);function s(e){let{url:t,language:o,title:s}=e;const[l,u]=(0,n.useState)("");return(0,n.useEffect)((()=>{!async function(e,t){const o=await fetch(e);t(await o.text())}(t,u)}),[]),(0,a.jsx)(r.A,{title:s??t,language:o,showLineNumbers:!0,children:l})}}}]); \ No newline at end of file diff --git a/assets/js/c54f4afd.7b612d79.js b/assets/js/c54f4afd.7b612d79.js deleted file mode 100644 index 768e15802..000000000 --- a/assets/js/c54f4afd.7b612d79.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[846],{9728:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>a,contentTitle:()=>t,default:()=>h,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var r=n(4848),i=n(8453);const o={},t="Permissioning",l={id:"permissioning",title:"Permissioning",description:"Komodo has a granular, layer-based permissioning system to provide non-admin users access only to intended Resources.",source:"@site/docs/permissioning.md",sourceDirName:".",slug:"/permissioning",permalink:"/docs/permissioning",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/permissioning.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Procedures and Actions",permalink:"/docs/procedures"},next:{title:"Sync Resources",permalink:"/docs/sync-resources"}},a={},c=[{value:"User Groups",id:"user-groups",level:2},{value:"Permission Levels",id:"permission-levels",level:2},{value:"Global permissions",id:"global-permissions",level:2},{value:"Administration",id:"administration",level:2}];function d(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"permissioning",children:"Permissioning"})}),"\n",(0,r.jsx)(s.p,{children:"Komodo has a granular, layer-based permissioning system to provide non-admin users access only to intended Resources."}),"\n",(0,r.jsx)(s.h2,{id:"user-groups",children:"User Groups"}),"\n",(0,r.jsxs)(s.p,{children:["While Komodo can assign permissions to specific users directly, it is recommended to instead ",(0,r.jsx)(s.strong,{children:"create User Groups and assign permissions to them"}),", as if they were a user."]}),"\n",(0,r.jsxs)(s.p,{children:["Users can then be ",(0,r.jsx)(s.strong,{children:"added to multiple User Groups"})," and they ",(0,r.jsx)(s.strong,{children:"inherit the group's permissions"}),", similar to linux permissions."]}),"\n",(0,r.jsxs)(s.p,{children:["For permissioning at scale, users can define ",(0,r.jsx)(s.a,{href:"/docs/sync-resources#user-group",children:(0,r.jsx)(s.strong,{children:"User Groups in Resource Syncs"})}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"permission-levels",children:"Permission Levels"}),"\n",(0,r.jsx)(s.p,{children:"There are 4 permission levels a user / group can be given on a Resource:"}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"None"}),". The user will not have any access to the resource. The user ",(0,r.jsx)(s.strong,{children:"will not see it in the GUI, and it will not show up if the user queries the Komodo API directly"}),". All attempts to view or update the resource will be blocked. This is the default for non-admins, unless using ",(0,r.jsx)(s.code,{children:"KOMODO_TRANSPARENT_MODE=true"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Read"}),". This is the first permission level that grants any access. It will enable the user to ",(0,r.jsx)(s.strong,{children:"see the resource in the GUI, read the configuration, and see any logs"}),". Any attempts to update configuration or trigger any action ",(0,r.jsx)(s.strong,{children:"will be blocked"}),". Using ",(0,r.jsx)(s.code,{children:"KOMODO_TRANSPARENT_MODE=true"})," will make this level the base level on all resources, for all users."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Execute"}),". This level will allow the user to execute actions on the resource, ",(0,r.jsx)(s.strong,{children:"like send a build command"})," or ",(0,r.jsx)(s.strong,{children:"trigger a redeploy"}),". The user will still be blocked from updating configuration on the resource."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Write"}),". The user has full access to the resource, ",(0,r.jsx)(s.strong,{children:"they can execute any actions, update the configuration, and delete the resource"}),"."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"global-permissions",children:"Global permissions"}),"\n",(0,r.jsx)(s.p,{children:"Users or User Groups can be given a base permission level on all Resources of a particular type, such as Stack.\nIn TOML form, this looks like:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-toml",children:'[[user_group]]\nname = "groupo"\nusers = ["mbecker20", "karamvirsingh98"]\nall.Build = "Execute" # <- Group members can run all builds (but not update config),\nall.Stack = "Read" # <- And see all Stacks / logs (not deploy / update).\n'})}),"\n",(0,r.jsx)(s.p,{children:"A user / group can still be given a greater permission level on select resources:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-toml",children:'permissions = [\n { target.type = "Stack", target.id = "my-stack", level = "Execute" },\n # Use regex to match multiple resources, for example give john execute on all of their Stacks\n { target.type = "Stack", target.id = "\\\\^john-(.+)$\\\\", level = "Execute" },\n]\n'})}),"\n",(0,r.jsx)(s.h2,{id:"administration",children:"Administration"}),"\n",(0,r.jsxs)(s.p,{children:["Users can be given Admin priviledges by a ",(0,r.jsx)(s.code,{children:"Super Admin"})," (only the first user is given this status, set with ",(0,r.jsx)(s.code,{children:"super_admin: true"}),' on a User document in database). Super admins will see the "Make Admin" button when on a User page ',(0,r.jsx)(s.code,{children:"/users/${user_id}"}),"."]}),"\n",(0,r.jsx)(s.p,{children:"These users have unrestricted access to all Komodo Resources. Additionally, these users can update other (non-admin) user's permissions on resources."}),"\n",(0,r.jsxs)(s.p,{children:["Komodo admins are responsible for managing user accounts as well. When a user logs into Komodo for the first time, they will not immediately be granted access (this can changed with ",(0,r.jsx)(s.code,{children:"KOMODO_ENABLE_NEW_USERS=true"}),"). An admin must first ",(0,r.jsx)(s.strong,{children:"enable"})," the user, which can be done from the ",(0,r.jsx)(s.code,{children:"Users"})," tab on ",(0,r.jsx)(s.code,{children:"Settings"})," page. Users can also be ",(0,r.jsx)(s.strong,{children:"disabled"})," by an admin at any time, which blocks all their access to the GUI and API."]}),"\n",(0,r.jsx)(s.p,{children:"Users also have some configurable global permissions, these are:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"create server permission"}),"\n",(0,r.jsx)(s.li,{children:"create build permission"}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"Only users with these permissions (as well as admins) can add additional servers to Komodo, and can create additional builds, respectively."})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},8453:(e,s,n)=>{n.d(s,{R:()=>t,x:()=>l});var r=n(6540);const i={},o=r.createContext(i);function t(e){const s=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),r.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c54f4afd.8ec27e24.js b/assets/js/c54f4afd.8ec27e24.js new file mode 100644 index 000000000..a35815f9d --- /dev/null +++ b/assets/js/c54f4afd.8ec27e24.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[846],{9728:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>a,contentTitle:()=>t,default:()=>h,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var r=n(4848),i=n(8453);const o={},t="Permissioning",l={id:"permissioning",title:"Permissioning",description:"Komodo has a granular, layer-based permissioning system to provide non-admin users access only to intended Resources.",source:"@site/docs/permissioning.md",sourceDirName:".",slug:"/permissioning",permalink:"/docs/permissioning",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/permissioning.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Procedures and Actions",permalink:"/docs/procedures"},next:{title:"Sync Resources",permalink:"/docs/sync-resources"}},a={},c=[{value:"User Groups",id:"user-groups",level:2},{value:"Permission Levels",id:"permission-levels",level:2},{value:"Global permissions",id:"global-permissions",level:2},{value:"Administration",id:"administration",level:2}];function d(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"permissioning",children:"Permissioning"})}),"\n",(0,r.jsx)(s.p,{children:"Komodo has a granular, layer-based permissioning system to provide non-admin users access only to intended Resources."}),"\n",(0,r.jsx)(s.h2,{id:"user-groups",children:"User Groups"}),"\n",(0,r.jsxs)(s.p,{children:["While Komodo can assign permissions to specific users directly, it is recommended to instead ",(0,r.jsx)(s.strong,{children:"create User Groups and assign permissions to them"}),", as if they were a user."]}),"\n",(0,r.jsxs)(s.p,{children:["Users can then be ",(0,r.jsx)(s.strong,{children:"added to multiple User Groups"})," and they ",(0,r.jsx)(s.strong,{children:"inherit the group's permissions"}),", similar to linux permissions."]}),"\n",(0,r.jsxs)(s.p,{children:["For permissioning at scale, users can define ",(0,r.jsx)(s.a,{href:"/docs/sync-resources#user-group",children:(0,r.jsx)(s.strong,{children:"User Groups in Resource Syncs"})}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"permission-levels",children:"Permission Levels"}),"\n",(0,r.jsx)(s.p,{children:"There are 4 permission levels a user / group can be given on a Resource:"}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"None"}),". The user will not have any access to the resource. The user ",(0,r.jsx)(s.strong,{children:"will not see it in the GUI, and it will not show up if the user queries the Komodo API directly"}),". All attempts to view or update the resource will be blocked. This is the default for non-admins, unless using ",(0,r.jsx)(s.code,{children:"KOMODO_TRANSPARENT_MODE=true"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Read"}),". This is the first permission level that grants any access. It will enable the user to ",(0,r.jsx)(s.strong,{children:"see the resource in the GUI, read the configuration, and see any logs"}),". Any attempts to update configuration or trigger any action ",(0,r.jsx)(s.strong,{children:"will be blocked"}),". Using ",(0,r.jsx)(s.code,{children:"KOMODO_TRANSPARENT_MODE=true"})," will make this level the base level on all resources, for all users."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Execute"}),". This level will allow the user to execute actions on the resource, ",(0,r.jsx)(s.strong,{children:"like send a build command"})," or ",(0,r.jsx)(s.strong,{children:"trigger a redeploy"}),". The user will still be blocked from updating configuration on the resource."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.strong,{children:"Write"}),". The user has full access to the resource, ",(0,r.jsx)(s.strong,{children:"they can execute any actions, update the configuration, and delete the resource"}),"."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"global-permissions",children:"Global permissions"}),"\n",(0,r.jsx)(s.p,{children:"Users or User Groups can be given a base permission level on all Resources of a particular type, such as Stack.\nIn TOML form, this looks like:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-toml",children:'[[user_group]]\nname = "groupo"\nusers = ["mbecker20", "karamvirsingh98"]\nall.Build = "Execute" # <- Group members can run all builds (but not update config),\nall.Stack = "Read" # <- And see all Stacks / logs (not deploy / update).\n'})}),"\n",(0,r.jsx)(s.p,{children:"A user / group can still be given a greater permission level on select resources:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-toml",children:'permissions = [\n { target.type = "Stack", target.id = "my-stack", level = "Execute" },\n # Use regex to match multiple resources, for example give john execute on all of their Stacks\n { target.type = "Stack", target.id = "\\\\^john-(.+)$\\\\", level = "Execute" },\n]\n'})}),"\n",(0,r.jsx)(s.h2,{id:"administration",children:"Administration"}),"\n",(0,r.jsxs)(s.p,{children:["Users can be given Admin priviledges by a ",(0,r.jsx)(s.code,{children:"Super Admin"})," (only the first user is given this status, set with ",(0,r.jsx)(s.code,{children:"super_admin: true"}),' on a User document in database). Super admins will see the "Make Admin" button when on a User page ',(0,r.jsx)(s.code,{children:"/users/${user_id}"}),"."]}),"\n",(0,r.jsx)(s.p,{children:"These users have unrestricted access to all Komodo Resources. Additionally, these users can update other (non-admin) user's permissions on resources."}),"\n",(0,r.jsxs)(s.p,{children:["Komodo admins are responsible for managing user accounts as well. When a user logs into Komodo for the first time, they will not immediately be granted access (this can changed with ",(0,r.jsx)(s.code,{children:"KOMODO_ENABLE_NEW_USERS=true"}),"). An admin must first ",(0,r.jsx)(s.strong,{children:"enable"})," the user, which can be done from the ",(0,r.jsx)(s.code,{children:"Users"})," tab on ",(0,r.jsx)(s.code,{children:"Settings"})," page. Users can also be ",(0,r.jsx)(s.strong,{children:"disabled"})," by an admin at any time, which blocks all their access to the GUI and API."]}),"\n",(0,r.jsx)(s.p,{children:"Users also have some configurable global permissions, these are:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"create server permission"}),"\n",(0,r.jsx)(s.li,{children:"create build permission"}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"Only users with these permissions (as well as admins) can add additional servers to Komodo, and can create additional builds, respectively."})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},8453:(e,s,n)=>{n.d(s,{R:()=>t,x:()=>l});var r=n(6540);const i={},o=r.createContext(i);function t(e){const s=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),r.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c65a6c17.23532b2a.js b/assets/js/c65a6c17.23532b2a.js deleted file mode 100644 index ac3bc3a72..000000000 --- a/assets/js/c65a6c17.23532b2a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[543],{1527:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>t,default:()=>u,frontMatter:()=>r,metadata:()=>d,toc:()=>l});var o=i(4848),s=i(8453);const r={},t="Pre-build command",d={id:"build-images/pre-build",title:"Pre-build command",description:"Sometimes a command needs to be run before running `docker build`, you can configure this in the pre build section.",source:"@site/docs/build-images/pre-build.md",sourceDirName:"build-images",slug:"/build-images/pre-build",permalink:"/docs/build-images/pre-build",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/build-images/pre-build.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Configuration",permalink:"/docs/build-images/configuration"},next:{title:"Builders",permalink:"/docs/build-images/builders"}},c={},l=[];function a(e){const n={code:"code",em:"em",h1:"h1",header:"header",p:"p",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"pre-build-command",children:"Pre-build command"})}),"\n",(0,o.jsxs)(n.p,{children:["Sometimes a command needs to be run before running ",(0,o.jsx)(n.code,{children:"docker build"}),", you can configure this in the ",(0,o.jsx)(n.em,{children:"pre build"})," section."]}),"\n",(0,o.jsxs)(n.p,{children:["There are two fields to pass for ",(0,o.jsx)(n.em,{children:"pre build"}),". the first is ",(0,o.jsx)(n.em,{children:"path"}),", which changes the working directory. To run the command in the root of the repo, just pass ",(0,o.jsx)(n.code,{children:"."}),". The second field is ",(0,o.jsx)(n.em,{children:"command"}),", this is the shell command to be executed after the repo is cloned."]}),"\n",(0,o.jsxs)(n.p,{children:["For example, say your repo had a folder in it called ",(0,o.jsx)(n.code,{children:"scripts"})," with a shell script ",(0,o.jsx)(n.code,{children:"on-clone.sh"}),". You would give ",(0,o.jsx)(n.em,{children:"path"})," as ",(0,o.jsx)(n.code,{children:"scripts"})," and command as ",(0,o.jsx)(n.code,{children:"sh on-clone.sh"}),". Or you could make ",(0,o.jsx)(n.em,{children:"path"})," just ",(0,o.jsx)(n.code,{children:"."})," and then the command would be ",(0,o.jsx)(n.code,{children:"sh scripts/on-clone.sh"}),". Either way works fine."]})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(a,{...e})}):a(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>t,x:()=>d});var o=i(6540);const s={},r=o.createContext(s);function t(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:t(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c65a6c17.3effb77f.js b/assets/js/c65a6c17.3effb77f.js new file mode 100644 index 000000000..20b40fd74 --- /dev/null +++ b/assets/js/c65a6c17.3effb77f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[543],{1527:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>u,frontMatter:()=>t,metadata:()=>d,toc:()=>l});var o=i(4848),s=i(8453);const t={},r="Pre-build command",d={id:"build-images/pre-build",title:"Pre-build command",description:"Sometimes a command needs to be run before running `docker build`, you can configure this in the pre build section.",source:"@site/docs/build-images/pre-build.md",sourceDirName:"build-images",slug:"/build-images/pre-build",permalink:"/docs/build-images/pre-build",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/build-images/pre-build.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Configuration",permalink:"/docs/build-images/configuration"},next:{title:"Builders",permalink:"/docs/build-images/builders"}},c={},l=[];function a(e){const n={code:"code",em:"em",h1:"h1",header:"header",p:"p",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"pre-build-command",children:"Pre-build command"})}),"\n",(0,o.jsxs)(n.p,{children:["Sometimes a command needs to be run before running ",(0,o.jsx)(n.code,{children:"docker build"}),", you can configure this in the ",(0,o.jsx)(n.em,{children:"pre build"})," section."]}),"\n",(0,o.jsxs)(n.p,{children:["There are two fields to pass for ",(0,o.jsx)(n.em,{children:"pre build"}),". the first is ",(0,o.jsx)(n.em,{children:"path"}),", which changes the working directory. To run the command in the root of the repo, just pass ",(0,o.jsx)(n.code,{children:"."}),". The second field is ",(0,o.jsx)(n.em,{children:"command"}),", this is the shell command to be executed after the repo is cloned."]}),"\n",(0,o.jsxs)(n.p,{children:["For example, say your repo had a folder in it called ",(0,o.jsx)(n.code,{children:"scripts"})," with a shell script ",(0,o.jsx)(n.code,{children:"on-clone.sh"}),". You would give ",(0,o.jsx)(n.em,{children:"path"})," as ",(0,o.jsx)(n.code,{children:"scripts"})," and command as ",(0,o.jsx)(n.code,{children:"sh on-clone.sh"}),". Or you could make ",(0,o.jsx)(n.em,{children:"path"})," just ",(0,o.jsx)(n.code,{children:"."})," and then the command would be ",(0,o.jsx)(n.code,{children:"sh scripts/on-clone.sh"}),". Either way works fine."]})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(a,{...e})}):a(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>d});var o=i(6540);const s={},t=o.createContext(s);function r(e){const n=o.useContext(t);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d92a3c43.b9562b20.js b/assets/js/d92a3c43.b9562b20.js deleted file mode 100644 index 37a0c336c..000000000 --- a/assets/js/d92a3c43.b9562b20.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[864],{5804:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>t,toc:()=>d});var s=r(4848),i=r(8453);const o={},l="Resources",t={id:"resources",title:"Resources",description:"Komodo is extendible through the Resource abstraction. Entities like Server, Deployment, and Stack are all Komodo Resources.",source:"@site/docs/resources.md",sourceDirName:".",slug:"/resources",permalink:"/docs/resources",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/resources.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"What is Komodo?",permalink:"/docs/intro"},next:{title:"Setup Komodo",permalink:"/docs/setup/"}},c={},d=[{value:"Server",id:"server",level:2},{value:"Deployment",id:"deployment",level:2},{value:"Stack",id:"stack",level:2},{value:"Repo",id:"repo",level:2},{value:"Build",id:"build",level:2},{value:"Builder",id:"builder",level:2},{value:"Procedure",id:"procedure",level:2},{value:"Action",id:"action",level:2},{value:"ResourceSync",id:"resourcesync",level:2},{value:"Alerter",id:"alerter",level:2},{value:"ServerTemplate",id:"servertemplate",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"resources",children:"Resources"})}),"\n",(0,s.jsxs)(n.p,{children:["Komodo is extendible through the ",(0,s.jsx)(n.strong,{children:"Resource"})," abstraction. Entities like ",(0,s.jsx)(n.code,{children:"Server"}),", ",(0,s.jsx)(n.code,{children:"Deployment"}),", and ",(0,s.jsx)(n.code,{children:"Stack"})," are all ",(0,s.jsx)(n.strong,{children:"Komodo Resources"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["All resources have common traits, such as a unique ",(0,s.jsx)(n.code,{children:"name"})," and ",(0,s.jsx)(n.code,{children:"id"})," amongst all other resources of the same resource type.\nAll resources can be assigned ",(0,s.jsx)(n.code,{children:"tags"}),", which can be used to group related resources."]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsx)(n.p,{children:"Many resources need access to git repos / docker registries. There is an in-built token management system (managed in UI or in config file) to give resources access to credentials.\nAll resources which depend on git repos / docker registries are able to use these credentials to access private repos."})}),"\n",(0,s.jsx)(n.h2,{id:"server",children:"Server"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Configure the connection to periphery agents."}),"\n",(0,s.jsx)(n.li,{children:"Set alerting thresholds."}),"\n",(0,s.jsxs)(n.li,{children:["Can be attached to by ",(0,s.jsx)(n.strong,{children:"Deployments"}),", ",(0,s.jsx)(n.strong,{children:"Stacks"}),", ",(0,s.jsx)(n.strong,{children:"Repos"}),", and ",(0,s.jsx)(n.strong,{children:"Builders"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"deployment",children:"Deployment"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Deploy a docker container on the attached Server."}),"\n",(0,s.jsxs)(n.li,{children:["Manage services at the container level, perform orchestration using ",(0,s.jsx)(n.strong,{children:"Procedures"})," and ",(0,s.jsx)(n.strong,{children:"ResourceSyncs"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"stack",children:"Stack"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Deploy with docker compose."}),"\n",(0,s.jsx)(n.li,{children:"Provide the compose file in UI, or move the files to a git repo and use a webhook for auto redeploy on push."}),"\n",(0,s.jsxs)(n.li,{children:["Supports composing multiple compose files using ",(0,s.jsx)(n.code,{children:"docker compose -f ... -f ..."}),"."]}),"\n",(0,s.jsx)(n.li,{children:"Pass environment variables usable within the compose file. Interpolate in app-wide variables / secrets."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"repo",children:"Repo"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Put scripts in git repos, and run them on a Server, or using a Builder."}),"\n",(0,s.jsx)(n.li,{children:"Can build binaries, perform automation, really whatever you can think of."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"build",children:"Build"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Build application source into docker images, and push them to the configured registry."}),"\n",(0,s.jsx)(n.li,{children:"The source can be any git repo containing a Dockerfile."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"builder",children:"Builder"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Either points to a connected server, or holds configuration to launch a single-use AWS instance to build the image."}),"\n",(0,s.jsxs)(n.li,{children:["Can be attached to ",(0,s.jsx)(n.strong,{children:"Builds"})," and ",(0,s.jsx)(n.strong,{children:"Repos"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"procedure",children:"Procedure"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Compose many actions on other resource type, like ",(0,s.jsx)(n.code,{children:"RunBuild"})," or ",(0,s.jsx)(n.code,{children:"DeployStack"}),", and run it on button push (or with a webhook)."]}),"\n",(0,s.jsx)(n.li,{children:'Can run one or more actions in parallel "stages", and compose a series of parallel stages to run sequentially.'}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"action",children:"Action"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Write scripts calling the Komodo API in Typescript"}),"\n",(0,s.jsx)(n.li,{children:"Use a pre-initialized Komodo client within the script, no api keys necessary."}),"\n",(0,s.jsx)(n.li,{children:"Type aware in UI editor. Get suggestions and see in depth docs as you type."}),"\n",(0,s.jsxs)(n.li,{children:["The Typescript client is also ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/package/komodo_client",children:"published on NPM"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"resourcesync",children:"ResourceSync"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Orchestrate all your configuration declaratively by defining it in ",(0,s.jsx)(n.code,{children:"toml"})," files, which are checked into a git repo."]}),"\n",(0,s.jsxs)(n.li,{children:["Can deploy ",(0,s.jsx)(n.strong,{children:"Deployments"})," and ",(0,s.jsx)(n.strong,{children:"Stacks"})," if changes are suggested."]}),"\n",(0,s.jsxs)(n.li,{children:["Specify deploy ordering with ",(0,s.jsx)(n.code,{children:"after"})," array. (like docker compose ",(0,s.jsx)(n.code,{children:"depends_on"})," but can span across servers.)."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"alerter",children:"Alerter"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Route alerts to various endpoints."}),"\n",(0,s.jsx)(n.li,{children:"Can configure rules on each Alerter, such as resource whitelist, blacklist, or alert type filter."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"servertemplate",children:"ServerTemplate"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Easily expand your cloud network by storing cloud server lauch templates on various providers."}),"\n",(0,s.jsxs)(n.li,{children:["Auto connect the server to Komodo on launch, using ",(0,s.jsx)(n.code,{children:"User Data"})," launch scripts."]}),"\n",(0,s.jsxs)(n.li,{children:["Currently supports ",(0,s.jsx)(n.strong,{children:"AWS EC2"})," and ",(0,s.jsx)(n.strong,{children:"Hetzner"})]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},8453:(e,n,r)=>{r.d(n,{R:()=>l,x:()=>t});var s=r(6540);const i={},o=s.createContext(i);function l(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:l(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d92a3c43.ed48ad6d.js b/assets/js/d92a3c43.ed48ad6d.js new file mode 100644 index 000000000..32b02bf68 --- /dev/null +++ b/assets/js/d92a3c43.ed48ad6d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[864],{5804:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>t,toc:()=>d});var s=r(4848),i=r(8453);const o={},l="Resources",t={id:"resources",title:"Resources",description:"Komodo is extendible through the Resource abstraction. Entities like Server, Deployment, and Stack are all Komodo Resources.",source:"@site/docs/resources.md",sourceDirName:".",slug:"/resources",permalink:"/docs/resources",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/resources.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"What is Komodo?",permalink:"/docs/intro"},next:{title:"Setup Komodo",permalink:"/docs/setup/"}},c={},d=[{value:"Server",id:"server",level:2},{value:"Deployment",id:"deployment",level:2},{value:"Stack",id:"stack",level:2},{value:"Repo",id:"repo",level:2},{value:"Build",id:"build",level:2},{value:"Builder",id:"builder",level:2},{value:"Procedure",id:"procedure",level:2},{value:"Action",id:"action",level:2},{value:"ResourceSync",id:"resourcesync",level:2},{value:"Alerter",id:"alerter",level:2},{value:"ServerTemplate",id:"servertemplate",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"resources",children:"Resources"})}),"\n",(0,s.jsxs)(n.p,{children:["Komodo is extendible through the ",(0,s.jsx)(n.strong,{children:"Resource"})," abstraction. Entities like ",(0,s.jsx)(n.code,{children:"Server"}),", ",(0,s.jsx)(n.code,{children:"Deployment"}),", and ",(0,s.jsx)(n.code,{children:"Stack"})," are all ",(0,s.jsx)(n.strong,{children:"Komodo Resources"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["All resources have common traits, such as a unique ",(0,s.jsx)(n.code,{children:"name"})," and ",(0,s.jsx)(n.code,{children:"id"})," amongst all other resources of the same resource type.\nAll resources can be assigned ",(0,s.jsx)(n.code,{children:"tags"}),", which can be used to group related resources."]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsx)(n.p,{children:"Many resources need access to git repos / docker registries. There is an in-built token management system (managed in UI or in config file) to give resources access to credentials.\nAll resources which depend on git repos / docker registries are able to use these credentials to access private repos."})}),"\n",(0,s.jsx)(n.h2,{id:"server",children:"Server"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Configure the connection to periphery agents."}),"\n",(0,s.jsx)(n.li,{children:"Set alerting thresholds."}),"\n",(0,s.jsxs)(n.li,{children:["Can be attached to by ",(0,s.jsx)(n.strong,{children:"Deployments"}),", ",(0,s.jsx)(n.strong,{children:"Stacks"}),", ",(0,s.jsx)(n.strong,{children:"Repos"}),", and ",(0,s.jsx)(n.strong,{children:"Builders"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"deployment",children:"Deployment"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Deploy a docker container on the attached Server."}),"\n",(0,s.jsxs)(n.li,{children:["Manage services at the container level, perform orchestration using ",(0,s.jsx)(n.strong,{children:"Procedures"})," and ",(0,s.jsx)(n.strong,{children:"ResourceSyncs"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"stack",children:"Stack"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Deploy with docker compose."}),"\n",(0,s.jsx)(n.li,{children:"Provide the compose file in UI, or move the files to a git repo and use a webhook for auto redeploy on push."}),"\n",(0,s.jsxs)(n.li,{children:["Supports composing multiple compose files using ",(0,s.jsx)(n.code,{children:"docker compose -f ... -f ..."}),"."]}),"\n",(0,s.jsx)(n.li,{children:"Pass environment variables usable within the compose file. Interpolate in app-wide variables / secrets."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"repo",children:"Repo"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Put scripts in git repos, and run them on a Server, or using a Builder."}),"\n",(0,s.jsx)(n.li,{children:"Can build binaries, perform automation, really whatever you can think of."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"build",children:"Build"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Build application source into docker images, and push them to the configured registry."}),"\n",(0,s.jsx)(n.li,{children:"The source can be any git repo containing a Dockerfile."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"builder",children:"Builder"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Either points to a connected server, or holds configuration to launch a single-use AWS instance to build the image."}),"\n",(0,s.jsxs)(n.li,{children:["Can be attached to ",(0,s.jsx)(n.strong,{children:"Builds"})," and ",(0,s.jsx)(n.strong,{children:"Repos"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"procedure",children:"Procedure"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Compose many actions on other resource type, like ",(0,s.jsx)(n.code,{children:"RunBuild"})," or ",(0,s.jsx)(n.code,{children:"DeployStack"}),", and run it on button push (or with a webhook)."]}),"\n",(0,s.jsx)(n.li,{children:'Can run one or more actions in parallel "stages", and compose a series of parallel stages to run sequentially.'}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"action",children:"Action"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Write scripts calling the Komodo API in Typescript"}),"\n",(0,s.jsx)(n.li,{children:"Use a pre-initialized Komodo client within the script, no api keys necessary."}),"\n",(0,s.jsx)(n.li,{children:"Type aware in UI editor. Get suggestions and see in depth docs as you type."}),"\n",(0,s.jsxs)(n.li,{children:["The Typescript client is also ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/package/komodo_client",children:"published on NPM"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"resourcesync",children:"ResourceSync"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Orchestrate all your configuration declaratively by defining it in ",(0,s.jsx)(n.code,{children:"toml"})," files, which are checked into a git repo."]}),"\n",(0,s.jsxs)(n.li,{children:["Can deploy ",(0,s.jsx)(n.strong,{children:"Deployments"})," and ",(0,s.jsx)(n.strong,{children:"Stacks"})," if changes are suggested."]}),"\n",(0,s.jsxs)(n.li,{children:["Specify deploy ordering with ",(0,s.jsx)(n.code,{children:"after"})," array. (like docker compose ",(0,s.jsx)(n.code,{children:"depends_on"})," but can span across servers.)."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"alerter",children:"Alerter"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Route alerts to various endpoints."}),"\n",(0,s.jsx)(n.li,{children:"Can configure rules on each Alerter, such as resource whitelist, blacklist, or alert type filter."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"servertemplate",children:"ServerTemplate"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Easily expand your cloud network by storing cloud server lauch templates on various providers."}),"\n",(0,s.jsxs)(n.li,{children:["Auto connect the server to Komodo on launch, using ",(0,s.jsx)(n.code,{children:"User Data"})," launch scripts."]}),"\n",(0,s.jsxs)(n.li,{children:["Currently supports ",(0,s.jsx)(n.strong,{children:"AWS EC2"})," and ",(0,s.jsx)(n.strong,{children:"Hetzner"})]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},8453:(e,n,r)=>{r.d(n,{R:()=>l,x:()=>t});var s=r(6540);const i={},o=s.createContext(i);function l(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:l(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ef1bbce5.90ebefc8.js b/assets/js/ef1bbce5.90ebefc8.js new file mode 100644 index 000000000..2d96af856 --- /dev/null +++ b/assets/js/ef1bbce5.90ebefc8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[100],{8151:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>u,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var t=i(4848),r=i(8453);const s={},o="Builders",a={id:"build-images/builders",title:"Builders",description:"A builder is a machine running the Komodo Periphery agent (and usually docker), which is able to handle a RunBuild / BuildRepo command from Komodo core. Any server connected to Komodo can be chosen as the builder for a build.",source:"@site/docs/build-images/builders.md",sourceDirName:"build-images",slug:"/build-images/builders",permalink:"/docs/build-images/builders",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/build-images/builders.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Pre-build command",permalink:"/docs/build-images/pre-build"},next:{title:"Image Versioning",permalink:"/docs/build-images/versioning"}},d={},c=[{value:"AWS builder",id:"aws-builder",level:2},{value:"Setup the instance",id:"setup-the-instance",level:3},{value:"Make an AMI from the instance",id:"make-an-ami-from-the-instance",level:3},{value:"Configure security groups / firewall",id:"configure-security-groups--firewall",level:3}];function l(e){const n={admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"builders",children:"Builders"})}),"\n",(0,t.jsx)(n.p,{children:"A builder is a machine running the Komodo Periphery agent (and usually docker), which is able to handle a RunBuild / BuildRepo command from Komodo core. Any server connected to Komodo can be chosen as the builder for a build."}),"\n",(0,t.jsx)(n.p,{children:"Building on a machine running production software is usually not a great idea, as this process can use a lot of system resources. It is better to start up a temporary cloud machine dedicated for the build, then shut it down when the build is finished. Komodo supports AWS EC2 for this task."}),"\n",(0,t.jsx)(n.h2,{id:"aws-builder",children:"AWS builder"}),"\n",(0,t.jsx)(n.p,{children:"Builders are now Komodo resources, and are managed via the core API / can be updated using the UI.\nTo use this feature, you need an AWS EC2 AMI with docker and Komodo Periphery configured to run on system start.\nOnce you create your builder and add the necessary configuration, it will be available to attach to builds."}),"\n",(0,t.jsx)(n.h3,{id:"setup-the-instance",children:"Setup the instance"}),"\n",(0,t.jsx)(n.p,{children:"Create an EC2 instance, and install Docker and Periphery on it."}),"\n",(0,t.jsx)(n.p,{children:"The following script is an example of installing Docker and Periphery onto a Ubuntu/Debian instance:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:"#!/bin/bash\napt update\napt upgrade -y\ncurl -fsSL https://get.docker.com | sh\nsystemctl enable docker.service\nsystemctl enable containerd.service\ncurl -sSL https://raw.githubusercontent.com/moghtech/komodo/main/scripts/setup-periphery.py | HOME=/root python3\nsystemctl enable periphery.service\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:'AWS provides a "user data" feature, which will run a provided script as root. The above can be used with AWS user data\nto provide a hands free setup.'})}),"\n",(0,t.jsx)(n.h3,{id:"make-an-ami-from-the-instance",children:"Make an AMI from the instance"}),"\n",(0,t.jsx)(n.p,{children:"Once the instance is up and running, ssh in and confirm Periphery is running using:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:"sudo systemctl status periphery.service\n"})}),"\n",(0,t.jsx)(n.p,{children:"If it is not, the install hasn't finished and you should wait a bit. It may take 5 minutes or more (all in updating / installing Docker, Periphery is just a 12 MB binary to download)."}),"\n",(0,t.jsxs)(n.p,{children:["Once Periphery is running, you can navigate to the instance in the AWS UI and choose ",(0,t.jsx)(n.code,{children:"Actions"})," -> ",(0,t.jsx)(n.code,{children:"Image and templates"})," -> ",(0,t.jsx)(n.code,{children:"Create image"}),". Just name the image and hit create."]}),"\n",(0,t.jsxs)(n.p,{children:["The AMI will provide a unique id starting with ",(0,t.jsx)(n.code,{children:"ami-"}),", use this with the builder configuration."]}),"\n",(0,t.jsx)(n.h3,{id:"configure-security-groups--firewall",children:"Configure security groups / firewall"}),"\n",(0,t.jsx)(n.p,{children:"The builders will need inbound access on port 8120 from Komodo Core, be sure to add a security group with this rule to the Builder configuration."})]})}function u(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>a});var t=i(6540);const r={},s=t.createContext(r);function o(e){const n=t.useContext(s);return t.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(r):e.components||r:o(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ef1bbce5.a58422fb.js b/assets/js/ef1bbce5.a58422fb.js deleted file mode 100644 index 68ab11f75..000000000 --- a/assets/js/ef1bbce5.a58422fb.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[100],{8151:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>u,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var t=i(4848),r=i(8453);const s={},o="Builders",a={id:"build-images/builders",title:"Builders",description:"A builder is a machine running the Komodo Periphery agent (and usually docker), which is able to handle a RunBuild / BuildRepo command from Komodo core. Any server connected to Komodo can be chosen as the builder for a build.",source:"@site/docs/build-images/builders.md",sourceDirName:"build-images",slug:"/build-images/builders",permalink:"/docs/build-images/builders",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/build-images/builders.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Pre-build command",permalink:"/docs/build-images/pre-build"},next:{title:"Image Versioning",permalink:"/docs/build-images/versioning"}},d={},c=[{value:"AWS builder",id:"aws-builder",level:2},{value:"Setup the instance",id:"setup-the-instance",level:3},{value:"Make an AMI from the instance",id:"make-an-ami-from-the-instance",level:3},{value:"Configure security groups / firewall",id:"configure-security-groups--firewall",level:3}];function l(e){const n={admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"builders",children:"Builders"})}),"\n",(0,t.jsx)(n.p,{children:"A builder is a machine running the Komodo Periphery agent (and usually docker), which is able to handle a RunBuild / BuildRepo command from Komodo core. Any server connected to Komodo can be chosen as the builder for a build."}),"\n",(0,t.jsx)(n.p,{children:"Building on a machine running production software is usually not a great idea, as this process can use a lot of system resources. It is better to start up a temporary cloud machine dedicated for the build, then shut it down when the build is finished. Komodo supports AWS EC2 for this task."}),"\n",(0,t.jsx)(n.h2,{id:"aws-builder",children:"AWS builder"}),"\n",(0,t.jsx)(n.p,{children:"Builders are now Komodo resources, and are managed via the core API / can be updated using the UI.\nTo use this feature, you need an AWS EC2 AMI with docker and Komodo Periphery configured to run on system start.\nOnce you create your builder and add the necessary configuration, it will be available to attach to builds."}),"\n",(0,t.jsx)(n.h3,{id:"setup-the-instance",children:"Setup the instance"}),"\n",(0,t.jsx)(n.p,{children:"Create an EC2 instance, and install Docker and Periphery on it."}),"\n",(0,t.jsx)(n.p,{children:"The following script is an example of installing Docker and Periphery onto a Ubuntu/Debian instance:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:"#!/bin/bash\napt update\napt upgrade -y\ncurl -fsSL https://get.docker.com | sh\nsystemctl enable docker.service\nsystemctl enable containerd.service\ncurl -sSL https://raw.githubusercontent.com/mbecker20/komodo/main/scripts/setup-periphery.py | HOME=/root python3\nsystemctl enable periphery.service\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:'AWS provides a "user data" feature, which will run a provided script as root. The above can be used with AWS user data\nto provide a hands free setup.'})}),"\n",(0,t.jsx)(n.h3,{id:"make-an-ami-from-the-instance",children:"Make an AMI from the instance"}),"\n",(0,t.jsx)(n.p,{children:"Once the instance is up and running, ssh in and confirm Periphery is running using:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:"sudo systemctl status periphery.service\n"})}),"\n",(0,t.jsx)(n.p,{children:"If it is not, the install hasn't finished and you should wait a bit. It may take 5 minutes or more (all in updating / installing Docker, Periphery is just a 12 MB binary to download)."}),"\n",(0,t.jsxs)(n.p,{children:["Once Periphery is running, you can navigate to the instance in the AWS UI and choose ",(0,t.jsx)(n.code,{children:"Actions"})," -> ",(0,t.jsx)(n.code,{children:"Image and templates"})," -> ",(0,t.jsx)(n.code,{children:"Create image"}),". Just name the image and hit create."]}),"\n",(0,t.jsxs)(n.p,{children:["The AMI will provide a unique id starting with ",(0,t.jsx)(n.code,{children:"ami-"}),", use this with the builder configuration."]}),"\n",(0,t.jsx)(n.h3,{id:"configure-security-groups--firewall",children:"Configure security groups / firewall"}),"\n",(0,t.jsx)(n.p,{children:"The builders will need inbound access on port 8120 from Komodo Core, be sure to add a security group with this rule to the Builder configuration."})]})}function u(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>a});var t=i(6540);const r={},s=t.createContext(r);function o(e){const n=t.useContext(s);return t.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(r):e.components||r:o(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ef526b88.d9bb270f.js b/assets/js/ef526b88.d9bb270f.js new file mode 100644 index 000000000..fd9297c6a --- /dev/null +++ b/assets/js/ef526b88.d9bb270f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[995],{9302:(e,o,n)=>{n.r(o),n.d(o,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var t=n(4848),i=n(8453);const r={},s="Configuration",a={id:"deploy-containers/configuration",title:"Configuration",description:"Choose the docker image",source:"@site/docs/deploy-containers/configuration.md",sourceDirName:"deploy-containers",slug:"/deploy-containers/configuration",permalink:"/docs/deploy-containers/configuration",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/deploy-containers/configuration.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Deploy Containers",permalink:"/docs/deploy-containers/"},next:{title:"Container Management",permalink:"/docs/deploy-containers/lifetime-management"}},c={},d=[{value:"Choose the docker image",id:"choose-the-docker-image",level:2},{value:"Attaching a Komodo build",id:"attaching-a-komodo-build",level:3},{value:"Using a custom image",id:"using-a-custom-image",level:3},{value:"Configuring the network",id:"configuring-the-network",level:2},{value:"Configuring restart behavior",id:"configuring-restart-behavior",level:2},{value:"Configuring environment variables",id:"configuring-environment-variables",level:2},{value:"Configuring volumes",id:"configuring-volumes",level:2},{value:"Extra args",id:"extra-args",level:2},{value:"Command",id:"command",level:2}];function l(e){const o={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(o.header,{children:(0,t.jsx)(o.h1,{id:"configuration",children:"Configuration"})}),"\n",(0,t.jsx)(o.h2,{id:"choose-the-docker-image",children:"Choose the docker image"}),"\n",(0,t.jsx)(o.p,{children:"There are two options to configure the docker image to deploy."}),"\n",(0,t.jsx)(o.h3,{id:"attaching-a-komodo-build",children:"Attaching a Komodo build"}),"\n",(0,t.jsx)(o.p,{children:"If the software you want to deploy is built by Komodo, you can attach the build directly to the deployment."}),"\n",(0,t.jsx)(o.p,{children:"By default, Komodo will deploy the latest available version of the build, or you can specify a specific version using the version dropdown."}),"\n",(0,t.jsx)(o.p,{children:"Also by default, Komodo will use the same docker account that is attached to the build in order to pull the image on the periphery server. If that account is not available on the server, you can specify another available account to use instead, this account just needs to have read access to the docker repository."}),"\n",(0,t.jsx)(o.h3,{id:"using-a-custom-image",children:"Using a custom image"}),"\n",(0,t.jsxs)(o.p,{children:["You can also manually specify an image name, like ",(0,t.jsx)(o.code,{children:"mongo"})," or ",(0,t.jsx)(o.code,{children:"ghcr.io/mbecker20/random_image:0.1.1"}),"."]}),"\n",(0,t.jsx)(o.p,{children:"If the image repository is private, you can still select an available docker account to use to pull the image."}),"\n",(0,t.jsx)(o.h2,{id:"configuring-the-network",children:"Configuring the network"}),"\n",(0,t.jsxs)(o.p,{children:["One feature of docker is that it allows for the creation of ",(0,t.jsx)(o.a,{href:"https://docs.docker.com/network/",children:"virtual networks between containers"}),". Komodo allows you to specify a docker virtual network to connect the container to, or to use the host system networking to bypass the docker virtual network."]}),"\n",(0,t.jsxs)(o.p,{children:["The default selection is ",(0,t.jsx)(o.code,{children:"host"}),", which bypasses the docker virtual network layer."]}),"\n",(0,t.jsx)(o.p,{children:"If you do select select a network other than host, you can specify port bindings with the GUI. For example, if you are running mongo (which defaults to port 27017), you could use the mapping:"}),"\n",(0,t.jsx)(o.pre,{children:(0,t.jsx)(o.code,{children:"27018 : 27017\n"})}),"\n",(0,t.jsxs)(o.p,{children:["In this case, you would access mongo from outside of the container on port ",(0,t.jsx)(o.code,{children:"27018"}),"."]}),"\n",(0,t.jsxs)(o.p,{children:["Note that this is not the only affect of using a network other than ",(0,t.jsx)(o.code,{children:"host"}),". For example, containers running on different networks can not communicate, and ones on the same network can not reach other containers on ",(0,t.jsx)(o.code,{children:"localhost"})," even when they are running on the same system. This behavior can be a bit confusing if you are not familiar with it, and it can be bypassed entirely by just using ",(0,t.jsx)(o.code,{children:"host"})," network."]}),"\n",(0,t.jsx)(o.h2,{id:"configuring-restart-behavior",children:"Configuring restart behavior"}),"\n",(0,t.jsxs)(o.p,{children:["Docker, like systemd, has a couple options for handling when a container exits. See ",(0,t.jsx)(o.a,{href:"https://docs.docker.com/config/containers/start-containers-automatically/",children:"docker restart policies"}),". Komodo allows you to select the appropriate restart behavior from these options."]}),"\n",(0,t.jsx)(o.h2,{id:"configuring-environment-variables",children:"Configuring environment variables"}),"\n",(0,t.jsx)(o.p,{children:"Komodo enables you to easily manage environment variables passed to the container.\nIn the GUI, navigate to the environment tab of the configuration on the deployment page."}),"\n",(0,t.jsxs)(o.p,{children:["You pass environment variables just as you would with a ",(0,t.jsx)(o.code,{children:".env"})," file:"]}),"\n",(0,t.jsx)(o.pre,{children:(0,t.jsx)(o.code,{children:"ENV_VAR_1=some_value\nENV_VAR_2=some_other_value\n"})}),"\n",(0,t.jsx)(o.h2,{id:"configuring-volumes",children:"Configuring volumes"}),"\n",(0,t.jsxs)(o.p,{children:["A docker container's filesystem is segregated from that of the host. However, it is still possible for a container to access system files and directories, this is accomplished by using ",(0,t.jsx)(o.a,{href:"https://docs.docker.com/storage/bind-mounts/",children:"bind mounts"}),"."]}),"\n",(0,t.jsxs)(o.p,{children:["Say your container needs to read a config file located on the system at ",(0,t.jsx)(o.code,{children:"/home/ubuntu/config.toml"}),". You can specify the bind mount to be:"]}),"\n",(0,t.jsx)(o.pre,{children:(0,t.jsx)(o.code,{children:"/home/ubuntu/config.toml : /config/config.toml\n"})}),"\n",(0,t.jsxs)(o.p,{children:["The first path is the one on the system, the second is the path in the container. Your application would then read the file at ",(0,t.jsx)(o.code,{children:"/config/config.toml"})," in order to load its contents."]}),"\n",(0,t.jsx)(o.p,{children:"These can be configured easily with the GUI in the 'volumes' card. You can configure as many bind mounts as you need."}),"\n",(0,t.jsx)(o.h2,{id:"extra-args",children:"Extra args"}),"\n",(0,t.jsxs)(o.p,{children:["Not all features of docker are mapped directly by Komodo, only the most common. You can still specify any custom flags for Komodo to include in the ",(0,t.jsx)(o.code,{children:"docker run"})," command by utilizing 'extra args'. For example, you can enable log rotation using these two extra args:"]}),"\n",(0,t.jsx)(o.pre,{children:(0,t.jsx)(o.code,{children:"--log-opt max-size=10M\n"})}),"\n",(0,t.jsx)(o.pre,{children:(0,t.jsx)(o.code,{children:"--log-opt max-file=3\n"})}),"\n",(0,t.jsx)(o.h2,{id:"command",children:"Command"}),"\n",(0,t.jsxs)(o.p,{children:["Sometimes you need to override the default command in the image, or specify some flags to be passed directly to the application. What is put here is inserted into the docker run command after the image. For example, to pass the ",(0,t.jsx)(o.code,{children:"--quiet"})," flag to MongoDB, the docker run command would be:"]}),"\n",(0,t.jsx)(o.pre,{children:(0,t.jsx)(o.code,{children:"docker run -d --name mongo-db mongo:6.0.3 --quiet\n"})}),"\n",(0,t.jsxs)(o.p,{children:["In order to achieve this with Komodo, just pass ",(0,t.jsx)(o.code,{children:"--quiet"})," to 'command'."]})]})}function h(e={}){const{wrapper:o}={...(0,i.R)(),...e.components};return o?(0,t.jsx)(o,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},8453:(e,o,n)=>{n.d(o,{R:()=>s,x:()=>a});var t=n(6540);const i={},r=t.createContext(i);function s(e){const o=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function a(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),t.createElement(r.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ef526b88.f1eb480d.js b/assets/js/ef526b88.f1eb480d.js deleted file mode 100644 index fe926e009..000000000 --- a/assets/js/ef526b88.f1eb480d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[995],{9302:(e,o,n)=>{n.r(o),n.d(o,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var t=n(4848),i=n(8453);const r={},s="Configuration",a={id:"deploy-containers/configuration",title:"Configuration",description:"Choose the docker image",source:"@site/docs/deploy-containers/configuration.md",sourceDirName:"deploy-containers",slug:"/deploy-containers/configuration",permalink:"/docs/deploy-containers/configuration",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/deploy-containers/configuration.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Deploy Containers",permalink:"/docs/deploy-containers/"},next:{title:"Container Management",permalink:"/docs/deploy-containers/lifetime-management"}},c={},d=[{value:"Choose the docker image",id:"choose-the-docker-image",level:2},{value:"Attaching a Komodo build",id:"attaching-a-komodo-build",level:3},{value:"Using a custom image",id:"using-a-custom-image",level:3},{value:"Configuring the network",id:"configuring-the-network",level:2},{value:"Configuring restart behavior",id:"configuring-restart-behavior",level:2},{value:"Configuring environment variables",id:"configuring-environment-variables",level:2},{value:"Configuring volumes",id:"configuring-volumes",level:2},{value:"Extra args",id:"extra-args",level:2},{value:"Command",id:"command",level:2}];function l(e){const o={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(o.header,{children:(0,t.jsx)(o.h1,{id:"configuration",children:"Configuration"})}),"\n",(0,t.jsx)(o.h2,{id:"choose-the-docker-image",children:"Choose the docker image"}),"\n",(0,t.jsx)(o.p,{children:"There are two options to configure the docker image to deploy."}),"\n",(0,t.jsx)(o.h3,{id:"attaching-a-komodo-build",children:"Attaching a Komodo build"}),"\n",(0,t.jsx)(o.p,{children:"If the software you want to deploy is built by Komodo, you can attach the build directly to the deployment."}),"\n",(0,t.jsx)(o.p,{children:"By default, Komodo will deploy the latest available version of the build, or you can specify a specific version using the version dropdown."}),"\n",(0,t.jsx)(o.p,{children:"Also by default, Komodo will use the same docker account that is attached to the build in order to pull the image on the periphery server. If that account is not available on the server, you can specify another available account to use instead, this account just needs to have read access to the docker repository."}),"\n",(0,t.jsx)(o.h3,{id:"using-a-custom-image",children:"Using a custom image"}),"\n",(0,t.jsxs)(o.p,{children:["You can also manually specify an image name, like ",(0,t.jsx)(o.code,{children:"mongo"})," or ",(0,t.jsx)(o.code,{children:"ghcr.io/mbecker20/random_image:0.1.1"}),"."]}),"\n",(0,t.jsx)(o.p,{children:"If the image repository is private, you can still select an available docker account to use to pull the image."}),"\n",(0,t.jsx)(o.h2,{id:"configuring-the-network",children:"Configuring the network"}),"\n",(0,t.jsxs)(o.p,{children:["One feature of docker is that it allows for the creation of ",(0,t.jsx)(o.a,{href:"https://docs.docker.com/network/",children:"virtual networks between containers"}),". Komodo allows you to specify a docker virtual network to connect the container to, or to use the host system networking to bypass the docker virtual network."]}),"\n",(0,t.jsxs)(o.p,{children:["The default selection is ",(0,t.jsx)(o.code,{children:"host"}),", which bypasses the docker virtual network layer."]}),"\n",(0,t.jsx)(o.p,{children:"If you do select select a network other than host, you can specify port bindings with the GUI. For example, if you are running mongo (which defaults to port 27017), you could use the mapping:"}),"\n",(0,t.jsx)(o.pre,{children:(0,t.jsx)(o.code,{children:"27018 : 27017\n"})}),"\n",(0,t.jsxs)(o.p,{children:["In this case, you would access mongo from outside of the container on port ",(0,t.jsx)(o.code,{children:"27018"}),"."]}),"\n",(0,t.jsxs)(o.p,{children:["Note that this is not the only affect of using a network other than ",(0,t.jsx)(o.code,{children:"host"}),". For example, containers running on different networks can not communicate, and ones on the same network can not reach other containers on ",(0,t.jsx)(o.code,{children:"localhost"})," even when they are running on the same system. This behavior can be a bit confusing if you are not familiar with it, and it can be bypassed entirely by just using ",(0,t.jsx)(o.code,{children:"host"})," network."]}),"\n",(0,t.jsx)(o.h2,{id:"configuring-restart-behavior",children:"Configuring restart behavior"}),"\n",(0,t.jsxs)(o.p,{children:["Docker, like systemd, has a couple options for handling when a container exits. See ",(0,t.jsx)(o.a,{href:"https://docs.docker.com/config/containers/start-containers-automatically/",children:"docker restart policies"}),". Komodo allows you to select the appropriate restart behavior from these options."]}),"\n",(0,t.jsx)(o.h2,{id:"configuring-environment-variables",children:"Configuring environment variables"}),"\n",(0,t.jsx)(o.p,{children:"Komodo enables you to easily manage environment variables passed to the container.\nIn the GUI, navigate to the environment tab of the configuration on the deployment page."}),"\n",(0,t.jsxs)(o.p,{children:["You pass environment variables just as you would with a ",(0,t.jsx)(o.code,{children:".env"})," file:"]}),"\n",(0,t.jsx)(o.pre,{children:(0,t.jsx)(o.code,{children:"ENV_VAR_1=some_value\nENV_VAR_2=some_other_value\n"})}),"\n",(0,t.jsx)(o.h2,{id:"configuring-volumes",children:"Configuring volumes"}),"\n",(0,t.jsxs)(o.p,{children:["A docker container's filesystem is segregated from that of the host. However, it is still possible for a container to access system files and directories, this is accomplished by using ",(0,t.jsx)(o.a,{href:"https://docs.docker.com/storage/bind-mounts/",children:"bind mounts"}),"."]}),"\n",(0,t.jsxs)(o.p,{children:["Say your container needs to read a config file located on the system at ",(0,t.jsx)(o.code,{children:"/home/ubuntu/config.toml"}),". You can specify the bind mount to be:"]}),"\n",(0,t.jsx)(o.pre,{children:(0,t.jsx)(o.code,{children:"/home/ubuntu/config.toml : /config/config.toml\n"})}),"\n",(0,t.jsxs)(o.p,{children:["The first path is the one on the system, the second is the path in the container. Your application would then read the file at ",(0,t.jsx)(o.code,{children:"/config/config.toml"})," in order to load its contents."]}),"\n",(0,t.jsx)(o.p,{children:"These can be configured easily with the GUI in the 'volumes' card. You can configure as many bind mounts as you need."}),"\n",(0,t.jsx)(o.h2,{id:"extra-args",children:"Extra args"}),"\n",(0,t.jsxs)(o.p,{children:["Not all features of docker are mapped directly by Komodo, only the most common. You can still specify any custom flags for Komodo to include in the ",(0,t.jsx)(o.code,{children:"docker run"})," command by utilizing 'extra args'. For example, you can enable log rotation using these two extra args:"]}),"\n",(0,t.jsx)(o.pre,{children:(0,t.jsx)(o.code,{children:"--log-opt max-size=10M\n"})}),"\n",(0,t.jsx)(o.pre,{children:(0,t.jsx)(o.code,{children:"--log-opt max-file=3\n"})}),"\n",(0,t.jsx)(o.h2,{id:"command",children:"Command"}),"\n",(0,t.jsxs)(o.p,{children:["Sometimes you need to override the default command in the image, or specify some flags to be passed directly to the application. What is put here is inserted into the docker run command after the image. For example, to pass the ",(0,t.jsx)(o.code,{children:"--quiet"})," flag to MongoDB, the docker run command would be:"]}),"\n",(0,t.jsx)(o.pre,{children:(0,t.jsx)(o.code,{children:"docker run -d --name mongo-db mongo:6.0.3 --quiet\n"})}),"\n",(0,t.jsxs)(o.p,{children:["In order to achieve this with Komodo, just pass ",(0,t.jsx)(o.code,{children:"--quiet"})," to 'command'."]})]})}function h(e={}){const{wrapper:o}={...(0,i.R)(),...e.components};return o?(0,t.jsx)(o,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},8453:(e,o,n)=>{n.d(o,{R:()=>s,x:()=>a});var t=n(6540);const i={},r=t.createContext(i);function s(e){const o=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function a(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),t.createElement(r.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ef9e0e28.0db1766d.js b/assets/js/ef9e0e28.0db1766d.js new file mode 100644 index 000000000..f2ef0c185 --- /dev/null +++ b/assets/js/ef9e0e28.0db1766d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[947],{2589:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>h,frontMatter:()=>s,metadata:()=>i,toc:()=>c});var o=n(4848),r=n(8453),a=n(5627);const s={},l="Sqlite",i={id:"setup/sqlite",title:"Sqlite",description:"FerritDB + Sqlite authentication support is still experimental,",source:"@site/docs/setup/sqlite.mdx",sourceDirName:"setup",slug:"/setup/sqlite",permalink:"/docs/setup/sqlite",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/setup/sqlite.mdx",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Postgres",permalink:"/docs/setup/postgres"},next:{title:"Advanced Configuration",permalink:"/docs/setup/advanced"}},u={},c=[];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"sqlite",children:"Sqlite"})}),"\n",(0,o.jsx)(t.admonition,{type:"info",children:(0,o.jsxs)(t.p,{children:["FerritDB + Sqlite authentication support is ",(0,o.jsx)(t.a,{href:"https://docs.ferretdb.io/security/authentication/#experimental-authentication-mode",children:"still experimental"}),",\nand is not enabled in this database configuration. Because of this, the values for ",(0,o.jsx)(t.code,{children:"DB_USERNAME"})," and ",(0,o.jsx)(t.code,{children:"DB_PASSWORD"}),"\nare ignored when using Sqlite, and the database port is not exposed publicly by default."]})}),"\n",(0,o.jsxs)(t.ol,{children:["\n",(0,o.jsxs)(t.li,{children:["Copy ",(0,o.jsx)(t.code,{children:"komodo/sqlite.compose.yaml"})," and ",(0,o.jsx)(t.code,{children:"komodo/compose.env"})," to your host:"]}),"\n"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"wget -P komodo https://raw.githubusercontent.com/moghtech/komodo/main/compose/sqlite.compose.yaml && \\\n wget -P komodo https://raw.githubusercontent.com/moghtech/komodo/main/compose/compose.env\n"})}),"\n",(0,o.jsxs)(t.ol,{start:"2",children:["\n",(0,o.jsxs)(t.li,{children:["Edit the variables in ",(0,o.jsx)(t.code,{children:"komodo/compose.env"}),"."]}),"\n",(0,o.jsx)(t.li,{children:"Deploy:"}),"\n"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"docker compose -p komodo -f komodo/sqlite.compose.yaml --env-file komodo/compose.env up -d\n"})}),"\n","\n",(0,o.jsx)(a.A,{file_name:"sqlite.compose.yaml"})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},5627:(e,t,n)=>{n.d(t,{A:()=>S});var o=n(6540),r=n(6695),a=n(4164),s=n(3104),l=n(6347),i=n(205),u=n(7485),c=n(1682),d=n(679);function h(e){return o.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,o.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function m(e){const{values:t,children:n}=e;return(0,o.useMemo)((()=>{const e=t??function(e){return h(e).map((e=>{let{props:{value:t,label:n,attributes:o,default:r}}=e;return{value:t,label:n,attributes:o,default:r}}))}(n);return function(e){const t=(0,c.XI)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,n])}function p(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function b(e){let{queryString:t=!1,groupId:n}=e;const r=(0,l.W6)(),a=function(e){let{queryString:t=!1,groupId:n}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!n)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:t,groupId:n});return[(0,u.aZ)(a),(0,o.useCallback)((e=>{if(!a)return;const t=new URLSearchParams(r.location.search);t.set(a,e),r.replace({...r.location,search:t.toString()})}),[a,r])]}function f(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,a=m(e),[s,l]=(0,o.useState)((()=>function(e){let{defaultValue:t,tabValues:n}=e;if(0===n.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!p({value:t,tabValues:n}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${n.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const o=n.find((e=>e.default))??n[0];if(!o)throw new Error("Unexpected error: 0 tabValues");return o.value}({defaultValue:t,tabValues:a}))),[u,c]=b({queryString:n,groupId:r}),[h,f]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,a]=(0,d.Dv)(n);return[r,(0,o.useCallback)((e=>{n&&a.set(e)}),[n,a])]}({groupId:r}),g=(()=>{const e=u??h;return p({value:e,tabValues:a})?e:null})();(0,i.A)((()=>{g&&l(g)}),[g]);return{selectedValue:s,selectValue:(0,o.useCallback)((e=>{if(!p({value:e,tabValues:a}))throw new Error(`Can't select invalid tab value=${e}`);l(e),c(e),f(e)}),[c,f,a]),tabValues:a}}var g=n(2303);const v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var x=n(4848);function j(e){let{className:t,block:n,selectedValue:o,selectValue:r,tabValues:l}=e;const i=[],{blockElementScrollPositionUntilNextRender:u}=(0,s.a_)(),c=e=>{const t=e.currentTarget,n=i.indexOf(t),a=l[n].value;a!==o&&(u(t),r(a))},d=e=>{let t=null;switch(e.key){case"Enter":c(e);break;case"ArrowRight":{const n=i.indexOf(e.currentTarget)+1;t=i[n]??i[0];break}case"ArrowLeft":{const n=i.indexOf(e.currentTarget)-1;t=i[n]??i[i.length-1];break}}t?.focus()};return(0,x.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,a.A)("tabs",{"tabs--block":n},t),children:l.map((e=>{let{value:t,label:n,attributes:r}=e;return(0,x.jsx)("li",{role:"tab",tabIndex:o===t?0:-1,"aria-selected":o===t,ref:e=>i.push(e),onKeyDown:d,onClick:c,...r,className:(0,a.A)("tabs__item",v.tabItem,r?.className,{"tabs__item--active":o===t}),children:n??t},t)}))})}function y(e){let{lazy:t,children:n,selectedValue:r}=e;const s=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){const e=s.find((e=>e.props.value===r));return e?(0,o.cloneElement)(e,{className:(0,a.A)("margin-top--md",e.props.className)}):null}return(0,x.jsx)("div",{className:"margin-top--md",children:s.map(((e,t)=>(0,o.cloneElement)(e,{key:t,hidden:e.props.value!==r})))})}function k(e){const t=f(e);return(0,x.jsxs)("div",{className:(0,a.A)("tabs-container",v.tabList),children:[(0,x.jsx)(j,{...t,...e}),(0,x.jsx)(y,{...t,...e})]})}function w(e){const t=(0,g.A)();return(0,x.jsx)(k,{...e,children:h(e.children)},String(t))}const q={tabItem:"tabItem_Ymn6"};function A(e){let{children:t,hidden:n,className:o}=e;return(0,x.jsx)("div",{role:"tabpanel",className:(0,a.A)(q.tabItem,o),hidden:n,children:t})}function S(e){let{file_name:t}=e;return(0,x.jsxs)(w,{children:[(0,x.jsx)(A,{value:t,children:(0,x.jsx)(r.A,{title:`https://github.com/moghtech/komodo/blob/main/compose/${t}`,url:`https://raw.githubusercontent.com/moghtech/komodo/main/compose/${t}`,language:"yaml"})}),(0,x.jsx)(A,{value:"compose.env",children:(0,x.jsx)(r.A,{title:"https://github.com/moghtech/komodo/blob/main/compose/compose.env",url:"https://raw.githubusercontent.com/moghtech/komodo/main/compose/compose.env",language:"bash"})})]})}},6695:(e,t,n)=>{n.d(t,{A:()=>s});var o=n(6540),r=n(1432),a=n(4848);function s(e){let{url:t,language:n,title:s}=e;const[l,i]=(0,o.useState)("");return(0,o.useEffect)((()=>{!async function(e,t){const n=await fetch(e);t(await n.text())}(t,i)}),[]),(0,a.jsx)(r.A,{title:s??t,language:n,showLineNumbers:!0,children:l})}}}]); \ No newline at end of file diff --git a/assets/js/ef9e0e28.7ebecfd6.js b/assets/js/ef9e0e28.7ebecfd6.js deleted file mode 100644 index 5807b7298..000000000 --- a/assets/js/ef9e0e28.7ebecfd6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[947],{2589:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>m,frontMatter:()=>s,metadata:()=>i,toc:()=>c});var r=n(4848),o=n(8453),a=n(5627);const s={},l="Sqlite",i={id:"setup/sqlite",title:"Sqlite",description:"FerritDB + Sqlite authentication support is still experimental,",source:"@site/docs/setup/sqlite.mdx",sourceDirName:"setup",slug:"/setup/sqlite",permalink:"/docs/setup/sqlite",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/setup/sqlite.mdx",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Postgres",permalink:"/docs/setup/postgres"},next:{title:"Advanced Configuration",permalink:"/docs/setup/advanced"}},u={},c=[];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"sqlite",children:"Sqlite"})}),"\n",(0,r.jsx)(t.admonition,{type:"info",children:(0,r.jsxs)(t.p,{children:["FerritDB + Sqlite authentication support is ",(0,r.jsx)(t.a,{href:"https://docs.ferretdb.io/security/authentication/#experimental-authentication-mode",children:"still experimental"}),",\nand is not enabled in this database configuration. Because of this, the values for ",(0,r.jsx)(t.code,{children:"DB_USERNAME"})," and ",(0,r.jsx)(t.code,{children:"DB_PASSWORD"}),"\nare ignored when using Sqlite, and the database port is not exposed publicly by default."]})}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["Copy ",(0,r.jsx)(t.code,{children:"komodo/sqlite.compose.yaml"})," and ",(0,r.jsx)(t.code,{children:"komodo/compose.env"})," to your host:"]}),"\n"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"wget -P komodo https://raw.githubusercontent.com/mbecker20/komodo/main/compose/sqlite.compose.yaml && \\\n wget -P komodo https://raw.githubusercontent.com/mbecker20/komodo/main/compose/compose.env\n"})}),"\n",(0,r.jsxs)(t.ol,{start:"2",children:["\n",(0,r.jsxs)(t.li,{children:["Edit the variables in ",(0,r.jsx)(t.code,{children:"komodo/compose.env"}),"."]}),"\n",(0,r.jsx)(t.li,{children:"Deploy:"}),"\n"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"docker compose -p komodo -f komodo/sqlite.compose.yaml --env-file komodo/compose.env up -d\n"})}),"\n","\n",(0,r.jsx)(a.A,{file_name:"sqlite.compose.yaml"})]})}function m(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},5627:(e,t,n)=>{n.d(t,{A:()=>S});var r=n(6540),o=n(6695),a=n(4164),s=n(3104),l=n(6347),i=n(205),u=n(7485),c=n(1682),d=n(679);function m(e){return r.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function p(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??function(e){return m(e).map((e=>{let{props:{value:t,label:n,attributes:r,default:o}}=e;return{value:t,label:n,attributes:r,default:o}}))}(n);return function(e){const t=(0,c.XI)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,n])}function h(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function b(e){let{queryString:t=!1,groupId:n}=e;const o=(0,l.W6)(),a=function(e){let{queryString:t=!1,groupId:n}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!n)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:t,groupId:n});return[(0,u.aZ)(a),(0,r.useCallback)((e=>{if(!a)return;const t=new URLSearchParams(o.location.search);t.set(a,e),o.replace({...o.location,search:t.toString()})}),[a,o])]}function f(e){const{defaultValue:t,queryString:n=!1,groupId:o}=e,a=p(e),[s,l]=(0,r.useState)((()=>function(e){let{defaultValue:t,tabValues:n}=e;if(0===n.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!h({value:t,tabValues:n}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${n.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:a}))),[u,c]=b({queryString:n,groupId:o}),[m,f]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[o,a]=(0,d.Dv)(n);return[o,(0,r.useCallback)((e=>{n&&a.set(e)}),[n,a])]}({groupId:o}),g=(()=>{const e=u??m;return h({value:e,tabValues:a})?e:null})();(0,i.A)((()=>{g&&l(g)}),[g]);return{selectedValue:s,selectValue:(0,r.useCallback)((e=>{if(!h({value:e,tabValues:a}))throw new Error(`Can't select invalid tab value=${e}`);l(e),c(e),f(e)}),[c,f,a]),tabValues:a}}var g=n(2303);const v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var x=n(4848);function k(e){let{className:t,block:n,selectedValue:r,selectValue:o,tabValues:l}=e;const i=[],{blockElementScrollPositionUntilNextRender:u}=(0,s.a_)(),c=e=>{const t=e.currentTarget,n=i.indexOf(t),a=l[n].value;a!==r&&(u(t),o(a))},d=e=>{let t=null;switch(e.key){case"Enter":c(e);break;case"ArrowRight":{const n=i.indexOf(e.currentTarget)+1;t=i[n]??i[0];break}case"ArrowLeft":{const n=i.indexOf(e.currentTarget)-1;t=i[n]??i[i.length-1];break}}t?.focus()};return(0,x.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,a.A)("tabs",{"tabs--block":n},t),children:l.map((e=>{let{value:t,label:n,attributes:o}=e;return(0,x.jsx)("li",{role:"tab",tabIndex:r===t?0:-1,"aria-selected":r===t,ref:e=>i.push(e),onKeyDown:d,onClick:c,...o,className:(0,a.A)("tabs__item",v.tabItem,o?.className,{"tabs__item--active":r===t}),children:n??t},t)}))})}function j(e){let{lazy:t,children:n,selectedValue:o}=e;const s=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){const e=s.find((e=>e.props.value===o));return e?(0,r.cloneElement)(e,{className:(0,a.A)("margin-top--md",e.props.className)}):null}return(0,x.jsx)("div",{className:"margin-top--md",children:s.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==o})))})}function y(e){const t=f(e);return(0,x.jsxs)("div",{className:(0,a.A)("tabs-container",v.tabList),children:[(0,x.jsx)(k,{...t,...e}),(0,x.jsx)(j,{...t,...e})]})}function w(e){const t=(0,g.A)();return(0,x.jsx)(y,{...e,children:m(e.children)},String(t))}const q={tabItem:"tabItem_Ymn6"};function A(e){let{children:t,hidden:n,className:r}=e;return(0,x.jsx)("div",{role:"tabpanel",className:(0,a.A)(q.tabItem,r),hidden:n,children:t})}function S(e){let{file_name:t}=e;return(0,x.jsxs)(w,{children:[(0,x.jsx)(A,{value:t,children:(0,x.jsx)(o.A,{title:`https://github.com/mbecker20/komodo/blob/main/compose/${t}`,url:`https://raw.githubusercontent.com/mbecker20/komodo/main/compose/${t}`,language:"yaml"})}),(0,x.jsx)(A,{value:"compose.env",children:(0,x.jsx)(o.A,{title:"https://github.com/mbecker20/komodo/blob/main/compose/compose.env",url:"https://raw.githubusercontent.com/mbecker20/komodo/main/compose/compose.env",language:"bash"})})]})}},6695:(e,t,n)=>{n.d(t,{A:()=>s});var r=n(6540),o=n(1432),a=n(4848);function s(e){let{url:t,language:n,title:s}=e;const[l,i]=(0,r.useState)("");return(0,r.useEffect)((()=>{!async function(e,t){const n=await fetch(e);t(await n.text())}(t,i)}),[]),(0,a.jsx)(o.A,{title:s??t,language:n,showLineNumbers:!0,children:l})}}}]); \ No newline at end of file diff --git a/assets/js/f600b847.a11bb485.js b/assets/js/f600b847.a11bb485.js deleted file mode 100644 index 6218bb381..000000000 --- a/assets/js/f600b847.a11bb485.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[238],{2945:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>l,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>d});var o=n(4848),s=n(8453),r=n(5871);const i={},l="Setup Komodo",c={id:"setup/index",title:"Setup Komodo",description:"To run Komodo, you will need Docker. See the docker install docs.",source:"@site/docs/setup/index.mdx",sourceDirName:"setup",slug:"/setup/",permalink:"/docs/setup/",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/setup/index.mdx",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Resources",permalink:"/docs/resources"},next:{title:"MongoDB",permalink:"/docs/setup/mongo"}},a={},d=[{value:"Deploy with Docker Compose",id:"deploy-with-docker-compose",level:3},{value:"First login",id:"first-login",level:3},{value:"Https",id:"https",level:3}];function u(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"setup-komodo",children:"Setup Komodo"})}),"\n",(0,o.jsxs)(t.p,{children:["To run Komodo, you will need Docker. See ",(0,o.jsx)(t.a,{href:"https://docs.docker.com/engine/install/",children:"the docker install docs"}),"."]}),"\n",(0,o.jsx)(t.h3,{id:"deploy-with-docker-compose",children:"Deploy with Docker Compose"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:(0,o.jsx)(t.a,{href:"/docs/setup/mongo",children:"Using MongoDB"})}),"\n",(0,o.jsx)(t.li,{children:(0,o.jsx)(t.a,{href:"/docs/setup/postgres",children:"Using Postgres"})}),"\n",(0,o.jsx)(t.li,{children:(0,o.jsx)(t.a,{href:"/docs/setup/sqlite",children:"Using Sqlite"})}),"\n"]}),"\n",(0,o.jsx)(t.admonition,{type:"info",children:(0,o.jsxs)(t.p,{children:["Komodo is able to support Postgres and Sqlite by utilizing the ",(0,o.jsx)(t.a,{href:"https://www.ferretdb.com/",children:"FerretDB Mongo Adapter"}),"."]})}),"\n",(0,o.jsx)(t.h3,{id:"first-login",children:"First login"}),"\n",(0,o.jsxs)(t.p,{children:["Core should now be accessible on the specified port, so navigating to ",(0,o.jsx)(t.code,{children:"http://
:"})," will display the login page."]}),"\n",(0,o.jsx)(t.p,{children:"The first user to log in will be auto enabled and made an admin. Any additional users to create accounts will be disabled by default, and must be enabled by an admin."}),"\n",(0,o.jsx)(t.h3,{id:"https",children:"Https"}),"\n",(0,o.jsxs)(t.p,{children:["Komodo Core only supports http, so a reverse proxy like ",(0,o.jsx)(t.a,{href:"https://caddyserver.com/",children:"caddy"})," should be used for https."]}),"\n","\n",(0,o.jsx)(r.A,{})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(u,{...e})}):u(e)}},5871:(e,t,n)=>{n.d(t,{A:()=>D});var o=n(6540),s=n(4164),r=n(6972),i=n(8774),l=n(4586);const c=["zero","one","two","few","many","other"];function a(e){return c.filter((t=>e.includes(t)))}const d={locale:"en",pluralForms:a(["one","other"]),select:e=>1===e?"one":"other"};function u(){const{i18n:{currentLocale:e}}=(0,l.A)();return(0,o.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:a(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),d}}),[e])}function h(){const e=u();return{selectMessage:(t,n)=>function(e,t,n){const o=e.split("|");if(1===o.length)return o[0];o.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${o.length}: ${e}`);const s=n.select(t),r=n.pluralForms.indexOf(s);return o[Math.min(r,o.length-1)]}(n,t,e)}}var p=n(6654),m=n(1312),f=n(1107);const x={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var g=n(4848);function j(e){let{href:t,children:n}=e;return(0,g.jsx)(i.A,{href:t,className:(0,s.A)("card padding--lg",x.cardContainer),children:n})}function y(e){let{href:t,icon:n,title:o,description:r}=e;return(0,g.jsxs)(j,{href:t,children:[(0,g.jsxs)(f.A,{as:"h2",className:(0,s.A)("text--truncate",x.cardTitle),title:o,children:[n," ",o]}),r&&(0,g.jsx)("p",{className:(0,s.A)("text--truncate",x.cardDescription),title:r,children:r})]})}function b(e){let{item:t}=e;const n=(0,r.Nr)(t),o=function(){const{selectMessage:e}=h();return t=>e(t,(0,m.T)({message:"1 item|{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t}))}();return n?(0,g.jsx)(y,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??o(t.items.length)}):null}function w(e){let{item:t}=e;const n=(0,p.A)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",o=(0,r.cC)(t.docId??void 0);return(0,g.jsx)(y,{href:t.href,icon:n,title:t.label,description:t.description??o?.description})}function k(e){let{item:t}=e;switch(t.type){case"link":return(0,g.jsx)(w,{item:t});case"category":return(0,g.jsx)(b,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function v(e){let{className:t}=e;const n=(0,r.$S)();return(0,g.jsx)(D,{items:n.items,className:t})}function D(e){const{items:t,className:n}=e;if(!t)return(0,g.jsx)(v,{...e});const o=(0,r.d1)(t);return(0,g.jsx)("section",{className:(0,s.A)("row",n),children:o.map(((e,t)=>(0,g.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,g.jsx)(k,{item:e})},t)))})}},8453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>l});var o=n(6540);const s={},r=o.createContext(s);function i(e){const t=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f600b847.e0e0cfeb.js b/assets/js/f600b847.e0e0cfeb.js new file mode 100644 index 000000000..dc348c48b --- /dev/null +++ b/assets/js/f600b847.e0e0cfeb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[238],{2945:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>l,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>d});var o=n(4848),s=n(8453),r=n(5871);const i={},l="Setup Komodo",c={id:"setup/index",title:"Setup Komodo",description:"To run Komodo, you will need Docker. See the docker install docs.",source:"@site/docs/setup/index.mdx",sourceDirName:"setup",slug:"/setup/",permalink:"/docs/setup/",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/setup/index.mdx",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Resources",permalink:"/docs/resources"},next:{title:"MongoDB",permalink:"/docs/setup/mongo"}},a={},d=[{value:"Deploy with Docker Compose",id:"deploy-with-docker-compose",level:3},{value:"First login",id:"first-login",level:3},{value:"Https",id:"https",level:3}];function u(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"setup-komodo",children:"Setup Komodo"})}),"\n",(0,o.jsxs)(t.p,{children:["To run Komodo, you will need Docker. See ",(0,o.jsx)(t.a,{href:"https://docs.docker.com/engine/install/",children:"the docker install docs"}),"."]}),"\n",(0,o.jsx)(t.h3,{id:"deploy-with-docker-compose",children:"Deploy with Docker Compose"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:(0,o.jsx)(t.a,{href:"/docs/setup/mongo",children:"Using MongoDB"})}),"\n",(0,o.jsx)(t.li,{children:(0,o.jsx)(t.a,{href:"/docs/setup/postgres",children:"Using Postgres"})}),"\n",(0,o.jsx)(t.li,{children:(0,o.jsx)(t.a,{href:"/docs/setup/sqlite",children:"Using Sqlite"})}),"\n"]}),"\n",(0,o.jsx)(t.admonition,{type:"info",children:(0,o.jsxs)(t.p,{children:["Komodo is able to support Postgres and Sqlite by utilizing the ",(0,o.jsx)(t.a,{href:"https://www.ferretdb.com/",children:"FerretDB Mongo Adapter"}),"."]})}),"\n",(0,o.jsx)(t.h3,{id:"first-login",children:"First login"}),"\n",(0,o.jsxs)(t.p,{children:["Core should now be accessible on the specified port, so navigating to ",(0,o.jsx)(t.code,{children:"http://
:"})," will display the login page."]}),"\n",(0,o.jsx)(t.p,{children:"The first user to log in will be auto enabled and made an admin. Any additional users to create accounts will be disabled by default, and must be enabled by an admin."}),"\n",(0,o.jsx)(t.h3,{id:"https",children:"Https"}),"\n",(0,o.jsxs)(t.p,{children:["Komodo Core only supports http, so a reverse proxy like ",(0,o.jsx)(t.a,{href:"https://caddyserver.com/",children:"caddy"})," should be used for https."]}),"\n","\n",(0,o.jsx)(r.A,{})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(u,{...e})}):u(e)}},5871:(e,t,n)=>{n.d(t,{A:()=>D});var o=n(6540),s=n(4164),r=n(6972),i=n(8774),l=n(4586);const c=["zero","one","two","few","many","other"];function a(e){return c.filter((t=>e.includes(t)))}const d={locale:"en",pluralForms:a(["one","other"]),select:e=>1===e?"one":"other"};function u(){const{i18n:{currentLocale:e}}=(0,l.A)();return(0,o.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:a(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),d}}),[e])}function h(){const e=u();return{selectMessage:(t,n)=>function(e,t,n){const o=e.split("|");if(1===o.length)return o[0];o.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${o.length}: ${e}`);const s=n.select(t),r=n.pluralForms.indexOf(s);return o[Math.min(r,o.length-1)]}(n,t,e)}}var p=n(6654),m=n(1312),f=n(1107);const x={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var g=n(4848);function j(e){let{href:t,children:n}=e;return(0,g.jsx)(i.A,{href:t,className:(0,s.A)("card padding--lg",x.cardContainer),children:n})}function y(e){let{href:t,icon:n,title:o,description:r}=e;return(0,g.jsxs)(j,{href:t,children:[(0,g.jsxs)(f.A,{as:"h2",className:(0,s.A)("text--truncate",x.cardTitle),title:o,children:[n," ",o]}),r&&(0,g.jsx)("p",{className:(0,s.A)("text--truncate",x.cardDescription),title:r,children:r})]})}function w(e){let{item:t}=e;const n=(0,r.Nr)(t),o=function(){const{selectMessage:e}=h();return t=>e(t,(0,m.T)({message:"1 item|{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t}))}();return n?(0,g.jsx)(y,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??o(t.items.length)}):null}function b(e){let{item:t}=e;const n=(0,p.A)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",o=(0,r.cC)(t.docId??void 0);return(0,g.jsx)(y,{href:t.href,icon:n,title:t.label,description:t.description??o?.description})}function k(e){let{item:t}=e;switch(t.type){case"link":return(0,g.jsx)(b,{item:t});case"category":return(0,g.jsx)(w,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function v(e){let{className:t}=e;const n=(0,r.$S)();return(0,g.jsx)(D,{items:n.items,className:t})}function D(e){const{items:t,className:n}=e;if(!t)return(0,g.jsx)(v,{...e});const o=(0,r.d1)(t);return(0,g.jsx)("section",{className:(0,s.A)("row",n),children:o.map(((e,t)=>(0,g.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,g.jsx)(k,{item:e})},t)))})}},8453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>l});var o=n(6540);const s={},r=o.createContext(s);function i(e){const t=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f8238c17.9d59e94b.js b/assets/js/f8238c17.9d59e94b.js new file mode 100644 index 000000000..b4a339329 --- /dev/null +++ b/assets/js/f8238c17.9d59e94b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[247],{2913:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>p,frontMatter:()=>a,metadata:()=>s,toc:()=>d});var i=n(4848),o=n(8453);const a={},r="Container Management",s={id:"deploy-containers/lifetime-management",title:"Container Management",description:"The lifetime of a docker container is more like a virtual machine. They can be created, started, stopped, and destroyed. Komodo will display the state of the container and provides an API to manage all your container's lifetimes.",source:"@site/docs/deploy-containers/lifetime-management.md",sourceDirName:"deploy-containers",slug:"/deploy-containers/lifetime-management",permalink:"/docs/deploy-containers/lifetime-management",draft:!1,unlisted:!1,editUrl:"https://github.com/moghtech/komodo/tree/main/docsite/docs/deploy-containers/lifetime-management.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Configuration",permalink:"/docs/deploy-containers/configuration"},next:{title:"Docker Compose",permalink:"/docs/docker-compose"}},c={},d=[{value:"Stopping a Container",id:"stopping-a-container",level:3},{value:"Container Redeploy",id:"container-redeploy",level:3}];function l(e){const t={em:"em",h1:"h1",h3:"h3",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"container-management",children:"Container Management"})}),"\n",(0,i.jsx)(t.p,{children:"The lifetime of a docker container is more like a virtual machine. They can be created, started, stopped, and destroyed. Komodo will display the state of the container and provides an API to manage all your container's lifetimes."}),"\n",(0,i.jsx)(t.p,{children:"This is achieved internally by running the appropriate docker command for the requested action (docker stop, docker start, etc)."}),"\n",(0,i.jsx)(t.h3,{id:"stopping-a-container",children:"Stopping a Container"}),"\n",(0,i.jsxs)(t.p,{children:["Sometimes you want to stop a running application but preserve its logs and configuration, either to be restarted later or to view the logs at a later time. It is more like ",(0,i.jsx)(t.em,{children:"pausing"})," the application with its current config, as no configuration (like environment variable, volume mounts, etc.) will be changed when the container is started again."]}),"\n",(0,i.jsxs)(t.p,{children:["Note that in order to restart an application with updated configuration, it must be ",(0,i.jsx)(t.em,{children:"redeployed"}),". stopping and starting a container again will keep all configuration as it was when the container was initially created."]}),"\n",(0,i.jsx)(t.h3,{id:"container-redeploy",children:"Container Redeploy"}),"\n",(0,i.jsx)(t.p,{children:"Redeploying is the action of destroying a container and recreating it. If you update deployment config, these changes will not take effect until the container is redeployed. Just note this will destroy the previous containers logs along with the container itself."})]})}function p(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>s});var i=n(6540);const o={},a=i.createContext(o);function r(e){const t=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),i.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f8238c17.caff83ad.js b/assets/js/f8238c17.caff83ad.js deleted file mode 100644 index 253cf4cfd..000000000 --- a/assets/js/f8238c17.caff83ad.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[247],{2913:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>p,frontMatter:()=>a,metadata:()=>s,toc:()=>d});var i=t(4848),o=t(8453);const a={},r="Container Management",s={id:"deploy-containers/lifetime-management",title:"Container Management",description:"The lifetime of a docker container is more like a virtual machine. They can be created, started, stopped, and destroyed. Komodo will display the state of the container and provides an API to manage all your container's lifetimes.",source:"@site/docs/deploy-containers/lifetime-management.md",sourceDirName:"deploy-containers",slug:"/deploy-containers/lifetime-management",permalink:"/docs/deploy-containers/lifetime-management",draft:!1,unlisted:!1,editUrl:"https://github.com/mbecker20/komodo/tree/main/docsite/docs/deploy-containers/lifetime-management.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Configuration",permalink:"/docs/deploy-containers/configuration"},next:{title:"Docker Compose",permalink:"/docs/docker-compose"}},c={},d=[{value:"Stopping a Container",id:"stopping-a-container",level:3},{value:"Container Redeploy",id:"container-redeploy",level:3}];function l(e){const n={em:"em",h1:"h1",h3:"h3",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"container-management",children:"Container Management"})}),"\n",(0,i.jsx)(n.p,{children:"The lifetime of a docker container is more like a virtual machine. They can be created, started, stopped, and destroyed. Komodo will display the state of the container and provides an API to manage all your container's lifetimes."}),"\n",(0,i.jsx)(n.p,{children:"This is achieved internally by running the appropriate docker command for the requested action (docker stop, docker start, etc)."}),"\n",(0,i.jsx)(n.h3,{id:"stopping-a-container",children:"Stopping a Container"}),"\n",(0,i.jsxs)(n.p,{children:["Sometimes you want to stop a running application but preserve its logs and configuration, either to be restarted later or to view the logs at a later time. It is more like ",(0,i.jsx)(n.em,{children:"pausing"})," the application with its current config, as no configuration (like environment variable, volume mounts, etc.) will be changed when the container is started again."]}),"\n",(0,i.jsxs)(n.p,{children:["Note that in order to restart an application with updated configuration, it must be ",(0,i.jsx)(n.em,{children:"redeployed"}),". stopping and starting a container again will keep all configuration as it was when the container was initially created."]}),"\n",(0,i.jsx)(n.h3,{id:"container-redeploy",children:"Container Redeploy"}),"\n",(0,i.jsx)(n.p,{children:"Redeploying is the action of destroying a container and recreating it. If you update deployment config, these changes will not take effect until the container is redeployed. Just note this will destroy the previous containers logs along with the container itself."})]})}function p(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>s});var i=t(6540);const o={},a=i.createContext(o);function r(e){const n=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/main.199f88a3.js b/assets/js/main.28532d14.js similarity index 74% rename from assets/js/main.199f88a3.js rename to assets/js/main.28532d14.js index 218ac3adc..6f90c5f9e 100644 --- a/assets/js/main.199f88a3.js +++ b/assets/js/main.28532d14.js @@ -1,2 +1,2 @@ -/*! For license information please see main.199f88a3.js.LICENSE.txt */ -(self.webpackChunkdocsite=self.webpackChunkdocsite||[]).push([[792],{8328:(e,t,n)=>{"use strict";n.d(t,{A:()=>f});n(6540);var r=n(3259),o=n.n(r),a=n(4054);const i={"0058b4c6":[()=>n.e(849).then(n.t.bind(n,6164,19)),"@generated/docusaurus-plugin-content-docs/default/p/docs-175.json",6164],"0e384e19":[()=>n.e(976).then(n.bind(n,619)),"@site/docs/intro.md",619],17896441:[()=>Promise.all([n.e(869),n.e(394),n.e(401)]).then(n.bind(n,6716)),"@theme/DocItem",6716],"1bd19f0c":[()=>Promise.all([n.e(869),n.e(394),n.e(469)]).then(n.bind(n,9723)),"@site/docs/setup/advanced.mdx",9723],"1df93b7f":[()=>Promise.all([n.e(869),n.e(583)]).then(n.bind(n,7143)),"@site/src/pages/index.tsx",7143],"209736a1":[()=>n.e(580).then(n.bind(n,8e3)),"@site/docs/variables.md",8e3],"2f7566f9":[()=>Promise.all([n.e(869),n.e(394),n.e(464)]).then(n.bind(n,8830)),"@site/docs/connect-servers.mdx",8830],"3734296e":[()=>n.e(92).then(n.bind(n,5918)),"@site/docs/file-paths.md",5918],"39c35b2c":[()=>n.e(782).then(n.bind(n,8327)),"@site/docs/webhooks.md",8327],"5e95c892":[()=>n.e(647).then(n.bind(n,7121)),"@theme/DocsRoot",7121],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,4784)),"@generated/docusaurus.config",4784],"5ea303bc":[()=>Promise.all([n.e(869),n.e(394),n.e(535)]).then(n.bind(n,2320)),"@site/docs/setup/postgres.mdx",2320],"5fbc5cf1":[()=>n.e(624).then(n.bind(n,6933)),"@site/docs/api.md",6933],"669fcf45":[()=>n.e(552).then(n.bind(n,7478)),"@site/docs/sync-resources.md",7478],"6aab5236":[()=>n.e(663).then(n.bind(n,487)),"@site/docs/version-upgrades.md",487],75245258:[()=>Promise.all([n.e(869),n.e(531)]).then(n.bind(n,4016)),"@site/docs/deploy-containers/index.mdx",4016],"79c522c5":[()=>n.e(943).then(n.bind(n,3827)),"@site/docs/procedures.md",3827],"8b13a4b4":[()=>Promise.all([n.e(869),n.e(848)]).then(n.bind(n,5846)),"@site/docs/build-images/index.mdx",5846],"8f030830":[()=>n.e(423).then(n.bind(n,1792)),"@site/docs/development.md",1792],a5a01e01:[()=>n.e(549).then(n.bind(n,6175)),"@site/docs/build-images/versioning.md",6175],a5c9d4c4:[()=>n.e(636).then(n.bind(n,2612)),"@site/docs/docker-compose.md",2612],a7456010:[()=>n.e(235).then(n.t.bind(n,8552,19)),"@generated/docusaurus-plugin-content-pages/default/__plugin.json",8552],a7bd4aaa:[()=>n.e(98).then(n.bind(n,1723)),"@theme/DocVersionRoot",1723],a94703ab:[()=>Promise.all([n.e(869),n.e(48)]).then(n.bind(n,1377)),"@theme/DocRoot",1377],a9cd8699:[()=>n.e(648).then(n.bind(n,593)),"@site/docs/build-images/configuration.md",593],aba21aa0:[()=>n.e(742).then(n.t.bind(n,7093,19)),"@generated/docusaurus-plugin-content-docs/default/__plugin.json",7093],b19e82df:[()=>Promise.all([n.e(869),n.e(394),n.e(842)]).then(n.bind(n,8929)),"@site/docs/setup/mongo.mdx",8929],c54f4afd:[()=>n.e(846).then(n.bind(n,9728)),"@site/docs/permissioning.md",9728],c65a6c17:[()=>n.e(543).then(n.bind(n,1527)),"@site/docs/build-images/pre-build.md",1527],d92a3c43:[()=>n.e(864).then(n.bind(n,5804)),"@site/docs/resources.md",5804],ef1bbce5:[()=>n.e(100).then(n.bind(n,8151)),"@site/docs/build-images/builders.md",8151],ef526b88:[()=>n.e(995).then(n.bind(n,9302)),"@site/docs/deploy-containers/configuration.md",9302],ef9e0e28:[()=>Promise.all([n.e(869),n.e(394),n.e(947)]).then(n.bind(n,2589)),"@site/docs/setup/sqlite.mdx",2589],f600b847:[()=>Promise.all([n.e(869),n.e(238)]).then(n.bind(n,2945)),"@site/docs/setup/index.mdx",2945],f8238c17:[()=>n.e(247).then(n.bind(n,2913)),"@site/docs/deploy-containers/lifetime-management.md",2913]};var l=n(4848);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 u=n(6921),c=n(3102);function d(e,t){if("*"===e)return o()({loading:s,loader:()=>n.e(237).then(n.bind(n,2237)),modules:["@theme/NotFound"],webpack:()=>[2237],render(e,t){const n=e.default;return(0,l.jsx)(c.W,{value:{plugin:{name:"native",id:"default"}},children:(0,l.jsx)(n,{...t})})}});const r=a[`${e}-${t}`],d={},f=[],p=[],m=(0,u.A)(r);return Object.entries(m).forEach((e=>{let[t,n]=e;const r=i[n];r&&(d[t]=r[0],f.push(r[1]),p.push(r[2]))})),o().Map({loading:s,loader:d,modules:f,webpack:()=>p,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;delete o.__context;const s=o.__props;return delete o.__props,(0,l.jsx)(c.W,{value:i,children:(0,l.jsx)(a,{...o,...s,...n})})}})}const f=[{path:"/docs",component:d("/docs","f90"),routes:[{path:"/docs",component:d("/docs","8a4"),routes:[{path:"/docs",component:d("/docs","551"),routes:[{path:"/docs/api",component:d("/docs/api","a0a"),exact:!0,sidebar:"docs"},{path:"/docs/build-images",component:d("/docs/build-images","758"),exact:!0,sidebar:"docs"},{path:"/docs/build-images/builders",component:d("/docs/build-images/builders","774"),exact:!0,sidebar:"docs"},{path:"/docs/build-images/configuration",component:d("/docs/build-images/configuration","426"),exact:!0,sidebar:"docs"},{path:"/docs/build-images/pre-build",component:d("/docs/build-images/pre-build","f2d"),exact:!0,sidebar:"docs"},{path:"/docs/build-images/versioning",component:d("/docs/build-images/versioning","2a4"),exact:!0,sidebar:"docs"},{path:"/docs/connect-servers",component:d("/docs/connect-servers","4fd"),exact:!0,sidebar:"docs"},{path:"/docs/deploy-containers",component:d("/docs/deploy-containers","44c"),exact:!0,sidebar:"docs"},{path:"/docs/deploy-containers/configuration",component:d("/docs/deploy-containers/configuration","dd4"),exact:!0,sidebar:"docs"},{path:"/docs/deploy-containers/lifetime-management",component:d("/docs/deploy-containers/lifetime-management","4f2"),exact:!0,sidebar:"docs"},{path:"/docs/development",component:d("/docs/development","698"),exact:!0,sidebar:"docs"},{path:"/docs/docker-compose",component:d("/docs/docker-compose","196"),exact:!0,sidebar:"docs"},{path:"/docs/file-paths",component:d("/docs/file-paths","560"),exact:!0},{path:"/docs/intro",component:d("/docs/intro","a6e"),exact:!0,sidebar:"docs"},{path:"/docs/permissioning",component:d("/docs/permissioning","6e0"),exact:!0,sidebar:"docs"},{path:"/docs/procedures",component:d("/docs/procedures","b38"),exact:!0,sidebar:"docs"},{path:"/docs/resources",component:d("/docs/resources","da4"),exact:!0,sidebar:"docs"},{path:"/docs/setup",component:d("/docs/setup","371"),exact:!0,sidebar:"docs"},{path:"/docs/setup/advanced",component:d("/docs/setup/advanced","c00"),exact:!0,sidebar:"docs"},{path:"/docs/setup/mongo",component:d("/docs/setup/mongo","88e"),exact:!0,sidebar:"docs"},{path:"/docs/setup/postgres",component:d("/docs/setup/postgres","274"),exact:!0,sidebar:"docs"},{path:"/docs/setup/sqlite",component:d("/docs/setup/sqlite","39c"),exact:!0,sidebar:"docs"},{path:"/docs/sync-resources",component:d("/docs/sync-resources","74e"),exact:!0,sidebar:"docs"},{path:"/docs/variables",component:d("/docs/variables","515"),exact:!0,sidebar:"docs"},{path:"/docs/version-upgrades",component:d("/docs/version-upgrades","0b8"),exact:!0,sidebar:"docs"},{path:"/docs/webhooks",component:d("/docs/webhooks","a2e"),exact:!0,sidebar:"docs"}]}]}]},{path:"/",component:d("/","e5f"),exact:!0},{path:"*",component:d("*")}]},6125:(e,t,n)=>{"use strict";n.d(t,{o:()=>a,x:()=>i});var r=n(6540),o=n(4848);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})}},7815:(e,t,n)=>{"use strict";var r=n(6540),o=n(5338),a=n(545),i=n(4625),l=n(4784),s=n(8193);const u=[n(119),n(6134),n(6294),n(1043)];var c=n(8328),d=n(6347),f=n(2831),p=n(4848);function m(e){let{children:t}=e;return(0,p.jsx)(p.Fragment,{children:t})}var g=n(5260),h=n(4586),y=n(6025),b=n(6342),v=n(1003),w=n(2131),k=n(4090);const x="default";var S=n(440),E=n(1463);function _(){const{i18n:{currentLocale:e,defaultLocale:t,localeConfigs:n}}=(0,h.A)(),r=(0,w.o)(),o=n[e].htmlLang,a=e=>e.replace("-","_");return(0,p.jsxs)(g.A,{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.A)(),r=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,h.A)(),{pathname:r}=(0,d.zy)();return e+(0,S.Ks)((0,y.Ay)(r),{trailingSlash:n,baseUrl:t})}(),o=t?`${n}${t}`:r;return(0,p.jsxs)(g.A,{children:[(0,p.jsx)("meta",{property:"og:url",content:o}),(0,p.jsx)("link",{rel:"canonical",href:o})]})}function A(){const{i18n:{currentLocale:e}}=(0,h.A)(),{metadata:t,image:n}=(0,b.p)();return(0,p.jsxs)(p.Fragment,{children:[(0,p.jsxs)(g.A,{children:[(0,p.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,p.jsx)("body",{className:k.w})]}),n&&(0,p.jsx)(v.be,{image:n}),(0,p.jsx)(C,{}),(0,p.jsx)(_,{}),(0,p.jsx)(E.A,{tag:x,locale:e}),(0,p.jsx)(g.A,{children:t.map(((e,t)=>(0,p.jsx)("meta",{...e},t)))})]})}const T=new Map;var N=n(6125),O=n(6988),P=n(205);function j(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 L=function(e){let{children:t,location:n,previousLocation:r}=e;return(0,P.A)((()=>{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}),j("onRouteDidUpdate",{previousLocation:r,location:n}))}),[r,n]),t};function R(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,f.u)(c.A,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=s.A.canUseDOM?j("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=j("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),R(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)(L,{previousLocation:this.previousLocation,location:t,children:(0,p.jsx)(d.qh,{location:t,render:()=>e})})}}const D=I,F="__docusaurus-base-url-issue-banner-container",M="__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 = '${F}';\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(/{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}}((0,d.zy)());return(0,p.jsx)(D,{location:e,children:q})}function K(){return(0,p.jsx)(V.A,{children:(0,p.jsx)(O.l,{children:(0,p.jsxs)(N.x,{children:[(0,p.jsxs)(m,{children:[(0,p.jsx)(H,{}),(0,p.jsx)(A,{}),(0,p.jsx)(U,{}),(0,p.jsx)(Y,{})]}),(0,p.jsx)(G,{})]})})})}var Q=n(4054);const Z=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{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 X=n(6921);const J=new Set,ee=new Set,te=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,ne={prefetch:e=>{if(!(e=>!te()&&!ee.has(e)&&!J.has(e))(e))return!1;J.add(e);const t=(0,f.u)(c.A,e).flatMap((e=>{return t=e.route.path,Object.entries(Q).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,X.A)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?Z(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!te()&&!ee.has(e))(e)&&(ee.add(e),R(e))},re=Object.freeze(ne);function oe(e){let{children:t}=e;return"hash"===l.default.future.experimental_router?(0,p.jsx)(i.I9,{children:t}):(0,p.jsx)(i.Kd,{children:t})}const ae=Boolean(!0);if(s.A.canUseDOM){window.docusaurus=re;const e=document.getElementById("__docusaurus"),t=(0,p.jsx)(a.vd,{children:(0,p.jsx)(oe,{children:(0,p.jsx)(K,{})})}),n=(e,t)=>{console.error("Docusaurus React Root onRecoverableError:",e,t)},i=()=>{if(window.docusaurusRoot)window.docusaurusRoot.render(t);else if(ae)window.docusaurusRoot=o.hydrateRoot(e,t,{onRecoverableError:n});else{const r=o.createRoot(e,{onRecoverableError:n});r.render(t),window.docusaurusRoot=r}};R(window.location.pathname).then((()=>{(0,r.startTransition)(i)}))}},6988:(e,t,n)=>{"use strict";n.d(t,{o:()=>d,l:()=>f});var r=n(6540),o=n(4784);const a=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/docs","mainDocId":"intro","docs":[{"id":"api","path":"/docs/api","sidebar":"docs"},{"id":"build-images/builders","path":"/docs/build-images/builders","sidebar":"docs"},{"id":"build-images/configuration","path":"/docs/build-images/configuration","sidebar":"docs"},{"id":"build-images/index","path":"/docs/build-images","sidebar":"docs"},{"id":"build-images/pre-build","path":"/docs/build-images/pre-build","sidebar":"docs"},{"id":"build-images/versioning","path":"/docs/build-images/versioning","sidebar":"docs"},{"id":"connect-servers","path":"/docs/connect-servers","sidebar":"docs"},{"id":"deploy-containers/configuration","path":"/docs/deploy-containers/configuration","sidebar":"docs"},{"id":"deploy-containers/index","path":"/docs/deploy-containers/","sidebar":"docs"},{"id":"deploy-containers/lifetime-management","path":"/docs/deploy-containers/lifetime-management","sidebar":"docs"},{"id":"development","path":"/docs/development","sidebar":"docs"},{"id":"docker-compose","path":"/docs/docker-compose","sidebar":"docs"},{"id":"file-paths","path":"/docs/file-paths"},{"id":"intro","path":"/docs/intro","sidebar":"docs"},{"id":"permissioning","path":"/docs/permissioning","sidebar":"docs"},{"id":"procedures","path":"/docs/procedures","sidebar":"docs"},{"id":"resources","path":"/docs/resources","sidebar":"docs"},{"id":"setup/advanced","path":"/docs/setup/advanced","sidebar":"docs"},{"id":"setup/index","path":"/docs/setup/","sidebar":"docs"},{"id":"setup/mongo","path":"/docs/setup/mongo","sidebar":"docs"},{"id":"setup/postgres","path":"/docs/setup/postgres","sidebar":"docs"},{"id":"setup/sqlite","path":"/docs/setup/sqlite","sidebar":"docs"},{"id":"sync-resources","path":"/docs/sync-resources","sidebar":"docs"},{"id":"variables","path":"/docs/variables","sidebar":"docs"},{"id":"version-upgrades","path":"/docs/version-upgrades","sidebar":"docs"},{"id":"webhooks","path":"/docs/webhooks","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/docs/intro","label":"intro"}}}}],"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(2654);const s=JSON.parse('{"docusaurusVersion":"3.5.2","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"3.5.2"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"3.5.2"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"3.5.2"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"3.5.2"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"3.5.2"}}}');var u=n(4848);const c={siteConfig:o.default,siteMetadata:s,globalData:a,i18n:i,codeTranslations:l},d=r.createContext(c);function f(e){let{children:t}=e;return(0,u.jsx)(d.Provider,{value:c,children:t})}},7489:(e,t,n)=>{"use strict";n.d(t,{A:()=>g});var r=n(6540),o=n(8193),a=n(5260),i=n(440),l=n(781),s=n(3102),u=n(4848);function c(e){let{error:t,tryAgain:n}=e;return(0,u.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,u.jsx)("h1",{style:{fontSize:"3rem"},children:"This page crashed"}),(0,u.jsx)("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"},children:"Try again"}),(0,u.jsx)(d,{error:t})]})}function d(e){let{error:t}=e;const n=(0,i.rA)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,u.jsx)("p",{style:{whiteSpace:"pre-wrap"},children:n})}function f(e){let{children:t}=e;return(0,u.jsx)(s.W,{value:{plugin:{name:"docusaurus-core-error-boundary",id:"default"}},children:t})}function p(e){let{error:t,tryAgain:n}=e;return(0,u.jsx)(f,{children:(0,u.jsxs)(g,{fallback:()=>(0,u.jsx)(c,{error:t,tryAgain:n}),children:[(0,u.jsx)(a.A,{children:(0,u.jsx)("title",{children:"Page Error"})}),(0,u.jsx)(l.A,{children:(0,u.jsx)(c,{error:t,tryAgain:n})})]})})}const m=e=>(0,u.jsx)(p,{...e});class g extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){o.A.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??m)(e)}return e??null}}},8193:(e,t,n)=>{"use strict";n.d(t,{A:()=>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}},5260:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});n(6540);var r=n(545),o=n(4848);function a(e){return(0,o.jsx)(r.mg,{...e})}},8774:(e,t,n)=>{"use strict";n.d(t,{A:()=>p});var r=n(6540),o=n(4625),a=n(440),i=n(4586),l=n(6654),s=n(8193),u=n(3427),c=n(6025),d=n(4848);function f(e,t){let{isNavLink:n,to:f,href:p,activeClassName:m,isActive:g,"data-noBrokenLinkCheck":h,autoAddBaseUrl:y=!0,...b}=e;const{siteConfig:v}=(0,i.A)(),{trailingSlash:w,baseUrl:k}=v,x=v.future.experimental_router,{withBaseUrl:S}=(0,c.hH)(),E=(0,u.A)(),_=(0,r.useRef)(null);(0,r.useImperativeHandle)(t,(()=>_.current));const C=f||p;const A=(0,l.A)(C),T=C?.replace("pathname://","");let N=void 0!==T?(O=T,y&&(e=>e.startsWith("/"))(O)?S(O):O):void 0;var O;"hash"===x&&N?.startsWith("./")&&(N=N?.slice(1)),N&&A&&(N=(0,a.Ks)(N,{trailingSlash:w,baseUrl:k}));const P=(0,r.useRef)(!1),j=n?o.k2:o.N_,L=s.A.canUseIntersectionObserver,R=(0,r.useRef)(),I=()=>{P.current||null==N||(window.docusaurus.preload(N),P.current=!0)};(0,r.useEffect)((()=>(!L&&A&&s.A.canUseDOM&&null!=N&&window.docusaurus.prefetch(N),()=>{L&&R.current&&R.current.disconnect()})),[R,N,L,A]);const D=N?.startsWith("#")??!1,F=!b.target||"_self"===b.target,M=!N||!A||!F||D&&"hash"!==x;h||!D&&M||E.collectLink(N),b.id&&E.collectAnchor(b.id);const z={};return M?(0,d.jsx)("a",{ref:_,href:N,...C&&!A&&{target:"_blank",rel:"noopener noreferrer"},...b,...z}):(0,d.jsx)(j,{...b,onMouseEnter:I,onTouchStart:I,innerRef:e=>{_.current=e,L&&e&&A&&(R.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(R.current.unobserve(e),R.current.disconnect(),null!=N&&window.docusaurus.prefetch(N))}))})),R.current.observe(e))},to:N,...n&&{isActive:g,activeClassName:m},...z})}const p=r.forwardRef(f)},418:(e,t,n)=>{"use strict";n.d(t,{A:()=>r});const r=()=>null},1312:(e,t,n)=>{"use strict";n.d(t,{A:()=>u,T:()=>s});var r=n(6540),o=n(4848);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(2654);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 u(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)})}},7065:(e,t,n)=>{"use strict";n.d(t,{W:()=>r});const r="default"},6654:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function o(e){return void 0!==e&&!r(e)}n.d(t,{A:()=>o,z:()=>r})},6025:(e,t,n)=>{"use strict";n.d(t,{Ay:()=>l,hH:()=>i});var r=n(6540),o=n(4586),a=n(6654);function i(){const{siteConfig:e}=(0,o.A)(),{baseUrl:t,url:n}=e,i=e.future.experimental_router,l=(0,r.useCallback)(((e,r)=>function(e){let{siteUrl:t,baseUrl:n,url:r,options:{forcePrependBaseUrl:o=!1,absolute:i=!1}={},router:l}=e;if(!r||r.startsWith("#")||(0,a.z)(r))return r;if("hash"===l)return r.startsWith("/")?`.${r}`:`./${r}`;if(o)return n+r.replace(/^\//,"");if(r===n.replace(/\/$/,""))return n;const s=r.startsWith(n)?r:n+r.replace(/^\//,"");return i?t+s:s}({siteUrl:n,baseUrl:t,url:e,options:r,router:i})),[n,t,i]);return{withBaseUrl:l}}function l(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},3427:(e,t,n)=>{"use strict";n.d(t,{A:()=>i});var r=n(6540);n(4848);const o=r.createContext({collectAnchor:()=>{},collectLink:()=>{}}),a=()=>(0,r.useContext)(o);function i(){return a()}},4586:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var r=n(6540),o=n(6988);function a(){return(0,r.useContext)(o.o)}},2303:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var r=n(6540),o=n(6125);function a(){return(0,r.useContext)(o.o)}},205:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=n(6540);const o=n(8193).A.canUseDOM?r.useLayoutEffect:r.useEffect},6921:(e,t,n)=>{"use strict";n.d(t,{A:()=>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}},3102:(e,t,n)=>{"use strict";n.d(t,{W:()=>i,o:()=>a});var r=n(6540),o=n(4848);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})}},3886:(e,t,n)=>{"use strict";n.d(t,{VQ:()=>h,g1:()=>b});var r=n(6540),o=n(4070),a=n(7065),i=n(6342),l=n(679),s=n(9532),u=n(4848);const c=e=>`docs-preferred-version-${e}`,d={save:(e,t,n)=>{(0,l.Wf)(c(e),{persistence:t}).set(n)},read:(e,t)=>(0,l.Wf)(c(e),{persistence:t}).get(),clear:(e,t)=>{(0,l.Wf)(c(e),{persistence:t}).del()}},f=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const p=r.createContext(null);function m(){const e=(0,o.Gy)(),t=(0,i.p)().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=d.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(d.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){d.save(e,t,n),l((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function g(e){let{children:t}=e;const n=m();return(0,u.jsx)(p.Provider,{value:n,children:t})}function h(e){let{children:t}=e;return(0,u.jsx)(g,{children:t})}function y(){const e=(0,r.useContext)(p);if(!e)throw new s.dV("DocsPreferredVersionContextProvider");return e}function b(e){void 0===e&&(e=a.W);const t=(0,o.ht)(e),[n,i]=y(),{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])}}},609:(e,t,n)=>{"use strict";n.d(t,{V:()=>s,t:()=>u});var r=n(6540),o=n(9532),a=n(4848);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 u(){const e=(0,r.useContext)(l);if(e===i)throw new o.dV("DocsSidebarProvider");return e}},6972:(e,t,n)=>{"use strict";n.d(t,{$S:()=>m,B5:()=>_,Nr:()=>p,OF:()=>k,QB:()=>E,Vd:()=>x,Y:()=>v,cC:()=>f,d1:()=>C,fW:()=>S,w8:()=>y});var r=n(6540),o=n(6347),a=n(2831),i=n(4070),l=n(9169),s=n(1682),u=n(3886),c=n(3025),d=n(609);function f(e){const t=(0,c.r)();if(!e)return;const n=t.docs[e];if(!n)throw new Error(`no version doc found by id=${e}`);return n}function p(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=p(t);if(e)return e}}(e):void 0:e.href}function m(){const{pathname:e}=(0,o.zy)(),t=(0,d.t)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");const n=w({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,l.ys)(e,t),h=(e,t)=>e.some((e=>y(e,t)));function y(e,t){return"link"===e.type?g(e.href,t):"category"===e.type&&(g(e.href,t)||h(e.items,t))}function b(e,t){switch(e.type){case"category":return y(e,t)||e.items.some((e=>b(e,t)));case"link":return!e.unlisted||y(e,t);default:return!0}}function v(e,t){return(0,r.useMemo)((()=>e.filter((e=>b(e,t)))),[e,t])}function w(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,l.ys)(a.href,n)||e(a.items))||"link"===a.type&&(0,l.ys)(a.href,n)){return r&&"category"!==a.type||o.unshift(a),!0}return!1}(t),o}function k(){const e=(0,d.t)(),{pathname:t}=(0,o.zy)(),n=(0,i.vT)()?.pluginData.breadcrumbs;return!1!==n&&e?w({sidebarItems:e.items,pathname:t}):null}function x(e){const{activeVersion:t}=(0,i.zK)(e),{preferredVersion:n}=(0,u.g1)(e),o=(0,i.r7)(e);return(0,r.useMemo)((()=>(0,s.sb)([t,n,o].filter(Boolean))),[t,n,o])}function S(e,t){const n=x(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 E(e,t){const n=x(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,s.sb)(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function _(e){let{route:t}=e;const n=(0,o.zy)(),r=(0,c.r)(),i=t.routes,l=i.find((e=>(0,o.B6)(n.pathname,e)));if(!l)return null;const s=l.sidebar,u=s?r.docsSidebars[s]:void 0;return{docElement:(0,a.v)(i),sidebarName:s,sidebarItems:u}}function C(e){return e.filter((e=>!("category"===e.type||"link"===e.type)||!!p(e)))}},3025:(e,t,n)=>{"use strict";n.d(t,{n:()=>l,r:()=>s});var r=n(6540),o=n(9532),a=n(4848);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.dV("DocsVersionProvider");return e}},4070:(e,t,n)=>{"use strict";n.d(t,{zK:()=>g,vT:()=>f,Gy:()=>c,HW:()=>h,ht:()=>d,r7:()=>m,jh:()=>p});var r=n(6347),o=n(4586),a=n(7065);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,o.A)();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=function(e,t){return[...e.versions].sort(((e,t)=>e.path===t.path?0:e.path.includes(t.path)?-1:t.path.includes(e.path)?1:0)).find((e=>!!(0,r.B6)(t,{path:e.path,exact:!1,strict:!1})))}(e,t),o=n?.docs.find((e=>!!(0,r.B6)(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={},c=()=>i("docusaurus-plugin-content-docs")??u,d=e=>{try{return function(e,t,n){void 0===t&&(t=a.W),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})}catch(t){throw new Error("You are using a feature of the Docusaurus docs plugin, but this plugin does not seem to be enabled"+("Default"===e?"":` (pluginId=${e}`),{cause:t})}};function f(e){void 0===e&&(e={});const t=c(),{pathname:n}=(0,r.zy)();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.B6)(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 p(e){return d(e).versions}function m(e){const t=d(e);return l(t)}function g(e){const t=d(e),{pathname:n}=(0,r.zy)();return s(t,n)}function h(e){const t=d(e),{pathname:n}=(0,r.zy)();return function(e,t){const n=l(e);return{latestDocSuggestion:s(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},6294:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(5947),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()}}},6134:(e,t,n)=>{"use strict";var r=n(1765),o=n(4784);!function(e){const{themeConfig:{prism:t}}=o.default,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{"php"===e&&n(9700),n(8133)(`./prism-${e}`)})),delete globalThis.Prism}(r.My)},1107:(e,t,n)=>{"use strict";n.d(t,{A:()=>c});n(6540);var r=n(4164),o=n(1312),a=n(6342),i=n(8774),l=n(3427);const s={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};var u=n(4848);function c(e){let{as:t,id:n,...c}=e;const d=(0,l.A)(),{navbar:{hideOnScroll:f}}=(0,a.p)();if("h1"===t||!n)return(0,u.jsx)(t,{...c,id:void 0});d.collectAnchor(n);const p=(0,o.T)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof c.children?c.children:n});return(0,u.jsxs)(t,{...c,className:(0,r.A)("anchor",f?s.anchorWithHideOnScrollNavbar:s.anchorWithStickyNavbar,c.className),id:n,children:[c.children,(0,u.jsx)(i.A,{className:"hash-link",to:`#${n}`,"aria-label":p,title:p,children:"\u200b"})]})}},3186:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});n(6540);const r={iconExternalLink:"iconExternalLink_nPIU"};var o=n(4848);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"})})}},781:(e,t,n)=>{"use strict";n.d(t,{A:()=>pt});var r=n(6540),o=n(4164),a=n(7489),i=n(1003),l=n(6347),s=n(1312),u=n(5062),c=n(4848);const d="__docusaurus_skipToContent_fallback";function f(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function p(){const e=(0,r.useRef)(null),{action:t}=(0,l.W6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&f(t)}),[]);return(0,u.$)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&f(e.current)})),{containerRef:e,onClick:n}}const m=(0,s.T)({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 g(e){const t=e.children??m,{containerRef:n,onClick:r}=p();return(0,c.jsx)("div",{ref:n,role:"region","aria-label":m,children:(0,c.jsx)("a",{...e,href:`#${d}`,onClick:r,children:t})})}var h=n(7559),y=n(4090);const b={skipToContent:"skipToContent_fXgn"};function v(){return(0,c.jsx)(g,{className:b.skipToContent})}var w=n(6342),k=n(5041);function x(e){let{width:t=21,height:n=21,color:r="currentColor",strokeWidth:o=1.2,className:a,...i}=e;return(0,c.jsx)("svg",{viewBox:"0 0 15 15",width:t,height:n,...i,children:(0,c.jsx)("g",{stroke:r,strokeWidth:o,children:(0,c.jsx)("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})})})}const S={closeButton:"closeButton_CVFx"};function E(e){return(0,c.jsx)("button",{type:"button","aria-label":(0,s.T)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"}),...e,className:(0,o.A)("clean-btn close",S.closeButton,e.className),children:(0,c.jsx)(x,{width:14,height:14,strokeWidth:3.1})})}const _={content:"content_knG7"};function C(e){const{announcementBar:t}=(0,w.p)(),{content:n}=t;return(0,c.jsx)("div",{...e,className:(0,o.A)(_.content,e.className),dangerouslySetInnerHTML:{__html:n}})}const A={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function T(){const{announcementBar:e}=(0,w.p)(),{isActive:t,close:n}=(0,k.M)();if(!t)return null;const{backgroundColor:r,textColor:o,isCloseable:a}=e;return(0,c.jsxs)("div",{className:A.announcementBar,style:{backgroundColor:r,color:o},role:"banner",children:[a&&(0,c.jsx)("div",{className:A.announcementBarPlaceholder}),(0,c.jsx)(C,{className:A.announcementBarContent}),a&&(0,c.jsx)(E,{onClick:n,className:A.announcementBarClose})]})}var N=n(2069),O=n(3104);var P=n(9532),j=n(5600);const L=r.createContext(null);function R(e){let{children:t}=e;const n=function(){const e=(0,N.M)(),t=(0,j.YL)(),[n,o]=(0,r.useState)(!1),a=null!==t.component,i=(0,P.ZC)(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,c.jsx)(L.Provider,{value:n,children:t})}function I(e){if(e.component){const t=e.component;return(0,c.jsx)(t,{...e.props})}}function D(){const e=(0,r.useContext)(L);if(!e)throw new P.dV("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,o=(0,r.useCallback)((()=>n(!1)),[n]),a=(0,j.YL)();return(0,r.useMemo)((()=>({shown:t,hide:o,content:I(a)})),[o,a,t])}function F(e){let{header:t,primaryMenu:n,secondaryMenu:r}=e;const{shown:a}=D();return(0,c.jsxs)("div",{className:"navbar-sidebar",children:[t,(0,c.jsxs)("div",{className:(0,o.A)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":a}),children:[(0,c.jsx)("div",{className:"navbar-sidebar__item menu",children:n}),(0,c.jsx)("div",{className:"navbar-sidebar__item menu",children:r})]})]})}var M=n(5293),z=n(2303);function B(e){return(0,c.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,c.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 $(e){return(0,c.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,c.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 U={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function H(e){let{className:t,buttonClassName:n,value:r,onChange:a}=e;const i=(0,z.A)(),l=(0,s.T)({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.T)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,s.T)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return(0,c.jsx)("div",{className:(0,o.A)(U.toggle,t),children:(0,c.jsxs)("button",{className:(0,o.A)("clean-btn",U.toggleButton,!i&&U.toggleButtonDisabled,n),type:"button",onClick:()=>a("dark"===r?"light":"dark"),disabled:!i,title:l,"aria-label":l,"aria-live":"polite",children:[(0,c.jsx)(B,{className:(0,o.A)(U.toggleIcon,U.lightToggleIcon)}),(0,c.jsx)($,{className:(0,o.A)(U.toggleIcon,U.darkToggleIcon)})]})})}const V=r.memo(H),W={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function G(e){let{className:t}=e;const n=(0,w.p)().navbar.style,r=(0,w.p)().colorMode.disableSwitch,{colorMode:o,setColorMode:a}=(0,M.G)();return r?null:(0,c.jsx)(V,{className:t,buttonClassName:"dark"===n?W.darkNavbarColorModeToggle:void 0,value:o,onChange:a})}var q=n(3465);function Y(){return(0,c.jsx)(q.A,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function K(){const e=(0,N.M)();return(0,c.jsx)("button",{type:"button","aria-label":(0,s.T)({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,c.jsx)(x,{color:"var(--ifm-color-emphasis-600)"})})}function Q(){return(0,c.jsxs)("div",{className:"navbar-sidebar__brand",children:[(0,c.jsx)(Y,{}),(0,c.jsx)(G,{className:"margin-right--md"}),(0,c.jsx)(K,{})]})}var Z=n(8774),X=n(6025),J=n(6654);function ee(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var te=n(3186);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:r,href:o,label:a,html:i,isDropdownLink:l,prependBaseUrlToHref:s,...u}=e;const d=(0,X.Ay)(r),f=(0,X.Ay)(t),p=(0,X.Ay)(o,{forcePrependBaseUrl:!0}),m=a&&o&&!(0,J.A)(o),g=i?{dangerouslySetInnerHTML:{__html:i}}:{children:(0,c.jsxs)(c.Fragment,{children:[a,m&&(0,c.jsx)(te.A,{...l&&{width:12,height:12}})]})};return o?(0,c.jsx)(Z.A,{href:s?p:o,...u,...g}):(0,c.jsx)(Z.A,{to:d,isNavLink:!0,...(t||n)&&{isActive:(e,t)=>n?ee(n,t.pathname):t.pathname.startsWith(f)},...u,...g})}function re(e){let{className:t,isDropdownItem:n=!1,...r}=e;const a=(0,c.jsx)(ne,{className:(0,o.A)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n,...r});return n?(0,c.jsx)("li",{children:a}):a}function oe(e){let{className:t,isDropdownItem:n,...r}=e;return(0,c.jsx)("li",{className:"menu__list-item",children:(0,c.jsx)(ne,{className:(0,o.A)("menu__link",t),...r})})}function ae(e){let{mobile:t=!1,position:n,...r}=e;const o=t?oe:re;return(0,c.jsx)(o,{...r,activeClassName:r.activeClassName??(t?"menu__link--active":"navbar__link--active")})}var ie=n(1422),le=n(9169),se=n(4586);const ue={dropdownNavbarItemMobile:"dropdownNavbarItemMobile_S0Fm"};function ce(e,t){return e.some((e=>function(e,t){return!!(0,le.ys)(e.to,t)||!!ee(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),[u,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,c.jsxs)("div",{ref:s,className:(0,o.A)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":u}),children:[(0,c.jsx)(ne,{"aria-haspopup":"true","aria-expanded":u,role:"button",href:l.to?void 0:"#",className:(0,o.A)("navbar__link",a),...l,onClick:l.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!u))},children:l.children??l.label}),(0,c.jsx)("ul",{className:"dropdown__menu",children:t.map(((e,t)=>(0,r.createElement)(_e,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t})))})]})}function fe(e){let{items:t,className:n,position:a,onClick:i,...s}=e;const u=function(){const{siteConfig:{baseUrl:e}}=(0,se.A)(),{pathname:t}=(0,l.zy)();return t.replace(e,"/")}(),d=ce(t,u),{collapsed:f,toggleCollapsed:p,setCollapsed:m}=(0,ie.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&m(!d)}),[u,d,m]),(0,c.jsxs)("li",{className:(0,o.A)("menu__list-item",{"menu__list-item--collapsed":f}),children:[(0,c.jsx)(ne,{role:"button",className:(0,o.A)(ue.dropdownNavbarItemMobile,"menu__link menu__link--sublist menu__link--sublist-caret",n),...s,onClick:e=>{e.preventDefault(),p()},children:s.children??s.label}),(0,c.jsx)(ie.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:f,children:t.map(((e,t)=>(0,r.createElement)(_e,{mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active",...e,key:t})))})]})}function pe(e){let{mobile:t=!1,...n}=e;const r=t?fe:de;return(0,c.jsx)(r,{...n})}var me=n(2131);function ge(e){let{width:t=20,height:n=20,...r}=e;return(0,c.jsx)("svg",{viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0,...r,children:(0,c.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 he="iconLanguage_nlXk";var ye=n(418);const be={navbarSearchContainer:"navbarSearchContainer_Bca1"};function ve(e){let{children:t,className:n}=e;return(0,c.jsx)("div",{className:(0,o.A)(n,be.navbarSearchContainer),children:t})}var we=n(4070),ke=n(6972);var xe=n(3886);function Se(e,t){return t.alternateDocVersions[e.name]??function(e){return e.docs.find((t=>t.id===e.mainDocId))}(e)}const Ee={default:ae,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:r,queryString:o="",...a}=e;const{i18n:{currentLocale:i,locales:u,localeConfigs:d}}=(0,se.A)(),f=(0,me.o)(),{search:p,hash:m}=(0,l.zy)(),g=[...n,...u.map((e=>{const n=`${`pathname://${f.createUrl({locale:e,fullyQualified:!1})}`}${p}${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],h=t?(0,s.T)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[i].label;return(0,c.jsx)(pe,{...a,mobile:t,label:(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(ge,{className:he}),h]}),items:g})},search:function(e){let{mobile:t,className:n}=e;return t?null:(0,c.jsx)(ve,{className:n,children:(0,c.jsx)(ye.A,{})})},dropdown:pe,html:function(e){let{value:t,className:n,mobile:r=!1,isDropdownItem:a=!1}=e;const i=a?"li":"div";return(0,c.jsx)(i,{className:(0,o.A)({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,we.zK)(r),i=(0,ke.QB)(t,r),l=a?.path===i?.path;return null===i||i.unlisted&&!l?null:(0,c.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,we.zK)(r),i=(0,ke.fW)(t,r).link;if(!i)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return(0,c.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,ke.Vd)(r)[0],i=t??a.label,l=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(a).path;return(0,c.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:u,hash:d}=(0,l.zy)(),f=(0,we.zK)(n),p=(0,we.jh)(n),{savePreferredVersionName:m}=(0,xe.g1)(n),g=[...o,...p.map((function(e){const t=Se(e,f);return{label:e.label,to:`${t.path}${u}${d}`,isActive:()=>e===f.activeVersion,onClick:()=>m(e.name)}})),...a],h=(0,ke.Vd)(n)[0],y=t&&g.length>1?(0,s.T)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):h.label,b=t&&g.length>1?void 0:Se(h,f).path;return g.length<=1?(0,c.jsx)(ae,{...i,mobile:t,label:y,to:b,isActive:r?()=>!1:void 0}):(0,c.jsx)(pe,{...i,mobile:t,label:y,to:b,items:g,isActive:r?()=>!1:void 0})}};function _e(e){let{type:t,...n}=e;const r=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=Ee[r];if(!o)throw new Error(`No NavbarItem component found for type "${t}".`);return(0,c.jsx)(o,{...n})}function Ce(){const e=(0,N.M)(),t=(0,w.p)().navbar.items;return(0,c.jsx)("ul",{className:"menu__list",children:t.map(((t,n)=>(0,r.createElement)(_e,{mobile:!0,...t,onClick:()=>e.toggle(),key:n})))})}function Ae(e){return(0,c.jsx)("button",{...e,type:"button",className:"clean-btn navbar-sidebar__back",children:(0,c.jsx)(s.A,{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 Te(){const e=0===(0,w.p)().navbar.items.length,t=D();return(0,c.jsxs)(c.Fragment,{children:[!e&&(0,c.jsx)(Ae,{onClick:()=>t.hide()}),t.content]})}function Ne(){const e=(0,N.M)();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,c.jsx)(F,{header:(0,c.jsx)(Q,{}),primaryMenu:(0,c.jsx)(Ce,{}),secondaryMenu:(0,c.jsx)(Te,{})}):null}const Oe={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Pe(e){return(0,c.jsx)("div",{role:"presentation",...e,className:(0,o.A)("navbar-sidebar__backdrop",e.className)})}function je(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:a}}=(0,w.p)(),i=(0,N.M)(),{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,O.Mq)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i=l?n(!1):i+u{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,c.jsxs)("nav",{ref:l,"aria-label":(0,s.T)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,o.A)("navbar","navbar--fixed-top",n&&[Oe.navbarHideable,!d&&Oe.navbarHidden],{"navbar--dark":"dark"===a,"navbar--primary":"primary"===a,"navbar-sidebar--show":i.shown}),children:[t,(0,c.jsx)(Pe,{onClick:i.toggle}),(0,c.jsx)(Ne,{})]})}var Le=n(440);const Re={errorBoundaryError:"errorBoundaryError_a6uf",errorBoundaryFallback:"errorBoundaryFallback_VBag"};function Ie(e){return(0,c.jsx)("button",{type:"button",...e,children:(0,c.jsx)(s.A,{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 De(e){let{error:t}=e;const n=(0,Le.rA)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,c.jsx)("p",{className:Re.errorBoundaryError,children:n})}class Fe extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}const Me="right";function ze(e){let{width:t=30,height:n=30,className:r,...o}=e;return(0,c.jsx)("svg",{className:r,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true",...o,children:(0,c.jsx)("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"})})}function Be(){const{toggle:e,shown:t}=(0,N.M)();return(0,c.jsx)("button",{onClick:e,"aria-label":(0,s.T)({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,c.jsx)(ze,{})})}const $e={colorModeToggle:"colorModeToggle_DEke"};function Ue(e){let{items:t}=e;return(0,c.jsx)(c.Fragment,{children:t.map(((e,t)=>(0,c.jsx)(Fe,{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,c.jsx)(_e,{...e})},t)))})}function He(e){let{left:t,right:n}=e;return(0,c.jsxs)("div",{className:"navbar__inner",children:[(0,c.jsx)("div",{className:"navbar__items",children:t}),(0,c.jsx)("div",{className:"navbar__items navbar__items--right",children:n})]})}function Ve(){const e=(0,N.M)(),t=(0,w.p)().navbar.items,[n,r]=function(e){function t(e){return"left"===(e.position??Me)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),o=t.find((e=>"search"===e.type));return(0,c.jsx)(He,{left:(0,c.jsxs)(c.Fragment,{children:[!e.disabled&&(0,c.jsx)(Be,{}),(0,c.jsx)(Y,{}),(0,c.jsx)(Ue,{items:n})]}),right:(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(Ue,{items:r}),(0,c.jsx)(G,{className:$e.colorModeToggle}),!o&&(0,c.jsx)(ve,{children:(0,c.jsx)(ye.A,{})})]})})}function We(){return(0,c.jsx)(je,{children:(0,c.jsx)(Ve,{})})}function Ge(e){let{item:t}=e;const{to:n,href:r,label:o,prependBaseUrlToHref:a,...i}=t,l=(0,X.Ay)(n),s=(0,X.Ay)(r,{forcePrependBaseUrl:!0});return(0,c.jsxs)(Z.A,{className:"footer__link-item",...r?{href:a?s:r}:{to:l},...i,children:[o,r&&!(0,J.A)(r)&&(0,c.jsx)(te.A,{})]})}function qe(e){let{item:t}=e;return t.html?(0,c.jsx)("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):(0,c.jsx)("li",{className:"footer__item",children:(0,c.jsx)(Ge,{item:t})},t.href??t.to)}function Ye(e){let{column:t}=e;return(0,c.jsxs)("div",{className:"col footer__col",children:[(0,c.jsx)("div",{className:"footer__title",children:t.title}),(0,c.jsx)("ul",{className:"footer__items clean-list",children:t.items.map(((e,t)=>(0,c.jsx)(qe,{item:e},t)))})]})}function Ke(e){let{columns:t}=e;return(0,c.jsx)("div",{className:"row footer__links",children:t.map(((e,t)=>(0,c.jsx)(Ye,{column:e},t)))})}function Qe(){return(0,c.jsx)("span",{className:"footer__link-separator",children:"\xb7"})}function Ze(e){let{item:t}=e;return t.html?(0,c.jsx)("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):(0,c.jsx)(Ge,{item:t})}function Xe(e){let{links:t}=e;return(0,c.jsx)("div",{className:"footer__links text--center",children:(0,c.jsx)("div",{className:"footer__links",children:t.map(((e,n)=>(0,c.jsxs)(r.Fragment,{children:[(0,c.jsx)(Ze,{item:e}),t.length!==n+1&&(0,c.jsx)(Qe,{})]},n)))})})}function Je(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?(0,c.jsx)(Ke,{columns:t}):(0,c.jsx)(Xe,{links:t})}var et=n(1122);const tt={footerLogoLink:"footerLogoLink_BH7S"};function nt(e){let{logo:t}=e;const{withBaseUrl:n}=(0,X.hH)(),r={light:n(t.src),dark:n(t.srcDark??t.src)};return(0,c.jsx)(et.A,{className:(0,o.A)("footer__logo",t.className),alt:t.alt,sources:r,width:t.width,height:t.height,style:t.style})}function rt(e){let{logo:t}=e;return t.href?(0,c.jsx)(Z.A,{href:t.href,className:tt.footerLogoLink,target:t.target,children:(0,c.jsx)(nt,{logo:t})}):(0,c.jsx)(nt,{logo:t})}function ot(e){let{copyright:t}=e;return(0,c.jsx)("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function at(e){let{style:t,links:n,logo:r,copyright:a}=e;return(0,c.jsx)("footer",{className:(0,o.A)("footer",{"footer--dark":"dark"===t}),children:(0,c.jsxs)("div",{className:"container container-fluid",children:[n,(r||a)&&(0,c.jsxs)("div",{className:"footer__bottom text--center",children:[r&&(0,c.jsx)("div",{className:"margin-bottom--sm",children:r}),a]})]})})}function it(){const{footer:e}=(0,w.p)();if(!e)return null;const{copyright:t,links:n,logo:r,style:o}=e;return(0,c.jsx)(at,{style:o,links:n&&n.length>0&&(0,c.jsx)(Je,{links:n}),logo:r&&(0,c.jsx)(rt,{logo:r}),copyright:t&&(0,c.jsx)(ot,{copyright:t})})}const lt=r.memo(it),st=(0,P.fM)([M.a,k.o,O.Tv,xe.VQ,i.Jx,function(e){let{children:t}=e;return(0,c.jsx)(j.y_,{children:(0,c.jsx)(N.e,{children:(0,c.jsx)(R,{children:t})})})}]);function ut(e){let{children:t}=e;return(0,c.jsx)(st,{children:t})}var ct=n(1107);function dt(e){let{error:t,tryAgain:n}=e;return(0,c.jsx)("main",{className:"container margin-vert--xl",children:(0,c.jsx)("div",{className:"row",children:(0,c.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,c.jsx)(ct.A,{as:"h1",className:"hero__title",children:(0,c.jsx)(s.A,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed",children:"This page crashed."})}),(0,c.jsx)("div",{className:"margin-vert--lg",children:(0,c.jsx)(Ie,{onClick:n,className:"button button--primary shadow--lw"})}),(0,c.jsx)("hr",{}),(0,c.jsx)("div",{className:"margin-vert--md",children:(0,c.jsx)(De,{error:t})})]})})})}const ft={mainWrapper:"mainWrapper_z2l0"};function pt(e){const{children:t,noFooter:n,wrapperClassName:r,title:l,description:s}=e;return(0,y.J)(),(0,c.jsxs)(ut,{children:[(0,c.jsx)(i.be,{title:l,description:s}),(0,c.jsx)(v,{}),(0,c.jsx)(T,{}),(0,c.jsx)(We,{}),(0,c.jsx)("div",{id:d,className:(0,o.A)(h.G.wrapper.main,ft.mainWrapper,r),children:(0,c.jsx)(a.A,{fallback:e=>(0,c.jsx)(dt,{...e}),children:t})}),!n&&(0,c.jsx)(lt,{})]})}},3465:(e,t,n)=>{"use strict";n.d(t,{A:()=>c});n(6540);var r=n(8774),o=n(6025),a=n(4586),i=n(6342),l=n(1122),s=n(4848);function u(e){let{logo:t,alt:n,imageClassName:r}=e;const a={light:(0,o.Ay)(t.src),dark:(0,o.Ay)(t.srcDark||t.src)},i=(0,s.jsx)(l.A,{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 c(e){const{siteConfig:{title:t}}=(0,a.A)(),{navbar:{title:n,logo:l}}=(0,i.p)(),{imageClassName:c,titleClassName:d,...f}=e,p=(0,o.Ay)(l?.href||"/"),m=n?"":t,g=l?.alt??m;return(0,s.jsxs)(r.A,{to:p,...f,...l?.target&&{target:l.target},children:[l&&(0,s.jsx)(u,{logo:l,alt:g,imageClassName:c}),null!=n&&(0,s.jsx)("b",{className:d,children:n})]})}},1463:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});n(6540);var r=n(5260),o=n(4848);function a(e){let{locale:t,version:n,tag:a}=e;const i=t;return(0,o.jsxs)(r.A,{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})]})}},1122:(e,t,n)=>{"use strict";n.d(t,{A:()=>c});var r=n(6540),o=n(4164),a=n(2303),i=n(5293);const l={themedComponent:"themedComponent_mlkZ","themedComponent--light":"themedComponent--light_NVdE","themedComponent--dark":"themedComponent--dark_xIcU"};var s=n(4848);function u(e){let{className:t,children:n}=e;const u=(0,a.A)(),{colorMode:c}=(0,i.G)();return(0,s.jsx)(s.Fragment,{children:(u?"dark"===c?["dark"]:["light"]:["light","dark"]).map((e=>{const a=n({theme:e,className:(0,o.A)(t,l.themedComponent,l[`themedComponent--${e}`])});return(0,s.jsx)(r.Fragment,{children:a},e)}))})}function c(e){const{sources:t,className:n,alt:r,...o}=e;return(0,s.jsx)(u,{className:n,children:e=>{let{theme:n,className:a}=e;return(0,s.jsx)("img",{src:t[n],alt:r,className:a,...o})}})}},1422:(e,t,n)=>{"use strict";n.d(t,{N:()=>y,u:()=>u});var r=n(6540),o=n(8193),a=n(205),i=n(3109),l=n(4848);const s="ease-in-out";function u(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 c={display:"none",overflow:"hidden",height:"0px"},d={display:"block",overflow:"visible",height:"auto"};function f(e,t){const n=t?c:d;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function p(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.O)())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 f(e,n),void(a.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(l(),requestAnimationFrame((()=>{e.style.height=c.height,e.style.overflow=c.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{l()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,o])}function m(e){if(!o.A.canUseDOM)return e?c:d}function g(e){let{as:t="div",collapsed:n,children:o,animation:a,onCollapseTransitionEnd:i,className:s,disableSSRStyle:u}=e;const c=(0,r.useRef)(null);return p({collapsibleRef:c,collapsed:n,animation:a}),(0,l.jsx)(t,{ref:c,style:u?void 0:m(n),onTransitionEnd:e=>{"height"===e.propertyName&&(f(c.current,n),i?.(n))},className:s,children:o})}function h(e){let{collapsed:t,...n}=e;const[o,i]=(0,r.useState)(!t),[s,u]=(0,r.useState)(t);return(0,a.A)((()=>{t||i(!0)}),[t]),(0,a.A)((()=>{o&&u(t)}),[o,t]),o?(0,l.jsx)(g,{...n,collapsed:s}):null}function y(e){let{lazy:t,...n}=e;const r=t?h:g;return(0,l.jsx)(r,{...n})}},5041:(e,t,n)=>{"use strict";n.d(t,{M:()=>g,o:()=>m});var r=n(6540),o=n(2303),a=n(679),i=n(9532),l=n(6342),s=n(4848);const u=(0,a.Wf)("docusaurus.announcement.dismiss"),c=(0,a.Wf)("docusaurus.announcement.id"),d=()=>"true"===u.get(),f=e=>u.set(String(e)),p=r.createContext(null);function m(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,l.p)(),t=(0,o.A)(),[n,a]=(0,r.useState)((()=>!!t&&d()));(0,r.useEffect)((()=>{a(d())}),[]);const i=(0,r.useCallback)((()=>{f(!0),a(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=c.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;c.set(t),r&&f(!1),!r&&d()||a(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return(0,s.jsx)(p.Provider,{value:n,children:t})}function g(){const e=(0,r.useContext)(p);if(!e)throw new i.dV("AnnouncementBarProvider");return e}},5293:(e,t,n)=>{"use strict";n.d(t,{G:()=>y,a:()=>h});var r=n(6540),o=n(8193),a=n(9532),i=n(679),l=n(6342),s=n(4848);const u=r.createContext(void 0),c="theme",d=(0,i.Wf)(c),f={light:"light",dark:"dark"},p=e=>e===f.dark?f.dark:f.light,m=e=>o.A.canUseDOM?p(document.documentElement.getAttribute("data-theme")):p(e),g=e=>{d.set(p(e))};function h(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,l.p)(),[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&&g(t)):(a(n?window.matchMedia("(prefers-color-scheme: dark)").matches?f.dark:f.light:e),d.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",p(o))}),[o]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==c)return;const t=d.get();null!==t&&i(p(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===f.dark},setLightTheme(){i(f.light)},setDarkTheme(){i(f.dark)}})),[o,i])}();return(0,s.jsx)(u.Provider,{value:n,children:t})}function y(){const e=(0,r.useContext)(u);if(null==e)throw new a.dV("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},2069:(e,t,n)=>{"use strict";n.d(t,{M:()=>p,e:()=>f});var r=n(6540),o=n(5600),a=n(4581),i=n(7485),l=n(6342),s=n(9532),u=n(4848);const c=r.createContext(void 0);function d(){const e=function(){const e=(0,o.YL)(),{items:t}=(0,l.p)().navbar;return 0===t.length&&!e.component}(),t=(0,a.l)(),n=!e&&"mobile"===t,[s,u]=(0,r.useState)(!1);(0,i.$Z)((()=>{if(s)return u(!1),!1}));const c=(0,r.useCallback)((()=>{u((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&u(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:c,shown:s})),[e,n,c,s])}function f(e){let{children:t}=e;const n=d();return(0,u.jsx)(c.Provider,{value:n,children:t})}function p(){const e=r.useContext(c);if(void 0===e)throw new s.dV("NavbarMobileSidebarProvider");return e}},5600:(e,t,n)=>{"use strict";n.d(t,{GX:()=>u,YL:()=>s,y_:()=>l});var r=n(6540),o=n(9532),a=n(4848);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.dV("NavbarSecondaryMenuContentProvider");return e[0]}function u(e){let{component:t,props:n}=e;const a=(0,r.useContext)(i);if(!a)throw new o.dV("NavbarSecondaryMenuContentProvider");const[,l]=a,s=(0,o.Be)(n);return(0,r.useEffect)((()=>{l({component:t,props:s})}),[l,t,s]),(0,r.useEffect)((()=>()=>l({component:null,props:null})),[l]),null}},4090:(e,t,n)=>{"use strict";n.d(t,{w:()=>o,J:()=>a});var r=n(6540);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)}}),[])}},4581:(e,t,n)=>{"use strict";n.d(t,{l:()=>l});var r=n(6540),o=n(8193);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.A.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}},7559:(e,t,n)=>{"use strict";n.d(t,{G:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",blogAuthorsListPage:"blog-authors-list-page",blogAuthorsPostsPage:"blog-authors-posts-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",draftBanner:"theme-draft-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:{blogFooterTagsRow:"theme-blog-footer-tags-row",blogFooterEditMetaRow:"theme-blog-footer-edit-meta-row"},pages:{pageFooterEditMetaRow:"theme-pages-footer-edit-meta-row"}}},3109:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{O:()=>r})},7485:(e,t,n)=>{"use strict";n.d(t,{$Z:()=>i,aZ:()=>s});var r=n(6540),o=n(6347),a=n(9532);function i(e){!function(e){const t=(0,o.W6)(),n=(0,a._q)(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){const t=(0,o.W6)();return(0,r.useSyncExternalStore)(t.listen,(()=>e(t)),(()=>e(t)))}function s(e){return l((t=>null===e?null:new URLSearchParams(t.location.search).get(e)))}},1682:(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,{XI:()=>r,sb:()=>o})},1003:(e,t,n)=>{"use strict";n.d(t,{e3:()=>p,be:()=>d,Jx:()=>m});var r=n(6540),o=n(4164),a=n(5260),i=n(3102);function l(){const e=r.useContext(i.o);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var s=n(6025),u=n(4586);var c=n(4848);function d(e){let{title:t,description:n,keywords:r,image:o,children:i}=e;const l=function(e){const{siteConfig:t}=(0,u.A)(),{title:n,titleDelimiter:r}=t;return e?.trim().length?`${e.trim()} ${r} ${n}`:n}(t),{withBaseUrl:d}=(0,s.hH)(),f=o?d(o,{absolute:!0}):void 0;return(0,c.jsxs)(a.A,{children:[t&&(0,c.jsx)("title",{children:l}),t&&(0,c.jsx)("meta",{property:"og:title",content:l}),n&&(0,c.jsx)("meta",{name:"description",content:n}),n&&(0,c.jsx)("meta",{property:"og:description",content:n}),r&&(0,c.jsx)("meta",{name:"keywords",content:Array.isArray(r)?r.join(","):r}),f&&(0,c.jsx)("meta",{property:"og:image",content:f}),f&&(0,c.jsx)("meta",{name:"twitter:image",content:f}),i]})}const f=r.createContext(void 0);function p(e){let{className:t,children:n}=e;const i=r.useContext(f),l=(0,o.A)(i,t);return(0,c.jsxs)(f.Provider,{value:l,children:[(0,c.jsx)(a.A,{children:(0,c.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,c.jsx)(p,{className:(0,o.A)(r,a),children:t})}},9532:(e,t,n)=>{"use strict";n.d(t,{Be:()=>u,ZC:()=>l,_q:()=>i,dV:()=>s,fM:()=>c});var r=n(6540),o=n(205),a=n(4848);function i(e){const t=(0,r.useRef)(e);return(0,o.A)((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function l(e){const t=(0,r.useRef)();return(0,o.A)((()=>{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 u(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function c(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)})}}},9169:(e,t,n)=>{"use strict";n.d(t,{Dt:()=>l,ys:()=>i});var r=n(6540),o=n(8328),a=n(4586);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.A)().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.A,baseUrl:e})),[e])}},3104:(e,t,n)=>{"use strict";n.d(t,{Mq:()=>p,Tv:()=>c,a_:()=>m,gk:()=>g});var r=n(6540),o=n(8193),a=n(2303),i=n(205),l=n(9532),s=n(4848);const u=r.createContext(void 0);function c(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)(u.Provider,{value:n,children:t})}function d(){const e=(0,r.useContext)(u);if(null==e)throw new l.dV("ScrollControllerProvider");return e}const f=()=>o.A.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function p(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=d(),o=(0,r.useRef)(f()),a=(0,l._q)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=f();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.A)((()=>{queueMicrotask((()=>n.current?.()))})),{blockElementScrollPositionUntilNextRender:o}}function g(){const e=(0,r.useRef)(null),t=(0,a.A)()&&"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?.()}}},679:(e,t,n)=>{"use strict";n.d(t,{Wf:()=>c,Dv:()=>d});var r=n(6540);const o=JSON.parse('{"N":"localStorage","M":""}'),a=o.N;function i(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 l(e){if(void 0===e&&(e=a),"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,s||(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),s=!0),null}var t}let s=!1;const u={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function c(e,t){const n=`${e}${o.M}`;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}}(n);const r=l(t?.persistence);return null===r?u:{get:()=>{try{return r.getItem(n)}catch(e){return console.error(`Docusaurus storage error, can't get key=${n}`,e),null}},set:e=>{try{const t=r.getItem(n);r.setItem(n,e),i({key:n,oldValue:t,newValue:e,storage:r})}catch(t){console.error(`Docusaurus storage error, can't set ${n}=${e}`,t)}},del:()=>{try{const e=r.getItem(n);r.removeItem(n),i({key:n,oldValue:e,newValue:null,storage:r})}catch(e){console.error(`Docusaurus storage error, can't delete key=${n}`,e)}},listen:e=>{try{const t=t=>{t.storageArea===r&&t.key===n&&e(t)};return window.addEventListener("storage",t),()=>window.removeEventListener("storage",t)}catch(t){return console.error(`Docusaurus storage error, can't listen for changes of key=${n}`,t),()=>{}}}}}function d(e,t){const n=(0,r.useRef)((()=>null===e?u: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]}},2131:(e,t,n)=>{"use strict";n.d(t,{o:()=>i});var r=n(4586),o=n(6347),a=n(440);function i(){const{siteConfig:{baseUrl:e,url:t,trailingSlash:n},i18n:{defaultLocale:i,currentLocale:l}}=(0,r.A)(),{pathname:s}=(0,o.zy)(),u=(0,a.Ks)(s,{trailingSlash:n,baseUrl:e}),c=l===i?e:e.replace(`/${l}/`,"/"),d=u.replace(e,"");return{createUrl:function(e){let{locale:n,fullyQualified:r}=e;return`${r?t:""}${function(e){return e===i?`${c}`:`${c}${e}/`}(n)}${d}`}}}},5062:(e,t,n)=>{"use strict";n.d(t,{$:()=>i});var r=n(6540),o=n(6347),a=n(9532);function i(e){const t=(0,o.zy)(),n=(0,a.ZC)(t),i=(0,a._q)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},6342:(e,t,n)=>{"use strict";n.d(t,{p:()=>o});var r=n(4586);function o(){return(0,r.A)().siteConfig.themeConfig}},2983:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.addTrailingSlash=o,t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[i]=e.split(/[#?]/),l="/"===i||i===r?i:(s=i,u=n,u?o(s):a(s));var s,u;return e.replace(i,l)},t.addLeadingSlash=function(e){return(0,r.addPrefix)(e,"/")},t.removeTrailingSlash=a;const r=n(2566);function o(e){return e.endsWith("/")?e:`${e}/`}function a(e){return(0,r.removeSuffix)(e,"/")}},253:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=function e(t){if(t.cause)return[t,...e(t.cause)];return[t]}},440:(e,t,n)=>{"use strict";t.rA=t.Ks=void 0;const r=n(1635);var o=n(2983);Object.defineProperty(t,"Ks",{enumerable:!0,get:function(){return r.__importDefault(o).default}});var a=n(2566);var i=n(253);Object.defineProperty(t,"rA",{enumerable:!0,get:function(){return i.getErrorCausalChain}})},2566:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.addPrefix=function(e,t){return e.startsWith(t)?e:`${t}${e}`},t.removeSuffix=function(e,t){if(""===t)return e;return e.endsWith(t)?e.slice(0,-t.length):e},t.addSuffix=function(e,t){return e.endsWith(t)?e:`${e}${t}`},t.removePrefix=function(e,t){return e.startsWith(t)?e.slice(t.length):e}},1513:(e,t,n)=>{"use strict";n.d(t,{zR:()=>w,TM:()=>C,yJ:()=>p,sC:()=>T,AO:()=>f});var r=n(8168);function o(e){return"/"===e.charAt(0)}function a(e,t){for(var n=t,r=n+1,o=e.length;r=0;f--){var p=i[f];"."===p?a(i,f):".."===p?(a(i,f),d++):d&&(a(i,f),d--)}if(!u)for(;d--;d)i.unshift("..");!u||""===i[0]||i[0]&&o(i[0])||i.unshift("");var m=i.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};var l=n(1561);function s(e){return"/"===e.charAt(0)?e:"/"+e}function u(e){return"/"===e.charAt(0)?e.substr(1):e}function c(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 d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function f(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 p(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.A)({},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 m(){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=p(e,t,g(),w.location);c.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(4363),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 u=Object.defineProperty,c=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,f=Object.getOwnPropertyDescriptor,p=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(m){var o=p(n);o&&o!==m&&e(t,o,r)}var i=c(n);d&&(i=i.concat(d(n)));for(var l=s(t),g=s(n),h=0;h{"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 u=[n,r,o,a,i,l],c=0;(s=new Error(t.replace(/%s/g,(function(){return u[c++]})))).name="Invariant Violation"}throw s.framesToPop=1,s}}},4634:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},119:(e,t,n)=>{"use strict";n.r(t)},1043:(e,t,n)=>{"use strict";n.r(t)},5947: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),u=a.querySelector(r.barSelector),c=r.speed,d=r.easing;return a.offsetWidth,l((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),s(u,i(e,c,d)),1===e?(s(a,{transition:"none",opacity:1}),a.offsetWidth,setTimeout((function(){s(a,{transition:"all "+c+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),c)}),c)):setTimeout(t,c)})),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");c(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),u=document.querySelector(r.parent);return s(i,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),r.showSpinner||(o=t.querySelector(r.spinnerSelector))&&p(o),u!=document.body&&c(u,"nprogress-custom-parent"),u.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&&p(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 u(e,t){return("string"==typeof e?e:f(e)).indexOf(" "+t+" ")>=0}function c(e,t){var n=f(e),r=n+t;u(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=f(e);u(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function f(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function p(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)},5302:(e,t,n)=>{var r=n(4634);e.exports=p,e.exports.parse=a,e.exports.compile=function(e,t){return l(a(e,t),t)},e.exports.tokensToFunction=l,e.exports.tokensToRegExp=f;var o=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function a(e,t){for(var n,r=[],a=0,i=0,l="",c=t&&t.delimiter||"/";null!=(n=o.exec(e));){var d=n[0],f=n[1],p=n.index;if(l+=e.slice(i,p),i=p+d.length,f)l+=f[1];else{var m=e[i],g=n[2],h=n[3],y=n[4],b=n[5],v=n[6],w=n[7];l&&(r.push(l),l="");var k=null!=g&&null!=m&&m!==g,x="+"===v||"*"===v,S="?"===v||"*"===v,E=n[2]||c,_=y||b;r.push({name:h||a++,prefix:g||"",delimiter:E,optional:S,repeat:x,partial:k,asterisk:!!w,pattern:_?u(_):w?".*":"[^"+s(E)+"]+?"})}}return i{!function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},r={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?:\.\w+)*(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},parameter:{pattern:/(^|\s)-{1,2}(?:\w+:[+-]?)?\w+(?:\.\w+)*(?=[=\s]|$)/,alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:r},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:r},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:r.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:r.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cargo|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|java|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|sysctl|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var o=["comment","function-name","for-or-select","assign-left","parameter","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],a=r.variable[1].inside,i=0;i{!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 u=l[s];if("string"==typeof u||u.content&&"string"==typeof u.content){var c=a[o],d=n.tokenStack[c],f="string"==typeof u?u:u.content,p=t(r,c),m=f.indexOf(p);if(m>-1){++o;var g=f.substring(0,m),h=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),y=f.substring(m+p.length),b=[];g&&b.push.apply(b,i([g])),b.push(h),y&&b.push.apply(b,i([y])),"string"==typeof u?l.splice.apply(l,[s,1].concat(b)):u.content=b}}else u.content&&i(u.content)}return l}(n.tokens)}}}})}(Prism)},132:()=>{!function(e){var t=/(?:[\w-]+|'[^'\n\r]*'|"(?:\\.|[^\\"\r\n])*")/.source;function n(e){return e.replace(/__/g,(function(){return t}))}e.languages.toml={comment:{pattern:/#.*/,greedy:!0},table:{pattern:RegExp(n(/(^[\t ]*\[\s*(?:\[\s*)?)__(?:\s*\.\s*__)*(?=\s*\])/.source),"m"),lookbehind:!0,greedy:!0,alias:"class-name"},key:{pattern:RegExp(n(/(^[\t ]*|[{,]\s*)__(?:\s*\.\s*__)*(?=\s*=)/.source),"m"),lookbehind:!0,greedy:!0,alias:"property"},string:{pattern:/"""(?:\\[\s\S]|[^\\])*?"""|'''[\s\S]*?'''|'[^'\n\r]*'|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},date:[{pattern:/\b\d{4}-\d{2}-\d{2}(?:[T\s]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})?)?\b/i,alias:"number"},{pattern:/\b\d{2}:\d{2}:\d{2}(?:\.\d+)?\b/,alias:"number"}],number:/(?:\b0(?:x[\da-zA-Z]+(?:_[\da-zA-Z]+)*|o[0-7]+(?:_[0-7]+)*|b[10]+(?:_[10]+)*))\b|[-+]?\b\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?\b|[-+]?\b(?:inf|nan)\b/,boolean:/\b(?:false|true)\b/,punctuation:/[.,=[\]{}]/}}(Prism)},83:()=>{!function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",o=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*/.source.replace(//g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),a=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\s*:\s)/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return"(?:"+o+"|"+a+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(a),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(Prism)},8133:(e,t,n)=>{var r={"./prism-bash":7022,"./prism-toml":132,"./prism-yaml":83};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=8133},2694:(e,t,n)=>{"use strict";var r=n(6925);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}},5556:(e,t,n)=>{e.exports=n(2694)()},6925:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},2551:(e,t,n)=>{"use strict";var r=n(6540),o=n(9982);function a(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n