import type { Metadata } from "next" import { getTranslations, getMessages, setRequestLocale } from "next-intl/server" import { Link } from "@/i18n/navigation" import Image from "next/image" import { DocHeader } from "@/components/ui/doc-header" import { Callout } from "@/components/ui/callout" import CopyableCode from "@/components/CopyableCode" export async function generateMetadata({ params, }: { params: Promise<{ locale: string }> }): Promise { const { locale } = await params const t = await getTranslations({ locale, namespace: "docs.storageShare.hostSamba.meta" }) return { title: t("title"), description: t("description"), openGraph: { title: t("ogTitle"), description: t("ogDescription"), type: "article", url: "https://macrimi.github.io/ProxMenux/docs/storage-share/host-samba", }, } } type StringItem = string type ModesRow = { method: string; mount?: string; mountRich?: string; ui: string; useCase?: string; useCaseRich?: string } type ContentRow = { type: string; allows?: string; allowsRich?: string } type RelatedItem = { href: string; label: string; tail?: string; tailRich?: string } export default async function HostSambaPage({ params, }: { params: Promise<{ locale: string }> }) { const { locale } = await params setRequestLocale(locale) const t = await getTranslations({ locale, namespace: "docs.storageShare.hostSamba" }) const messages = (await getMessages({ locale })) as unknown as { docs: { storageShare: { hostSamba: { modes: { rows: ModesRow[] } pvesmBranch: { items: StringItem[]; rows: ContentRow[] } fstabBranch: { items: StringItem[]; applies: StringItem[] } related: { items: RelatedItem[] } } } } } const modesRows = messages.docs.storageShare.hostSamba.modes.rows const pvesmItems = messages.docs.storageShare.hostSamba.pvesmBranch.items const contentRows = messages.docs.storageShare.hostSamba.pvesmBranch.rows const fstabItems = messages.docs.storageShare.hostSamba.fstabBranch.items const fstabAppliesItems = messages.docs.storageShare.hostSamba.fstabBranch.applies const relatedItems = messages.docs.storageShare.hostSamba.related.items const code = (chunks: React.ReactNode) => {chunks} const strong = (chunks: React.ReactNode) => {chunks} const em = (chunks: React.ReactNode) => {chunks} const mountLink = (chunks: React.ReactNode) => ( {chunks} ) return (
{t.rich("intro.body", { code, strong })}

{t("opening.heading")}

{t.rich("opening.body", { strong })}

{t("opening.imageAlt")}

{t("howRuns.heading")}

{t.rich("howRuns.body", { code })}

{`┌─────────────────────────────────────────────┐
│  PHASE 1 — Discover, validate, choose       │
│  (nothing touched yet)                      │
└──────────────────┬──────────────────────────┘
                   ▼
      Server discovery (nmap 139/445 + nmblookup)
                   │
                   ▼
      Authentication (User or Guest)
                   │
                   ▼
      Share selection (smbclient -L)
                   │
                   ▼
      ╔═════════════════════════════════════╗
      ║   MOUNT METHOD PICKER  (checklist)  ║
      ║   [ ] As Proxmox storage  (pvesm)   ║
      ║   [ ] As host fstab mount only      ║
      ║   (mark one or both — re-prompts    ║
      ║    if you press OK without marks)   ║
      ╚════════════════╤════════════════════╝
                       │
        ┌──────────────┴──────────────┐
        ▼                             ▼
   pvesm branch                  fstab branch
   ├─ storage ID                 ├─ mount path
   ├─ content types              ├─ mount options
                                 └─ (User) write
                                     /etc/samba/credentials/...cred
                                     (mode 0600)
   ▼                             ▼
   ┌─────────────────────────────────────────┐
   │  PHASE 2 — Apply (only marked methods)  │
   └──────────────────┬──────────────────────┘
                      ▼
   pvesm add cifs  ...    +  mkdir -p 
   (auto-mount at            mount -t cifs ...
    /mnt/pve/ with        (uid=0,gid=0,
    default options)           file_mode=0777,
                               dir_mode=0777)
                             append /etc/fstab
                             systemctl daemon-reload
                      ▼
              Summary printed`}
      

{t("modes.heading")}

{t("modes.intro")}

{modesRows.map((row, idx) => ( ))}
{t("modes.headerMethod")} {t("modes.headerMount")} {t("modes.headerUi")} {t("modes.headerUseCase")}
{t.rich(`modes.rows.${idx}.method`, { strong })} {row.mountRich ? t.rich(`modes.rows.${idx}.mountRich`, { code }) : row.mount} {row.ui} {row.useCaseRich ? t.rich(`modes.rows.${idx}.useCaseRich`, { em }) : row.useCase}
{t.rich("modes.bothBody", { code })}

{t("pvesmBranch.heading")}

{t.rich("pvesmBranch.intro", { em })}

    {pvesmItems.map((_, idx) => (
  1. {t.rich(`pvesmBranch.items.${idx}`, { strong, em, code })}
  2. ))}
{contentRows.map((row, idx) => ( ))}
{t("pvesmBranch.headerType")} {t("pvesmBranch.headerAllows")}
{row.type} {row.allowsRich ? t.rich(`pvesmBranch.rows.${idx}.allowsRich`, { code, strong }) : row.allows}
{t.rich("pvesmBranch.warnBody", { code })} {t.rich("pvesmBranch.credsBody", { code })}

{t("fstabBranch.heading")}

{t.rich("fstabBranch.intro", { em, code })}

    {fstabItems.map((_, idx) => (
  1. {t.rich(`fstabBranch.items.${idx}`, { strong, em, code })}
  2. ))}
{t.rich("fstabBranch.credsBody", { code })}

{t("fstabBranch.appliesIntro")}

    {fstabAppliesItems.map((_, idx) => (
  • {t.rich(`fstabBranch.applies.${idx}`, { code })}
  • ))}
{t.rich("fstabBranch.lxcBody", { code, strong, mountLink })} {t.rich("fstabBranch.noUiBody", { em })}

{t("manual.heading")}

{t("manual.pvesmIntro")}

{t("manual.fstabUserIntro")}

/etc/samba/credentials/nas01_share.cred <<'EOF' username=admin password=s3cret EOF chmod 0600 /etc/samba/credentials/nas01_share.cred # 2. mount with open uid/gid/file_mode (for unpriv LXC bind-mounts) mkdir -p /mnt/data mount -t cifs //10.0.0.50/share /mnt/data \\ -o "rw,uid=0,gid=0,file_mode=0777,dir_mode=0777,iocharset=utf8,nofail,_netdev,credentials=/etc/samba/credentials/nas01_share.cred" # 3. persist echo "//10.0.0.50/share /mnt/data cifs rw,uid=0,gid=0,file_mode=0777,dir_mode=0777,iocharset=utf8,nofail,_netdev,credentials=/etc/samba/credentials/nas01_share.cred 0 0" \\ >> /etc/fstab systemctl daemon-reload # 4. bind into an unpriv LXC (no changes inside the CT) pct set -mp0 /mnt/data,mp=/mnt/data,shared=1,backup=0 pct reboot `} />

{t("manual.fstabGuestIntro")}

> /etc/fstab systemctl daemon-reload`} />

{t("view.heading")}

{t.rich("view.body", { code, em, strong })}

{t("remove.heading")}

{t.rich("remove.body", { code, strong })}

{t("remove.warnBody")}

{t("test.heading")}

{t.rich("test.body", { code })}

{t("troubleshoot.heading")}

{t.rich("troubleshoot.noServersBody", { code, em })} {t.rich("troubleshoot.noSharesBody", { code })} {t.rich("troubleshoot.denyBody", { code })} {t.rich("troubleshoot.sleepBody", { code })} {t.rich("troubleshoot.lxcNoWriteBody", { code })} {t.rich("troubleshoot.fstabBootBody", { code })}

{t("related.heading")}

    {relatedItems.map((item, idx) => (
  • {item.label} {item.tailRich ? t.rich(`related.items.${idx}.tailRich`, { code }) : item.tail}
  • ))}
) }