diff --git a/404.html b/404.html index 54224059..0889beac 100644 --- a/404.html +++ b/404.html @@ -10,7 +10,7 @@ - + diff --git a/assets/js/5396078f.c4a1e82e.js b/assets/js/5396078f.c4a1e82e.js new file mode 100644 index 00000000..b0549fd4 --- /dev/null +++ b/assets/js/5396078f.c4a1e82e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4863],{31181:(e,n,o)=>{o.d(n,{Ay:()=>c,RM:()=>t});var i=o(74848),r=o(28453);const t=[{value:"Docker Instance",id:"docker-instance",level:2},{value:"Create the Docker Compose Project",id:"create-the-docker-compose-project",level:3},{value:"YOLO",id:"yolo",level:4},{value:"I'll Do it Myself",id:"ill-do-it-myself",level:4},{value:"Basic Configuration (No TLS, Localhost Only)",id:"basic-configuration-no-tls-localhost-only",level:3},{value:"DNS Configuration (Optional for localhost-only setup)",id:"dns-configuration-optional-for-localhost-only-setup",level:4},{value:"Configure the Docker Compose Project Environment",id:"configure-the-docker-compose-project-environment",level:4},{value:"Start the Docker Compose Project",id:"start-the-docker-compose-project",level:4},{value:"Expanded Configuration with TLS (Caddy or Traefik)",id:"expanded-configuration-with-tls-caddy-or-traefik",level:3},{value:"DNS Configuration for TLS",id:"dns-configuration-for-tls",level:4},{value:"Configure the Docker Compose File",id:"configure-the-docker-compose-file",level:4},{value:"Caddy Configuration",id:"caddy-configuration",level:4},{value:"Traefik Configuration",id:"traefik-configuration",level:4},{value:"Start the Docker Compose Project",id:"start-the-docker-compose-project-1",level:4},{value:"Set up a User Account",id:"set-up-a-user-account",level:3},{value:"Enable the User Environment",id:"enable-the-user-environment",level:3},{value:"Firewall Configuration",id:"firewall-configuration",level:3},{value:"Additional Configuration Options",id:"additional-configuration-options",level:3},{value:"\u26a0\ufe0f OAuth Configuration Note",id:"\ufe0f-oauth-configuration-note",level:4},{value:"Troubleshooting",id:"troubleshooting",level:3}];function s(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",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)(n.h2,{id:"docker-instance",children:"Docker Instance"}),"\n",(0,i.jsx)("iframe",{width:"100%",height:"315",src:"https://www.youtube.com/embed/70zJ_h4uiD8",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowfullscreen:!0}),"\n",(0,i.jsx)(n.p,{children:"This Docker Compose project creates a zrok instance supported by a OpenZiti controller and router. It supports flexible deployment configurations:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Basic Configuration"}),": Services exposed on localhost only (no TLS)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"With Caddy"}),": Services published using Caddy (TLS)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"With Traefik"}),": Services published using Traefik (TLS)"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"create-the-docker-compose-project",children:"Create the Docker Compose Project"}),"\n",(0,i.jsx)(n.p,{children:"Create a working directory on your Docker host and save these Docker Compose project files."}),"\n",(0,i.jsx)(n.h4,{id:"yolo",children:"YOLO"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Run this script to download the files in the current directory."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"curl https://get.openziti.io/zrok-instance/fetch.bash | bash\n"})}),"\n",(0,i.jsx)(n.p,{children:"Or, specify the Compose project directory."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"curl https://get.openziti.io/zrok-instance/fetch.bash | bash -s /path/to/compose/project/dir\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"ill-do-it-myself",children:"I'll Do it Myself"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Get the zrok repo ZIP file."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"wget https://github.com/openziti/zrok/archive/refs/heads/main.zip\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Unzip the zrok-instance files into the project directory."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"unzip -j -d . main.zip '*/docker/compose/zrok-instance/*'\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"basic-configuration-no-tls-localhost-only",children:"Basic Configuration (No TLS, Localhost Only)"}),"\n",(0,i.jsx)(n.p,{children:"This is the simplest way to get started with zrok, exposing services on localhost only, without TLS."}),"\n",(0,i.jsx)(n.h4,{id:"dns-configuration-optional-for-localhost-only-setup",children:"DNS Configuration (Optional for localhost-only setup)"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["If you plan to use this beyond localhost, set up a wildcard record for the IP address where the zrok instance will run\n(e.g., if your DNS zone is ",(0,i.jsx)(n.code,{children:"share.example.com"}),", then your wildcard record is ",(0,i.jsx)(n.code,{children:"*.share.example.com"}),")."]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"configure-the-docker-compose-project-environment",children:"Configure the Docker Compose Project Environment"}),"\n",(0,i.jsxs)(n.p,{children:["Create an ",(0,i.jsx)(n.code,{children:".env"})," file in the working directory with the minimal required configuration:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title=".env minimal configuration"',children:"# Required settings\nZROK_DNS_ZONE=share.example.com\nZROK_USER_EMAIL=me@example.com\nZROK_USER_PWD=zrokuserpw\nZITI_PWD=zitiadminpw\nZROK_ADMIN_TOKEN=zroktoken\n\n# Expose services only on localhost (default)\nZROK_INSECURE_INTERFACE=127.0.0.1\n\n# Service ports\nZROK_CTRL_PORT=18080\nZROK_FRONTEND_PORT=8080\nZROK_OAUTH_PORT=8081\nZITI_CTRL_ADVERTISED_PORT=80\nZITI_ROUTER_PORT=3022\n"})}),"\n",(0,i.jsx)(n.h4,{id:"start-the-docker-compose-project",children:"Start the Docker Compose Project"}),"\n",(0,i.jsx)(n.p,{children:"Start the zrok instance:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"docker compose up --build --detach\n"})}),"\n",(0,i.jsx)(n.h3,{id:"expanded-configuration-with-tls-caddy-or-traefik",children:"Expanded Configuration with TLS (Caddy or Traefik)"}),"\n",(0,i.jsx)(n.p,{children:"For production deployments, you should use TLS. You can choose between Caddy or Traefik for TLS termination and reverse proxy to the zrok services. The ziti services are always published directly, not proxied, and they bring their own TLS."}),"\n",(0,i.jsx)(n.h4,{id:"dns-configuration-for-tls",children:"DNS Configuration for TLS"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Ensure a wildcard record exists for the IP address where the zrok instance will run\n(e.g., if your DNS zone is ",(0,i.jsx)(n.code,{children:"share.example.com"}),", then your wildcard record is ",(0,i.jsx)(n.code,{children:"*.share.example.com"}),")."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Choose a DNS provider that supports automatic DNS challenge for obtaining wildcard certificates and for which a plugin is available in Caddy or Traefik."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"configure-the-docker-compose-file",children:"Configure the Docker Compose File"}),"\n",(0,i.jsxs)(n.p,{children:["Add this setting to your ",(0,i.jsx)(n.code,{children:".env"})," file to select which TLS provider to use:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# Use one of the following:\nCOMPOSE_FILE=compose.yml:compose.caddy.yml # For Caddy\n# OR\nCOMPOSE_FILE=compose.yml:compose.traefik.yml # For Traefik\n"})}),"\n",(0,i.jsx)(n.h4,{id:"caddy-configuration",children:"Caddy Configuration"}),"\n",(0,i.jsxs)(n.p,{children:["If using Caddy, add these settings to your ",(0,i.jsx)(n.code,{children:".env"})," file:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title=".env for Caddy"',children:"# Caddy TLS configuration\nCADDY_DNS_PLUGIN=cloudflare # Plugin name for your DNS provider (see github.com/caddy-dns)\nCADDY_DNS_PLUGIN_TOKEN=abcd1234 # API token from your DNS provider\nCADDY_ACME_API=https://acme-v02.api.letsencrypt.org/directory # ACME API endpoint\nCADDY_HTTPS_PORT=443 # HTTPS port (optional, defaults to 443)\nCADDY_INTERFACE=0.0.0.0 # Interface to bind to (optional, defaults to all interfaces)\n\n# For AWS Route53, uncomment and set these instead of CADDY_DNS_PLUGIN_TOKEN:\n# AWS_ACCESS_KEY_ID=your-access-key\n# AWS_SECRET_ACCESS_KEY=your-secret-key\n# AWS_REGION=your-region\n# AWS_SESSION_TOKEN=your-session-token # Only if using temporary credentials\n"})}),"\n",(0,i.jsx)(n.h4,{id:"traefik-configuration",children:"Traefik Configuration"}),"\n",(0,i.jsxs)(n.p,{children:["If using Traefik, add these settings to your ",(0,i.jsx)(n.code,{children:".env"})," file:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title=".env for Traefik"',children:"# Traefik TLS configuration\nTRAEFIK_DNS_PROVIDER=digitalocean # DNS provider for Traefik\nTRAEFIK_DNS_PROVIDER_TOKEN=abcd1234 # API token from your DNS provider\nTRAEFIK_ACME_API=https://acme-v02.api.letsencrypt.org/directory # ACME API endpoint\nTRAEFIK_HTTPS_PORT=443 # HTTPS port (optional, defaults to 443)\nTRAEFIK_INTERFACE=0.0.0.0 # Interface to bind to (optional, defaults to all interfaces)\n\n# For AWS Route53, uncomment and set these instead of TRAEFIK_DNS_PROVIDER_TOKEN:\n# AWS_ACCESS_KEY_ID=your-access-key\n# AWS_SECRET_ACCESS_KEY=your-secret-key\n# AWS_REGION=your-region\n# AWS_SESSION_TOKEN=your-session-token # Only if using temporary credentials\n"})}),"\n",(0,i.jsx)(n.h4,{id:"start-the-docker-compose-project-1",children:"Start the Docker Compose Project"}),"\n",(0,i.jsx)(n.p,{children:"Start the zrok instance with TLS support:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"docker compose up --build --detach\n"})}),"\n",(0,i.jsx)(n.h3,{id:"set-up-a-user-account",children:"Set up a User Account"}),"\n",(0,i.jsxs)(n.p,{children:["This step creates a user account. You will log in to the zrok web console with the account password created in this step. The ZROK_USER_EMAIL and ZROK_USER_PWD variables are set in the ",(0,i.jsx)(n.code,{children:".env"})," file."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="Create the first user account"',children:"docker compose exec zrok-controller bash -xc 'zrok admin create account ${ZROK_USER_EMAIL} ${ZROK_USER_PWD}'\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-buttonless",metastring:'title="Example output"',children:"+ zrok admin create account me@example.com zrokuserpw\n[ 0.000] INFO zrok/controller/store.Open: database connected\n[ 0.002] INFO zrok/controller/store.(*Store).migrate: applied 0 migrations\nheMqncCyxZcx\n"})}),"\n",(0,i.jsx)(n.p,{children:"Create additional users by running the command again with a different email and password."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="Create another user"',children:"docker compose exec zrok-controller zrok admin create account \n"})}),"\n",(0,i.jsx)(n.h3,{id:"enable-the-user-environment",children:"Enable the User Environment"}),"\n",(0,i.jsx)(n.p,{children:"You must enable each device environment with the account token obtained when the account was created. This is separate from the account password that's used to log in to the web console."}),"\n",(0,i.jsxs)(n.p,{children:["Follow ",(0,i.jsx)(n.a,{href:"/docs/getting-started#installing-the-zrok-command",children:"the getting started guide"})," to install the zrok CLI on some device and enable a zrok environment."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Configure the environment with the zrok API endpoint:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# If using TLS (Caddy or Traefik)\nzrok config set apiEndpoint https://zrok.share.example.com\n\n# If using basic configuration (localhost, no TLS)\nzrok config set apiEndpoint http://localhost:18080\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Enable an environment on this device with the account token from the previous step."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"zrok enable heMqncCyxZcx\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"firewall-configuration",children:"Firewall Configuration"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"443/tcp"})," - HTTPS for all services (Caddy or Traefik)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"80/tcp"})," - ziti ctrl plane"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"3022/tcp"})," - ziti data plane"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"additional-configuration-options",children:"Additional Configuration Options"}),"\n",(0,i.jsxs)(n.p,{children:["You can add these additional settings to your ",(0,i.jsx)(n.code,{children:".env"})," file for more customization:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# OAuth configuration for public shares\nZROK_OAUTH_HASH_KEY=oauthhashkeysecret\nZROK_OAUTH_GITHUB_CLIENT_ID=abcd1234\nZROK_OAUTH_GITHUB_CLIENT_SECRET=abcd1234\nZROK_OAUTH_GOOGLE_CLIENT_ID=abcd1234\nZROK_OAUTH_GOOGLE_CLIENT_SECRET=abcd1234\n"})}),"\n",(0,i.jsx)(n.h4,{id:"\ufe0f-oauth-configuration-note",children:"\u26a0\ufe0f OAuth Configuration Note"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"If you are NOT using OAuth for public shares"}),", remove the entire OAuth section from ",(0,i.jsx)(n.code,{children:"zrok-frontend-config.yml.envsubst"})," to avoid configuration errors:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"# Remove this entire section if not using OAuth\noauth:\n bind_address: 0.0.0.0:${ZROK_OAUTH_PORT}\n endpoint_url: https://oauth.${ZROK_DNS_ZONE}\n cookie_name: zrok-auth-session\n cookie_domain: ${ZROK_DNS_ZONE}\n session_lifetime: 6h\n intermediate_lifetime: 5m\n signing_key: ${ZROK_OAUTH_HASH_KEY}\n encryption_key: ${ZROK_OAUTH_HASH_KEY}\n providers:\n - name: github\n type: github\n client_id: ${ZROK_OAUTH_GITHUB_CLIENT_ID}\n client_secret: ${ZROK_OAUTH_GITHUB_CLIENT_SECRET}\n\n - name: google\n type: google\n client_id: ${ZROK_OAUTH_GOOGLE_CLIENT_ID}\n client_secret: ${ZROK_OAUTH_GOOGLE_CLIENT_SECRET}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Then rebuild: ",(0,i.jsx)(n.code,{children:"docker compose up -d --build zrok-frontend"})]}),"\n",(0,i.jsx)(n.h3,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Check the service logs:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# View logs for a specific service\ndocker compose logs zrok-controller\ndocker compose logs zrok-frontend\ndocker compose logs ziti-quickstart\n\n# View logs for Caddy (if using)\ndocker compose logs caddy\n\n# View logs for Traefik (if using)\ndocker compose logs traefik\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Validate TLS configuration:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# For Caddy\ndocker compose exec caddy caddy validate --config /etc/caddy/Caddyfile\n\n# For Traefik\ndocker compose exec traefik traefik healthcheck\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Check certificate status:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'# For Caddy\ndocker compose exec caddy curl -s "http://localhost:2019/certificates"\n\n# For Traefik - view the ACME certificate file directly\ndocker compose exec traefik cat /etc/traefik/acme/acme.json | grep -A 5 "Certificates"\n'})}),"\n"]}),"\n"]})]})}function c(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(s,{...e})}):s(e)}},15167:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>c,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"guides/self-hosting/docker","title":"Self-hosting guide for Docker","description":"","source":"@site/versioned_docs/version-1.0/guides/self-hosting/docker.mdx","sourceDirName":"guides/self-hosting","slug":"/guides/self-hosting/docker","permalink":"/docs/1.0/guides/self-hosting/docker","draft":false,"unlisted":false,"editUrl":"https://github.com/openziti/zrok/blob/main/docs/versioned_docs/version-1.0/guides/self-hosting/docker.mdx","tags":[],"version":"1.0","sidebarPosition":45,"frontMatter":{"title":"Self-hosting guide for Docker","sidebar_label":"Docker","sidebar_position":45},"sidebar":"tutorialSidebar","previous":{"title":"Personalized Frontend","permalink":"/docs/1.0/guides/self-hosting/personalized-frontend"},"next":{"title":"Kubernetes","permalink":"/docs/1.0/guides/self-hosting/kubernetes"}}');var r=o(74848),t=o(28453),s=o(31181);const c={title:"Self-hosting guide for Docker",sidebar_label:"Docker",sidebar_position:45},a=void 0,l={},d=[...s.RM];function h(e){return(0,r.jsx)(s.Ay,{})}function u(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(h,{...e})}):h()}},28453:(e,n,o)=>{o.d(n,{R:()=>s,x:()=>c});var i=o(96540);const r={},t=i.createContext(r);function s(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5396078f.dc668b7d.js b/assets/js/5396078f.dc668b7d.js deleted file mode 100644 index 6e712b24..00000000 --- a/assets/js/5396078f.dc668b7d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4863],{31181:(e,n,o)=>{o.d(n,{Ay:()=>c,RM:()=>t});var i=o(74848),r=o(28453);const t=[{value:"Docker Instance",id:"docker-instance",level:2},{value:"Create the Docker Compose Project",id:"create-the-docker-compose-project",level:3},{value:"YOLO",id:"yolo",level:4},{value:"I'll Do it Myself",id:"ill-do-it-myself",level:4},{value:"Basic Configuration (No TLS, Localhost Only)",id:"basic-configuration-no-tls-localhost-only",level:3},{value:"DNS Configuration (Optional for localhost-only setup)",id:"dns-configuration-optional-for-localhost-only-setup",level:4},{value:"Configure the Docker Compose Project Environment",id:"configure-the-docker-compose-project-environment",level:4},{value:"Start the Docker Compose Project",id:"start-the-docker-compose-project",level:4},{value:"Expanded Configuration with TLS (Caddy or Traefik)",id:"expanded-configuration-with-tls-caddy-or-traefik",level:3},{value:"DNS Configuration for TLS",id:"dns-configuration-for-tls",level:4},{value:"Configure the Docker Compose File",id:"configure-the-docker-compose-file",level:4},{value:"Caddy Configuration",id:"caddy-configuration",level:4},{value:"Traefik Configuration",id:"traefik-configuration",level:4},{value:"Start the Docker Compose Project",id:"start-the-docker-compose-project-1",level:4},{value:"Set up a User Account",id:"set-up-a-user-account",level:3},{value:"Enable the User Environment",id:"enable-the-user-environment",level:3},{value:"Firewall Configuration",id:"firewall-configuration",level:3},{value:"Additional Configuration Options",id:"additional-configuration-options",level:3},{value:"Troubleshooting",id:"troubleshooting",level:3}];function s(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",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)(n.h2,{id:"docker-instance",children:"Docker Instance"}),"\n",(0,i.jsx)("iframe",{width:"100%",height:"315",src:"https://www.youtube.com/embed/70zJ_h4uiD8",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowfullscreen:!0}),"\n",(0,i.jsx)(n.p,{children:"This Docker Compose project creates a zrok instance supported by a OpenZiti controller and router. It supports flexible deployment configurations:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Basic Configuration"}),": Services exposed on localhost only (no TLS)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"With Caddy"}),": Services published using Caddy (TLS)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"With Traefik"}),": Services published using Traefik (TLS)"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"create-the-docker-compose-project",children:"Create the Docker Compose Project"}),"\n",(0,i.jsx)(n.p,{children:"Create a working directory on your Docker host and save these Docker Compose project files."}),"\n",(0,i.jsx)(n.h4,{id:"yolo",children:"YOLO"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Run this script to download the files in the current directory."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"curl https://get.openziti.io/zrok-instance/fetch.bash | bash\n"})}),"\n",(0,i.jsx)(n.p,{children:"Or, specify the Compose project directory."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"curl https://get.openziti.io/zrok-instance/fetch.bash | bash -s /path/to/compose/project/dir\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"ill-do-it-myself",children:"I'll Do it Myself"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Get the zrok repo ZIP file."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"wget https://github.com/openziti/zrok/archive/refs/heads/main.zip\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Unzip the zrok-instance files into the project directory."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"unzip -j -d . main.zip '*/docker/compose/zrok-instance/*'\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"basic-configuration-no-tls-localhost-only",children:"Basic Configuration (No TLS, Localhost Only)"}),"\n",(0,i.jsx)(n.p,{children:"This is the simplest way to get started with zrok, exposing services on localhost only, without TLS."}),"\n",(0,i.jsx)(n.h4,{id:"dns-configuration-optional-for-localhost-only-setup",children:"DNS Configuration (Optional for localhost-only setup)"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["If you plan to use this beyond localhost, set up a wildcard record for the IP address where the zrok instance will run\n(e.g., if your DNS zone is ",(0,i.jsx)(n.code,{children:"share.example.com"}),", then your wildcard record is ",(0,i.jsx)(n.code,{children:"*.share.example.com"}),")."]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"configure-the-docker-compose-project-environment",children:"Configure the Docker Compose Project Environment"}),"\n",(0,i.jsxs)(n.p,{children:["Create an ",(0,i.jsx)(n.code,{children:".env"})," file in the working directory with the minimal required configuration:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title=".env minimal configuration"',children:"# Required settings\nZROK_DNS_ZONE=share.example.com\nZROK_USER_EMAIL=me@example.com\nZROK_USER_PWD=zrokuserpw\nZITI_PWD=zitiadminpw\nZROK_ADMIN_TOKEN=zroktoken\n\n# Expose services only on localhost (default)\nZROK_INSECURE_INTERFACE=127.0.0.1\n\n# Service ports\nZROK_CTRL_PORT=18080\nZROK_FRONTEND_PORT=8080\nZROK_OAUTH_PORT=8081\nZITI_CTRL_ADVERTISED_PORT=80\nZITI_ROUTER_PORT=3022\n"})}),"\n",(0,i.jsx)(n.h4,{id:"start-the-docker-compose-project",children:"Start the Docker Compose Project"}),"\n",(0,i.jsx)(n.p,{children:"Start the zrok instance:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"docker compose up --build --detach\n"})}),"\n",(0,i.jsx)(n.h3,{id:"expanded-configuration-with-tls-caddy-or-traefik",children:"Expanded Configuration with TLS (Caddy or Traefik)"}),"\n",(0,i.jsx)(n.p,{children:"For production deployments, you should use TLS. You can choose between Caddy or Traefik for TLS termination and reverse proxy to the zrok services. The ziti services are always published directly, not proxied, and they bring their own TLS."}),"\n",(0,i.jsx)(n.h4,{id:"dns-configuration-for-tls",children:"DNS Configuration for TLS"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Ensure a wildcard record exists for the IP address where the zrok instance will run\n(e.g., if your DNS zone is ",(0,i.jsx)(n.code,{children:"share.example.com"}),", then your wildcard record is ",(0,i.jsx)(n.code,{children:"*.share.example.com"}),")."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Choose a DNS provider that supports automatic DNS challenge for obtaining wildcard certificates and for which a plugin is available in Caddy or Traefik."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"configure-the-docker-compose-file",children:"Configure the Docker Compose File"}),"\n",(0,i.jsxs)(n.p,{children:["Add this setting to your ",(0,i.jsx)(n.code,{children:".env"})," file to select which TLS provider to use:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# Use one of the following:\nCOMPOSE_FILE=compose.yml:compose.caddy.yml # For Caddy\n# OR\nCOMPOSE_FILE=compose.yml:compose.traefik.yml # For Traefik\n"})}),"\n",(0,i.jsx)(n.h4,{id:"caddy-configuration",children:"Caddy Configuration"}),"\n",(0,i.jsxs)(n.p,{children:["If using Caddy, add these settings to your ",(0,i.jsx)(n.code,{children:".env"})," file:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title=".env for Caddy"',children:"# Caddy TLS configuration\nCADDY_DNS_PLUGIN=cloudflare # Plugin name for your DNS provider (see github.com/caddy-dns)\nCADDY_DNS_PLUGIN_TOKEN=abcd1234 # API token from your DNS provider\nCADDY_ACME_API=https://acme-v02.api.letsencrypt.org/directory # ACME API endpoint\nCADDY_HTTPS_PORT=443 # HTTPS port (optional, defaults to 443)\nCADDY_INTERFACE=0.0.0.0 # Interface to bind to (optional, defaults to all interfaces)\n\n# For AWS Route53, uncomment and set these instead of CADDY_DNS_PLUGIN_TOKEN:\n# AWS_ACCESS_KEY_ID=your-access-key\n# AWS_SECRET_ACCESS_KEY=your-secret-key\n# AWS_REGION=your-region\n# AWS_SESSION_TOKEN=your-session-token # Only if using temporary credentials\n"})}),"\n",(0,i.jsx)(n.h4,{id:"traefik-configuration",children:"Traefik Configuration"}),"\n",(0,i.jsxs)(n.p,{children:["If using Traefik, add these settings to your ",(0,i.jsx)(n.code,{children:".env"})," file:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title=".env for Traefik"',children:"# Traefik TLS configuration\nTRAEFIK_DNS_PROVIDER=digitalocean # DNS provider for Traefik\nTRAEFIK_DNS_PROVIDER_TOKEN=abcd1234 # API token from your DNS provider\nTRAEFIK_ACME_API=https://acme-v02.api.letsencrypt.org/directory # ACME API endpoint\nTRAEFIK_HTTPS_PORT=443 # HTTPS port (optional, defaults to 443)\nTRAEFIK_INTERFACE=0.0.0.0 # Interface to bind to (optional, defaults to all interfaces)\n\n# For AWS Route53, uncomment and set these instead of TRAEFIK_DNS_PROVIDER_TOKEN:\n# AWS_ACCESS_KEY_ID=your-access-key\n# AWS_SECRET_ACCESS_KEY=your-secret-key\n# AWS_REGION=your-region\n# AWS_SESSION_TOKEN=your-session-token # Only if using temporary credentials\n"})}),"\n",(0,i.jsx)(n.h4,{id:"start-the-docker-compose-project-1",children:"Start the Docker Compose Project"}),"\n",(0,i.jsx)(n.p,{children:"Start the zrok instance with TLS support:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"docker compose up --build --detach\n"})}),"\n",(0,i.jsx)(n.h3,{id:"set-up-a-user-account",children:"Set up a User Account"}),"\n",(0,i.jsxs)(n.p,{children:["This step creates a user account. You will log in to the zrok web console with the account password created in this step. The ZROK_USER_EMAIL and ZROK_USER_PWD variables are set in the ",(0,i.jsx)(n.code,{children:".env"})," file."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="Create the first user account"',children:"docker compose exec zrok-controller bash -xc 'zrok admin create account ${ZROK_USER_EMAIL} ${ZROK_USER_PWD}'\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-buttonless",metastring:'title="Example output"',children:"+ zrok admin create account me@example.com zrokuserpw\n[ 0.000] INFO zrok/controller/store.Open: database connected\n[ 0.002] INFO zrok/controller/store.(*Store).migrate: applied 0 migrations\nheMqncCyxZcx\n"})}),"\n",(0,i.jsx)(n.p,{children:"Create additional users by running the command again with a different email and password."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="Create another user"',children:"docker compose exec zrok-controller zrok admin create account \n"})}),"\n",(0,i.jsx)(n.h3,{id:"enable-the-user-environment",children:"Enable the User Environment"}),"\n",(0,i.jsx)(n.p,{children:"You must enable each device environment with the account token obtained when the account was created. This is separate from the account password that's used to log in to the web console."}),"\n",(0,i.jsxs)(n.p,{children:["Follow ",(0,i.jsx)(n.a,{href:"/docs/getting-started#installing-the-zrok-command",children:"the getting started guide"})," to install the zrok CLI on some device and enable a zrok environment."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Configure the environment with the zrok API endpoint:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# If using TLS (Caddy or Traefik)\nzrok config set apiEndpoint https://zrok.share.example.com\n\n# If using basic configuration (localhost, no TLS)\nzrok config set apiEndpoint http://localhost:18080\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Enable an environment on this device with the account token from the previous step."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"zrok enable heMqncCyxZcx\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"firewall-configuration",children:"Firewall Configuration"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"443/tcp"})," - HTTPS for all services (Caddy or Traefik)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"80/tcp"})," - ziti ctrl plane"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"3022/tcp"})," - ziti data plane"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"additional-configuration-options",children:"Additional Configuration Options"}),"\n",(0,i.jsxs)(n.p,{children:["You can add these additional settings to your ",(0,i.jsx)(n.code,{children:".env"})," file for more customization:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# OAuth configuration for public shares\nZROK_OAUTH_HASH_KEY=oauthhashkeysecret\nZROK_OAUTH_GITHUB_CLIENT_ID=abcd1234\nZROK_OAUTH_GITHUB_CLIENT_SECRET=abcd1234\nZROK_OAUTH_GOOGLE_CLIENT_ID=abcd1234\nZROK_OAUTH_GOOGLE_CLIENT_SECRET=abcd1234\n"})}),"\n",(0,i.jsx)(n.h3,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Check the service logs:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# View logs for a specific service\ndocker compose logs zrok-controller\ndocker compose logs zrok-frontend\ndocker compose logs ziti-quickstart\n\n# View logs for Caddy (if using)\ndocker compose logs caddy\n\n# View logs for Traefik (if using)\ndocker compose logs traefik\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Validate TLS configuration:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# For Caddy\ndocker compose exec caddy caddy validate --config /etc/caddy/Caddyfile\n\n# For Traefik\ndocker compose exec traefik traefik healthcheck\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Check certificate status:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'# For Caddy\ndocker compose exec caddy curl -s "http://localhost:2019/certificates"\n\n# For Traefik - view the ACME certificate file directly\ndocker compose exec traefik cat /etc/traefik/acme/acme.json | grep -A 5 "Certificates"\n'})}),"\n"]}),"\n"]})]})}function c(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(s,{...e})}):s(e)}},15167:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>c,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"guides/self-hosting/docker","title":"Self-hosting guide for Docker","description":"","source":"@site/versioned_docs/version-1.0/guides/self-hosting/docker.mdx","sourceDirName":"guides/self-hosting","slug":"/guides/self-hosting/docker","permalink":"/docs/1.0/guides/self-hosting/docker","draft":false,"unlisted":false,"editUrl":"https://github.com/openziti/zrok/blob/main/docs/versioned_docs/version-1.0/guides/self-hosting/docker.mdx","tags":[],"version":"1.0","sidebarPosition":45,"frontMatter":{"title":"Self-hosting guide for Docker","sidebar_label":"Docker","sidebar_position":45},"sidebar":"tutorialSidebar","previous":{"title":"Personalized Frontend","permalink":"/docs/1.0/guides/self-hosting/personalized-frontend"},"next":{"title":"Kubernetes","permalink":"/docs/1.0/guides/self-hosting/kubernetes"}}');var r=o(74848),t=o(28453),s=o(31181);const c={title:"Self-hosting guide for Docker",sidebar_label:"Docker",sidebar_position:45},a=void 0,l={},d=[...s.RM];function h(e){return(0,r.jsx)(s.Ay,{})}function u(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(h,{...e})}):h()}},28453:(e,n,o)=>{o.d(n,{R:()=>s,x:()=>c});var i=o(96540);const r={},t=i.createContext(r);function s(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/685bed1a.5f4ddfb0.js b/assets/js/685bed1a.5f4ddfb0.js new file mode 100644 index 00000000..26f333b1 --- /dev/null +++ b/assets/js/685bed1a.5f4ddfb0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5689],{31181:(e,n,o)=>{o.d(n,{Ay:()=>c,RM:()=>t});var i=o(74848),r=o(28453);const t=[{value:"Docker Instance",id:"docker-instance",level:2},{value:"Create the Docker Compose Project",id:"create-the-docker-compose-project",level:3},{value:"YOLO",id:"yolo",level:4},{value:"I'll Do it Myself",id:"ill-do-it-myself",level:4},{value:"Basic Configuration (No TLS, Localhost Only)",id:"basic-configuration-no-tls-localhost-only",level:3},{value:"DNS Configuration (Optional for localhost-only setup)",id:"dns-configuration-optional-for-localhost-only-setup",level:4},{value:"Configure the Docker Compose Project Environment",id:"configure-the-docker-compose-project-environment",level:4},{value:"Start the Docker Compose Project",id:"start-the-docker-compose-project",level:4},{value:"Expanded Configuration with TLS (Caddy or Traefik)",id:"expanded-configuration-with-tls-caddy-or-traefik",level:3},{value:"DNS Configuration for TLS",id:"dns-configuration-for-tls",level:4},{value:"Configure the Docker Compose File",id:"configure-the-docker-compose-file",level:4},{value:"Caddy Configuration",id:"caddy-configuration",level:4},{value:"Traefik Configuration",id:"traefik-configuration",level:4},{value:"Start the Docker Compose Project",id:"start-the-docker-compose-project-1",level:4},{value:"Set up a User Account",id:"set-up-a-user-account",level:3},{value:"Enable the User Environment",id:"enable-the-user-environment",level:3},{value:"Firewall Configuration",id:"firewall-configuration",level:3},{value:"Additional Configuration Options",id:"additional-configuration-options",level:3},{value:"\u26a0\ufe0f OAuth Configuration Note",id:"\ufe0f-oauth-configuration-note",level:4},{value:"Troubleshooting",id:"troubleshooting",level:3}];function s(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",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)(n.h2,{id:"docker-instance",children:"Docker Instance"}),"\n",(0,i.jsx)("iframe",{width:"100%",height:"315",src:"https://www.youtube.com/embed/70zJ_h4uiD8",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowfullscreen:!0}),"\n",(0,i.jsx)(n.p,{children:"This Docker Compose project creates a zrok instance supported by a OpenZiti controller and router. It supports flexible deployment configurations:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Basic Configuration"}),": Services exposed on localhost only (no TLS)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"With Caddy"}),": Services published using Caddy (TLS)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"With Traefik"}),": Services published using Traefik (TLS)"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"create-the-docker-compose-project",children:"Create the Docker Compose Project"}),"\n",(0,i.jsx)(n.p,{children:"Create a working directory on your Docker host and save these Docker Compose project files."}),"\n",(0,i.jsx)(n.h4,{id:"yolo",children:"YOLO"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Run this script to download the files in the current directory."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"curl https://get.openziti.io/zrok-instance/fetch.bash | bash\n"})}),"\n",(0,i.jsx)(n.p,{children:"Or, specify the Compose project directory."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"curl https://get.openziti.io/zrok-instance/fetch.bash | bash -s /path/to/compose/project/dir\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"ill-do-it-myself",children:"I'll Do it Myself"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Get the zrok repo ZIP file."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"wget https://github.com/openziti/zrok/archive/refs/heads/main.zip\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Unzip the zrok-instance files into the project directory."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"unzip -j -d . main.zip '*/docker/compose/zrok-instance/*'\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"basic-configuration-no-tls-localhost-only",children:"Basic Configuration (No TLS, Localhost Only)"}),"\n",(0,i.jsx)(n.p,{children:"This is the simplest way to get started with zrok, exposing services on localhost only, without TLS."}),"\n",(0,i.jsx)(n.h4,{id:"dns-configuration-optional-for-localhost-only-setup",children:"DNS Configuration (Optional for localhost-only setup)"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["If you plan to use this beyond localhost, set up a wildcard record for the IP address where the zrok instance will run\n(e.g., if your DNS zone is ",(0,i.jsx)(n.code,{children:"share.example.com"}),", then your wildcard record is ",(0,i.jsx)(n.code,{children:"*.share.example.com"}),")."]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"configure-the-docker-compose-project-environment",children:"Configure the Docker Compose Project Environment"}),"\n",(0,i.jsxs)(n.p,{children:["Create an ",(0,i.jsx)(n.code,{children:".env"})," file in the working directory with the minimal required configuration:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title=".env minimal configuration"',children:"# Required settings\nZROK_DNS_ZONE=share.example.com\nZROK_USER_EMAIL=me@example.com\nZROK_USER_PWD=zrokuserpw\nZITI_PWD=zitiadminpw\nZROK_ADMIN_TOKEN=zroktoken\n\n# Expose services only on localhost (default)\nZROK_INSECURE_INTERFACE=127.0.0.1\n\n# Service ports\nZROK_CTRL_PORT=18080\nZROK_FRONTEND_PORT=8080\nZROK_OAUTH_PORT=8081\nZITI_CTRL_ADVERTISED_PORT=80\nZITI_ROUTER_PORT=3022\n"})}),"\n",(0,i.jsx)(n.h4,{id:"start-the-docker-compose-project",children:"Start the Docker Compose Project"}),"\n",(0,i.jsx)(n.p,{children:"Start the zrok instance:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"docker compose up --build --detach\n"})}),"\n",(0,i.jsx)(n.h3,{id:"expanded-configuration-with-tls-caddy-or-traefik",children:"Expanded Configuration with TLS (Caddy or Traefik)"}),"\n",(0,i.jsx)(n.p,{children:"For production deployments, you should use TLS. You can choose between Caddy or Traefik for TLS termination and reverse proxy to the zrok services. The ziti services are always published directly, not proxied, and they bring their own TLS."}),"\n",(0,i.jsx)(n.h4,{id:"dns-configuration-for-tls",children:"DNS Configuration for TLS"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Ensure a wildcard record exists for the IP address where the zrok instance will run\n(e.g., if your DNS zone is ",(0,i.jsx)(n.code,{children:"share.example.com"}),", then your wildcard record is ",(0,i.jsx)(n.code,{children:"*.share.example.com"}),")."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Choose a DNS provider that supports automatic DNS challenge for obtaining wildcard certificates and for which a plugin is available in Caddy or Traefik."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"configure-the-docker-compose-file",children:"Configure the Docker Compose File"}),"\n",(0,i.jsxs)(n.p,{children:["Add this setting to your ",(0,i.jsx)(n.code,{children:".env"})," file to select which TLS provider to use:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# Use one of the following:\nCOMPOSE_FILE=compose.yml:compose.caddy.yml # For Caddy\n# OR\nCOMPOSE_FILE=compose.yml:compose.traefik.yml # For Traefik\n"})}),"\n",(0,i.jsx)(n.h4,{id:"caddy-configuration",children:"Caddy Configuration"}),"\n",(0,i.jsxs)(n.p,{children:["If using Caddy, add these settings to your ",(0,i.jsx)(n.code,{children:".env"})," file:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title=".env for Caddy"',children:"# Caddy TLS configuration\nCADDY_DNS_PLUGIN=cloudflare # Plugin name for your DNS provider (see github.com/caddy-dns)\nCADDY_DNS_PLUGIN_TOKEN=abcd1234 # API token from your DNS provider\nCADDY_ACME_API=https://acme-v02.api.letsencrypt.org/directory # ACME API endpoint\nCADDY_HTTPS_PORT=443 # HTTPS port (optional, defaults to 443)\nCADDY_INTERFACE=0.0.0.0 # Interface to bind to (optional, defaults to all interfaces)\n\n# For AWS Route53, uncomment and set these instead of CADDY_DNS_PLUGIN_TOKEN:\n# AWS_ACCESS_KEY_ID=your-access-key\n# AWS_SECRET_ACCESS_KEY=your-secret-key\n# AWS_REGION=your-region\n# AWS_SESSION_TOKEN=your-session-token # Only if using temporary credentials\n"})}),"\n",(0,i.jsx)(n.h4,{id:"traefik-configuration",children:"Traefik Configuration"}),"\n",(0,i.jsxs)(n.p,{children:["If using Traefik, add these settings to your ",(0,i.jsx)(n.code,{children:".env"})," file:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title=".env for Traefik"',children:"# Traefik TLS configuration\nTRAEFIK_DNS_PROVIDER=digitalocean # DNS provider for Traefik\nTRAEFIK_DNS_PROVIDER_TOKEN=abcd1234 # API token from your DNS provider\nTRAEFIK_ACME_API=https://acme-v02.api.letsencrypt.org/directory # ACME API endpoint\nTRAEFIK_HTTPS_PORT=443 # HTTPS port (optional, defaults to 443)\nTRAEFIK_INTERFACE=0.0.0.0 # Interface to bind to (optional, defaults to all interfaces)\n\n# For AWS Route53, uncomment and set these instead of TRAEFIK_DNS_PROVIDER_TOKEN:\n# AWS_ACCESS_KEY_ID=your-access-key\n# AWS_SECRET_ACCESS_KEY=your-secret-key\n# AWS_REGION=your-region\n# AWS_SESSION_TOKEN=your-session-token # Only if using temporary credentials\n"})}),"\n",(0,i.jsx)(n.h4,{id:"start-the-docker-compose-project-1",children:"Start the Docker Compose Project"}),"\n",(0,i.jsx)(n.p,{children:"Start the zrok instance with TLS support:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"docker compose up --build --detach\n"})}),"\n",(0,i.jsx)(n.h3,{id:"set-up-a-user-account",children:"Set up a User Account"}),"\n",(0,i.jsxs)(n.p,{children:["This step creates a user account. You will log in to the zrok web console with the account password created in this step. The ZROK_USER_EMAIL and ZROK_USER_PWD variables are set in the ",(0,i.jsx)(n.code,{children:".env"})," file."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="Create the first user account"',children:"docker compose exec zrok-controller bash -xc 'zrok admin create account ${ZROK_USER_EMAIL} ${ZROK_USER_PWD}'\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-buttonless",metastring:'title="Example output"',children:"+ zrok admin create account me@example.com zrokuserpw\n[ 0.000] INFO zrok/controller/store.Open: database connected\n[ 0.002] INFO zrok/controller/store.(*Store).migrate: applied 0 migrations\nheMqncCyxZcx\n"})}),"\n",(0,i.jsx)(n.p,{children:"Create additional users by running the command again with a different email and password."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="Create another user"',children:"docker compose exec zrok-controller zrok admin create account \n"})}),"\n",(0,i.jsx)(n.h3,{id:"enable-the-user-environment",children:"Enable the User Environment"}),"\n",(0,i.jsx)(n.p,{children:"You must enable each device environment with the account token obtained when the account was created. This is separate from the account password that's used to log in to the web console."}),"\n",(0,i.jsxs)(n.p,{children:["Follow ",(0,i.jsx)(n.a,{href:"/docs/getting-started#installing-the-zrok-command",children:"the getting started guide"})," to install the zrok CLI on some device and enable a zrok environment."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Configure the environment with the zrok API endpoint:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# If using TLS (Caddy or Traefik)\nzrok config set apiEndpoint https://zrok.share.example.com\n\n# If using basic configuration (localhost, no TLS)\nzrok config set apiEndpoint http://localhost:18080\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Enable an environment on this device with the account token from the previous step."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"zrok enable heMqncCyxZcx\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"firewall-configuration",children:"Firewall Configuration"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"443/tcp"})," - HTTPS for all services (Caddy or Traefik)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"80/tcp"})," - ziti ctrl plane"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"3022/tcp"})," - ziti data plane"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"additional-configuration-options",children:"Additional Configuration Options"}),"\n",(0,i.jsxs)(n.p,{children:["You can add these additional settings to your ",(0,i.jsx)(n.code,{children:".env"})," file for more customization:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# OAuth configuration for public shares\nZROK_OAUTH_HASH_KEY=oauthhashkeysecret\nZROK_OAUTH_GITHUB_CLIENT_ID=abcd1234\nZROK_OAUTH_GITHUB_CLIENT_SECRET=abcd1234\nZROK_OAUTH_GOOGLE_CLIENT_ID=abcd1234\nZROK_OAUTH_GOOGLE_CLIENT_SECRET=abcd1234\n"})}),"\n",(0,i.jsx)(n.h4,{id:"\ufe0f-oauth-configuration-note",children:"\u26a0\ufe0f OAuth Configuration Note"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"If you are NOT using OAuth for public shares"}),", remove the entire OAuth section from ",(0,i.jsx)(n.code,{children:"zrok-frontend-config.yml.envsubst"})," to avoid configuration errors:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"# Remove this entire section if not using OAuth\noauth:\n bind_address: 0.0.0.0:${ZROK_OAUTH_PORT}\n endpoint_url: https://oauth.${ZROK_DNS_ZONE}\n cookie_name: zrok-auth-session\n cookie_domain: ${ZROK_DNS_ZONE}\n session_lifetime: 6h\n intermediate_lifetime: 5m\n signing_key: ${ZROK_OAUTH_HASH_KEY}\n encryption_key: ${ZROK_OAUTH_HASH_KEY}\n providers:\n - name: github\n type: github\n client_id: ${ZROK_OAUTH_GITHUB_CLIENT_ID}\n client_secret: ${ZROK_OAUTH_GITHUB_CLIENT_SECRET}\n\n - name: google\n type: google\n client_id: ${ZROK_OAUTH_GOOGLE_CLIENT_ID}\n client_secret: ${ZROK_OAUTH_GOOGLE_CLIENT_SECRET}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Then rebuild: ",(0,i.jsx)(n.code,{children:"docker compose up -d --build zrok-frontend"})]}),"\n",(0,i.jsx)(n.h3,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Check the service logs:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# View logs for a specific service\ndocker compose logs zrok-controller\ndocker compose logs zrok-frontend\ndocker compose logs ziti-quickstart\n\n# View logs for Caddy (if using)\ndocker compose logs caddy\n\n# View logs for Traefik (if using)\ndocker compose logs traefik\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Validate TLS configuration:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# For Caddy\ndocker compose exec caddy caddy validate --config /etc/caddy/Caddyfile\n\n# For Traefik\ndocker compose exec traefik traefik healthcheck\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Check certificate status:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'# For Caddy\ndocker compose exec caddy curl -s "http://localhost:2019/certificates"\n\n# For Traefik - view the ACME certificate file directly\ndocker compose exec traefik cat /etc/traefik/acme/acme.json | grep -A 5 "Certificates"\n'})}),"\n"]}),"\n"]})]})}function c(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(s,{...e})}):s(e)}},654:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>c,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"guides/self-hosting/docker","title":"Self-hosting guide for Docker","description":"","source":"@site/versioned_docs/version-0.4/guides/self-hosting/docker.mdx","sourceDirName":"guides/self-hosting","slug":"/guides/self-hosting/docker","permalink":"/docs/0.4/guides/self-hosting/docker","draft":false,"unlisted":false,"editUrl":"https://github.com/openziti/zrok/blob/main/docs/versioned_docs/version-0.4/guides/self-hosting/docker.mdx","tags":[],"version":"0.4","sidebarPosition":45,"frontMatter":{"title":"Self-hosting guide for Docker","sidebar_label":"Docker","sidebar_position":45},"sidebar":"tutorialSidebar","previous":{"title":"Personalized Frontend","permalink":"/docs/0.4/guides/self-hosting/personalized-frontend"},"next":{"title":"Kubernetes","permalink":"/docs/0.4/guides/self-hosting/kubernetes"}}');var r=o(74848),t=o(28453),s=o(31181);const c={title:"Self-hosting guide for Docker",sidebar_label:"Docker",sidebar_position:45},a=void 0,l={},d=[...s.RM];function h(e){return(0,r.jsx)(s.Ay,{})}function u(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(h,{...e})}):h()}},28453:(e,n,o)=>{o.d(n,{R:()=>s,x:()=>c});var i=o(96540);const r={},t=i.createContext(r);function s(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/685bed1a.6a52472c.js b/assets/js/685bed1a.6a52472c.js deleted file mode 100644 index 250aa05b..00000000 --- a/assets/js/685bed1a.6a52472c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5689],{31181:(e,n,o)=>{o.d(n,{Ay:()=>c,RM:()=>t});var i=o(74848),r=o(28453);const t=[{value:"Docker Instance",id:"docker-instance",level:2},{value:"Create the Docker Compose Project",id:"create-the-docker-compose-project",level:3},{value:"YOLO",id:"yolo",level:4},{value:"I'll Do it Myself",id:"ill-do-it-myself",level:4},{value:"Basic Configuration (No TLS, Localhost Only)",id:"basic-configuration-no-tls-localhost-only",level:3},{value:"DNS Configuration (Optional for localhost-only setup)",id:"dns-configuration-optional-for-localhost-only-setup",level:4},{value:"Configure the Docker Compose Project Environment",id:"configure-the-docker-compose-project-environment",level:4},{value:"Start the Docker Compose Project",id:"start-the-docker-compose-project",level:4},{value:"Expanded Configuration with TLS (Caddy or Traefik)",id:"expanded-configuration-with-tls-caddy-or-traefik",level:3},{value:"DNS Configuration for TLS",id:"dns-configuration-for-tls",level:4},{value:"Configure the Docker Compose File",id:"configure-the-docker-compose-file",level:4},{value:"Caddy Configuration",id:"caddy-configuration",level:4},{value:"Traefik Configuration",id:"traefik-configuration",level:4},{value:"Start the Docker Compose Project",id:"start-the-docker-compose-project-1",level:4},{value:"Set up a User Account",id:"set-up-a-user-account",level:3},{value:"Enable the User Environment",id:"enable-the-user-environment",level:3},{value:"Firewall Configuration",id:"firewall-configuration",level:3},{value:"Additional Configuration Options",id:"additional-configuration-options",level:3},{value:"Troubleshooting",id:"troubleshooting",level:3}];function s(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",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)(n.h2,{id:"docker-instance",children:"Docker Instance"}),"\n",(0,i.jsx)("iframe",{width:"100%",height:"315",src:"https://www.youtube.com/embed/70zJ_h4uiD8",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowfullscreen:!0}),"\n",(0,i.jsx)(n.p,{children:"This Docker Compose project creates a zrok instance supported by a OpenZiti controller and router. It supports flexible deployment configurations:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Basic Configuration"}),": Services exposed on localhost only (no TLS)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"With Caddy"}),": Services published using Caddy (TLS)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"With Traefik"}),": Services published using Traefik (TLS)"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"create-the-docker-compose-project",children:"Create the Docker Compose Project"}),"\n",(0,i.jsx)(n.p,{children:"Create a working directory on your Docker host and save these Docker Compose project files."}),"\n",(0,i.jsx)(n.h4,{id:"yolo",children:"YOLO"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Run this script to download the files in the current directory."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"curl https://get.openziti.io/zrok-instance/fetch.bash | bash\n"})}),"\n",(0,i.jsx)(n.p,{children:"Or, specify the Compose project directory."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"curl https://get.openziti.io/zrok-instance/fetch.bash | bash -s /path/to/compose/project/dir\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"ill-do-it-myself",children:"I'll Do it Myself"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Get the zrok repo ZIP file."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"wget https://github.com/openziti/zrok/archive/refs/heads/main.zip\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Unzip the zrok-instance files into the project directory."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"unzip -j -d . main.zip '*/docker/compose/zrok-instance/*'\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"basic-configuration-no-tls-localhost-only",children:"Basic Configuration (No TLS, Localhost Only)"}),"\n",(0,i.jsx)(n.p,{children:"This is the simplest way to get started with zrok, exposing services on localhost only, without TLS."}),"\n",(0,i.jsx)(n.h4,{id:"dns-configuration-optional-for-localhost-only-setup",children:"DNS Configuration (Optional for localhost-only setup)"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["If you plan to use this beyond localhost, set up a wildcard record for the IP address where the zrok instance will run\n(e.g., if your DNS zone is ",(0,i.jsx)(n.code,{children:"share.example.com"}),", then your wildcard record is ",(0,i.jsx)(n.code,{children:"*.share.example.com"}),")."]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"configure-the-docker-compose-project-environment",children:"Configure the Docker Compose Project Environment"}),"\n",(0,i.jsxs)(n.p,{children:["Create an ",(0,i.jsx)(n.code,{children:".env"})," file in the working directory with the minimal required configuration:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title=".env minimal configuration"',children:"# Required settings\nZROK_DNS_ZONE=share.example.com\nZROK_USER_EMAIL=me@example.com\nZROK_USER_PWD=zrokuserpw\nZITI_PWD=zitiadminpw\nZROK_ADMIN_TOKEN=zroktoken\n\n# Expose services only on localhost (default)\nZROK_INSECURE_INTERFACE=127.0.0.1\n\n# Service ports\nZROK_CTRL_PORT=18080\nZROK_FRONTEND_PORT=8080\nZROK_OAUTH_PORT=8081\nZITI_CTRL_ADVERTISED_PORT=80\nZITI_ROUTER_PORT=3022\n"})}),"\n",(0,i.jsx)(n.h4,{id:"start-the-docker-compose-project",children:"Start the Docker Compose Project"}),"\n",(0,i.jsx)(n.p,{children:"Start the zrok instance:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"docker compose up --build --detach\n"})}),"\n",(0,i.jsx)(n.h3,{id:"expanded-configuration-with-tls-caddy-or-traefik",children:"Expanded Configuration with TLS (Caddy or Traefik)"}),"\n",(0,i.jsx)(n.p,{children:"For production deployments, you should use TLS. You can choose between Caddy or Traefik for TLS termination and reverse proxy to the zrok services. The ziti services are always published directly, not proxied, and they bring their own TLS."}),"\n",(0,i.jsx)(n.h4,{id:"dns-configuration-for-tls",children:"DNS Configuration for TLS"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Ensure a wildcard record exists for the IP address where the zrok instance will run\n(e.g., if your DNS zone is ",(0,i.jsx)(n.code,{children:"share.example.com"}),", then your wildcard record is ",(0,i.jsx)(n.code,{children:"*.share.example.com"}),")."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Choose a DNS provider that supports automatic DNS challenge for obtaining wildcard certificates and for which a plugin is available in Caddy or Traefik."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"configure-the-docker-compose-file",children:"Configure the Docker Compose File"}),"\n",(0,i.jsxs)(n.p,{children:["Add this setting to your ",(0,i.jsx)(n.code,{children:".env"})," file to select which TLS provider to use:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# Use one of the following:\nCOMPOSE_FILE=compose.yml:compose.caddy.yml # For Caddy\n# OR\nCOMPOSE_FILE=compose.yml:compose.traefik.yml # For Traefik\n"})}),"\n",(0,i.jsx)(n.h4,{id:"caddy-configuration",children:"Caddy Configuration"}),"\n",(0,i.jsxs)(n.p,{children:["If using Caddy, add these settings to your ",(0,i.jsx)(n.code,{children:".env"})," file:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title=".env for Caddy"',children:"# Caddy TLS configuration\nCADDY_DNS_PLUGIN=cloudflare # Plugin name for your DNS provider (see github.com/caddy-dns)\nCADDY_DNS_PLUGIN_TOKEN=abcd1234 # API token from your DNS provider\nCADDY_ACME_API=https://acme-v02.api.letsencrypt.org/directory # ACME API endpoint\nCADDY_HTTPS_PORT=443 # HTTPS port (optional, defaults to 443)\nCADDY_INTERFACE=0.0.0.0 # Interface to bind to (optional, defaults to all interfaces)\n\n# For AWS Route53, uncomment and set these instead of CADDY_DNS_PLUGIN_TOKEN:\n# AWS_ACCESS_KEY_ID=your-access-key\n# AWS_SECRET_ACCESS_KEY=your-secret-key\n# AWS_REGION=your-region\n# AWS_SESSION_TOKEN=your-session-token # Only if using temporary credentials\n"})}),"\n",(0,i.jsx)(n.h4,{id:"traefik-configuration",children:"Traefik Configuration"}),"\n",(0,i.jsxs)(n.p,{children:["If using Traefik, add these settings to your ",(0,i.jsx)(n.code,{children:".env"})," file:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title=".env for Traefik"',children:"# Traefik TLS configuration\nTRAEFIK_DNS_PROVIDER=digitalocean # DNS provider for Traefik\nTRAEFIK_DNS_PROVIDER_TOKEN=abcd1234 # API token from your DNS provider\nTRAEFIK_ACME_API=https://acme-v02.api.letsencrypt.org/directory # ACME API endpoint\nTRAEFIK_HTTPS_PORT=443 # HTTPS port (optional, defaults to 443)\nTRAEFIK_INTERFACE=0.0.0.0 # Interface to bind to (optional, defaults to all interfaces)\n\n# For AWS Route53, uncomment and set these instead of TRAEFIK_DNS_PROVIDER_TOKEN:\n# AWS_ACCESS_KEY_ID=your-access-key\n# AWS_SECRET_ACCESS_KEY=your-secret-key\n# AWS_REGION=your-region\n# AWS_SESSION_TOKEN=your-session-token # Only if using temporary credentials\n"})}),"\n",(0,i.jsx)(n.h4,{id:"start-the-docker-compose-project-1",children:"Start the Docker Compose Project"}),"\n",(0,i.jsx)(n.p,{children:"Start the zrok instance with TLS support:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"docker compose up --build --detach\n"})}),"\n",(0,i.jsx)(n.h3,{id:"set-up-a-user-account",children:"Set up a User Account"}),"\n",(0,i.jsxs)(n.p,{children:["This step creates a user account. You will log in to the zrok web console with the account password created in this step. The ZROK_USER_EMAIL and ZROK_USER_PWD variables are set in the ",(0,i.jsx)(n.code,{children:".env"})," file."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="Create the first user account"',children:"docker compose exec zrok-controller bash -xc 'zrok admin create account ${ZROK_USER_EMAIL} ${ZROK_USER_PWD}'\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-buttonless",metastring:'title="Example output"',children:"+ zrok admin create account me@example.com zrokuserpw\n[ 0.000] INFO zrok/controller/store.Open: database connected\n[ 0.002] INFO zrok/controller/store.(*Store).migrate: applied 0 migrations\nheMqncCyxZcx\n"})}),"\n",(0,i.jsx)(n.p,{children:"Create additional users by running the command again with a different email and password."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="Create another user"',children:"docker compose exec zrok-controller zrok admin create account \n"})}),"\n",(0,i.jsx)(n.h3,{id:"enable-the-user-environment",children:"Enable the User Environment"}),"\n",(0,i.jsx)(n.p,{children:"You must enable each device environment with the account token obtained when the account was created. This is separate from the account password that's used to log in to the web console."}),"\n",(0,i.jsxs)(n.p,{children:["Follow ",(0,i.jsx)(n.a,{href:"/docs/getting-started#installing-the-zrok-command",children:"the getting started guide"})," to install the zrok CLI on some device and enable a zrok environment."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Configure the environment with the zrok API endpoint:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# If using TLS (Caddy or Traefik)\nzrok config set apiEndpoint https://zrok.share.example.com\n\n# If using basic configuration (localhost, no TLS)\nzrok config set apiEndpoint http://localhost:18080\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Enable an environment on this device with the account token from the previous step."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"zrok enable heMqncCyxZcx\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"firewall-configuration",children:"Firewall Configuration"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"443/tcp"})," - HTTPS for all services (Caddy or Traefik)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"80/tcp"})," - ziti ctrl plane"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"3022/tcp"})," - ziti data plane"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"additional-configuration-options",children:"Additional Configuration Options"}),"\n",(0,i.jsxs)(n.p,{children:["You can add these additional settings to your ",(0,i.jsx)(n.code,{children:".env"})," file for more customization:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# OAuth configuration for public shares\nZROK_OAUTH_HASH_KEY=oauthhashkeysecret\nZROK_OAUTH_GITHUB_CLIENT_ID=abcd1234\nZROK_OAUTH_GITHUB_CLIENT_SECRET=abcd1234\nZROK_OAUTH_GOOGLE_CLIENT_ID=abcd1234\nZROK_OAUTH_GOOGLE_CLIENT_SECRET=abcd1234\n"})}),"\n",(0,i.jsx)(n.h3,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Check the service logs:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# View logs for a specific service\ndocker compose logs zrok-controller\ndocker compose logs zrok-frontend\ndocker compose logs ziti-quickstart\n\n# View logs for Caddy (if using)\ndocker compose logs caddy\n\n# View logs for Traefik (if using)\ndocker compose logs traefik\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Validate TLS configuration:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# For Caddy\ndocker compose exec caddy caddy validate --config /etc/caddy/Caddyfile\n\n# For Traefik\ndocker compose exec traefik traefik healthcheck\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Check certificate status:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'# For Caddy\ndocker compose exec caddy curl -s "http://localhost:2019/certificates"\n\n# For Traefik - view the ACME certificate file directly\ndocker compose exec traefik cat /etc/traefik/acme/acme.json | grep -A 5 "Certificates"\n'})}),"\n"]}),"\n"]})]})}function c(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(s,{...e})}):s(e)}},654:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>c,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"guides/self-hosting/docker","title":"Self-hosting guide for Docker","description":"","source":"@site/versioned_docs/version-0.4/guides/self-hosting/docker.mdx","sourceDirName":"guides/self-hosting","slug":"/guides/self-hosting/docker","permalink":"/docs/0.4/guides/self-hosting/docker","draft":false,"unlisted":false,"editUrl":"https://github.com/openziti/zrok/blob/main/docs/versioned_docs/version-0.4/guides/self-hosting/docker.mdx","tags":[],"version":"0.4","sidebarPosition":45,"frontMatter":{"title":"Self-hosting guide for Docker","sidebar_label":"Docker","sidebar_position":45},"sidebar":"tutorialSidebar","previous":{"title":"Personalized Frontend","permalink":"/docs/0.4/guides/self-hosting/personalized-frontend"},"next":{"title":"Kubernetes","permalink":"/docs/0.4/guides/self-hosting/kubernetes"}}');var r=o(74848),t=o(28453),s=o(31181);const c={title:"Self-hosting guide for Docker",sidebar_label:"Docker",sidebar_position:45},a=void 0,l={},d=[...s.RM];function h(e){return(0,r.jsx)(s.Ay,{})}function u(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(h,{...e})}):h()}},28453:(e,n,o)=>{o.d(n,{R:()=>s,x:()=>c});var i=o(96540);const r={},t=i.createContext(r);function s(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e1dfe4fe.7f7012be.js b/assets/js/e1dfe4fe.7f7012be.js new file mode 100644 index 00000000..26ae08a0 --- /dev/null +++ b/assets/js/e1dfe4fe.7f7012be.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3423],{31181:(e,n,o)=>{o.d(n,{Ay:()=>c,RM:()=>t});var i=o(74848),r=o(28453);const t=[{value:"Docker Instance",id:"docker-instance",level:2},{value:"Create the Docker Compose Project",id:"create-the-docker-compose-project",level:3},{value:"YOLO",id:"yolo",level:4},{value:"I'll Do it Myself",id:"ill-do-it-myself",level:4},{value:"Basic Configuration (No TLS, Localhost Only)",id:"basic-configuration-no-tls-localhost-only",level:3},{value:"DNS Configuration (Optional for localhost-only setup)",id:"dns-configuration-optional-for-localhost-only-setup",level:4},{value:"Configure the Docker Compose Project Environment",id:"configure-the-docker-compose-project-environment",level:4},{value:"Start the Docker Compose Project",id:"start-the-docker-compose-project",level:4},{value:"Expanded Configuration with TLS (Caddy or Traefik)",id:"expanded-configuration-with-tls-caddy-or-traefik",level:3},{value:"DNS Configuration for TLS",id:"dns-configuration-for-tls",level:4},{value:"Configure the Docker Compose File",id:"configure-the-docker-compose-file",level:4},{value:"Caddy Configuration",id:"caddy-configuration",level:4},{value:"Traefik Configuration",id:"traefik-configuration",level:4},{value:"Start the Docker Compose Project",id:"start-the-docker-compose-project-1",level:4},{value:"Set up a User Account",id:"set-up-a-user-account",level:3},{value:"Enable the User Environment",id:"enable-the-user-environment",level:3},{value:"Firewall Configuration",id:"firewall-configuration",level:3},{value:"Additional Configuration Options",id:"additional-configuration-options",level:3},{value:"\u26a0\ufe0f OAuth Configuration Note",id:"\ufe0f-oauth-configuration-note",level:4},{value:"Troubleshooting",id:"troubleshooting",level:3}];function s(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",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)(n.h2,{id:"docker-instance",children:"Docker Instance"}),"\n",(0,i.jsx)("iframe",{width:"100%",height:"315",src:"https://www.youtube.com/embed/70zJ_h4uiD8",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowfullscreen:!0}),"\n",(0,i.jsx)(n.p,{children:"This Docker Compose project creates a zrok instance supported by a OpenZiti controller and router. It supports flexible deployment configurations:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Basic Configuration"}),": Services exposed on localhost only (no TLS)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"With Caddy"}),": Services published using Caddy (TLS)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"With Traefik"}),": Services published using Traefik (TLS)"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"create-the-docker-compose-project",children:"Create the Docker Compose Project"}),"\n",(0,i.jsx)(n.p,{children:"Create a working directory on your Docker host and save these Docker Compose project files."}),"\n",(0,i.jsx)(n.h4,{id:"yolo",children:"YOLO"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Run this script to download the files in the current directory."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"curl https://get.openziti.io/zrok-instance/fetch.bash | bash\n"})}),"\n",(0,i.jsx)(n.p,{children:"Or, specify the Compose project directory."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"curl https://get.openziti.io/zrok-instance/fetch.bash | bash -s /path/to/compose/project/dir\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"ill-do-it-myself",children:"I'll Do it Myself"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Get the zrok repo ZIP file."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"wget https://github.com/openziti/zrok/archive/refs/heads/main.zip\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Unzip the zrok-instance files into the project directory."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"unzip -j -d . main.zip '*/docker/compose/zrok-instance/*'\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"basic-configuration-no-tls-localhost-only",children:"Basic Configuration (No TLS, Localhost Only)"}),"\n",(0,i.jsx)(n.p,{children:"This is the simplest way to get started with zrok, exposing services on localhost only, without TLS."}),"\n",(0,i.jsx)(n.h4,{id:"dns-configuration-optional-for-localhost-only-setup",children:"DNS Configuration (Optional for localhost-only setup)"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["If you plan to use this beyond localhost, set up a wildcard record for the IP address where the zrok instance will run\n(e.g., if your DNS zone is ",(0,i.jsx)(n.code,{children:"share.example.com"}),", then your wildcard record is ",(0,i.jsx)(n.code,{children:"*.share.example.com"}),")."]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"configure-the-docker-compose-project-environment",children:"Configure the Docker Compose Project Environment"}),"\n",(0,i.jsxs)(n.p,{children:["Create an ",(0,i.jsx)(n.code,{children:".env"})," file in the working directory with the minimal required configuration:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title=".env minimal configuration"',children:"# Required settings\nZROK_DNS_ZONE=share.example.com\nZROK_USER_EMAIL=me@example.com\nZROK_USER_PWD=zrokuserpw\nZITI_PWD=zitiadminpw\nZROK_ADMIN_TOKEN=zroktoken\n\n# Expose services only on localhost (default)\nZROK_INSECURE_INTERFACE=127.0.0.1\n\n# Service ports\nZROK_CTRL_PORT=18080\nZROK_FRONTEND_PORT=8080\nZROK_OAUTH_PORT=8081\nZITI_CTRL_ADVERTISED_PORT=80\nZITI_ROUTER_PORT=3022\n"})}),"\n",(0,i.jsx)(n.h4,{id:"start-the-docker-compose-project",children:"Start the Docker Compose Project"}),"\n",(0,i.jsx)(n.p,{children:"Start the zrok instance:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"docker compose up --build --detach\n"})}),"\n",(0,i.jsx)(n.h3,{id:"expanded-configuration-with-tls-caddy-or-traefik",children:"Expanded Configuration with TLS (Caddy or Traefik)"}),"\n",(0,i.jsx)(n.p,{children:"For production deployments, you should use TLS. You can choose between Caddy or Traefik for TLS termination and reverse proxy to the zrok services. The ziti services are always published directly, not proxied, and they bring their own TLS."}),"\n",(0,i.jsx)(n.h4,{id:"dns-configuration-for-tls",children:"DNS Configuration for TLS"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Ensure a wildcard record exists for the IP address where the zrok instance will run\n(e.g., if your DNS zone is ",(0,i.jsx)(n.code,{children:"share.example.com"}),", then your wildcard record is ",(0,i.jsx)(n.code,{children:"*.share.example.com"}),")."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Choose a DNS provider that supports automatic DNS challenge for obtaining wildcard certificates and for which a plugin is available in Caddy or Traefik."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"configure-the-docker-compose-file",children:"Configure the Docker Compose File"}),"\n",(0,i.jsxs)(n.p,{children:["Add this setting to your ",(0,i.jsx)(n.code,{children:".env"})," file to select which TLS provider to use:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# Use one of the following:\nCOMPOSE_FILE=compose.yml:compose.caddy.yml # For Caddy\n# OR\nCOMPOSE_FILE=compose.yml:compose.traefik.yml # For Traefik\n"})}),"\n",(0,i.jsx)(n.h4,{id:"caddy-configuration",children:"Caddy Configuration"}),"\n",(0,i.jsxs)(n.p,{children:["If using Caddy, add these settings to your ",(0,i.jsx)(n.code,{children:".env"})," file:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title=".env for Caddy"',children:"# Caddy TLS configuration\nCADDY_DNS_PLUGIN=cloudflare # Plugin name for your DNS provider (see github.com/caddy-dns)\nCADDY_DNS_PLUGIN_TOKEN=abcd1234 # API token from your DNS provider\nCADDY_ACME_API=https://acme-v02.api.letsencrypt.org/directory # ACME API endpoint\nCADDY_HTTPS_PORT=443 # HTTPS port (optional, defaults to 443)\nCADDY_INTERFACE=0.0.0.0 # Interface to bind to (optional, defaults to all interfaces)\n\n# For AWS Route53, uncomment and set these instead of CADDY_DNS_PLUGIN_TOKEN:\n# AWS_ACCESS_KEY_ID=your-access-key\n# AWS_SECRET_ACCESS_KEY=your-secret-key\n# AWS_REGION=your-region\n# AWS_SESSION_TOKEN=your-session-token # Only if using temporary credentials\n"})}),"\n",(0,i.jsx)(n.h4,{id:"traefik-configuration",children:"Traefik Configuration"}),"\n",(0,i.jsxs)(n.p,{children:["If using Traefik, add these settings to your ",(0,i.jsx)(n.code,{children:".env"})," file:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title=".env for Traefik"',children:"# Traefik TLS configuration\nTRAEFIK_DNS_PROVIDER=digitalocean # DNS provider for Traefik\nTRAEFIK_DNS_PROVIDER_TOKEN=abcd1234 # API token from your DNS provider\nTRAEFIK_ACME_API=https://acme-v02.api.letsencrypt.org/directory # ACME API endpoint\nTRAEFIK_HTTPS_PORT=443 # HTTPS port (optional, defaults to 443)\nTRAEFIK_INTERFACE=0.0.0.0 # Interface to bind to (optional, defaults to all interfaces)\n\n# For AWS Route53, uncomment and set these instead of TRAEFIK_DNS_PROVIDER_TOKEN:\n# AWS_ACCESS_KEY_ID=your-access-key\n# AWS_SECRET_ACCESS_KEY=your-secret-key\n# AWS_REGION=your-region\n# AWS_SESSION_TOKEN=your-session-token # Only if using temporary credentials\n"})}),"\n",(0,i.jsx)(n.h4,{id:"start-the-docker-compose-project-1",children:"Start the Docker Compose Project"}),"\n",(0,i.jsx)(n.p,{children:"Start the zrok instance with TLS support:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"docker compose up --build --detach\n"})}),"\n",(0,i.jsx)(n.h3,{id:"set-up-a-user-account",children:"Set up a User Account"}),"\n",(0,i.jsxs)(n.p,{children:["This step creates a user account. You will log in to the zrok web console with the account password created in this step. The ZROK_USER_EMAIL and ZROK_USER_PWD variables are set in the ",(0,i.jsx)(n.code,{children:".env"})," file."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="Create the first user account"',children:"docker compose exec zrok-controller bash -xc 'zrok admin create account ${ZROK_USER_EMAIL} ${ZROK_USER_PWD}'\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-buttonless",metastring:'title="Example output"',children:"+ zrok admin create account me@example.com zrokuserpw\n[ 0.000] INFO zrok/controller/store.Open: database connected\n[ 0.002] INFO zrok/controller/store.(*Store).migrate: applied 0 migrations\nheMqncCyxZcx\n"})}),"\n",(0,i.jsx)(n.p,{children:"Create additional users by running the command again with a different email and password."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="Create another user"',children:"docker compose exec zrok-controller zrok admin create account \n"})}),"\n",(0,i.jsx)(n.h3,{id:"enable-the-user-environment",children:"Enable the User Environment"}),"\n",(0,i.jsx)(n.p,{children:"You must enable each device environment with the account token obtained when the account was created. This is separate from the account password that's used to log in to the web console."}),"\n",(0,i.jsxs)(n.p,{children:["Follow ",(0,i.jsx)(n.a,{href:"/docs/getting-started#installing-the-zrok-command",children:"the getting started guide"})," to install the zrok CLI on some device and enable a zrok environment."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Configure the environment with the zrok API endpoint:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# If using TLS (Caddy or Traefik)\nzrok config set apiEndpoint https://zrok.share.example.com\n\n# If using basic configuration (localhost, no TLS)\nzrok config set apiEndpoint http://localhost:18080\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Enable an environment on this device with the account token from the previous step."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"zrok enable heMqncCyxZcx\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"firewall-configuration",children:"Firewall Configuration"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"443/tcp"})," - HTTPS for all services (Caddy or Traefik)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"80/tcp"})," - ziti ctrl plane"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"3022/tcp"})," - ziti data plane"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"additional-configuration-options",children:"Additional Configuration Options"}),"\n",(0,i.jsxs)(n.p,{children:["You can add these additional settings to your ",(0,i.jsx)(n.code,{children:".env"})," file for more customization:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# OAuth configuration for public shares\nZROK_OAUTH_HASH_KEY=oauthhashkeysecret\nZROK_OAUTH_GITHUB_CLIENT_ID=abcd1234\nZROK_OAUTH_GITHUB_CLIENT_SECRET=abcd1234\nZROK_OAUTH_GOOGLE_CLIENT_ID=abcd1234\nZROK_OAUTH_GOOGLE_CLIENT_SECRET=abcd1234\n"})}),"\n",(0,i.jsx)(n.h4,{id:"\ufe0f-oauth-configuration-note",children:"\u26a0\ufe0f OAuth Configuration Note"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"If you are NOT using OAuth for public shares"}),", remove the entire OAuth section from ",(0,i.jsx)(n.code,{children:"zrok-frontend-config.yml.envsubst"})," to avoid configuration errors:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"# Remove this entire section if not using OAuth\noauth:\n bind_address: 0.0.0.0:${ZROK_OAUTH_PORT}\n endpoint_url: https://oauth.${ZROK_DNS_ZONE}\n cookie_name: zrok-auth-session\n cookie_domain: ${ZROK_DNS_ZONE}\n session_lifetime: 6h\n intermediate_lifetime: 5m\n signing_key: ${ZROK_OAUTH_HASH_KEY}\n encryption_key: ${ZROK_OAUTH_HASH_KEY}\n providers:\n - name: github\n type: github\n client_id: ${ZROK_OAUTH_GITHUB_CLIENT_ID}\n client_secret: ${ZROK_OAUTH_GITHUB_CLIENT_SECRET}\n\n - name: google\n type: google\n client_id: ${ZROK_OAUTH_GOOGLE_CLIENT_ID}\n client_secret: ${ZROK_OAUTH_GOOGLE_CLIENT_SECRET}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Then rebuild: ",(0,i.jsx)(n.code,{children:"docker compose up -d --build zrok-frontend"})]}),"\n",(0,i.jsx)(n.h3,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Check the service logs:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# View logs for a specific service\ndocker compose logs zrok-controller\ndocker compose logs zrok-frontend\ndocker compose logs ziti-quickstart\n\n# View logs for Caddy (if using)\ndocker compose logs caddy\n\n# View logs for Traefik (if using)\ndocker compose logs traefik\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Validate TLS configuration:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# For Caddy\ndocker compose exec caddy caddy validate --config /etc/caddy/Caddyfile\n\n# For Traefik\ndocker compose exec traefik traefik healthcheck\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Check certificate status:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'# For Caddy\ndocker compose exec caddy curl -s "http://localhost:2019/certificates"\n\n# For Traefik - view the ACME certificate file directly\ndocker compose exec traefik cat /etc/traefik/acme/acme.json | grep -A 5 "Certificates"\n'})}),"\n"]}),"\n"]})]})}function c(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(s,{...e})}):s(e)}},72465:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>c,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"guides/self-hosting/docker","title":"Self-hosting guide for Docker","description":"","source":"@site/../docs/guides/self-hosting/docker.mdx","sourceDirName":"guides/self-hosting","slug":"/guides/self-hosting/docker","permalink":"/docs/guides/self-hosting/docker","draft":false,"unlisted":false,"editUrl":"https://github.com/openziti/zrok/blob/main/docs/../docs/guides/self-hosting/docker.mdx","tags":[],"version":"current","sidebarPosition":45,"frontMatter":{"title":"Self-hosting guide for Docker","sidebar_label":"Docker","sidebar_position":45},"sidebar":"tutorialSidebar","previous":{"title":"Organizations","permalink":"/docs/guides/self-hosting/organizations"},"next":{"title":"Kubernetes","permalink":"/docs/guides/self-hosting/kubernetes"}}');var r=o(74848),t=o(28453),s=o(31181);const c={title:"Self-hosting guide for Docker",sidebar_label:"Docker",sidebar_position:45},a=void 0,l={},d=[...s.RM];function h(e){return(0,r.jsx)(s.Ay,{})}function u(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(h,{...e})}):h()}},28453:(e,n,o)=>{o.d(n,{R:()=>s,x:()=>c});var i=o(96540);const r={},t=i.createContext(r);function s(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e1dfe4fe.dfa8c381.js b/assets/js/e1dfe4fe.dfa8c381.js deleted file mode 100644 index 4b275747..00000000 --- a/assets/js/e1dfe4fe.dfa8c381.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3423],{31181:(e,n,o)=>{o.d(n,{Ay:()=>c,RM:()=>t});var i=o(74848),r=o(28453);const t=[{value:"Docker Instance",id:"docker-instance",level:2},{value:"Create the Docker Compose Project",id:"create-the-docker-compose-project",level:3},{value:"YOLO",id:"yolo",level:4},{value:"I'll Do it Myself",id:"ill-do-it-myself",level:4},{value:"Basic Configuration (No TLS, Localhost Only)",id:"basic-configuration-no-tls-localhost-only",level:3},{value:"DNS Configuration (Optional for localhost-only setup)",id:"dns-configuration-optional-for-localhost-only-setup",level:4},{value:"Configure the Docker Compose Project Environment",id:"configure-the-docker-compose-project-environment",level:4},{value:"Start the Docker Compose Project",id:"start-the-docker-compose-project",level:4},{value:"Expanded Configuration with TLS (Caddy or Traefik)",id:"expanded-configuration-with-tls-caddy-or-traefik",level:3},{value:"DNS Configuration for TLS",id:"dns-configuration-for-tls",level:4},{value:"Configure the Docker Compose File",id:"configure-the-docker-compose-file",level:4},{value:"Caddy Configuration",id:"caddy-configuration",level:4},{value:"Traefik Configuration",id:"traefik-configuration",level:4},{value:"Start the Docker Compose Project",id:"start-the-docker-compose-project-1",level:4},{value:"Set up a User Account",id:"set-up-a-user-account",level:3},{value:"Enable the User Environment",id:"enable-the-user-environment",level:3},{value:"Firewall Configuration",id:"firewall-configuration",level:3},{value:"Additional Configuration Options",id:"additional-configuration-options",level:3},{value:"Troubleshooting",id:"troubleshooting",level:3}];function s(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",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)(n.h2,{id:"docker-instance",children:"Docker Instance"}),"\n",(0,i.jsx)("iframe",{width:"100%",height:"315",src:"https://www.youtube.com/embed/70zJ_h4uiD8",title:"YouTube video player",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowfullscreen:!0}),"\n",(0,i.jsx)(n.p,{children:"This Docker Compose project creates a zrok instance supported by a OpenZiti controller and router. It supports flexible deployment configurations:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Basic Configuration"}),": Services exposed on localhost only (no TLS)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"With Caddy"}),": Services published using Caddy (TLS)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"With Traefik"}),": Services published using Traefik (TLS)"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"create-the-docker-compose-project",children:"Create the Docker Compose Project"}),"\n",(0,i.jsx)(n.p,{children:"Create a working directory on your Docker host and save these Docker Compose project files."}),"\n",(0,i.jsx)(n.h4,{id:"yolo",children:"YOLO"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Run this script to download the files in the current directory."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"curl https://get.openziti.io/zrok-instance/fetch.bash | bash\n"})}),"\n",(0,i.jsx)(n.p,{children:"Or, specify the Compose project directory."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"curl https://get.openziti.io/zrok-instance/fetch.bash | bash -s /path/to/compose/project/dir\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"ill-do-it-myself",children:"I'll Do it Myself"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Get the zrok repo ZIP file."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"wget https://github.com/openziti/zrok/archive/refs/heads/main.zip\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Unzip the zrok-instance files into the project directory."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"unzip -j -d . main.zip '*/docker/compose/zrok-instance/*'\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"basic-configuration-no-tls-localhost-only",children:"Basic Configuration (No TLS, Localhost Only)"}),"\n",(0,i.jsx)(n.p,{children:"This is the simplest way to get started with zrok, exposing services on localhost only, without TLS."}),"\n",(0,i.jsx)(n.h4,{id:"dns-configuration-optional-for-localhost-only-setup",children:"DNS Configuration (Optional for localhost-only setup)"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["If you plan to use this beyond localhost, set up a wildcard record for the IP address where the zrok instance will run\n(e.g., if your DNS zone is ",(0,i.jsx)(n.code,{children:"share.example.com"}),", then your wildcard record is ",(0,i.jsx)(n.code,{children:"*.share.example.com"}),")."]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"configure-the-docker-compose-project-environment",children:"Configure the Docker Compose Project Environment"}),"\n",(0,i.jsxs)(n.p,{children:["Create an ",(0,i.jsx)(n.code,{children:".env"})," file in the working directory with the minimal required configuration:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title=".env minimal configuration"',children:"# Required settings\nZROK_DNS_ZONE=share.example.com\nZROK_USER_EMAIL=me@example.com\nZROK_USER_PWD=zrokuserpw\nZITI_PWD=zitiadminpw\nZROK_ADMIN_TOKEN=zroktoken\n\n# Expose services only on localhost (default)\nZROK_INSECURE_INTERFACE=127.0.0.1\n\n# Service ports\nZROK_CTRL_PORT=18080\nZROK_FRONTEND_PORT=8080\nZROK_OAUTH_PORT=8081\nZITI_CTRL_ADVERTISED_PORT=80\nZITI_ROUTER_PORT=3022\n"})}),"\n",(0,i.jsx)(n.h4,{id:"start-the-docker-compose-project",children:"Start the Docker Compose Project"}),"\n",(0,i.jsx)(n.p,{children:"Start the zrok instance:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"docker compose up --build --detach\n"})}),"\n",(0,i.jsx)(n.h3,{id:"expanded-configuration-with-tls-caddy-or-traefik",children:"Expanded Configuration with TLS (Caddy or Traefik)"}),"\n",(0,i.jsx)(n.p,{children:"For production deployments, you should use TLS. You can choose between Caddy or Traefik for TLS termination and reverse proxy to the zrok services. The ziti services are always published directly, not proxied, and they bring their own TLS."}),"\n",(0,i.jsx)(n.h4,{id:"dns-configuration-for-tls",children:"DNS Configuration for TLS"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Ensure a wildcard record exists for the IP address where the zrok instance will run\n(e.g., if your DNS zone is ",(0,i.jsx)(n.code,{children:"share.example.com"}),", then your wildcard record is ",(0,i.jsx)(n.code,{children:"*.share.example.com"}),")."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Choose a DNS provider that supports automatic DNS challenge for obtaining wildcard certificates and for which a plugin is available in Caddy or Traefik."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"configure-the-docker-compose-file",children:"Configure the Docker Compose File"}),"\n",(0,i.jsxs)(n.p,{children:["Add this setting to your ",(0,i.jsx)(n.code,{children:".env"})," file to select which TLS provider to use:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# Use one of the following:\nCOMPOSE_FILE=compose.yml:compose.caddy.yml # For Caddy\n# OR\nCOMPOSE_FILE=compose.yml:compose.traefik.yml # For Traefik\n"})}),"\n",(0,i.jsx)(n.h4,{id:"caddy-configuration",children:"Caddy Configuration"}),"\n",(0,i.jsxs)(n.p,{children:["If using Caddy, add these settings to your ",(0,i.jsx)(n.code,{children:".env"})," file:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title=".env for Caddy"',children:"# Caddy TLS configuration\nCADDY_DNS_PLUGIN=cloudflare # Plugin name for your DNS provider (see github.com/caddy-dns)\nCADDY_DNS_PLUGIN_TOKEN=abcd1234 # API token from your DNS provider\nCADDY_ACME_API=https://acme-v02.api.letsencrypt.org/directory # ACME API endpoint\nCADDY_HTTPS_PORT=443 # HTTPS port (optional, defaults to 443)\nCADDY_INTERFACE=0.0.0.0 # Interface to bind to (optional, defaults to all interfaces)\n\n# For AWS Route53, uncomment and set these instead of CADDY_DNS_PLUGIN_TOKEN:\n# AWS_ACCESS_KEY_ID=your-access-key\n# AWS_SECRET_ACCESS_KEY=your-secret-key\n# AWS_REGION=your-region\n# AWS_SESSION_TOKEN=your-session-token # Only if using temporary credentials\n"})}),"\n",(0,i.jsx)(n.h4,{id:"traefik-configuration",children:"Traefik Configuration"}),"\n",(0,i.jsxs)(n.p,{children:["If using Traefik, add these settings to your ",(0,i.jsx)(n.code,{children:".env"})," file:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title=".env for Traefik"',children:"# Traefik TLS configuration\nTRAEFIK_DNS_PROVIDER=digitalocean # DNS provider for Traefik\nTRAEFIK_DNS_PROVIDER_TOKEN=abcd1234 # API token from your DNS provider\nTRAEFIK_ACME_API=https://acme-v02.api.letsencrypt.org/directory # ACME API endpoint\nTRAEFIK_HTTPS_PORT=443 # HTTPS port (optional, defaults to 443)\nTRAEFIK_INTERFACE=0.0.0.0 # Interface to bind to (optional, defaults to all interfaces)\n\n# For AWS Route53, uncomment and set these instead of TRAEFIK_DNS_PROVIDER_TOKEN:\n# AWS_ACCESS_KEY_ID=your-access-key\n# AWS_SECRET_ACCESS_KEY=your-secret-key\n# AWS_REGION=your-region\n# AWS_SESSION_TOKEN=your-session-token # Only if using temporary credentials\n"})}),"\n",(0,i.jsx)(n.h4,{id:"start-the-docker-compose-project-1",children:"Start the Docker Compose Project"}),"\n",(0,i.jsx)(n.p,{children:"Start the zrok instance with TLS support:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"docker compose up --build --detach\n"})}),"\n",(0,i.jsx)(n.h3,{id:"set-up-a-user-account",children:"Set up a User Account"}),"\n",(0,i.jsxs)(n.p,{children:["This step creates a user account. You will log in to the zrok web console with the account password created in this step. The ZROK_USER_EMAIL and ZROK_USER_PWD variables are set in the ",(0,i.jsx)(n.code,{children:".env"})," file."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="Create the first user account"',children:"docker compose exec zrok-controller bash -xc 'zrok admin create account ${ZROK_USER_EMAIL} ${ZROK_USER_PWD}'\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-buttonless",metastring:'title="Example output"',children:"+ zrok admin create account me@example.com zrokuserpw\n[ 0.000] INFO zrok/controller/store.Open: database connected\n[ 0.002] INFO zrok/controller/store.(*Store).migrate: applied 0 migrations\nheMqncCyxZcx\n"})}),"\n",(0,i.jsx)(n.p,{children:"Create additional users by running the command again with a different email and password."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",metastring:'title="Create another user"',children:"docker compose exec zrok-controller zrok admin create account \n"})}),"\n",(0,i.jsx)(n.h3,{id:"enable-the-user-environment",children:"Enable the User Environment"}),"\n",(0,i.jsx)(n.p,{children:"You must enable each device environment with the account token obtained when the account was created. This is separate from the account password that's used to log in to the web console."}),"\n",(0,i.jsxs)(n.p,{children:["Follow ",(0,i.jsx)(n.a,{href:"/docs/getting-started#installing-the-zrok-command",children:"the getting started guide"})," to install the zrok CLI on some device and enable a zrok environment."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Configure the environment with the zrok API endpoint:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# If using TLS (Caddy or Traefik)\nzrok config set apiEndpoint https://zrok.share.example.com\n\n# If using basic configuration (localhost, no TLS)\nzrok config set apiEndpoint http://localhost:18080\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Enable an environment on this device with the account token from the previous step."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"zrok enable heMqncCyxZcx\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"firewall-configuration",children:"Firewall Configuration"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"443/tcp"})," - HTTPS for all services (Caddy or Traefik)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"80/tcp"})," - ziti ctrl plane"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"3022/tcp"})," - ziti data plane"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"additional-configuration-options",children:"Additional Configuration Options"}),"\n",(0,i.jsxs)(n.p,{children:["You can add these additional settings to your ",(0,i.jsx)(n.code,{children:".env"})," file for more customization:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# OAuth configuration for public shares\nZROK_OAUTH_HASH_KEY=oauthhashkeysecret\nZROK_OAUTH_GITHUB_CLIENT_ID=abcd1234\nZROK_OAUTH_GITHUB_CLIENT_SECRET=abcd1234\nZROK_OAUTH_GOOGLE_CLIENT_ID=abcd1234\nZROK_OAUTH_GOOGLE_CLIENT_SECRET=abcd1234\n"})}),"\n",(0,i.jsx)(n.h3,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Check the service logs:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# View logs for a specific service\ndocker compose logs zrok-controller\ndocker compose logs zrok-frontend\ndocker compose logs ziti-quickstart\n\n# View logs for Caddy (if using)\ndocker compose logs caddy\n\n# View logs for Traefik (if using)\ndocker compose logs traefik\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Validate TLS configuration:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# For Caddy\ndocker compose exec caddy caddy validate --config /etc/caddy/Caddyfile\n\n# For Traefik\ndocker compose exec traefik traefik healthcheck\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Check certificate status:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'# For Caddy\ndocker compose exec caddy curl -s "http://localhost:2019/certificates"\n\n# For Traefik - view the ACME certificate file directly\ndocker compose exec traefik cat /etc/traefik/acme/acme.json | grep -A 5 "Certificates"\n'})}),"\n"]}),"\n"]})]})}function c(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(s,{...e})}):s(e)}},72465:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>c,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"guides/self-hosting/docker","title":"Self-hosting guide for Docker","description":"","source":"@site/../docs/guides/self-hosting/docker.mdx","sourceDirName":"guides/self-hosting","slug":"/guides/self-hosting/docker","permalink":"/docs/guides/self-hosting/docker","draft":false,"unlisted":false,"editUrl":"https://github.com/openziti/zrok/blob/main/docs/../docs/guides/self-hosting/docker.mdx","tags":[],"version":"current","sidebarPosition":45,"frontMatter":{"title":"Self-hosting guide for Docker","sidebar_label":"Docker","sidebar_position":45},"sidebar":"tutorialSidebar","previous":{"title":"Organizations","permalink":"/docs/guides/self-hosting/organizations"},"next":{"title":"Kubernetes","permalink":"/docs/guides/self-hosting/kubernetes"}}');var r=o(74848),t=o(28453),s=o(31181);const c={title:"Self-hosting guide for Docker",sidebar_label:"Docker",sidebar_position:45},a=void 0,l={},d=[...s.RM];function h(e){return(0,r.jsx)(s.Ay,{})}function u(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(h,{...e})}):h()}},28453:(e,n,o)=>{o.d(n,{R:()=>s,x:()=>c});var i=o(96540);const r={},t=i.createContext(r);function s(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/runtime~main.564b7b76.js b/assets/js/runtime~main.f6bca20f.js similarity index 82% rename from assets/js/runtime~main.564b7b76.js rename to assets/js/runtime~main.f6bca20f.js index a89a52ba..a0ead928 100644 --- a/assets/js/runtime~main.564b7b76.js +++ b/assets/js/runtime~main.f6bca20f.js @@ -1 +1 @@ -(()=>{"use strict";var e,c,a,b,d,f={},t={};function r(e){var c=t[e];if(void 0!==c)return c.exports;var a=t[e]={id:e,loaded:!1,exports:{}};return f[e].call(a.exports,a,a.exports,r),a.loaded=!0,a.exports}r.m=f,r.c=t,r.amdO={},e=[],r.O=(c,a,b,d)=>{if(!a){var f=1/0;for(i=0;i=d)&&Object.keys(r.O).every((e=>r.O[e](a[o])))?a.splice(o--,1):(t=!1,d0&&e[i-1][2]>d;i--)e[i]=e[i-1];e[i]=[a,b,d]},r.n=e=>{var c=e&&e.__esModule?()=>e.default:()=>e;return r.d(c,{a:c}),c},a=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,b){if(1&b&&(e=this(e)),8&b)return e;if("object"==typeof e&&e){if(4&b&&e.__esModule)return e;if(16&b&&"function"==typeof e.then)return e}var d=Object.create(null);r.r(d);var f={};c=c||[null,a({}),a([]),a(a)];for(var t=2&b&&e;"object"==typeof t&&!~c.indexOf(t);t=a(t))Object.getOwnPropertyNames(t).forEach((c=>f[c]=()=>e[c]));return f.default=()=>e,r.d(d,f),d},r.d=(e,c)=>{for(var a in c)r.o(c,a)&&!r.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:c[a]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((c,a)=>(r.f[a](e,c),c)),[])),r.u=e=>"assets/js/"+({37:"ebc0e2a0",277:"4f1777fd",351:"3fab0acb",428:"19ee95d5",429:"50ef9c44",471:"7dd0c8d0",596:"6cfa960d",598:"9939c4f4",627:"d087459a",714:"b6569025",749:"21880a4d",822:"6772556c",826:"bc32cbb6",867:"4b570305",874:"45383a38",887:"c015c796",957:"c141421f",1057:"bbbe662c",1087:"395a6105",1145:"0343fd66",1194:"01eca461",1214:"5b3e4787",1235:"a7456010",1332:"8e1d6b7d",1346:"d3a54718",1421:"71c8a211",1595:"1ddd36f2",1748:"a897899b",1769:"aad6478e",1831:"80941509",1864:"8a9ffb5d",1929:"21bca57c",1939:"7f5ec875",2100:"0b158102",2138:"1a4e3797",2229:"f3e7016d",2256:"11b43341",2379:"81f04120",2634:"c4f5d8e4",2757:"cda0d2e5",2759:"1ba5bc99",2867:"6a6a5bbc",2870:"c7a4efaf",2917:"f47ef525",3074:"8b6e57ce",3165:"c88279fc",3373:"6e881e32",3423:"e1dfe4fe",3434:"bfe99541",3441:"e0c2d235",3574:"4cb7be2f",3588:"288b1075",3747:"01cb08ea",3786:"c304be44",3921:"36b94792",3979:"2c440c24",4074:"5cd0a723",4119:"6ee0d94e",4247:"d768dc0f",4277:"27b0284c",4466:"7d0a541a",4470:"f888b719",4504:"b36bb0c9",4513:"81b00d5b",4653:"ff8b6dc7",4717:"392083ed",4739:"7f4474e1",4863:"5396078f",4909:"bc747cac",4927:"47881d5c",5009:"3459d496",5010:"f7186647",5043:"64ad3d04",5084:"37e686a5",5114:"a23b507a",5117:"8dbf8f84",5552:"0e8762f7",5684:"2e99975e",5689:"685bed1a",5695:"f8f494be",5742:"aba21aa0",5894:"8abd8ea8",5939:"946bcc4e",5955:"8b4ddd1a",6034:"d7d1649b",6055:"4277b6a0",6063:"6ad1709d",6240:"36176e50",6268:"a3ce5350",6289:"ce04f2ae",6297:"e4694d9e",6332:"2da89d45",6381:"1f91e8db",6412:"e539cb46",6475:"033e8fc8",6595:"0c1cdb3d",6694:"f00eed01",6878:"1dd31738",6946:"2cc2e835",6969:"14eb3368",6974:"bf372175",7098:"a7bd4aaa",7120:"2fede397",7158:"58ca5ccc",7216:"0c66edb9",7242:"6272ba0e",7499:"07d0b302",7599:"f7af5a99",7709:"cad548f1",7726:"8eb30cc3",7749:"7bb0ec5d",7752:"339d500a",7845:"8c19f7f0",7932:"633396ef",8051:"adf8dca1",8173:"0efac3c3",8189:"b18baa23",8239:"12b29424",8240:"28f20845",8268:"a59c7ada",8301:"81fb89b8",8365:"dbde034b",8401:"17896441",8406:"85d55244",8436:"0da40196",8471:"2e812224",8503:"1b39c707",8528:"43e1c8e4",8582:"20595907",8675:"54fa7005",8690:"ad61cf77",8746:"25ef1bb8",8875:"17f4c24e",9002:"ecf841c3",9025:"75b20590",9033:"901ef07d",9048:"a94703ab",9148:"35a60099",9253:"e2c4d679",9355:"600b2345",9471:"48341697",9476:"7452427d",9576:"61ea36d9",9606:"bc4f8b80",9631:"9af26a4e",9647:"5e95c892",9691:"392e1f0b",9803:"06e9c92f",9851:"e3e0bfdc",9905:"ef8afbfd"}[e]||e)+"."+{37:"6f0f3234",165:"c71829f0",277:"2aa86229",310:"fbead38c",351:"cdd67f30",375:"350dc95f",382:"d3709a07",416:"05118c27",428:"a5fb61fe",429:"6fca8180",471:"f51b19d8",596:"0ca7bcc5",598:"c52110fd",627:"5b953d23",714:"eaedac4d",725:"f7c371e8",749:"bbb85f93",822:"37ef0229",826:"9367a440",867:"50a845d4",874:"b6a49026",887:"53f679a9",957:"3b940a8d",962:"ef86b89e",1039:"9759cd6a",1057:"7ed39729",1087:"f4d96df5",1145:"cf59df48",1194:"2fe253f0",1214:"fd175e84",1235:"2ec2f6c0",1332:"b27c4f03",1346:"af58d2ed",1421:"79e828b6",1595:"3f935685",1748:"519890f5",1769:"09c5d7cd",1831:"73a5019b",1864:"80d71e8d",1929:"50683900",1939:"dff001de",2068:"7f77c6c1",2076:"8d5127b6",2100:"aec358ff",2123:"b4892be7",2130:"0b99be21",2138:"c4b4a442",2159:"e1a2a6eb",2229:"32e4a170",2237:"427692f4",2256:"a279b12a",2334:"229b3721",2379:"2d2a3ad4",2498:"b25e601c",2518:"db427446",2634:"6f9e4a27",2757:"fca4714d",2759:"0b96536b",2822:"e7e5b342",2867:"962940c1",2870:"9c7e32c4",2917:"5c46d0aa",3074:"d741da24",3165:"ed6a852f",3373:"f93f567a",3423:"dfa8c381",3434:"1f75e62c",3441:"4a89f039",3574:"16c44000",3588:"88577e27",3624:"bf5ba2bd",3633:"30fceca1",3736:"81f93632",3747:"7fd145cb",3786:"c46070e1",3921:"8c2605ff",3956:"5d23568c",3979:"579c2e8b",4074:"65ed8027",4119:"442ae7a9",4247:"c5082256",4277:"c8af570c",4458:"34768e68",4466:"f03241f9",4470:"f8dd5afa",4504:"cf221647",4513:"67c6cf24",4653:"5ce08dea",4717:"de67f226",4739:"ae7e9859",4863:"dc668b7d",4866:"c030ef9c",4909:"fa51c318",4914:"f0c46b66",4927:"f2347ace",5009:"a6987f47",5010:"6d5e0158",5043:"39dc7b02",5084:"13f91447",5114:"9b484a70",5117:"1d6292dc",5388:"2036fd3a",5392:"3e5751ad",5552:"119afce6",5684:"2048a062",5689:"6a52472c",5695:"ec8cfbfc",5742:"a48c4f75",5759:"7a4ec915",5775:"c4c71ea5",5864:"c51b9426",5894:"8ecf3e7e",5939:"ff98d6ac",5955:"5aa5796d",6034:"1201560f",6055:"9e697967",6063:"d2364630",6143:"c5b2839b",6240:"d37e580e",6268:"188f1743",6289:"5284ef5a",6297:"e8db6c63",6332:"e61a8e1c",6381:"792c69d7",6412:"58514299",6433:"6712975d",6475:"05fca131",6595:"e904e8ac",6694:"965bf4b4",6795:"a7c181be",6796:"dd7cccf5",6878:"5c6ef126",6946:"a34bb2f7",6969:"7b8c0ab0",6974:"8fc5c5ca",7098:"f2d25e69",7120:"45dcaebc",7158:"d02e0c17",7216:"25c50cd9",7242:"d5ffec06",7340:"1283e2f3",7499:"7bf17850",7599:"68607bfb",7709:"8efdd8fc",7726:"be64cc36",7749:"21ec94b0",7752:"a77b9d03",7835:"557ff97d",7845:"4cf49067",7900:"808f9053",7932:"a8092eae",8051:"e294b16b",8158:"4d82f1a9",8173:"2b18cac3",8188:"820f46cc",8189:"aba5168e",8239:"52cb5196",8240:"4fb1964f",8268:"1dcc732a",8301:"b2932e08",8365:"96688177",8379:"902c9f53",8401:"d25b5865",8406:"6767e297",8436:"e5753952",8471:"0a5187b6",8503:"130e2181",8528:"5cef3e0a",8582:"e0a397b5",8583:"6e1abd67",8665:"e7673950",8675:"69588fdb",8690:"7daa5fa6",8716:"743ae12e",8731:"4836caff",8746:"21df5c75",8875:"8b53d875",8913:"3eea0e0d",9002:"84af1dcc",9025:"5c65e981",9033:"363fd353",9048:"d869450d",9107:"02288822",9148:"7938c8fd",9157:"27c62f52",9253:"e6f5ce9b",9349:"6d739db7",9355:"cad1bb29",9471:"f7738d96",9476:"04af226a",9576:"b4a1481a",9606:"2965c2bc",9631:"d9008975",9647:"ad6215ad",9691:"23b0d326",9803:"043cebe5",9851:"6ed46ab4",9905:"bbda6a53"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,c)=>Object.prototype.hasOwnProperty.call(e,c),b={},d="website:",r.l=(e,c,a,f)=>{if(b[e])b[e].push(c);else{var t,o;if(void 0!==a)for(var n=document.getElementsByTagName("script"),i=0;i{t.onerror=t.onload=null,clearTimeout(s);var d=b[e];if(delete b[e],t.parentNode&&t.parentNode.removeChild(t),d&&d.forEach((e=>e(a))),c)return c(a)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=l.bind(null,t.onerror),t.onload=l.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/",r.gca=function(e){return e={17896441:"8401",20595907:"8582",48341697:"9471",80941509:"1831",ebc0e2a0:"37","4f1777fd":"277","3fab0acb":"351","19ee95d5":"428","50ef9c44":"429","7dd0c8d0":"471","6cfa960d":"596","9939c4f4":"598",d087459a:"627",b6569025:"714","21880a4d":"749","6772556c":"822",bc32cbb6:"826","4b570305":"867","45383a38":"874",c015c796:"887",c141421f:"957",bbbe662c:"1057","395a6105":"1087","0343fd66":"1145","01eca461":"1194","5b3e4787":"1214",a7456010:"1235","8e1d6b7d":"1332",d3a54718:"1346","71c8a211":"1421","1ddd36f2":"1595",a897899b:"1748",aad6478e:"1769","8a9ffb5d":"1864","21bca57c":"1929","7f5ec875":"1939","0b158102":"2100","1a4e3797":"2138",f3e7016d:"2229","11b43341":"2256","81f04120":"2379",c4f5d8e4:"2634",cda0d2e5:"2757","1ba5bc99":"2759","6a6a5bbc":"2867",c7a4efaf:"2870",f47ef525:"2917","8b6e57ce":"3074",c88279fc:"3165","6e881e32":"3373",e1dfe4fe:"3423",bfe99541:"3434",e0c2d235:"3441","4cb7be2f":"3574","288b1075":"3588","01cb08ea":"3747",c304be44:"3786","36b94792":"3921","2c440c24":"3979","5cd0a723":"4074","6ee0d94e":"4119",d768dc0f:"4247","27b0284c":"4277","7d0a541a":"4466",f888b719:"4470",b36bb0c9:"4504","81b00d5b":"4513",ff8b6dc7:"4653","392083ed":"4717","7f4474e1":"4739","5396078f":"4863",bc747cac:"4909","47881d5c":"4927","3459d496":"5009",f7186647:"5010","64ad3d04":"5043","37e686a5":"5084",a23b507a:"5114","8dbf8f84":"5117","0e8762f7":"5552","2e99975e":"5684","685bed1a":"5689",f8f494be:"5695",aba21aa0:"5742","8abd8ea8":"5894","946bcc4e":"5939","8b4ddd1a":"5955",d7d1649b:"6034","4277b6a0":"6055","6ad1709d":"6063","36176e50":"6240",a3ce5350:"6268",ce04f2ae:"6289",e4694d9e:"6297","2da89d45":"6332","1f91e8db":"6381",e539cb46:"6412","033e8fc8":"6475","0c1cdb3d":"6595",f00eed01:"6694","1dd31738":"6878","2cc2e835":"6946","14eb3368":"6969",bf372175:"6974",a7bd4aaa:"7098","2fede397":"7120","58ca5ccc":"7158","0c66edb9":"7216","6272ba0e":"7242","07d0b302":"7499",f7af5a99:"7599",cad548f1:"7709","8eb30cc3":"7726","7bb0ec5d":"7749","339d500a":"7752","8c19f7f0":"7845","633396ef":"7932",adf8dca1:"8051","0efac3c3":"8173",b18baa23:"8189","12b29424":"8239","28f20845":"8240",a59c7ada:"8268","81fb89b8":"8301",dbde034b:"8365","85d55244":"8406","0da40196":"8436","2e812224":"8471","1b39c707":"8503","43e1c8e4":"8528","54fa7005":"8675",ad61cf77:"8690","25ef1bb8":"8746","17f4c24e":"8875",ecf841c3:"9002","75b20590":"9025","901ef07d":"9033",a94703ab:"9048","35a60099":"9148",e2c4d679:"9253","600b2345":"9355","7452427d":"9476","61ea36d9":"9576",bc4f8b80:"9606","9af26a4e":"9631","5e95c892":"9647","392e1f0b":"9691","06e9c92f":"9803",e3e0bfdc:"9851",ef8afbfd:"9905"}[e]||e,r.p+r.u(e)},(()=>{var e={5354:0,1869:0};r.f.j=(c,a)=>{var b=r.o(e,c)?e[c]:void 0;if(0!==b)if(b)a.push(b[2]);else if(/^(1869|5354)$/.test(c))e[c]=0;else{var d=new Promise(((a,d)=>b=e[c]=[a,d]));a.push(b[2]=d);var f=r.p+r.u(c),t=new Error;r.l(f,(a=>{if(r.o(e,c)&&(0!==(b=e[c])&&(e[c]=void 0),b)){var d=a&&("load"===a.type?"missing":a.type),f=a&&a.target&&a.target.src;t.message="Loading chunk "+c+" failed.\n("+d+": "+f+")",t.name="ChunkLoadError",t.type=d,t.request=f,b[1](t)}}),"chunk-"+c,c)}},r.O.j=c=>0===e[c];var c=(c,a)=>{var b,d,f=a[0],t=a[1],o=a[2],n=0;if(f.some((c=>0!==e[c]))){for(b in t)r.o(t,b)&&(r.m[b]=t[b]);if(o)var i=o(r)}for(c&&c(a);n{"use strict";var e,c,a,d,b,f={},t={};function r(e){var c=t[e];if(void 0!==c)return c.exports;var a=t[e]={id:e,loaded:!1,exports:{}};return f[e].call(a.exports,a,a.exports,r),a.loaded=!0,a.exports}r.m=f,r.c=t,r.amdO={},e=[],r.O=(c,a,d,b)=>{if(!a){var f=1/0;for(i=0;i=b)&&Object.keys(r.O).every((e=>r.O[e](a[o])))?a.splice(o--,1):(t=!1,b0&&e[i-1][2]>b;i--)e[i]=e[i-1];e[i]=[a,d,b]},r.n=e=>{var c=e&&e.__esModule?()=>e.default:()=>e;return r.d(c,{a:c}),c},a=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,d){if(1&d&&(e=this(e)),8&d)return e;if("object"==typeof e&&e){if(4&d&&e.__esModule)return e;if(16&d&&"function"==typeof e.then)return e}var b=Object.create(null);r.r(b);var f={};c=c||[null,a({}),a([]),a(a)];for(var t=2&d&&e;"object"==typeof t&&!~c.indexOf(t);t=a(t))Object.getOwnPropertyNames(t).forEach((c=>f[c]=()=>e[c]));return f.default=()=>e,r.d(b,f),b},r.d=(e,c)=>{for(var a in c)r.o(c,a)&&!r.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:c[a]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((c,a)=>(r.f[a](e,c),c)),[])),r.u=e=>"assets/js/"+({37:"ebc0e2a0",277:"4f1777fd",351:"3fab0acb",428:"19ee95d5",429:"50ef9c44",471:"7dd0c8d0",596:"6cfa960d",598:"9939c4f4",627:"d087459a",714:"b6569025",749:"21880a4d",822:"6772556c",826:"bc32cbb6",867:"4b570305",874:"45383a38",887:"c015c796",957:"c141421f",1057:"bbbe662c",1087:"395a6105",1145:"0343fd66",1194:"01eca461",1214:"5b3e4787",1235:"a7456010",1332:"8e1d6b7d",1346:"d3a54718",1421:"71c8a211",1595:"1ddd36f2",1748:"a897899b",1769:"aad6478e",1831:"80941509",1864:"8a9ffb5d",1929:"21bca57c",1939:"7f5ec875",2100:"0b158102",2138:"1a4e3797",2229:"f3e7016d",2256:"11b43341",2379:"81f04120",2634:"c4f5d8e4",2757:"cda0d2e5",2759:"1ba5bc99",2867:"6a6a5bbc",2870:"c7a4efaf",2917:"f47ef525",3074:"8b6e57ce",3165:"c88279fc",3373:"6e881e32",3423:"e1dfe4fe",3434:"bfe99541",3441:"e0c2d235",3574:"4cb7be2f",3588:"288b1075",3747:"01cb08ea",3786:"c304be44",3921:"36b94792",3979:"2c440c24",4074:"5cd0a723",4119:"6ee0d94e",4247:"d768dc0f",4277:"27b0284c",4466:"7d0a541a",4470:"f888b719",4504:"b36bb0c9",4513:"81b00d5b",4653:"ff8b6dc7",4717:"392083ed",4739:"7f4474e1",4863:"5396078f",4909:"bc747cac",4927:"47881d5c",5009:"3459d496",5010:"f7186647",5043:"64ad3d04",5084:"37e686a5",5114:"a23b507a",5117:"8dbf8f84",5552:"0e8762f7",5684:"2e99975e",5689:"685bed1a",5695:"f8f494be",5742:"aba21aa0",5894:"8abd8ea8",5939:"946bcc4e",5955:"8b4ddd1a",6034:"d7d1649b",6055:"4277b6a0",6063:"6ad1709d",6240:"36176e50",6268:"a3ce5350",6289:"ce04f2ae",6297:"e4694d9e",6332:"2da89d45",6381:"1f91e8db",6412:"e539cb46",6475:"033e8fc8",6595:"0c1cdb3d",6694:"f00eed01",6878:"1dd31738",6946:"2cc2e835",6969:"14eb3368",6974:"bf372175",7098:"a7bd4aaa",7120:"2fede397",7158:"58ca5ccc",7216:"0c66edb9",7242:"6272ba0e",7499:"07d0b302",7599:"f7af5a99",7709:"cad548f1",7726:"8eb30cc3",7749:"7bb0ec5d",7752:"339d500a",7845:"8c19f7f0",7932:"633396ef",8051:"adf8dca1",8173:"0efac3c3",8189:"b18baa23",8239:"12b29424",8240:"28f20845",8268:"a59c7ada",8301:"81fb89b8",8365:"dbde034b",8401:"17896441",8406:"85d55244",8436:"0da40196",8471:"2e812224",8503:"1b39c707",8528:"43e1c8e4",8582:"20595907",8675:"54fa7005",8690:"ad61cf77",8746:"25ef1bb8",8875:"17f4c24e",9002:"ecf841c3",9025:"75b20590",9033:"901ef07d",9048:"a94703ab",9148:"35a60099",9253:"e2c4d679",9355:"600b2345",9471:"48341697",9476:"7452427d",9576:"61ea36d9",9606:"bc4f8b80",9631:"9af26a4e",9647:"5e95c892",9691:"392e1f0b",9803:"06e9c92f",9851:"e3e0bfdc",9905:"ef8afbfd"}[e]||e)+"."+{37:"6f0f3234",165:"c71829f0",277:"2aa86229",310:"fbead38c",351:"cdd67f30",375:"350dc95f",382:"d3709a07",416:"05118c27",428:"a5fb61fe",429:"6fca8180",471:"f51b19d8",596:"0ca7bcc5",598:"c52110fd",627:"5b953d23",714:"eaedac4d",725:"f7c371e8",749:"bbb85f93",822:"37ef0229",826:"9367a440",867:"50a845d4",874:"b6a49026",887:"53f679a9",957:"3b940a8d",962:"ef86b89e",1039:"9759cd6a",1057:"7ed39729",1087:"f4d96df5",1145:"cf59df48",1194:"2fe253f0",1214:"fd175e84",1235:"2ec2f6c0",1332:"b27c4f03",1346:"af58d2ed",1421:"79e828b6",1595:"3f935685",1748:"519890f5",1769:"09c5d7cd",1831:"73a5019b",1864:"80d71e8d",1929:"50683900",1939:"dff001de",2068:"7f77c6c1",2076:"8d5127b6",2100:"aec358ff",2123:"b4892be7",2130:"0b99be21",2138:"c4b4a442",2159:"e1a2a6eb",2229:"32e4a170",2237:"427692f4",2256:"a279b12a",2334:"229b3721",2379:"2d2a3ad4",2498:"b25e601c",2518:"db427446",2634:"6f9e4a27",2757:"fca4714d",2759:"0b96536b",2822:"e7e5b342",2867:"962940c1",2870:"9c7e32c4",2917:"5c46d0aa",3074:"d741da24",3165:"ed6a852f",3373:"f93f567a",3423:"7f7012be",3434:"1f75e62c",3441:"4a89f039",3574:"16c44000",3588:"88577e27",3624:"bf5ba2bd",3633:"30fceca1",3736:"81f93632",3747:"7fd145cb",3786:"c46070e1",3921:"8c2605ff",3956:"5d23568c",3979:"579c2e8b",4074:"65ed8027",4119:"442ae7a9",4247:"c5082256",4277:"c8af570c",4458:"34768e68",4466:"f03241f9",4470:"f8dd5afa",4504:"cf221647",4513:"67c6cf24",4653:"5ce08dea",4717:"de67f226",4739:"ae7e9859",4863:"c4a1e82e",4866:"c030ef9c",4909:"fa51c318",4914:"f0c46b66",4927:"f2347ace",5009:"a6987f47",5010:"6d5e0158",5043:"39dc7b02",5084:"13f91447",5114:"9b484a70",5117:"1d6292dc",5388:"2036fd3a",5392:"3e5751ad",5552:"119afce6",5684:"2048a062",5689:"5f4ddfb0",5695:"ec8cfbfc",5742:"a48c4f75",5759:"7a4ec915",5775:"c4c71ea5",5864:"c51b9426",5894:"8ecf3e7e",5939:"ff98d6ac",5955:"5aa5796d",6034:"1201560f",6055:"9e697967",6063:"d2364630",6143:"c5b2839b",6240:"d37e580e",6268:"188f1743",6289:"5284ef5a",6297:"e8db6c63",6332:"e61a8e1c",6381:"792c69d7",6412:"58514299",6433:"6712975d",6475:"05fca131",6595:"e904e8ac",6694:"965bf4b4",6795:"a7c181be",6796:"dd7cccf5",6878:"5c6ef126",6946:"a34bb2f7",6969:"7b8c0ab0",6974:"8fc5c5ca",7098:"f2d25e69",7120:"45dcaebc",7158:"d02e0c17",7216:"25c50cd9",7242:"d5ffec06",7340:"1283e2f3",7499:"7bf17850",7599:"68607bfb",7709:"8efdd8fc",7726:"be64cc36",7749:"21ec94b0",7752:"a77b9d03",7835:"557ff97d",7845:"4cf49067",7900:"808f9053",7932:"a8092eae",8051:"e294b16b",8158:"4d82f1a9",8173:"2b18cac3",8188:"820f46cc",8189:"aba5168e",8239:"52cb5196",8240:"4fb1964f",8268:"1dcc732a",8301:"b2932e08",8365:"96688177",8379:"902c9f53",8401:"d25b5865",8406:"6767e297",8436:"e5753952",8471:"0a5187b6",8503:"130e2181",8528:"5cef3e0a",8582:"e0a397b5",8583:"6e1abd67",8665:"e7673950",8675:"69588fdb",8690:"7daa5fa6",8716:"743ae12e",8731:"4836caff",8746:"21df5c75",8875:"8b53d875",8913:"3eea0e0d",9002:"84af1dcc",9025:"5c65e981",9033:"363fd353",9048:"d869450d",9107:"02288822",9148:"7938c8fd",9157:"27c62f52",9253:"e6f5ce9b",9349:"6d739db7",9355:"cad1bb29",9471:"f7738d96",9476:"04af226a",9576:"b4a1481a",9606:"2965c2bc",9631:"d9008975",9647:"ad6215ad",9691:"23b0d326",9803:"043cebe5",9851:"6ed46ab4",9905:"bbda6a53"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,c)=>Object.prototype.hasOwnProperty.call(e,c),d={},b="website:",r.l=(e,c,a,f)=>{if(d[e])d[e].push(c);else{var t,o;if(void 0!==a)for(var n=document.getElementsByTagName("script"),i=0;i{t.onerror=t.onload=null,clearTimeout(s);var b=d[e];if(delete d[e],t.parentNode&&t.parentNode.removeChild(t),b&&b.forEach((e=>e(a))),c)return c(a)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=l.bind(null,t.onerror),t.onload=l.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/",r.gca=function(e){return e={17896441:"8401",20595907:"8582",48341697:"9471",80941509:"1831",ebc0e2a0:"37","4f1777fd":"277","3fab0acb":"351","19ee95d5":"428","50ef9c44":"429","7dd0c8d0":"471","6cfa960d":"596","9939c4f4":"598",d087459a:"627",b6569025:"714","21880a4d":"749","6772556c":"822",bc32cbb6:"826","4b570305":"867","45383a38":"874",c015c796:"887",c141421f:"957",bbbe662c:"1057","395a6105":"1087","0343fd66":"1145","01eca461":"1194","5b3e4787":"1214",a7456010:"1235","8e1d6b7d":"1332",d3a54718:"1346","71c8a211":"1421","1ddd36f2":"1595",a897899b:"1748",aad6478e:"1769","8a9ffb5d":"1864","21bca57c":"1929","7f5ec875":"1939","0b158102":"2100","1a4e3797":"2138",f3e7016d:"2229","11b43341":"2256","81f04120":"2379",c4f5d8e4:"2634",cda0d2e5:"2757","1ba5bc99":"2759","6a6a5bbc":"2867",c7a4efaf:"2870",f47ef525:"2917","8b6e57ce":"3074",c88279fc:"3165","6e881e32":"3373",e1dfe4fe:"3423",bfe99541:"3434",e0c2d235:"3441","4cb7be2f":"3574","288b1075":"3588","01cb08ea":"3747",c304be44:"3786","36b94792":"3921","2c440c24":"3979","5cd0a723":"4074","6ee0d94e":"4119",d768dc0f:"4247","27b0284c":"4277","7d0a541a":"4466",f888b719:"4470",b36bb0c9:"4504","81b00d5b":"4513",ff8b6dc7:"4653","392083ed":"4717","7f4474e1":"4739","5396078f":"4863",bc747cac:"4909","47881d5c":"4927","3459d496":"5009",f7186647:"5010","64ad3d04":"5043","37e686a5":"5084",a23b507a:"5114","8dbf8f84":"5117","0e8762f7":"5552","2e99975e":"5684","685bed1a":"5689",f8f494be:"5695",aba21aa0:"5742","8abd8ea8":"5894","946bcc4e":"5939","8b4ddd1a":"5955",d7d1649b:"6034","4277b6a0":"6055","6ad1709d":"6063","36176e50":"6240",a3ce5350:"6268",ce04f2ae:"6289",e4694d9e:"6297","2da89d45":"6332","1f91e8db":"6381",e539cb46:"6412","033e8fc8":"6475","0c1cdb3d":"6595",f00eed01:"6694","1dd31738":"6878","2cc2e835":"6946","14eb3368":"6969",bf372175:"6974",a7bd4aaa:"7098","2fede397":"7120","58ca5ccc":"7158","0c66edb9":"7216","6272ba0e":"7242","07d0b302":"7499",f7af5a99:"7599",cad548f1:"7709","8eb30cc3":"7726","7bb0ec5d":"7749","339d500a":"7752","8c19f7f0":"7845","633396ef":"7932",adf8dca1:"8051","0efac3c3":"8173",b18baa23:"8189","12b29424":"8239","28f20845":"8240",a59c7ada:"8268","81fb89b8":"8301",dbde034b:"8365","85d55244":"8406","0da40196":"8436","2e812224":"8471","1b39c707":"8503","43e1c8e4":"8528","54fa7005":"8675",ad61cf77:"8690","25ef1bb8":"8746","17f4c24e":"8875",ecf841c3:"9002","75b20590":"9025","901ef07d":"9033",a94703ab:"9048","35a60099":"9148",e2c4d679:"9253","600b2345":"9355","7452427d":"9476","61ea36d9":"9576",bc4f8b80:"9606","9af26a4e":"9631","5e95c892":"9647","392e1f0b":"9691","06e9c92f":"9803",e3e0bfdc:"9851",ef8afbfd:"9905"}[e]||e,r.p+r.u(e)},(()=>{var e={5354:0,1869:0};r.f.j=(c,a)=>{var d=r.o(e,c)?e[c]:void 0;if(0!==d)if(d)a.push(d[2]);else if(/^(1869|5354)$/.test(c))e[c]=0;else{var b=new Promise(((a,b)=>d=e[c]=[a,b]));a.push(d[2]=b);var f=r.p+r.u(c),t=new Error;r.l(f,(a=>{if(r.o(e,c)&&(0!==(d=e[c])&&(e[c]=void 0),d)){var b=a&&("load"===a.type?"missing":a.type),f=a&&a.target&&a.target.src;t.message="Loading chunk "+c+" failed.\n("+b+": "+f+")",t.name="ChunkLoadError",t.type=b,t.request=f,d[1](t)}}),"chunk-"+c,c)}},r.O.j=c=>0===e[c];var c=(c,a)=>{var d,b,f=a[0],t=a[1],o=a[2],n=0;if(f.some((c=>0!==e[c]))){for(d in t)r.o(t,d)&&(r.m[d]=t[d]);if(o)var i=o(r)}for(c&&c(a);n