[{"data":1,"prerenderedAt":2115},["ShallowReactive",2],{"navigation_docs_en":3,"-en-serveex-advanced-arcane-":377,"-en-serveex-advanced-arcane--surround":2110},[4,16,94,262,271,332],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":15},"About","i-noto-star","\u002Fen\u002Fabout","en\u002F1.about",[10],{"title":11,"path":12,"stem":13,"icon":14},"Welcome","\u002Fen\u002Fabout\u002Fwelcome","en\u002F1.about\u002F1.welcome","i-lucide-home",false,{"title":17,"icon":18,"path":19,"stem":20,"children":21,"page":15},"General","i-noto-open-book","\u002Fen\u002Fgeneral","en\u002F2.general",[22,26,44,58,76],{"title":17,"path":23,"stem":24,"icon":25},"\u002Fen\u002Fgeneral\u002Fsummary","en\u002F2.general\u002F1.summary","i-lucide-bookmark",{"title":27,"icon":28,"path":29,"stem":30,"children":31,"page":15},"Networking","i-lucide-network","\u002Fen\u002Fgeneral\u002Fnetworking","en\u002F2.general\u002F2.networking",[32,36,40],{"title":33,"path":34,"stem":35},"NAT & DHCP","\u002Fen\u002Fgeneral\u002Fnetworking\u002Fnat","en\u002F2.general\u002F2.networking\u002F1.nat",{"title":37,"path":38,"stem":39},"DNS Zone","\u002Fen\u002Fgeneral\u002Fnetworking\u002Fdns","en\u002F2.general\u002F2.networking\u002F2.dns",{"title":41,"path":42,"stem":43},"Samba","\u002Fen\u002Fgeneral\u002Fnetworking\u002Fsamba","en\u002F2.general\u002F2.networking\u002F3.samba",{"title":45,"icon":46,"path":47,"stem":48,"children":49,"page":15},"Storage","i-lucide-hard-drive","\u002Fen\u002Fgeneral\u002Fstorage","en\u002F2.general\u002F3.storage",[50,54],{"title":51,"path":52,"stem":53},"RAID","\u002Fen\u002Fgeneral\u002Fstorage\u002Fraid","en\u002F2.general\u002F3.storage\u002F1.raid",{"title":55,"path":56,"stem":57},"ZFS","\u002Fen\u002Fgeneral\u002Fstorage\u002Fzfs","en\u002F2.general\u002F3.storage\u002F2.zfs",{"title":59,"icon":60,"path":61,"stem":62,"children":63,"page":15},"Hardware","i-lucide-server","\u002Fen\u002Fgeneral\u002Fhardware","en\u002F2.general\u002F4.hardware",[64,68,72],{"title":65,"path":66,"stem":67},"The Basics","\u002Fen\u002Fgeneral\u002Fhardware\u002Fbasics","en\u002F2.general\u002F4.hardware\u002F1.basics",{"title":69,"path":70,"stem":71},"Network","\u002Fen\u002Fgeneral\u002Fhardware\u002Fnetwork","en\u002F2.general\u002F4.hardware\u002F2.network",{"title":73,"path":74,"stem":75},"The ProloNAS","\u002Fen\u002Fgeneral\u002Fhardware\u002Fprolonas","en\u002F2.general\u002F4.hardware\u002F3.prolonas",{"title":77,"icon":78,"path":79,"stem":80,"children":81,"page":15},"Linux tips for dummies","i-lucide-terminal","\u002Fen\u002Fgeneral\u002Flinux","en\u002F2.general\u002F5.linux",[82,86,90],{"title":83,"path":84,"stem":85},"Command line basics","\u002Fen\u002Fgeneral\u002Flinux\u002Fcli-basics","en\u002F2.general\u002F5.linux\u002F1.cli-basics",{"title":87,"path":88,"stem":89},"Folders and partitions","\u002Fen\u002Fgeneral\u002Flinux\u002Ffilesystem","en\u002F2.general\u002F5.linux\u002F2.filesystem",{"title":91,"path":92,"stem":93},"Handy CLI tools","\u002Fen\u002Fgeneral\u002Flinux\u002Fhandy-tools","en\u002F2.general\u002F5.linux\u002F3.handy-tools",{"title":95,"icon":96,"path":97,"stem":98,"children":99,"page":15},"Serveex","i-noto-microscope","\u002Fen\u002Fserveex","en\u002F3.serveex",[100,104,126,144,170,188,202,216,234,248],{"title":101,"path":102,"stem":103,"icon":25},"Introduction","\u002Fen\u002Fserveex\u002Fintroduction","en\u002F3.serveex\u002F1.introduction",{"title":105,"icon":106,"path":107,"stem":108,"children":109,"page":15},"Server core","i-lucide-server-cog","\u002Fen\u002Fserveex\u002Fcore","en\u002F3.serveex\u002F2.core",[110,114,118,122],{"title":111,"path":112,"stem":113},"Debian 13","\u002Fen\u002Fserveex\u002Fcore\u002Finstallation","en\u002F3.serveex\u002F2.core\u002F1.installation",{"title":115,"path":116,"stem":117},"Docker","\u002Fen\u002Fserveex\u002Fcore\u002Fdocker","en\u002F3.serveex\u002F2.core\u002F2.docker",{"title":119,"path":120,"stem":121},"Wireguard","\u002Fen\u002Fserveex\u002Fcore\u002Fwireguard","en\u002F3.serveex\u002F2.core\u002F3.wireguard",{"title":123,"path":124,"stem":125},"SWAG","\u002Fen\u002Fserveex\u002Fcore\u002Fswag","en\u002F3.serveex\u002F2.core\u002F4.swag",{"title":127,"icon":128,"path":129,"stem":130,"children":131,"page":15},"Security","i-lucide-shield","\u002Fen\u002Fserveex\u002Fsecurity","en\u002F3.serveex\u002F3.security",[132,136,140],{"title":133,"path":134,"stem":135},"Cloudflare Zero Trust","\u002Fen\u002Fserveex\u002Fsecurity\u002Fcloudflare","en\u002F3.serveex\u002F3.security\u002F2.cloudflare",{"title":137,"path":138,"stem":139},"TinyAuth","\u002Fen\u002Fserveex\u002Fsecurity\u002Ftinyauth","en\u002F3.serveex\u002F3.security\u002F3.tinyauth",{"title":141,"path":142,"stem":143},"Pocket ID","\u002Fen\u002Fserveex\u002Fsecurity\u002Fpocket-id","en\u002F3.serveex\u002F3.security\u002F4.pocket-id",{"title":145,"icon":146,"path":147,"stem":148,"children":149,"page":15},"Monitoring","i-lucide-chart-no-axes-column","\u002Fen\u002Fserveex\u002Fmonitoring","en\u002F3.serveex\u002F4.monitoring",[150,154,158,162,166],{"title":151,"path":152,"stem":153},"Uptime-Kuma","\u002Fen\u002Fserveex\u002Fmonitoring\u002Fuptime-kuma","en\u002F3.serveex\u002F4.monitoring\u002F1.uptime-kuma",{"title":155,"path":156,"stem":157},"Dozzle","\u002Fen\u002Fserveex\u002Fmonitoring\u002Fdozzle","en\u002F3.serveex\u002F4.monitoring\u002F2.dozzle",{"title":159,"path":160,"stem":161},"Speedtest Tracker","\u002Fen\u002Fserveex\u002Fmonitoring\u002Fspeedtest-tracker","en\u002F3.serveex\u002F4.monitoring\u002F3.speedtest-tracker",{"title":163,"path":164,"stem":165},"Beszel","\u002Fen\u002Fserveex\u002Fmonitoring\u002Fbeszel","en\u002F3.serveex\u002F4.monitoring\u002F4.beszel",{"title":167,"path":168,"stem":169},"UpSnap","\u002Fen\u002Fserveex\u002Fmonitoring\u002Fupsnap","en\u002F3.serveex\u002F4.monitoring\u002F5.upsnap",{"title":171,"icon":172,"path":173,"stem":174,"children":175,"page":15},"Media & Seedbox","i-lucide-list-video","\u002Fen\u002Fserveex\u002Fmedia","en\u002F3.serveex\u002F5.media",[176,180,184],{"title":177,"path":178,"stem":179},"Jellyfin","\u002Fen\u002Fserveex\u002Fmedia\u002Fjellyfin","en\u002F3.serveex\u002F5.media\u002F1.jellyfin",{"title":181,"path":182,"stem":183},"Qbittorrent","\u002Fen\u002Fserveex\u002Fmedia\u002Fqbittorrent","en\u002F3.serveex\u002F5.media\u002F2.qbittorrent",{"title":185,"path":186,"stem":187},"Automation","\u002Fen\u002Fserveex\u002Fmedia\u002Fservarr","en\u002F3.serveex\u002F5.media\u002F3.servarr",{"title":189,"icon":190,"path":191,"stem":192,"children":193,"page":15},"Cloud Drive & Photos","i-lucide-cloud-upload","\u002Fen\u002Fserveex\u002Fcloud","en\u002F3.serveex\u002F6.cloud",[194,198],{"title":195,"path":196,"stem":197},"Immich","\u002Fen\u002Fserveex\u002Fcloud\u002Fimmich","en\u002F3.serveex\u002F6.cloud\u002F1.immich",{"title":199,"path":200,"stem":201},"Nextcloud","\u002Fen\u002Fserveex\u002Fcloud\u002Fnextcloud","en\u002F3.serveex\u002F6.cloud\u002F2.nextcloud",{"title":203,"icon":204,"path":205,"stem":206,"children":207,"page":15},"File & share","i-lucide-folder-tree","\u002Fen\u002Fserveex\u002Ffiles","en\u002F3.serveex\u002F7.files",[208,212],{"title":209,"path":210,"stem":211},"File Browser Quantum","\u002Fen\u002Fserveex\u002Ffiles\u002Ffile-browser-quantum","en\u002F3.serveex\u002F7.files\u002F1.file-browser-quantum",{"title":213,"path":214,"stem":215},"Pingvin","\u002Fen\u002Fserveex\u002Ffiles\u002Fpingvin","en\u002F3.serveex\u002F7.files\u002F2.pingvin",{"title":217,"icon":218,"path":219,"stem":220,"children":221,"page":15},"Developpement","i-lucide-code-xml","\u002Fen\u002Fserveex\u002Fdevelopment","en\u002F3.serveex\u002F8.development",[222,226,230],{"title":223,"path":224,"stem":225},"Code-Server","\u002Fen\u002Fserveex\u002Fdevelopment\u002Fcode-server","en\u002F3.serveex\u002F8.development\u002F1.code-server",{"title":227,"path":228,"stem":229},"Forgejo","\u002Fen\u002Fserveex\u002Fdevelopment\u002Fforgejo","en\u002F3.serveex\u002F8.development\u002F2.forgejo",{"title":231,"path":232,"stem":233},"IT Tools","\u002Fen\u002Fserveex\u002Fdevelopment\u002Fit-tools","en\u002F3.serveex\u002F8.development\u002F3.it-tools",{"title":235,"icon":236,"path":237,"stem":238,"children":239,"page":15},"Useful Apps","i-lucide-award","\u002Fen\u002Fserveex\u002Fapps","en\u002F3.serveex\u002F9.apps",[240,244],{"title":241,"path":242,"stem":243},"Adguard Home","\u002Fen\u002Fserveex\u002Fapps\u002Fadguard","en\u002F3.serveex\u002F9.apps\u002F1.adguard",{"title":245,"path":246,"stem":247},"Vaultwarden","\u002Fen\u002Fserveex\u002Fapps\u002Fvaultwarden","en\u002F3.serveex\u002F9.apps\u002F2.vaultwarden",{"title":249,"icon":250,"path":251,"stem":252,"children":253,"page":15},"Advanced","i-lucide-flask-conical","\u002Fen\u002Fserveex\u002Fadvanced","en\u002F3.serveex\u002F91.advanced",[254,258],{"title":255,"path":256,"stem":257},"Authentik","\u002Fen\u002Fserveex\u002Fadvanced\u002Fauthentik","en\u002F3.serveex\u002F91.advanced\u002F1.authentik",{"title":259,"path":260,"stem":261},"Arcane","\u002Fen\u002Fserveex\u002Fadvanced\u002Farcane","en\u002F3.serveex\u002F91.advanced\u002F2.arcane",{"title":263,"icon":264,"path":265,"stem":266,"children":267,"page":15},"Stockeex","i-noto-computer-disk","\u002Fen\u002Fstockeex","en\u002F4.stockeex",[268],{"title":101,"path":269,"stem":270,"icon":25},"\u002Fen\u002Fstockeex\u002Fintroduction","en\u002F4.stockeex\u002F1.introduction",{"title":272,"icon":273,"path":274,"stem":275,"children":276,"page":15},"My nonsense","i-noto-test-tube","\u002Fen\u002Fnonsense","en\u002F5.nonsense",[277,280,302],{"title":272,"path":278,"stem":279,"icon":25},"\u002Fen\u002Fnonsense\u002Fsummary","en\u002F5.nonsense\u002F1.summary",{"title":281,"icon":282,"path":283,"stem":284,"children":285,"page":15},"Python","i-lucide-file-code-2","\u002Fen\u002Fnonsense\u002Fpython","en\u002F5.nonsense\u002F2.python",[286,290,294,298],{"title":287,"path":288,"stem":289},"Nvidia Stock Bot","\u002Fen\u002Fnonsense\u002Fpython\u002Fnvidia-stock-bot","en\u002F5.nonsense\u002F2.python\u002F1.nvidia-stock-bot",{"title":291,"path":292,"stem":293},"Adguard CIDRE","\u002Fen\u002Fnonsense\u002Fpython\u002Fadguard-cidre","en\u002F5.nonsense\u002F2.python\u002F2.adguard-cidre",{"title":295,"path":296,"stem":297},"Lumeex","\u002Fen\u002Fnonsense\u002Fpython\u002Flumeex","en\u002F5.nonsense\u002F2.python\u002F3.lumeex",{"title":299,"path":300,"stem":301},"Instameex","\u002Fen\u002Fnonsense\u002Fpython\u002Finstameex","en\u002F5.nonsense\u002F2.python\u002F4.instameex",{"title":303,"icon":304,"path":305,"stem":306,"children":307,"page":15},"Bash","i-lucide-file-terminal","\u002Fen\u002Fnonsense\u002Fbash","en\u002F5.nonsense\u002F3.bash",[308,312,316,320,324,328],{"title":309,"path":310,"stem":311},"Servarr corrector","\u002Fen\u002Fnonsense\u002Fbash\u002Fservarr-duplicates","en\u002F5.nonsense\u002F3.bash\u002F1.servarr-duplicates",{"title":313,"path":314,"stem":315},"LUKS Backup","\u002Fen\u002Fnonsense\u002Fbash\u002Fluks-backup","en\u002F5.nonsense\u002F3.bash\u002F2.luks-backup",{"title":317,"path":318,"stem":319},"Socat Proxy","\u002Fen\u002Fnonsense\u002Fbash\u002Fsocat-proxy","en\u002F5.nonsense\u002F3.bash\u002F3.socat-proxy",{"title":321,"path":322,"stem":323},"HotDisk","\u002Fen\u002Fnonsense\u002Fbash\u002Fhotdisk","en\u002F5.nonsense\u002F3.bash\u002F4.hotdisk",{"title":325,"path":326,"stem":327},"Backrest Docker Stop","\u002Fen\u002Fnonsense\u002Fbash\u002Fbackrest-docker-stop","en\u002F5.nonsense\u002F3.bash\u002F5.backrest-docker-stop",{"title":329,"path":330,"stem":331},"rm Confirmation Guard","\u002Fen\u002Fnonsense\u002Fbash\u002Frm-confirmation","en\u002F5.nonsense\u002F3.bash\u002F6.rm-confirmation",{"title":333,"icon":334,"path":335,"stem":336,"children":337,"page":15},"Recycled","i-noto-recycling-symbol","\u002Fen\u002Frecycled","en\u002F6.recycled",[338,341,355],{"title":333,"path":339,"stem":340,"icon":25},"\u002Fen\u002Frecycled\u002Fsummary","en\u002F6.recycled\u002F1.summary",{"title":342,"icon":343,"path":344,"stem":345,"children":346,"page":15},"Deprecated","i-lucide-trash-2","\u002Fen\u002Frecycled\u002Fdeprecated","en\u002F6.recycled\u002F2.deprecated",[347,351],{"title":348,"path":349,"stem":350},"Wireguard 14","\u002Fen\u002Frecycled\u002Fdeprecated\u002Fwireguard-14","en\u002F6.recycled\u002F2.deprecated\u002F1.wireguard-14",{"title":352,"path":353,"stem":354},"File Browser","\u002Fen\u002Frecycled\u002Fdeprecated\u002Ffile-browser","en\u002F6.recycled\u002F2.deprecated\u002F2.file-browser",{"title":356,"icon":357,"path":358,"stem":359,"children":360,"page":15},"Alternatives","i-lucide-arrow-left-right","\u002Fen\u002Frecycled\u002Falternatives","en\u002F6.recycled\u002F3.alternatives",[361,365,369,373],{"title":362,"path":363,"stem":364},"Plex","\u002Fen\u002Frecycled\u002Falternatives\u002Fplex","en\u002F6.recycled\u002F3.alternatives\u002F1.plex",{"title":366,"path":367,"stem":368},"Qbittorrent for Plex","\u002Fen\u002Frecycled\u002Falternatives\u002Fqbittorrent-for-plex","en\u002F6.recycled\u002F3.alternatives\u002F2.qbittorrent for plex",{"title":370,"path":371,"stem":372},"Servarr for Plex","\u002Fen\u002Frecycled\u002Falternatives\u002Fservarr-for-plex","en\u002F6.recycled\u002F3.alternatives\u002F3.servarr for plex",{"title":374,"path":375,"stem":376},"Gitea","\u002Fen\u002Frecycled\u002Falternatives\u002Fgitea","en\u002F6.recycled\u002F3.alternatives\u002F4.gitea",{"id":378,"title":259,"body":379,"contributors":2102,"description":2104,"extension":2105,"hideCopyPage":15,"hideHeader":15,"hideToc":15,"links":2106,"meta":2107,"navigation":687,"path":260,"seo":2108,"stem":261,"__hash__":2109},"docs_en\u002Fen\u002F3.serveex\u002F91.advanced\u002F2.arcane.md",{"type":380,"value":381,"toc":2078},"minimark",[382,390,400,410,416,433,441,446,450,1181,1188,1192,1195,1211,1247,1679,1682,1686,1697,1713,1862,1866,1869,2027,2030,2074],[383,384],"ellipsis",{"blur":385,"left":386,"top":387,"width":388,"z-index":389},"140px","0px","10rem","40rem","60",[391,392,394,395,399],"note",{"to":393},"\u002Fserveex\u002Fcore\u002Fdocker#installer-dockge-pour-gérer-et-déployer-les-conteneurs","This is an advanced alternative to ",[396,397,398],"strong",{},"Dockge",": it can manage several remote Docker hosts from a single instance, and supports OIDC login natively instead of relying on a separate forward-auth proxy.",[401,402,403,409],"p",{},[404,405,259],"a",{"href":406,"rel":407},"https:\u002F\u002Fgithub.com\u002Fgetarcaneapp\u002Farcane",[408],"nofollow"," is a self-hosted web UI for managing Docker containers, images, volumes, and Compose stacks.",[401,411,412],{},[413,414],"img",{"alt":259,"src":415},"\u002Fimg\u002Fserveex\u002Farcane.png",[417,418,419,427],"ul",{},[420,421,422],"li",{},[404,423,426],{"href":424,"rel":425},"https:\u002F\u002Fgetarcane.app\u002Fdocs\u002F",[408],"Arcane documentation",[420,428,429],{},[404,430,432],{"href":406,"rel":431},[408],"Arcane on GitHub",[391,434,436,437,440],{"to":435},"https:\u002F\u002Fdocs.linuxserver.io\u002Fimages\u002Fdocker-socket-proxy\u002F","Arcane needs access to the Docker socket to manage containers, which is effectively root access to your host. Instead of mounting the socket directly, this guide sits ",[396,438,439],{},"Docker Socket Proxy"," in front of it, only allowing the specific API permissions Arcane actually needs. Whatever you use, make sure Arcane itself is never reachable without authentication.",[442,443,445],"h2",{"id":444},"installation","Installation",[447,448],"file-tree",{":tree":449},"{\"\u002F\":[{\"srv\":[{\"docker\":[{\"arcane\":[\"compose.yaml\",\".env\",\"data\u002F\"]}]}]}]}",[451,452,454,459,491,498,502,524,942,963,1010,1014,1020,1077,1170,1177],"steps",{"level":453},"3",[455,456,458],"h3",{"id":457},"generate-an-encryption-key","Generate an encryption key",[460,461,467],"pre",{"className":462,"code":463,"filename":464,"language":465,"meta":466,"style":466},"language-bash shiki shiki-themes github-dark material-theme github-dark","openssl rand -base64 32\n","Terminal","bash","",[468,469,470],"code",{"__ignoreMap":466},[471,472,475,479,483,487],"span",{"class":473,"line":474},"line",1,[471,476,478],{"class":477},"sEgDM","openssl",[471,480,482],{"class":481},"s11XM"," rand",[471,484,486],{"class":485},"sJWha"," -base64",[471,488,490],{"class":489},"swwWl"," 32\n",[401,492,493,494,497],{},"Keep the output, you'll need it for the ",[468,495,496],{},".env"," file below.",[455,499,501],{"id":500},"deploy-the-stack","Deploy the stack",[401,503,504,505,508,509,512,513,515,516,519,520,523],{},"Open Dockge, click ",[468,506,507],{},"compose",", name the stack ",[468,510,511],{},"arcane",", and add the following config. It includes the socket proxy: ",[468,514,511],{}," never touches ",[468,517,518],{},"\u002Fvar\u002Frun\u002Fdocker.sock"," directly, only ",[468,521,522],{},"docker-socket-proxy"," does, and it only allows the specific permissions Arcane needs (containers, images, networks, volumes, exec, build\u002Fcommit), on their own internal network:",[460,525,530],{"className":526,"code":527,"filename":528,"language":529,"meta":466,"style":466},"language-yaml shiki shiki-themes github-dark material-theme github-dark","---\nservices:\n  arcane:\n    image: ghcr.io\u002Fgetarcaneapp\u002Fmanager:latest\n    container_name: arcane\n    restart: unless-stopped\n    cgroup: host\n    env_file:\n      - .env\n    volumes:\n      - \u002Fsrv\u002Fdocker\u002Farcane\u002Fdata:\u002Fapp\u002Fdata\n    networks:\n      - arcane-internal\n    ports:\n      - 3552:3552\n    depends_on:\n      - docker-socket-proxy\n\n  docker-socket-proxy:\n    image: lscr.io\u002Flinuxserver\u002Fsocket-proxy:latest\n    container_name: arcane-docker-proxy\n    security_opt:\n      - no-new-privileges:true\n    networks:\n      - arcane-internal\n    volumes:\n      - \u002Fvar\u002Frun\u002Fdocker.sock:\u002Fvar\u002Frun\u002Fdocker.sock:ro\n    environment:\n      - CONTAINERS=1\n      - IMAGES=1\n      - NETWORKS=1\n      - VOLUMES=1\n      - EXEC=1\n      - BUILD=1\n      - COMMIT=1\n      - INFO=1\n      - SYSTEM=1\n      - POST=1\n      - ALLOW_START=1\n      - ALLOW_STOP=1\n      - ALLOW_RESTARTS=1\n    restart: unless-stopped\n    read_only: true\n    tmpfs:\n      - \u002Frun\n\nnetworks:\n  arcane-internal:\n    name: arcane-internal\n","compose.yaml","yaml",[468,531,532,537,548,556,568,579,590,601,609,618,626,634,642,650,658,666,674,682,689,697,707,717,725,733,740,747,754,762,770,778,786,794,802,810,818,826,834,842,850,858,866,874,883,895,903,911,916,924,932],{"__ignoreMap":466},[471,533,534],{"class":473,"line":474},[471,535,536],{"class":477},"---\n",[471,538,540,544],{"class":473,"line":539},2,[471,541,543],{"class":542},"sRuoG","services",[471,545,547],{"class":546},"s8jd1",":\n",[471,549,551,554],{"class":473,"line":550},3,[471,552,553],{"class":542},"  arcane",[471,555,547],{"class":546},[471,557,559,562,565],{"class":473,"line":558},4,[471,560,561],{"class":542},"    image",[471,563,564],{"class":546},":",[471,566,567],{"class":481}," ghcr.io\u002Fgetarcaneapp\u002Fmanager:latest\n",[471,569,571,574,576],{"class":473,"line":570},5,[471,572,573],{"class":542},"    container_name",[471,575,564],{"class":546},[471,577,578],{"class":481}," arcane\n",[471,580,582,585,587],{"class":473,"line":581},6,[471,583,584],{"class":542},"    restart",[471,586,564],{"class":546},[471,588,589],{"class":481}," unless-stopped\n",[471,591,593,596,598],{"class":473,"line":592},7,[471,594,595],{"class":542},"    cgroup",[471,597,564],{"class":546},[471,599,600],{"class":481}," host\n",[471,602,604,607],{"class":473,"line":603},8,[471,605,606],{"class":542},"    env_file",[471,608,547],{"class":546},[471,610,612,615],{"class":473,"line":611},9,[471,613,614],{"class":546},"      -",[471,616,617],{"class":481}," .env\n",[471,619,621,624],{"class":473,"line":620},10,[471,622,623],{"class":542},"    volumes",[471,625,547],{"class":546},[471,627,629,631],{"class":473,"line":628},11,[471,630,614],{"class":546},[471,632,633],{"class":481}," \u002Fsrv\u002Fdocker\u002Farcane\u002Fdata:\u002Fapp\u002Fdata\n",[471,635,637,640],{"class":473,"line":636},12,[471,638,639],{"class":542},"    networks",[471,641,547],{"class":546},[471,643,645,647],{"class":473,"line":644},13,[471,646,614],{"class":546},[471,648,649],{"class":481}," arcane-internal\n",[471,651,653,656],{"class":473,"line":652},14,[471,654,655],{"class":542},"    ports",[471,657,547],{"class":546},[471,659,661,663],{"class":473,"line":660},15,[471,662,614],{"class":546},[471,664,665],{"class":481}," 3552:3552\n",[471,667,669,672],{"class":473,"line":668},16,[471,670,671],{"class":542},"    depends_on",[471,673,547],{"class":546},[471,675,677,679],{"class":473,"line":676},17,[471,678,614],{"class":546},[471,680,681],{"class":481}," docker-socket-proxy\n",[471,683,685],{"class":473,"line":684},18,[471,686,688],{"emptyLinePlaceholder":687},true,"\n",[471,690,692,695],{"class":473,"line":691},19,[471,693,694],{"class":542},"  docker-socket-proxy",[471,696,547],{"class":546},[471,698,700,702,704],{"class":473,"line":699},20,[471,701,561],{"class":542},[471,703,564],{"class":546},[471,705,706],{"class":481}," lscr.io\u002Flinuxserver\u002Fsocket-proxy:latest\n",[471,708,710,712,714],{"class":473,"line":709},21,[471,711,573],{"class":542},[471,713,564],{"class":546},[471,715,716],{"class":481}," arcane-docker-proxy\n",[471,718,720,723],{"class":473,"line":719},22,[471,721,722],{"class":542},"    security_opt",[471,724,547],{"class":546},[471,726,728,730],{"class":473,"line":727},23,[471,729,614],{"class":546},[471,731,732],{"class":481}," no-new-privileges:true\n",[471,734,736,738],{"class":473,"line":735},24,[471,737,639],{"class":542},[471,739,547],{"class":546},[471,741,743,745],{"class":473,"line":742},25,[471,744,614],{"class":546},[471,746,649],{"class":481},[471,748,750,752],{"class":473,"line":749},26,[471,751,623],{"class":542},[471,753,547],{"class":546},[471,755,757,759],{"class":473,"line":756},27,[471,758,614],{"class":546},[471,760,761],{"class":481}," \u002Fvar\u002Frun\u002Fdocker.sock:\u002Fvar\u002Frun\u002Fdocker.sock:ro\n",[471,763,765,768],{"class":473,"line":764},28,[471,766,767],{"class":542},"    environment",[471,769,547],{"class":546},[471,771,773,775],{"class":473,"line":772},29,[471,774,614],{"class":546},[471,776,777],{"class":481}," CONTAINERS=1\n",[471,779,781,783],{"class":473,"line":780},30,[471,782,614],{"class":546},[471,784,785],{"class":481}," IMAGES=1\n",[471,787,789,791],{"class":473,"line":788},31,[471,790,614],{"class":546},[471,792,793],{"class":481}," NETWORKS=1\n",[471,795,797,799],{"class":473,"line":796},32,[471,798,614],{"class":546},[471,800,801],{"class":481}," VOLUMES=1\n",[471,803,805,807],{"class":473,"line":804},33,[471,806,614],{"class":546},[471,808,809],{"class":481}," EXEC=1\n",[471,811,813,815],{"class":473,"line":812},34,[471,814,614],{"class":546},[471,816,817],{"class":481}," BUILD=1\n",[471,819,821,823],{"class":473,"line":820},35,[471,822,614],{"class":546},[471,824,825],{"class":481}," COMMIT=1\n",[471,827,829,831],{"class":473,"line":828},36,[471,830,614],{"class":546},[471,832,833],{"class":481}," INFO=1\n",[471,835,837,839],{"class":473,"line":836},37,[471,838,614],{"class":546},[471,840,841],{"class":481}," SYSTEM=1\n",[471,843,845,847],{"class":473,"line":844},38,[471,846,614],{"class":546},[471,848,849],{"class":481}," POST=1\n",[471,851,853,855],{"class":473,"line":852},39,[471,854,614],{"class":546},[471,856,857],{"class":481}," ALLOW_START=1\n",[471,859,861,863],{"class":473,"line":860},40,[471,862,614],{"class":546},[471,864,865],{"class":481}," ALLOW_STOP=1\n",[471,867,869,871],{"class":473,"line":868},41,[471,870,614],{"class":546},[471,872,873],{"class":481}," ALLOW_RESTARTS=1\n",[471,875,877,879,881],{"class":473,"line":876},42,[471,878,584],{"class":542},[471,880,564],{"class":546},[471,882,589],{"class":481},[471,884,886,889,891],{"class":473,"line":885},43,[471,887,888],{"class":542},"    read_only",[471,890,564],{"class":546},[471,892,894],{"class":893},"s08Ry"," true\n",[471,896,898,901],{"class":473,"line":897},44,[471,899,900],{"class":542},"    tmpfs",[471,902,547],{"class":546},[471,904,906,908],{"class":473,"line":905},45,[471,907,614],{"class":546},[471,909,910],{"class":481}," \u002Frun\n",[471,912,914],{"class":473,"line":913},46,[471,915,688],{"emptyLinePlaceholder":687},[471,917,919,922],{"class":473,"line":918},47,[471,920,921],{"class":542},"networks",[471,923,547],{"class":546},[471,925,927,930],{"class":473,"line":926},48,[471,928,929],{"class":542},"  arcane-internal",[471,931,547],{"class":546},[471,933,935,938,940],{"class":473,"line":934},49,[471,936,937],{"class":542},"    name",[471,939,564],{"class":546},[471,941,649],{"class":481},[391,943,944,947,948,951,952,951,955,958,959,962],{},[468,945,946],{},"POST=1"," is the blanket write-enable needed for creating\u002Fremoving containers, images, networks and volumes; ",[468,949,950],{},"ALLOW_START","\u002F",[468,953,954],{},"ALLOW_STOP",[468,956,957],{},"ALLOW_RESTARTS"," cover container lifecycle actions separately. Everything else (Swarm, secrets, configs, auth) is left at its default ",[468,960,961],{},"0",", since this site doesn't use them.",[964,965,966,969],"tip",{"icon":466},[401,967,968],{},"✨ Add the Watchtower label to automate updates:",[460,970,972],{"className":526,"code":971,"filename":528,"language":529,"meta":466,"style":466},"---\nservices:\n  arcane:\n    #...\n    labels:\n      - com.centurylinklabs.watchtower.enable=true\n",[468,973,974,978,984,990,996,1003],{"__ignoreMap":466},[471,975,976],{"class":473,"line":474},[471,977,536],{"class":477},[471,979,980,982],{"class":473,"line":539},[471,981,543],{"class":542},[471,983,547],{"class":546},[471,985,986,988],{"class":473,"line":550},[471,987,553],{"class":542},[471,989,547],{"class":546},[471,991,992],{"class":473,"line":558},[471,993,995],{"class":994},"sDvJj","    #...\n",[471,997,998,1001],{"class":473,"line":570},[471,999,1000],{"class":542},"    labels",[471,1002,547],{"class":546},[471,1004,1005,1007],{"class":473,"line":581},[471,1006,614],{"class":546},[471,1008,1009],{"class":481}," com.centurylinklabs.watchtower.enable=true\n",[455,1011,1013],{"id":1012},"set-your-environment-variables","Set your environment variables",[401,1015,1016,1017,1019],{},"Fill in the ",[468,1018,496],{}," file:",[460,1021,1025],{"className":1022,"code":1023,"filename":496,"language":1024,"meta":466,"style":466},"language-properties shiki shiki-themes github-dark material-theme github-dark","APP_URL=https:\u002F\u002Farcane.mydomain.com\nENCRYPTION_KEY=\nDOCKER_HOST=tcp:\u002F\u002Fdocker-socket-proxy:2375\nPUID=1000\nPGID=1000\n","properties",[468,1026,1027,1040,1048,1058,1068],{"__ignoreMap":466},[471,1028,1029,1033,1036],{"class":473,"line":474},[471,1030,1032],{"class":1031},"szyEh","APP_URL",[471,1034,1035],{"class":546},"=",[471,1037,1039],{"class":1038},"slcoZ","https:\u002F\u002Farcane.mydomain.com\n",[471,1041,1042,1045],{"class":473,"line":539},[471,1043,1044],{"class":1031},"ENCRYPTION_KEY",[471,1046,1047],{"class":546},"=\n",[471,1049,1050,1053,1055],{"class":473,"line":550},[471,1051,1052],{"class":1031},"DOCKER_HOST",[471,1054,1035],{"class":546},[471,1056,1057],{"class":1038},"tcp:\u002F\u002Fdocker-socket-proxy:2375\n",[471,1059,1060,1063,1065],{"class":473,"line":558},[471,1061,1062],{"class":1031},"PUID",[471,1064,1035],{"class":546},[471,1066,1067],{"class":1038},"1000\n",[471,1069,1070,1073,1075],{"class":473,"line":570},[471,1071,1072],{"class":1031},"PGID",[471,1074,1035],{"class":546},[471,1076,1067],{"class":1038},[1078,1079,1080,1096],"table",{},[1081,1082,1083],"thead",{},[1084,1085,1086,1090,1093],"tr",{},[1087,1088,1089],"th",{},"Variable",[1087,1091,1092],{},"Value",[1087,1094,1095],{},"Example",[1097,1098,1099,1116,1132,1148],"tbody",{},[1084,1100,1101,1108,1111],{},[1102,1103,1104],"td",{},[468,1105,1106],{"className":1022,"language":1024,"style":466},[471,1107,1032],{"class":1038},[1102,1109,1110],{},"The public URL you'll use to reach Arcane (see exposure below), without a port",[1102,1112,1113],{},[468,1114,1115],{},"https:\u002F\u002Farcane.mydomain.com",[1084,1117,1118,1124,1127],{},[1102,1119,1120],{},[468,1121,1122],{"className":1022,"language":1024,"style":466},[471,1123,1044],{"class":1038},[1102,1125,1126],{},"The key generated above",[1102,1128,1129],{},[468,1130,1131],{},"Q2pVEqsTNRkJSO9SkJzU3KZ2...",[1084,1133,1134,1140,1143],{},[1102,1135,1136],{},[468,1137,1138],{"className":1022,"language":1024,"style":466},[471,1139,1052],{"class":1038},[1102,1141,1142],{},"Points Arcane at the socket proxy instead of a mounted socket",[1102,1144,1145],{},[468,1146,1147],{},"tcp:\u002F\u002Fdocker-socket-proxy:2375",[1084,1149,1150,1159,1165],{},[1102,1151,1152,1154,1155],{},[468,1153,1062],{}," \u002F ",[468,1156,1157],{"className":1022,"language":1024,"style":466},[471,1158,1072],{"class":1038},[1102,1160,1161,1162],{},"Your user and group ID, from ",[468,1163,1164],{},"id yourusername",[1102,1166,1167],{},[468,1168,1169],{},"1000",[401,1171,1172,1173,1176],{},"Deploy the stack. The local interface is available at ",[468,1174,1175],{},"http:\u002F\u002Fyourserverip:3552",".",[455,1178,1180],{"id":1179},"done","Done !",[1182,1183,1184,1187],"caution",{},[396,1185,1186],{},"If it fails:"," check your firewall rules.",[442,1189,1191],{"id":1190},"exposing-arcane-with-swag","Exposing Arcane with SWAG",[401,1193,1194],{},"The main benefit of this setup is being able to access Arcane remotely from all your devices. We'll expose it using SWAG.",[1196,1197,1198,1199,1202,1203,1206,1207,1210],"warning",{},"Arcane's own local login has no multi-factor authentication. Only expose it if you're using ",[404,1200,141],{"href":1201},"\u002Fserveex\u002Fsecurity\u002Fpocket-id"," (see below) or ",[404,1204,255],{"href":1205},"\u002Fserveex\u002Fadvanced\u002Fauthentik"," for login. Otherwise, don't expose it with SWAG. Use a VPN like ",[404,1208,119],{"href":1209},"\u002Fserveex\u002Fcore\u002Fwireguard"," instead, especially given the level of access Arcane has over your host.",[391,1212,1213,1214,1217,1218,1221,1222,1225,1226,1230,1231,1235,1236,1239,1240,1242,1243,1176],{},"We assume you have the subdomain ",[468,1215,1216],{},"arcane.mydomain.com"," with a ",[468,1219,1220],{},"CNAME"," pointing to ",[468,1223,1224],{},"mydomain.com"," in your ",[404,1227,1229],{"href":1228},"\u002Fgeneral\u002Fnetworking\u002Fdns","DNS zone",". And of course, ",[404,1232,1234],{"href":1233},"\u002Fserveex\u002Fsecurity\u002Fcloudflare","unless you use Cloudflare Zero Trust",", your box's port ",[468,1237,1238],{},"443"," must be forwarded to your server's port ",[468,1241,1238],{}," in ",[404,1244,1246],{"href":1245},"\u002Fgeneral\u002Fnetworking\u002Fnat","NAT rules",[451,1248,1249,1253,1256,1370,1373,1383,1387,1393,1404,1420,1423,1646,1660,1676],{"level":453},[455,1250,1252],{"id":1251},"add-arcanes-network-to-swag","Add Arcane's network to SWAG",[401,1254,1255],{},"Go to Dockge and edit SWAG's compose file by adding Arcane's network:",[460,1257,1259],{"className":526,"code":1258,"filename":528,"language":529,"meta":466,"style":466},"---\nservices:\n  swag:\n     container_name: # ...\n      # ... \n     networks:              # Attach container to custom network \n      # ...           \n      - arcane              # Name of the declared network\n\nnetworks:                   # Define the custom network\n  # ...\n  arcane:                   # Declared network name\n    name: arcane_default    # Actual external network name\n    external: true          # Marks it as externally defined\n",[468,1260,1261,1265,1271,1278,1288,1293,1303,1308,1318,1322,1331,1336,1345,1357],{"__ignoreMap":466},[471,1262,1263],{"class":473,"line":474},[471,1264,536],{"class":477},[471,1266,1267,1269],{"class":473,"line":539},[471,1268,543],{"class":542},[471,1270,547],{"class":546},[471,1272,1273,1276],{"class":473,"line":550},[471,1274,1275],{"class":542},"  swag",[471,1277,547],{"class":546},[471,1279,1280,1283,1285],{"class":473,"line":558},[471,1281,1282],{"class":542},"     container_name",[471,1284,564],{"class":546},[471,1286,1287],{"class":994}," # ...\n",[471,1289,1290],{"class":473,"line":570},[471,1291,1292],{"class":994},"      # ... \n",[471,1294,1295,1298,1300],{"class":473,"line":581},[471,1296,1297],{"class":542},"     networks",[471,1299,564],{"class":546},[471,1301,1302],{"class":994},"              # Attach container to custom network \n",[471,1304,1305],{"class":473,"line":592},[471,1306,1307],{"class":994},"      # ...           \n",[471,1309,1310,1312,1315],{"class":473,"line":603},[471,1311,614],{"class":546},[471,1313,1314],{"class":481}," arcane",[471,1316,1317],{"class":994},"              # Name of the declared network\n",[471,1319,1320],{"class":473,"line":611},[471,1321,688],{"emptyLinePlaceholder":687},[471,1323,1324,1326,1328],{"class":473,"line":620},[471,1325,921],{"class":542},[471,1327,564],{"class":546},[471,1329,1330],{"class":994},"                   # Define the custom network\n",[471,1332,1333],{"class":473,"line":628},[471,1334,1335],{"class":994},"  # ...\n",[471,1337,1338,1340,1342],{"class":473,"line":636},[471,1339,553],{"class":542},[471,1341,564],{"class":546},[471,1343,1344],{"class":994},"                   # Declared network name\n",[471,1346,1347,1349,1351,1354],{"class":473,"line":644},[471,1348,937],{"class":542},[471,1350,564],{"class":546},[471,1352,1353],{"class":481}," arcane_default",[471,1355,1356],{"class":994},"    # Actual external network name\n",[471,1358,1359,1362,1364,1367],{"class":473,"line":652},[471,1360,1361],{"class":542},"    external",[471,1363,564],{"class":546},[471,1365,1366],{"class":893}," true",[471,1368,1369],{"class":994},"          # Marks it as externally defined\n",[401,1371,1372],{},"Redeploy the stack and wait for SWAG to be fully operational.",[391,1374,1375,1376,1379,1380,1176],{},"Here we assume the Arcane network name is ",[468,1377,1378],{},"arcane_default",". You can check the connection by visiting SWAG's dashboard at ",[468,1381,1382],{},"http:\u002F\u002Fyourserverip:81",[455,1384,1386],{"id":1385},"create-the-subdomainconf-file","Create the subdomain.conf file",[401,1388,1389,1390,564],{},"In the Swag folders, create the file ",[468,1391,1392],{},"arcane.subdomain.conf",[964,1394,1396,1397,1400,1401,1403],{"icon":466,"to":1395},"\u002Fserveex\u002Ffiles\u002Ffile-browser-quantum","✨ ",[396,1398,1399],{},"Tip:"," Use ",[396,1402,209],{}," to navigate and edit files instead of using terminal commands.",[460,1405,1407],{"className":462,"code":1406,"filename":464,"language":465,"meta":466,"style":466},"sudo nano \u002Fsrv\u002Fdocker\u002Fswag\u002Fconfig\u002Fnginx\u002Fproxy-confs\u002Farcane.subdomain.conf\n",[468,1408,1409],{"__ignoreMap":466},[471,1410,1411,1414,1417],{"class":473,"line":474},[471,1412,1413],{"class":477},"sudo",[471,1415,1416],{"class":481}," nano",[471,1418,1419],{"class":481}," \u002Fsrv\u002Fdocker\u002Fswag\u002Fconfig\u002Fnginx\u002Fproxy-confs\u002Farcane.subdomain.conf\n",[401,1421,1422],{},"Paste the following configuration:",[460,1424,1428],{"className":1425,"code":1426,"filename":1392,"language":1427,"meta":466,"style":466},"language-nginx shiki shiki-themes github-dark material-theme github-dark","## Version 2023\u002F12\u002F19\n\nserver {\n    listen 443 ssl;\n    listen [::]:443 ssl;\n\n    server_name arcane.*;\n\n    include \u002Fconfig\u002Fnginx\u002Fssl.conf;\n\n    client_max_body_size 0;\n\n    location \u002F {\n        include \u002Fconfig\u002Fnginx\u002Fproxy.conf;\n        include \u002Fconfig\u002Fnginx\u002Fresolver.conf;\n        set $upstream_app arcane;\n        set $upstream_port 3552;\n        set $upstream_proto http;\n        proxy_pass $upstream_proto:\u002F\u002F$upstream_app:$upstream_port;\n\n        proxy_set_header Upgrade $http_upgrade;\n        proxy_set_header Connection \"upgrade\";\n    }\n}\n","nginx",[468,1429,1430,1435,1439,1448,1462,1471,1475,1485,1489,1499,1503,1512,1516,1526,1536,1545,1558,1572,1583,1605,1609,1624,1636,1641],{"__ignoreMap":466},[471,1431,1432],{"class":473,"line":474},[471,1433,1434],{"class":994},"## Version 2023\u002F12\u002F19\n",[471,1436,1437],{"class":473,"line":539},[471,1438,688],{"emptyLinePlaceholder":687},[471,1440,1441,1445],{"class":473,"line":550},[471,1442,1444],{"class":1443},"sAoO4","server",[471,1446,1447],{"class":1038}," {\n",[471,1449,1450,1454,1456,1459],{"class":473,"line":558},[471,1451,1453],{"class":1452},"sJPTy","    listen ",[471,1455,1238],{"class":489},[471,1457,1458],{"class":1038}," ssl",[471,1460,1461],{"class":546},";\n",[471,1463,1464,1466,1469],{"class":473,"line":570},[471,1465,1453],{"class":1452},[471,1467,1468],{"class":1038},"[::]:443 ssl",[471,1470,1461],{"class":546},[471,1472,1473],{"class":473,"line":581},[471,1474,688],{"emptyLinePlaceholder":687},[471,1476,1477,1480,1483],{"class":473,"line":592},[471,1478,1479],{"class":1452},"    server_name ",[471,1481,1482],{"class":1038},"arcane.*",[471,1484,1461],{"class":546},[471,1486,1487],{"class":473,"line":603},[471,1488,688],{"emptyLinePlaceholder":687},[471,1490,1491,1494,1497],{"class":473,"line":611},[471,1492,1493],{"class":1452},"    include ",[471,1495,1496],{"class":1038},"\u002Fconfig\u002Fnginx\u002Fssl.conf",[471,1498,1461],{"class":546},[471,1500,1501],{"class":473,"line":620},[471,1502,688],{"emptyLinePlaceholder":687},[471,1504,1505,1508,1510],{"class":473,"line":628},[471,1506,1507],{"class":1452},"    client_max_body_size ",[471,1509,961],{"class":489},[471,1511,1461],{"class":546},[471,1513,1514],{"class":473,"line":636},[471,1515,688],{"emptyLinePlaceholder":687},[471,1517,1518,1521,1523],{"class":473,"line":644},[471,1519,1520],{"class":1443},"    location",[471,1522,1154],{"class":477},[471,1524,1525],{"class":1038},"{\n",[471,1527,1528,1531,1534],{"class":473,"line":652},[471,1529,1530],{"class":1452},"        include ",[471,1532,1533],{"class":1038},"\u002Fconfig\u002Fnginx\u002Fproxy.conf",[471,1535,1461],{"class":546},[471,1537,1538,1540,1543],{"class":473,"line":660},[471,1539,1530],{"class":1452},[471,1541,1542],{"class":1038},"\u002Fconfig\u002Fnginx\u002Fresolver.conf",[471,1544,1461],{"class":546},[471,1546,1547,1550,1553,1556],{"class":473,"line":668},[471,1548,1549],{"class":1452},"        set ",[471,1551,1552],{"class":546},"$",[471,1554,1555],{"class":1038},"upstream_app arcane",[471,1557,1461],{"class":546},[471,1559,1560,1562,1564,1567,1570],{"class":473,"line":676},[471,1561,1549],{"class":1452},[471,1563,1552],{"class":546},[471,1565,1566],{"class":1038},"upstream_port ",[471,1568,1569],{"class":489},"3552",[471,1571,1461],{"class":546},[471,1573,1574,1576,1578,1581],{"class":473,"line":684},[471,1575,1549],{"class":1452},[471,1577,1552],{"class":546},[471,1579,1580],{"class":1038},"upstream_proto http",[471,1582,1461],{"class":546},[471,1584,1585,1588,1590,1593,1595,1598,1600,1603],{"class":473,"line":691},[471,1586,1587],{"class":1452},"        proxy_pass ",[471,1589,1552],{"class":546},[471,1591,1592],{"class":1038},"upstream_proto:\u002F\u002F",[471,1594,1552],{"class":546},[471,1596,1597],{"class":1038},"upstream_app:",[471,1599,1552],{"class":546},[471,1601,1602],{"class":1038},"upstream_port",[471,1604,1461],{"class":546},[471,1606,1607],{"class":473,"line":699},[471,1608,688],{"emptyLinePlaceholder":687},[471,1610,1611,1614,1617,1619,1622],{"class":473,"line":709},[471,1612,1613],{"class":1452},"        proxy_set_header ",[471,1615,1616],{"class":1038},"Upgrade ",[471,1618,1552],{"class":546},[471,1620,1621],{"class":1038},"http_upgrade",[471,1623,1461],{"class":546},[471,1625,1626,1628,1631,1634],{"class":473,"line":719},[471,1627,1613],{"class":1452},[471,1629,1630],{"class":1038},"Connection ",[471,1632,1633],{"class":481},"\"upgrade\"",[471,1635,1461],{"class":546},[471,1637,1638],{"class":473,"line":727},[471,1639,1640],{"class":1038},"    }\n",[471,1642,1643],{"class":473,"line":735},[471,1644,1645],{"class":1038},"}\n",[391,1647,1648,1649,951,1652,1655,1656,1659],{},"Arcane's live updates run over a websocket, hence the ",[468,1650,1651],{},"Upgrade",[468,1653,1654],{},"Connection"," headers above, on top of the usual ",[468,1657,1658],{},"proxy.conf"," include.",[401,1661,1662,1663,1667,1668,1671,1672,1675],{},"Press ",[1664,1665],"kbd",{"value":1666},"Ctrl+O",", then ",[1664,1669],{"value":1670},"Enter"," to save, and ",[1664,1673],{"value":1674},"Ctrl+X"," to exit.",[455,1677,1180],{"id":1678},"done-1",[401,1680,1681],{},"That's it! Arcane is now accessible from the internet.",[442,1683,1685],{"id":1684},"connecting-a-remote-host","Connecting a Remote Host",[401,1687,1688,1689,1692,1693,1696],{},"Arcane can manage several Docker hosts from a single instance. Each remote host runs a lightweight ",[396,1690,1691],{},"agent"," container that connects back to Arcane. Rather than exposing that connection to the internet, we'll route it over the ",[404,1694,1695],{"href":1209},"WireGuard VPN"," already set up earlier, so the agent traffic never leaves your private network.",[391,1698,1700,1701,1704,1705,1708,1709,1712],{"to":1699},"\u002Fserveex\u002Fcore\u002Fwireguard#client-server-setup","This assumes both the Arcane host and the remote host already run their own WireGuard client, connected to your VPN as described in ",[396,1702,1703],{},"Client Server Setup",". Note the VPN address wg-easy assigned to the ",[396,1706,1707],{},"Arcane host"," (e.g. ",[468,1710,1711],{},"10.8.0.3","); that's the address the remote agent will target below.",[451,1714,1715,1719,1731,1735,1744,1846,1849,1852,1856,1859],{"level":453},[455,1716,1718],{"id":1717},"add-the-remote-environment-in-arcane","Add the remote environment in Arcane",[401,1720,1721,1722,1726,1727,1730],{},"In Arcane, go to ",[1723,1724,1725],"em",{},"Environments > Add Environment",". Arcane generates a one-time ",[396,1728,1729],{},"Agent Token"," and the compose snippet to deploy on the remote host.",[455,1732,1734],{"id":1733},"deploy-the-agent-on-the-remote-host","Deploy the agent on the remote host",[401,1736,1737,1738,508,1740,1743],{},"On the remote host, open Dockge, click ",[468,1739,507],{},[468,1741,1742],{},"arcane-agent",", and add the following config, replacing the token with the one Arcane gave you and the URL with your Arcane host's VPN address:",[460,1745,1747],{"className":526,"code":1746,"filename":528,"language":529,"meta":466,"style":466},"---\nservices:\n  arcane-agent:\n    image: ghcr.io\u002Fgetarcaneapp\u002Fagent:latest\n    container_name: arcane-agent\n    restart: unless-stopped\n    environment:\n      - EDGE_AGENT=true\n      - EDGE_TRANSPORT=poll\n      - AGENT_TOKEN=arc_yourtoken\n      - MANAGER_API_URL=http:\u002F\u002F10.8.0.3:3552\n    volumes:\n      - \u002Fvar\u002Frun\u002Fdocker.sock:\u002Fvar\u002Frun\u002Fdocker.sock\n      - \u002Fsrv\u002Fdocker\u002Farcane-agent\u002Fdata:\u002Fapp\u002Fdata\n",[468,1748,1749,1753,1759,1766,1775,1784,1792,1798,1805,1812,1819,1826,1832,1839],{"__ignoreMap":466},[471,1750,1751],{"class":473,"line":474},[471,1752,536],{"class":477},[471,1754,1755,1757],{"class":473,"line":539},[471,1756,543],{"class":542},[471,1758,547],{"class":546},[471,1760,1761,1764],{"class":473,"line":550},[471,1762,1763],{"class":542},"  arcane-agent",[471,1765,547],{"class":546},[471,1767,1768,1770,1772],{"class":473,"line":558},[471,1769,561],{"class":542},[471,1771,564],{"class":546},[471,1773,1774],{"class":481}," ghcr.io\u002Fgetarcaneapp\u002Fagent:latest\n",[471,1776,1777,1779,1781],{"class":473,"line":570},[471,1778,573],{"class":542},[471,1780,564],{"class":546},[471,1782,1783],{"class":481}," arcane-agent\n",[471,1785,1786,1788,1790],{"class":473,"line":581},[471,1787,584],{"class":542},[471,1789,564],{"class":546},[471,1791,589],{"class":481},[471,1793,1794,1796],{"class":473,"line":592},[471,1795,767],{"class":542},[471,1797,547],{"class":546},[471,1799,1800,1802],{"class":473,"line":603},[471,1801,614],{"class":546},[471,1803,1804],{"class":481}," EDGE_AGENT=true\n",[471,1806,1807,1809],{"class":473,"line":611},[471,1808,614],{"class":546},[471,1810,1811],{"class":481}," EDGE_TRANSPORT=poll\n",[471,1813,1814,1816],{"class":473,"line":620},[471,1815,614],{"class":546},[471,1817,1818],{"class":481}," AGENT_TOKEN=arc_yourtoken\n",[471,1820,1821,1823],{"class":473,"line":628},[471,1822,614],{"class":546},[471,1824,1825],{"class":481}," MANAGER_API_URL=http:\u002F\u002F10.8.0.3:3552\n",[471,1827,1828,1830],{"class":473,"line":636},[471,1829,623],{"class":542},[471,1831,547],{"class":546},[471,1833,1834,1836],{"class":473,"line":644},[471,1835,614],{"class":546},[471,1837,1838],{"class":481}," \u002Fvar\u002Frun\u002Fdocker.sock:\u002Fvar\u002Frun\u002Fdocker.sock\n",[471,1840,1841,1843],{"class":473,"line":652},[471,1842,614],{"class":546},[471,1844,1845],{"class":481}," \u002Fsrv\u002Fdocker\u002Farcane-agent\u002Fdata:\u002Fapp\u002Fdata\n",[391,1847,1848],{},"This is \"edge mode\": the agent connects out to Arcane instead of the other way around, so it works from behind NAT without forwarding anything on the remote host's router. Using the VPN address instead of a public domain means that connection stays on the WireGuard tunnel even though the agent is technically in \"edge\" mode. Unlike the manager above, the agent needs the real Docker socket mounted directly, since it's the one actually running commands on that host; there's no documented socket-proxy option for it.",[401,1850,1851],{},"Deploy the stack.",[455,1853,1855],{"id":1854},"verify-the-connection","Verify the connection",[401,1857,1858],{},"Back in Arcane, the new environment should show as connected within a few seconds. Switch to it from the environment picker to manage that host's containers and stacks.",[455,1860,1180],{"id":1861},"done-2",[442,1863,1865],{"id":1864},"connecting-pocket-id","Connecting Pocket ID",[401,1867,1868],{},"Arcane supports OIDC natively, so you can require a Pocket ID login before letting anyone manage your containers, instead of (or alongside) the app's own accounts.",[451,1870,1871,1875,1885,1893,1897,1903,1962,2010,2013,2024],{"level":453},[455,1872,1874],{"id":1873},"register-arcane-as-an-oidc-client","Register Arcane as an OIDC client",[401,1876,1877,1881,1882,1884],{},[404,1878,1880],{"href":1879},"\u002Fserveex\u002Fsecurity\u002Fpocket-id#registering-an-oidc-client","Register an OIDC client in Pocket ID"," named ",[468,1883,511],{},", with this callback URL:",[460,1886,1891],{"className":1887,"code":1889,"language":1890,"meta":466},[1888],"language-text","https:\u002F\u002Farcane.mydomain.com\u002Fauth\u002Foidc\u002Fcallback\n","text",[468,1892,1889],{"__ignoreMap":466},[455,1894,1896],{"id":1895},"enable-oidc-in-arcane","Enable OIDC in Arcane",[401,1898,1899,1900,1902],{},"Edit Arcane's ",[468,1901,496],{}," file and add:",[460,1904,1906],{"className":1022,"code":1905,"filename":496,"language":1024,"meta":466,"style":466},"OIDC_ENABLED=true\nOIDC_CLIENT_ID=\nOIDC_CLIENT_SECRET=\nOIDC_ISSUER_URL=https:\u002F\u002Fid.mydomain.com\nOIDC_SCOPES=openid email profile\nOIDC_PROVIDER_NAME=Pocket ID\n",[468,1907,1908,1918,1925,1932,1942,1952],{"__ignoreMap":466},[471,1909,1910,1913,1915],{"class":473,"line":474},[471,1911,1912],{"class":1031},"OIDC_ENABLED",[471,1914,1035],{"class":546},[471,1916,1917],{"class":1038},"true\n",[471,1919,1920,1923],{"class":473,"line":539},[471,1921,1922],{"class":1031},"OIDC_CLIENT_ID",[471,1924,1047],{"class":546},[471,1926,1927,1930],{"class":473,"line":550},[471,1928,1929],{"class":1031},"OIDC_CLIENT_SECRET",[471,1931,1047],{"class":546},[471,1933,1934,1937,1939],{"class":473,"line":558},[471,1935,1936],{"class":1031},"OIDC_ISSUER_URL",[471,1938,1035],{"class":546},[471,1940,1941],{"class":1038},"https:\u002F\u002Fid.mydomain.com\n",[471,1943,1944,1947,1949],{"class":473,"line":570},[471,1945,1946],{"class":1031},"OIDC_SCOPES",[471,1948,1035],{"class":546},[471,1950,1951],{"class":1038},"openid email profile\n",[471,1953,1954,1957,1959],{"class":473,"line":581},[471,1955,1956],{"class":1031},"OIDC_PROVIDER_NAME",[471,1958,1035],{"class":546},[471,1960,1961],{"class":1038},"Pocket ID\n",[1078,1963,1964,1972],{},[1081,1965,1966],{},[1084,1967,1968,1970],{},[1087,1969,1089],{},[1087,1971,1092],{},[1097,1973,1974,1985,1996],{},[1084,1975,1976,1982],{},[1102,1977,1978],{},[468,1979,1980],{"className":1022,"language":1024,"style":466},[471,1981,1922],{"class":1038},[1102,1983,1984],{},"The client ID copied from Pocket ID",[1084,1986,1987,1993],{},[1102,1988,1989],{},[468,1990,1991],{"className":1022,"language":1024,"style":466},[471,1992,1929],{"class":1038},[1102,1994,1995],{},"The client secret copied from Pocket ID",[1084,1997,1998,2004],{},[1102,1999,2000],{},[468,2001,2002],{"className":1022,"language":1024,"style":466},[471,2003,1936],{"class":1038},[1102,2005,2006,2007],{},"Pocket ID's public URL, no trailing slash; Arcane discovers the rest via ",[468,2008,2009],{},".well-known\u002Fopenid-configuration",[401,2011,2012],{},"Redeploy the stack.",[964,2014,2015,2016,2019,2020,2023],{"icon":466},"✨ To skip straight to Pocket ID and hide the local login form, set ",[468,2017,2018],{},"OIDC_AUTO_REDIRECT_TO_PROVIDER=true",", or disable local login entirely under ",[1723,2021,2022],{},"Settings > Authentication"," for OIDC-only access.",[455,2025,1180],{"id":2026},"done-3",[401,2028,2029],{},"That's it! Arcane now offers a \"Login with Pocket ID\" option alongside the local login form.",[964,2031,2032,2038],{"icon":466,"to":1205},[401,2033,2034,2035,2037],{},"✨ You can use ",[396,2036,255],{}," instead of Pocket ID:",[2039,2040,2041,2054,2064],"ol",{},[420,2042,2043,2044,2046,2047,2050,2051,1176],{},"In Authentik, create an application and an OAuth2\u002FOpenID Connect provider named ",[468,2045,259],{},", with a redirect URI (type ",[468,2048,2049],{},"Strict",") of ",[468,2052,2053],{},"https:\u002F\u002Farcane.mydomain.com\u002Fauth\u002Foidc\u002Fcallback",[420,2055,2056,2057,2060,2061,1176],{},"Note the provider's ",[396,2058,2059],{},"Client ID"," and ",[396,2062,2063],{},"Client Secret",[420,2065,2066,2067,2069,2070,2073],{},"In Arcane's ",[468,2068,496],{},", set ",[468,2071,2072],{},"OIDC_ISSUER_URL=https:\u002F\u002Fauthentik.mydomain.com\u002Fapplication\u002Fo\u002Farcane\u002F",", then fill in the Client ID and Client Secret.",[2075,2076,2077],"style",{},"html pre.shiki code .sEgDM, html code.shiki .sEgDM{--shiki-light:#B392F0;--shiki-default:#FFCB6B;--shiki-dark:#B392F0}html pre.shiki code .s11XM, html code.shiki .s11XM{--shiki-light:#9ECBFF;--shiki-default:#C3E88D;--shiki-dark:#9ECBFF}html pre.shiki code .sJWha, html code.shiki .sJWha{--shiki-light:#79B8FF;--shiki-default:#C3E88D;--shiki-dark:#79B8FF}html pre.shiki code .swwWl, html code.shiki .swwWl{--shiki-light:#79B8FF;--shiki-default:#F78C6C;--shiki-dark:#79B8FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sRuoG, html code.shiki .sRuoG{--shiki-light:#85E89D;--shiki-default:#F07178;--shiki-dark:#85E89D}html pre.shiki code .s8jd1, html code.shiki .s8jd1{--shiki-light:#E1E4E8;--shiki-default:#89DDFF;--shiki-dark:#E1E4E8}html pre.shiki code .s08Ry, html code.shiki .s08Ry{--shiki-light:#79B8FF;--shiki-default:#FF9CAC;--shiki-dark:#79B8FF}html pre.shiki code .sDvJj, html code.shiki .sDvJj{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .szyEh, html code.shiki .szyEh{--shiki-light:#F97583;--shiki-default:#F07178;--shiki-dark:#F97583}html pre.shiki code .slcoZ, html code.shiki .slcoZ{--shiki-light:#E1E4E8;--shiki-default:#EEFFFF;--shiki-dark:#E1E4E8}html pre.shiki code .sAoO4, html code.shiki .sAoO4{--shiki-light:#F97583;--shiki-default:#C792EA;--shiki-dark:#F97583}html pre.shiki code .sJPTy, html code.shiki .sJPTy{--shiki-light:#F97583;--shiki-default:#89DDFF;--shiki-dark:#F97583}",{"title":466,"searchDepth":539,"depth":539,"links":2079},[2080,2086,2091,2097],{"id":444,"depth":539,"text":445,"children":2081},[2082,2083,2084,2085],{"id":457,"depth":550,"text":458},{"id":500,"depth":550,"text":501},{"id":1012,"depth":550,"text":1013},{"id":1179,"depth":550,"text":1180},{"id":1190,"depth":539,"text":1191,"children":2087},[2088,2089,2090],{"id":1251,"depth":550,"text":1252},{"id":1385,"depth":550,"text":1386},{"id":1678,"depth":550,"text":1180},{"id":1684,"depth":539,"text":1685,"children":2092},[2093,2094,2095,2096],{"id":1717,"depth":550,"text":1718},{"id":1733,"depth":550,"text":1734},{"id":1854,"depth":550,"text":1855},{"id":1861,"depth":550,"text":1180},{"id":1864,"depth":539,"text":1865,"children":2098},[2099,2100,2101],{"id":1873,"depth":550,"text":1874},{"id":1895,"depth":550,"text":1896},{"id":2026,"depth":550,"text":1180},[2103],"Djeex","Install Arcane, a modern Docker and Compose management web UI, as a more advanced alternative to Dockge with multi-host support and OIDC login.","md",null,{},{"title":259,"description":2104},"rTVaYi5KA8y5UQ7agOAm8EkWpjW2bIlKgT31M5IjLV4",[2111,2113],{"title":255,"path":256,"stem":257,"description":2112,"children":-1},"Install Authentik as a self-hosted identity provider, configure MFA and protect your services with SSO and reverse proxy authentication.",{"title":101,"path":269,"stem":270,"description":2114,"icon":25,"children":-1},"Introduction to Stockeex, a personal project for stock and inventory management. Documentation coming soon.",1788645849161]