1"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5759],{6820:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>m,frontMatter:()=>d,metadata:()=>i,toc:()=>a});var o=t(5893),s=t(1151);const d={sidebar_position:4},r="Caddy",i={id:"self-hosting/reverse-proxy/caddy",title:"Caddy",description:"Caddy is a modern web server with automatic HTTPS built in. It obtains and renews SSL certificates from Let's Encrypt automatically with no additional configuration.",source:"@site/docs/self-hosting/reverse-proxy/caddy.md",sourceDirName:"self-hosting/reverse-proxy",slug:"/self-hosting/reverse-proxy/caddy",permalink:"/docs/self-hosting/reverse-proxy/caddy",draft:!1,unlisted:!1,editUrl:"https://github.com/docmost/docs/edit/main/docs/self-hosting/reverse-proxy/caddy.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Traefik",permalink:"/docs/self-hosting/reverse-proxy/traefik"},next:{title:"Configuration",permalink:"/docs/self-hosting/configuration/"}},c={},a=[{value:"Docker Compose with Caddy",id:"docker-compose-with-caddy",level:2},{value:"File Structure",id:"file-structure",level:2},{value:"Verify",id:"verify",level:2}];function l(e){const n={code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,s.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"caddy",children:"Caddy"}),"\n",(0,o.jsx)(n.p,{children:"Caddy is a modern web server with automatic HTTPS built in. It obtains and renews SSL certificates from Let's Encrypt automatically with no additional configuration."}),"\n",(0,o.jsx)(n.h2,{id:"docker-compose-with-caddy",children:"Docker Compose with Caddy"}),"\n",(0,o.jsxs)(n.p,{children:["Create a ",(0,o.jsx)(n.code,{children:"Caddyfile"})," in the same directory as your ",(0,o.jsx)(n.code,{children:"docker-compose.yml"}),":\nReplace ",(0,o.jsx)(n.code,{children:"docmost.example.com"})," with your actual domain."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-text",metastring:'title="Caddyfile"',children:"docmost.example.com {\n reverse_proxy docmost:3000\n}\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Below is a full ",(0,o.jsx)(n.code,{children:"docker-compose.yml"})," that includes Docmost with Caddy as the reverse proxy."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",metastring:'title="docker-compose.yml"',children:'services:\n caddy:\n image: caddy:2\n ports:\n - "80:80"\n - "443:443"\n volumes:\n - ./Caddyfile:/etc/caddy/Caddyfile:ro\n - caddy_data:/data\n - caddy_config:/config\n depends_on:\n - docmost\n restart: unless-stopped\n\n docmost:\n image: docmost/docmost:latest\n depends_on:\n - db\n - redis\n environment:\n APP_URL: \'https://docmost.example.com\'\n APP_SECRET: \'REPLACE_WITH_LONG_SECRET\'\n DATABASE_URL: \'postgresql://docmost:STRONG_DB_PASSWORD@db:5432/docmost\'\n REDIS_URL: \'redis://redis:6379\'\n ports:\n - "3000:3000"\n restart: unless-stopped\n volumes:\n - docmost:/app/data/storage\n\n db:\n image: postgres:18\n environment:\n POSTGRES_DB: docmost\n POSTGRES_USER: docmost\n POSTGRES_PASSWORD: STRONG_DB_PASSWORD\n restart: unless-stopped\n volumes:\n - db_data:/var/lib/postgresql\n\n redis:\n image: redis:8\n command: ["redis-server", "--appendonly", "yes", "--maxmemory-policy", "noeviction"]\n restart: unless-stopped\n volumes:\n - redis_data:/data\n\nvolumes:\n docmost:\n db_data:\n redis_data:\n caddy_data:\n caddy_config:\n'})}),"\n",(0,o.jsx)(n.p,{children:"That's it. Caddy automatically handles SSL certificates and WebSocket connections."}),"\n",(0,o.jsx)(n.h2,{id:"file-structure",children:"File Structure"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"docmost/\n\u251c\u2500\u2500 docker-compose.yml\n\u2514\u2500\u2500 Caddyfile\n"})}),"\n",(0,o.jsx)(n.h2,{id:"verify",children:"Verify"}),"\n",(0,o.jsxs)(n.p,{children:["After starting the services with ",(0,o.jsx)(n.code,{children:"docker
1compose up -d"}),", navigate to ",(0,o.jsx)(n.code,{children:"https://docmost.example.com"})," in your browser. You should see the Docmost setup page."]})]})}function m(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>i,a:()=>r});var o=t(7294);const s={},d=o.createContext(s);function r(e){const n=o.useContext(d);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(d.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.