"use strict";(globalThis.webpackChunktripdocs=globalThis.webpackChunktripdocs||[]).push([[26],{1270:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>P,contentTitle:()=>D,default:()=>q,frontMatter:()=>N,metadata:()=>t,toc:()=>V});const t=JSON.parse('{"id":"misc/synology","title":"Installing on Synology NAS","description":"Installing on Synology NAS using Docker and Portainer","source":"@site/docs/misc/synology.md","sourceDirName":"misc","slug":"/misc/synology","permalink":"/trip/docs/misc/synology","draft":false,"unlisted":false,"tags":[],"version":"current","sidebarPosition":2,"frontMatter":{"sidebar_position":2,"description":"Installing on Synology NAS using Docker and Portainer"},"sidebar":"docSidebar","previous":{"title":"Backup and Restore","permalink":"/trip/docs/misc/backup"},"next":{"title":"Contributing","permalink":"/trip/docs/contributing"}}');var o=r(4848),i=r(8453),s=r(6540),a=r(4164),l=r(7559),c=r(3104),u=r(6347),d=r(205),p=r(7485),h=r(1682),g=r(679);function m(e){return s.Children.toArray(e).filter(e=>"\n"!==e).map(e=>{if(!e||(0,s.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)})?.filter(Boolean)??[]}function f(e){const{values:n,children:r}=e;return(0,s.useMemo)(()=>{const e=n??function(e){return m(e).map(({props:{value:e,label:n,attributes:r,default:t}})=>({value:e,label:n,attributes:r,default:t}))}(r);return function(e){const n=(0,h.XI)(e,(e,n)=>e.value===n.value);if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map(e=>e.value).join(", ")}" found in . Every value needs to be unique.`)}(e),e},[n,r])}function x({value:e,tabValues:n}){return n.some(n=>n.value===e)}function j({queryString:e=!1,groupId:n}){const r=(0,u.W6)(),t=function({queryString:e=!1,groupId:n}){if("string"==typeof e)return e;if(!1===e)return null;if(!0===e&&!n)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:e,groupId:n});return[(0,p.aZ)(t),(0,s.useCallback)(e=>{if(!t)return;const n=new URLSearchParams(r.location.search);n.set(t,e),r.replace({...r.location,search:n.toString()})},[t,r])]}function y(e){const{defaultValue:n,queryString:r=!1,groupId:t}=e,o=f(e),[i,a]=(0,s.useState)(()=>function({defaultValue:e,tabValues:n}){if(0===n.length)throw new Error("Docusaurus error: the component requires at least one children component");if(e){if(!x({value:e,tabValues:n}))throw new Error(`Docusaurus error: The has a defaultValue "${e}" but none of its children has the corresponding value. Available values are: ${n.map(e=>e.value).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return e}const r=n.find(e=>e.default)??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:n,tabValues:o})),[l,c]=j({queryString:r,groupId:t}),[u,p]=function({groupId:e}){const n=function(e){return e?`docusaurus.tab.${e}`:null}(e),[r,t]=(0,g.Dv)(n);return[r,(0,s.useCallback)(e=>{n&&t.set(e)},[n,t])]}({groupId:t}),h=(()=>{const e=l??u;return x({value:e,tabValues:o})?e:null})();(0,d.A)(()=>{h&&a(h)},[h]);return{selectedValue:i,selectValue:(0,s.useCallback)(e=>{if(!x({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);a(e),c(e),p(e)},[c,p,o]),tabValues:o}}var b=r(2303);const v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function S({className:e,block:n,selectedValue:r,selectValue:t,tabValues:i}){const s=[],{blockElementScrollPositionUntilNextRender:l}=(0,c.a_)(),u=e=>{const n=e.currentTarget,o=s.indexOf(n),a=i[o].value;a!==r&&(l(n),t(a))},d=e=>{let n=null;switch(e.key){case"Enter":u(e);break;case"ArrowRight":{const r=s.indexOf(e.currentTarget)+1;n=s[r]??s[0];break}case"ArrowLeft":{const r=s.indexOf(e.currentTarget)-1;n=s[r]??s[s.length-1];break}}n?.focus()};return(0,o.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,a.A)("tabs",{"tabs--block":n},e),children:i.map(({value:e,label:n,attributes:t})=>(0,o.jsx)("li",{role:"tab",tabIndex:r===e?0:-1,"aria-selected":r===e,ref:e=>{s.push(e)},onKeyDown:d,onClick:u,...t,className:(0,a.A)("tabs__item",v.tabItem,t?.className,{"tabs__item--active":r===e}),children:n??e},e))})}function k({lazy:e,children:n,selectedValue:r}){const t=(Array.isArray(n)?n:[n]).filter(Boolean);if(e){const e=t.find(e=>e.props.value===r);return e?(0,s.cloneElement)(e,{className:(0,a.A)("margin-top--md",e.props.className)}):null}return(0,o.jsx)("div",{className:"margin-top--md",children:t.map((e,n)=>(0,s.cloneElement)(e,{key:n,hidden:e.props.value!==r}))})}function w(e){const n=y(e);return(0,o.jsxs)("div",{className:(0,a.A)(l.G.tabs.container,"tabs-container",v.tabList),children:[(0,o.jsx)(S,{...n,...e}),(0,o.jsx)(k,{...n,...e})]})}function I(e){const n=(0,b.A)();return(0,o.jsx)(w,{...e,children:m(e.children)},String(n))}const A={tabItem:"tabItem_Ymn6"};function C({children:e,hidden:n,className:r}){return(0,o.jsx)("div",{role:"tabpanel",className:(0,a.A)(A.tabItem,r),hidden:n,children:e})}const N={sidebar_position:2,description:"Installing on Synology NAS using Docker and Portainer"},D="Installing on Synology NAS",P={},V=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Step 1: Storage directory",id:"step-1-storage-directory",level:2},{value:"Step 2: Deploy",id:"step-2-deploy",level:2},{value:"Step 3: Access the App",id:"step-3-access-the-app",level:2},{value:"Step 4: Optional Configuration",id:"step-4-optional-configuration",level:2}];function T(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"installing-on-synology-nas",children:"Installing on Synology NAS"})}),"\n",(0,o.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Synology NAS with Docker support"}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.a,{href:"https://www.synology.com/en-us/dsm/packages/Docker",children:"Docker"})," installed via Synology Package Center"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.a,{href:"https://www.portainer.io/",children:"Portainer"})," (Community Edition) installed and running"]}),"\n",(0,o.jsx)(n.li,{children:"Basic knowledge of Synology DSM, Portainer, and network setup"}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"step-1-storage-directory",children:"Step 1: Storage directory"}),"\n",(0,o.jsx)(n.p,{children:"Create a directory for persistent storage:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"mkdir -p /volume1/docker/trip-storage\n"})}),"\n",(0,o.jsx)(n.p,{children:"Alternatively, create the folder using Synology File Station"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"/volume1/docker/trip-storage\n"})}),"\n",(0,o.jsx)(n.h2,{id:"step-2-deploy",children:"Step 2: Deploy"}),"\n",(0,o.jsxs)(I,{children:[(0,o.jsxs)(C,{value:"dcompose",label:"Docker Compose (Recommended)",default:!0,children:[(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsx)(n.li,{children:"Open Portainer"}),"\n",(0,o.jsx)(n.li,{children:"Go to Stacks \u2192 Add Stack."}),"\n",(0,o.jsxs)(n.li,{children:["Name the stack (e.g., ",(0,o.jsx)(n.code,{children:"trip"}),")."]}),"\n",(0,o.jsx)(n.li,{children:"Paste this content:"}),"\n"]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:'version: "3.9"\nservices:\n trip:\n container_name: trip\n image: ghcr.io/itskovacs/trip:1\n user: 1000:1000 # Adjust to your Synology PUID:PGID\n security_opt:\n - no-new-privileges:true\n volumes:\n - /volume1/docker/trip-storage:/app/storage # Adjust to storage dir\n restart: on-failure:5\n ports:\n - "8080:8000"\n'})}),(0,o.jsxs)(n.ol,{start:"5",children:["\n",(0,o.jsx)(n.li,{children:"Click Deploy the stack."}),"\n"]})]}),(0,o.jsxs)(C,{value:"manual",label:"Docker run",children:[(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsx)(n.li,{children:"In Portainer, go to Containers \u2192 Add Container."}),"\n",(0,o.jsx)(n.li,{children:"Fill out the following fields:"}),"\n"]}),(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.strong,{children:"Name"}),": ",(0,o.jsx)(n.code,{children:"trip"})]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.strong,{children:"Image"}),": ",(0,o.jsx)(n.code,{children:"ghcr.io/itskovacs/trip:1"})]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.strong,{children:"Port mapping"}),": ",(0,o.jsx)(n.code,{children:"8080"})," \u2192 ",(0,o.jsx)(n.code,{children:"8000"})]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.strong,{children:"Volume mapping"}),":","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Host: ",(0,o.jsx)(n.code,{children:"/volume1/docker/trip-storage"})," (adjust to storage dir)"]}),"\n",(0,o.jsxs)(n.li,{children:["Container: ",(0,o.jsx)(n.code,{children:"/app/storage"})]}),"\n"]}),"\n"]}),"\n"]}),(0,o.jsxs)(n.ol,{start:"3",children:["\n",(0,o.jsx)(n.li,{children:"Click Deploy the container."}),"\n"]})]})]}),"\n",(0,o.jsx)(n.h2,{id:"step-3-access-the-app",children:"Step 3: Access the App"}),"\n",(0,o.jsx)(n.p,{children:"Open a browser and go to:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:":8080\n"})}),"\n",(0,o.jsx)(n.p,{children:"You should see the TRIP web interface."}),"\n",(0,o.jsx)(n.h2,{id:"step-4-optional-configuration",children:"Step 4: Optional Configuration"}),"\n",(0,o.jsx)(n.admonition,{type:"note",children:(0,o.jsxs)(n.p,{children:["TRIP supports advanced configuration via a ",(0,o.jsx)(n.code,{children:"config.yml"})," file or environment variables. See ",(0,o.jsx)(n.a,{href:"http://thinkcentre:9999/trip/docs/getting-started/configuration",children:"Configuration"})," for details."]})}),"\n",(0,o.jsx)(n.p,{children:"For your Synology, you can either:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Edit or create ",(0,o.jsx)(n.code,{children:"config.yml"})," in ",(0,o.jsx)(n.code,{children:"/volume1/docker/trip-storage"})]}),"\n",(0,o.jsx)(n.li,{children:"Set environment variables in your container settings via the Synology Docker or Portainer interface"}),"\n"]}),"\n",(0,o.jsx)(n.admonition,{type:"tip",children:(0,o.jsx)(n.p,{children:"Changes require restarting the container to take effect"})})]})}function q(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(T,{...e})}):T(e)}},8453:(e,n,r)=>{r.d(n,{R:()=>s,x:()=>a});var t=r(6540);const o={},i=t.createContext(o);function s(e){const n=t.useContext(i);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]);