> ## Documentation Index
> Fetch the complete documentation index at: https://docs.livepeer.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Install go-livepeer on Docker, Linux, or Windows

> Install a Livepeer Gateway on Docker, Linux, or Windows from one consolidated page.

export const latestVersion_0 = undefined

export const LINUX_CODE = {
  wgetCheck: {
    filename: 'Verify Prerequisites',
    icon: 'terminal',
    language: 'bash',
    codeString: `wget --version | head -1
tar --version | head -1`
  },
  downloadLinux: {
    filename: 'Download Binary (Linux amd64)',
    icon: 'linux',
    language: 'bash',
    codeString: `sudo wget https://github.com/livepeer/go-livepeer/releases/download/{PLACEHOLDER}/livepeer-linux-amd64.tar.gz`
  },
  downloadMacIntel: {
    filename: 'Download Binary (macOS Intel)',
    icon: 'apple',
    language: 'bash',
    codeString: `curl -LO https://github.com/livepeer/go-livepeer/releases/download/{PLACEHOLDER}/livepeer-darwin-amd64.tar.gz`
  },
  downloadMacArm: {
    filename: 'Download Binary (macOS Apple Silicon)',
    icon: 'apple',
    language: 'bash',
    codeString: `curl -LO https://github.com/livepeer/go-livepeer/releases/download/{PLACEHOLDER}/livepeer-darwin-arm64.tar.gz`
  },
  extractInstall: {
    filename: 'Extract & Install',
    icon: 'terminal',
    language: 'bash',
    codeString: `sudo tar -zxvf livepeer-linux-amd64.tar.gz
sudo rm livepeer-linux-amd64.tar.gz
sudo mv livepeer-linux-amd64/* /usr/local/bin/`
  },
  testInstall: {
    filename: 'Run the Gateway',
    icon: 'terminal',
    language: 'bash',
    codeString: `livepeer -gateway`
  },
  testInstallOutput: {
    filename: 'Expected Log Output',
    icon: 'terminal',
    language: 'txt',
    codeString: `>_ livepeer -gateway

*---------*------*
| Gateway | true |
*---------*------*
I1222 12:37:23.339916   97244 starter.go:537] ***Livepeer is running on the offchain network***
I1222 12:37:23.340276   97244 starter.go:554] Creating data dir: /Users/<me>/.lpData/offchain
I1222 12:37:23.344584   97244 starter.go:723] ***Livepeer is in off-chain mode***
E1222 12:37:23.345022   97244 starter.go:1586] No orchestrator specified; transcoding will not happen
I1222 12:37:23.350972   97244 starter.go:1827] ***Livepeer Running in Gateway Mode***
I1222 12:37:23.350991   97244 starter.go:1828] Video Ingest Endpoint - rtmp://127.0.0.1:1935
I1222 12:37:23.351002   97244 starter.go:1837] Livepeer Node version: 0.8.8
I1222 12:37:23.351124   97244 mediaserver.go:247] HTTP Server listening on http://127.0.0.1:9935
I1222 12:37:23.351398   97244 webserver.go:20] CLI server listening on 127.0.0.1:5935`
  },
  downloadBinary: {
    filename: 'Download Binary',
    icon: 'terminal',
    language: 'bash',
    preNote: 'Download the latest binary from the go-livepeer releases page',
    codeString: `sudo wget https://github.com/livepeer/go-livepeer/releases/download/{PLACEHOLDER}/livepeer-linux-amd64.tar.gz`
  },
  install: {
    filename: 'Install go-livepeer',
    icon: 'terminal',
    language: 'bash',
    codeString: `sudo wget https://github.com/livepeer/go-livepeer/releases/download/{PLACEHOLDER}/livepeer-linux-amd64.tar.gz`
  },
  clone: {
    filename: 'Clone go-livepeer',
    icon: 'terminal',
    language: 'bash',
    preNote: 'Clone the go-livepeer repository',
    codeString: `
      git clone https://github.com/livepeer/go-livepeer.git
      cd go-livepeer
      `
  },
  dependecyInstall: {
    go: {
      filename: 'Install Go Dependencies',
      icon: 'terminal',
      language: 'bash',
      preNote: 'Install Go Dependencies',
      codeString: `go mod download`
    },
    ffmpeg: {
      filename: 'Install FFmpeg',
      icon: 'terminal',
      language: 'bash',
      preNote: 'Install FFmpeg',
      codeString: `./install_ffmpeg.sh`
    }
  }
};

export const LinuxInstallCheck = () => {
  return <>
      To quickly test installation, run the gateway in off-chain mode:
      <CustomCodeBlock {...LINUX_CODE.testInstall} wrap />
      The gateway starts in off-chain mode by default, which requires no
      blockchain connectivity. This confirms the binary is installed correctly.
      <CustomCodeBlock {...LINUX_CODE.testInstallOutput} wrap />
    </>;
};

export const LinuxInstallBinary = () => {
  return <>
      Download the latest{' '}
      <DoubleIconLink label="go-livepeer binary" href="https://github.com/livepeer/go-livepeer/releases" iconLeft="github" />{' '}
      for your platform
      <Tabs>
        <Tab title="Linux" icon="linux">
          <CustomCodeBlock {...LINUX_CODE.downloadLinux} placeholderValue={latestVersion} wrap />
        </Tab>
        <Tab title="macOS Intel" icon="apple">
          <CustomCodeBlock {...LINUX_CODE.downloadMacIntel} placeholderValue={latestVersion} wrap />
        </Tab>
        <Tab title="macOS Apple Silicon" icon="apple">
          <CustomCodeBlock {...LINUX_CODE.downloadMacArm} placeholderValue={latestVersion} wrap />
        </Tab>
      </Tabs>
      Unpack the archive and move the binary into your PATH:
      <CustomCodeBlock {...LINUX_CODE.extractInstall} wrap />
      <Note>
        Adjust the archive filename if you downloaded a macOS or ARM64 variant.
      </Note>
    </>;
};

export const LinuxPrerequisites = () => {
  return <>
      Ensure <code>wget</code> (or <code>curl</code>) and <code>tar</code> are
      installed and up to date on your system. Both are pre-installed on most
      Linux distributions.
      <CustomCodeBlock {...LINUX_CODE.wgetCheck} wrap />
      <Tip>
        macOS users can install <code>wget</code> via{' '}
        <a href="https://brew.sh/">Homebrew</a>: <code>brew install wget</code>.
        macOS also ships with <code>curl</code> and <code>tar</code> by default.
      </Tip>
    </>;
};

export const LinuxSupport = () => {
  const distroRows = [{
    Distribution: 'Ubuntu 20.04+',
    Status: 'Tested in CI',
    Notes: 'Primary platform'
  }, {
    Distribution: 'Debian and derivatives',
    Status: 'Supported',
    Notes: ''
  }, {
    Distribution: 'CentOS / RHEL',
    Status: 'Supported',
    Notes: 'With adjustments'
  }, {
    Distribution: 'Arch Linux',
    Status: 'Community supported',
    Notes: ''
  }];
  const archRows = [{
    Architecture: 'x86_64 / amd64',
    Status: 'Primary platform',
    Binary: 'livepeer-linux-amd64'
  }, {
    Architecture: 'ARM64 / aarch64',
    Status: 'For ARM servers',
    Binary: 'livepeer-linux-arm64'
  }];
  const macArchRows = [{
    Architecture: 'x86_64 / amd64 (Intel)',
    Binary: 'livepeer-darwin-amd64'
  }, {
    Architecture: 'ARM64 (Apple Silicon)',
    Binary: 'livepeer-darwin-arm64'
  }];
  const prereqItems = [{
    key: 'wget',
    content: <>
          <code>wget</code> or <code>curl</code> — for downloading binaries
        </>
  }, {
    key: 'tar',
    content: <>
          <code>tar</code> — pre-installed on most Linux distributions and macOS
        </>
  }];
  const supportNotes = ['Linux is recommended for full feature support in production.', 'macOS support is primarily for development and testing.', 'GPU transcoding (NVIDIA) is supported on Linux only.'];
  return <div style={{
    margin: '1rem 0'
  }}>
      <Accordion title="Binary Install Supported Platforms" icon="warning">
        <Info>
          Pre-built binaries are available for {linux()} and {mac()} on amd64
          and arm64 architectures.
        </Info>

        <DynamicTable tableTitle="Supported Linux Distributions" headerList={['Distribution', 'Status', 'Notes']} itemsList={distroRows} contentFitColumns={['Status']} />

        <AccordionGroup>
          <Accordion title="Linux Architectures" icon="linux">
            <DynamicTable tableTitle="Linux Binaries" headerList={['Architecture', 'Status', 'Binary']} itemsList={archRows} contentFitColumns={['Status']} />
          </Accordion>

          <Accordion title="macOS Architectures" icon="apple">
            <DynamicTable tableTitle="macOS Binaries" headerList={['Architecture', 'Binary']} itemsList={macArchRows} />
          </Accordion>

          <Accordion title="Prerequisites" icon="list-check">
            <ul>
              {prereqItems.map(({key, content}) => <li key={key}>{content}</li>)}
            </ul>
          </Accordion>
        </AccordionGroup>

        <Warning>
          <strong>FFmpeg</strong> is a common cause of errors when building from
          source. Livepeer uses a custom build of FFmpeg that must not conflict
          with existing installations. Pre-built binaries include the correct
          FFmpeg version — no separate FFmpeg install is required.
        </Warning>

        <CardGroup cols={2}>
          {supportNotes.map(note => <Card key={note} title={<CustomCardTitle title="Support Note" icon="circle-info" />}>
              {note}
            </Card>)}

          <Card title={<CustomCardTitle title="go-livepeer Releases" icon="github" />} href="https://github.com/livepeer/go-livepeer/releases" arrow horizontal>
            All available binaries and release notes.
          </Card>
        </CardGroup>
      </Accordion>
    </div>;
};

export const linuxGroup = () => <div style={{
  display: 'flex',
  gap: '0.5rem',
  alignItems: 'center',
  marginBottom: '1rem'
}}>
    <span>
      <Icon icon="linux" color="#ff9a0e" size={22} /> <Badge> Linux </Badge>
    </span>
    <span>
      <Icon icon="apple" color="#60ba47" size={22} /> <Badge> macOS </Badge>
    </span>
  </div>;

export const CustomCardTitle = ({icon, title, variant = "card", iconSize, style = {}, className = "", ...rest}) => {
  const variants = {
    card: {
      display: 'flex',
      alignItems: 'center',
      gap: "var(--lp-spacing-2)",
      marginBottom: "var(--lp-spacing-3)",
      color: 'var(--lp-color-text-primary)',
      fontSize: '1rem',
      fontWeight: 600
    },
    accordion: {
      display: 'inline-flex',
      alignItems: 'center',
      gap: "var(--lp-spacing-2)"
    },
    tab: {
      display: 'inline-flex',
      alignItems: 'center',
      gap: '0.4rem',
      fontSize: '0.875rem'
    }
  };
  const sizes = {
    card: 20,
    accordion: 18,
    tab: 14
  };
  const size = iconSize || sizes[variant] || 20;
  const baseStyle = variants[variant] || variants.card;
  return variant === 'card' ? <div className={className} style={{
    ...baseStyle,
    ...style
  }} {...rest}>
      {typeof icon === 'string' ? <Icon icon={icon} size={size} color="var(--lp-color-accent)" /> : icon}
      {title}
    </div> : <span className={className} style={{
    ...baseStyle,
    ...style
  }} {...rest}>
      {typeof icon === 'string' ? <Icon icon={icon} size={size} color="var(--lp-color-accent)" /> : icon}
      {title}
    </span>;
};

export const DynamicTable = ({tableTitle = null, headerList = [], itemsList = [], monospaceColumns = [], columnWidths = {}, contentFitColumns = [], showSeparators = false, margin, className = "", style = {}, ...rest}) => {
  if (!headerList.length) {
    return <div>No headers provided</div>;
  }
  const safeContentFitColumns = Array.isArray(contentFitColumns) ? contentFitColumns : [];
  const usesContentFitColumns = safeContentFitColumns.length > 0;
  const isContentFitColumn = header => safeContentFitColumns.includes(header);
  const getColumnStyle = header => {
    const widthStyle = columnWidths[header] ? {
      width: columnWidths[header],
      minWidth: columnWidths[header],
      maxWidth: columnWidths[header]
    } : {};
    const contentFitStyle = !columnWidths[header] && isContentFitColumn(header) ? {
      width: "1%",
      whiteSpace: "nowrap"
    } : {};
    return {
      ...contentFitStyle,
      ...widthStyle
    };
  };
  return <div className={className} style={style} {...rest}>
      {tableTitle && <div style={{
    fontStyle: "italic",
    margin: 0
  }}>
          <strong>{tableTitle}</strong>
        </div>}
      <div style={{
    overflowX: "auto",
    ...margin != null && ({
      margin
    })
  }} role="region" tabIndex={0} aria-label={tableTitle ? `Scrollable table: ${tableTitle}` : "Scrollable table"}>
        <table data-docs-dynamic-table style={{
    width: "100%",
    tableLayout: usesContentFitColumns ? "auto" : "fixed",
    borderCollapse: "collapse",
    fontSize: "0.9rem",
    marginTop: 0
  }}>
          <thead>
            <tr style={{
    backgroundColor: "var(--lp-color-accent)",
    color: "var(--lp-color-on-accent)",
    borderBottom: "1px solid var(--lp-color-border-default)"
  }}>
              {headerList.map((header, index) => <th key={index} style={{
    padding: "10px 8px",
    textAlign: "left",
    fontWeight: "600",
    color: "var(--lp-color-on-accent)",
    ...getColumnStyle(header)
  }}>
                  {header}
                </th>)}
            </tr>
          </thead>
          <tbody>
            {itemsList.filter(item => showSeparators || !item?.__separator).map((item, rowIndex) => item?.__separator ? <tr key={rowIndex} style={{
    backgroundColor: "var(--lp-color-accent)",
    color: "var(--lp-color-on-accent)",
    borderBottom: "1px solid var(--lp-color-accent)"
  }}>
                  <td colSpan={headerList.length} style={{
    padding: "6px 8px",
    fontWeight: "700",
    color: "var(--lp-color-on-accent)",
    letterSpacing: "0.01em"
  }}>
                    {(item[headerList[0]] ?? item.Category) ?? "Category"}
                  </td>
                </tr> : <tr key={rowIndex} style={{
    borderBottom: "1px solid var(--lp-color-border-default)"
  }}>
                  {headerList.map((header, colIndex) => {
    const value = (item[header] ?? item[header.toLowerCase()]) ?? "-";
    const isMonospace = monospaceColumns.includes(colIndex);
    return <td key={colIndex} style={{
      padding: "8px 8px",
      fontFamily: isMonospace ? "monospace" : "inherit",
      wordWrap: "break-word",
      overflowWrap: "break-word",
      ...getColumnStyle(header)
    }}>
                        {isMonospace ? <code>{value}</code> : value}
                      </td>;
  })}
                </tr>)}
          </tbody>
        </table>
      </div>
    </div>;
};

export const DOCKER_CODE = {
  dockerSetup: {
    filename: 'Check Docker Version',
    icon: 'docker',
    language: 'bash',
    codeString: `docker --version`
  },
  install: {
    filename: 'Install go-livepeer',
    icon: 'docker',
    language: 'bash',
    codeString: `docker pull livepeer/go-livepeer:stable`
  },
  testInstall: {
    filename: 'Run the Gateway',
    icon: 'docker',
    language: 'bash',
    codeString: `docker run --rm -it --name gateway
-p 1935:1935 -p 8935:8935 -p 7935:7935
livepeer/go-livepeer
-gateway -v 6`,
    description: 'This starts a gateway in off-chain mode with verbose logging. The container will exit if no services are enabled, which confirms the binary runs correctly.'
  },
  testInstallOutput: {
    filename: 'Expected Log Output',
    icon: 'docker',
    language: 'txt',
    codeString: `Livepeer Node version: [version]
Golang runtime version: [compiler] [go version]
Architecture: [arch]
Operating system: [os]`
  },
  create: {
    filename: 'Create the Gateway Volume',
    icon: 'terminal',
    language: 'bash',
    codeString: `docker volume create dual-gateway-lpData`,
    description: 'Creates a Docker volume with the name `dual-gateway-lpData` for persistent storage.',
    output: ` ✔ Volume dual-gateway-lpData  Created`
  },
  run: {
    filename: 'Run the Gateway',
    icon: 'terminal',
    language: 'bash',
    codeString: `docker-compose up -d`,
    description: "Starts the gateway container in detached mode (-d flag). The volume is created if it doesn't exist.",
    output: `
    [+] Running 2/2
    ✔ Volume dual-gateway-lpData  Created
    ✔ Container dual-gateway    Started `
  },
  verify: {
    filename: 'Verify Gateway is Running',
    icon: 'terminal',
    language: 'bash',
    codeString: `docker logs dual-gateway`,
    description: 'The logs show the gateway starting up, binding to the configured ports, and connecting to the orchestrator',
    postNote: 'Expected Output:',
    output: {
      icon: 'docker',
      codeString: `
INFO[0000] Livepeer v0.5.32
INFO[0000] Starting Livepeer node...
INFO[0000] Node type: BroadcasterNode
INFO[0000] RTMP server listening on 0.0.0.0:1935
INFO[0000] HTTP server listening on 0.0.0.0:8935
INFO[0000] CLI server listening on 0.0.0.0:5935
INFO[0000] Connected to orchestrator at <ORCHESTRATOR_IP:PORT>
INFO[0000] Gateway ready
    `
    }
  },
  flags: {
    filename: 'View all available flags',
    icon: 'terminal',
    language: 'bash',
    codeString: `docker run --rm livepeer/go-livepeer:master -help`
  },
  sendVideo: {
    filename: 'Verify FFmpeg is installed',
    icon: 'terminal',
    language: 'bash',
    codeString: `docker run --rm -v "$(pwd):/workspace" -w /workspace \
      jrottenberg/ffmpeg:4.4-alpine \
      -re -i test-video.mp4 -c copy -f flv rtmp://host.docker.internal:1935/stream/test-key`,
    preNote: '',
    postNote: 'Use host.docker.internal instead of localhost when running FFmpeg from a Docker container to connect to services on the host machine.'
  },
  verifyEthConnection: {
    filename: 'Verify ETH Connection',
    icon: 'terminal',
    language: 'bash',
    codeString: `docker logs dual-gateway | grep -i "ethereum\|eth\|blockchain"`,
    preNote: 'Ensure your Gateway is properly configured by verifying that your Gateway has an active Ethereum connection:',
    description: 'The logs should show the ETH account address, balance, and connection status.',
    output: `
    INFO[0000] ETH account address: 0x...
    INFO[0000] ETH balance: 1000000000000000000
    INFO[0000] ETH connection active
    `
  },
  verifyOnChainConfig: {
    filename: 'Verify On-Chain Configuration',
    icon: 'terminal',
    language: 'bash',
    codeString: `# Verify Ethereum connection
docker logs dual-gateway | grep -i "ethereum\|eth\|blockchain"

# Check account address
curl http://localhost:5935/status | jq '.eth.accountAddr'
    `,
    preNote: `
      The gateway must have an active Ethereum connection and valid account.

      Before testing, verify your Gateway is properly configured by checking the on-chain settings:
      `,
    postNote: 'Expected Output:',
    description: 'The logs should show the ETH account address, balance, and connection status.',
    output: {
      icon: 'docker',
      codeString: `
INFO[0000] ETH account address: 0x...
INFO[0000] ETH balance: 1000000000000000000
INFO[0000] ETH connection active
    `
    }
  }
};

export const DockerInstallCheck = () => {
  return <>
      To quickly test installation, run the gateway with minimal configuration:
      <CustomCodeBlock {...DOCKER_CODE.testInstall} wrap />
      This starts a gateway in off-chain mode with verbose logging. The
      container will exit if no services are enabled, which confirms the binary
      runs correctly.
      <CustomCodeBlock {...DOCKER_CODE.testInstallOutput} wrap />
    </>;
};

export const DockerPull = () => {
  return <>
      Fetch the latest{' '}
      <DoubleIconLink label="Livepeer Docker image" href="https://hub.docker.com/r/livepeer/go-livepeer" iconLeft="docker" />{' '}
      from Docker Hub
      <CustomCodeBlock {...DOCKER_CODE.install} wrap />
    </>;
};

export const DockerUpdate = () => {
  return <>
      Docker must be installed and on a recent version. Follow the official{' '}
      <DoubleIconLink label="Docker Engine" href="https://docs.docker.com/engine/install/" iconLeft="docker" />{' '}
      installation guide for your platform.
      <br /> <br />
      Verify you have Docker installed and on a recent release:
      <CustomCodeBlock {...DOCKER_CODE.dockerSetup} wrap />
      <Note>
        Gateway nodes do not require NVIDIA GPU drivers as a baseline
        prerequisite. NVIDIA drivers apply to orchestrator or other GPU compute
        workloads.
      </Note>
      <Tip>
        Windows hosts should run Docker with WSL2 for best compatibility:
        [Docker Desktop WSL2
        backend](https://docs.docker.com/desktop/windows/wsl/).
      </Tip>
    </>;
};

export const DockerSupport = () => {
  const platformRows = [{
    OS: linux(),
    Architectures: 'amd64, arm64',
    'GPU Compute Support': 'NVIDIA (GPU workloads only)',
    Notes: 'Full feature support'
  }, {
    OS: mac(),
    Architectures: 'amd64, arm64',
    'GPU Compute Support': 'No',
    Notes: 'CPU-only transcoding'
  }, {
    OS: windows(),
    Architectures: 'amd64',
    'GPU Compute Support': 'No',
    Notes: 'CPU-only transcoding'
  }];
  const buildMatrixItems = [{
    key: 'linux-matrix',
    content: <>{linux()} amd64/arm64 (CPU and GPU variants)</>
  }, {
    key: 'mac-matrix',
    content: <>{mac()} amd64/arm64 (CPU only)</>
  }, {
    key: 'windows-matrix',
    content: <>{windows()} amd64 (CPU only)</>
  }];
  const compilationTargets = ['Darwin (macOS) with Intel and Apple Silicon', 'Linux with x86_64 and ARM64', 'Windows x86_64'];
  const supportNotes = ['ARM64 Docker images are built, but ARM64 support is still experimental.', 'Linux is recommended for full feature support in production.', 'macOS and Windows support is primarily for development and testing.'];
  return <div style={{
    margin: '1rem 0'
  }}>
      <Accordion title="Docker Supported Hosts Details" icon="warning">
        <Info>
          Docker supports running Livepeer gateway nodes on {linux()} {mac()}
          {' and '}
          {windows()} with different architecture support and feature
          limitations.
        </Info>

        <DynamicTable tableTitle="Supported Platforms" headerList={['OS', 'Architectures', 'GPU Compute Support', 'Notes']} itemsList={platformRows} contentFitColumns={['OS', 'Architectures']} />

        <Note>
          NVIDIA drivers are not a baseline requirement for a gateway. They are
          only required when the same host is also running GPU workloads such as
          an orchestrator or AI worker.
        </Note>

        <AccordionGroup>
          <Accordion title="Docker Build Configuration" icon="boxes-stacked">
            The Dockerfile uses a multi-stage build with CUDA base images for
            GPU support. The build process supports cross-compilation for
            multiple architectures.
          </Accordion>

          <Accordion title="Build Matrix" icon="table-cells-large">
            <ul>
              {buildMatrixItems.map(({key, content}) => <li key={key}>{content}</li>)}
            </ul>
          </Accordion>

          <Accordion title="Cross-Compilation Support" icon="code-branch">
            <ul>
              {compilationTargets.map(item => <li key={item}>{item}</li>)}
            </ul>
          </Accordion>
        </AccordionGroup>

        <Warning>
          GPU transcoding is supported on {linux()} hosts only. The Docker
          images include NVIDIA CUDA support, but that path does not apply on
          macOS or Windows hosts.
        </Warning>

        <CardGroup cols={2}>
          {supportNotes.map(note => <Card key={note} title={<CustomCardTitle title="Support Note" icon="circle-info" />}>
              {note}
            </Card>)}

          <Card title={<CustomCardTitle title="Box Example Gateway" icon="github" />} href="https://github.com/livepeer/go-livepeer/blob/master/box/box.md" arrow horizontal>
            Linux and macOS development environment example.
          </Card>
        </CardGroup>
      </Accordion>
    </div>;
};

export const dockerGroup = () => <div style={{
  display: 'flex',
  gap: '0.5rem',
  alignItems: 'center',
  marginBottom: '1rem'
}}>
    <span>
      <Icon icon="linux" color="#ff9a0e" size={22} /> <Badge> Linux </Badge>
    </span>
    <span>
      <Icon icon="windows" color="#0078d6" size={22} /> <Badge> Windows </Badge>
    </span>
    <span>
      <Icon icon="apple" color="#60ba47" size={22} /> <Badge> macOS </Badge>
    </span>
  </div>;

export const docker = () => <span>
    <Icon icon="docker" color="#2496ed" size={22} /> <Badge> Docker </Badge>
  </span>;

export const windows = () => <span>
    <Icon icon="windows" color="#0078d6" size={22} /> <Badge> Windows </Badge>
  </span>;

export const mac = () => <span>
    <Icon icon="apple" color="#60ba47" size={22} /> <Badge> MacOS </Badge>
  </span>;

export const linux = () => <span>
    <Icon icon="linux" color="#ff9a0e" size={22} /> <Badge> Linux </Badge>
  </span>;

export const onChain = () => <span>
    <Icon icon="server" size={20} /> <strong>on-chain</strong>
  </span>;

export const offChain = () => <span>
    <Icon icon="floppy-disk" size={20} /> <strong>off-chain</strong>
  </span>;

export const dual = () => <Badge color="green">Dual-mode</Badge>;

export const ai = () => <Badge color="purple">AI</Badge>;

export const video = () => <Badge color="blue">Video</Badge>;

export const latestVersion = "v0.8.10";

export const StyledStep = ({title, icon, titleSize = 'h3', iconColor = null, titleColor = null, children, className = '', style = {}, ...rest}) => {
  const styledTitle = titleColor ? <span style={{
    color: titleColor
  }}>{title}</span> : title;
  return <Step title={styledTitle} icon={icon} iconColor={iconColor || undefined} titleSize={titleSize} className={className} style={style} {...rest}>
      {children}
    </Step>;
};

export const StyledSteps = ({children, iconColor, titleColor, lineColor, iconSize = '24px', className = '', style = {}, ...rest}) => {
  const resolvedIconColor = iconColor || 'var(--accent-dark, #18794E)';
  const resolvedTitleColor = titleColor || 'var(--lp-color-accent)';
  const resolvedLineColor = lineColor || 'var(--lp-color-accent)';
  return <div className={['docs-styled-steps', className].filter(Boolean).join(' ')} style={style} {...rest}>
      <style>{`
        .docs-styled-steps .steps > div > div.absolute > div {
          background-color: ${resolvedIconColor};
        }
        .docs-styled-steps .steps > div > div.w-full > p {
          color: ${resolvedTitleColor};
        }
        .docs-styled-steps .steps > div > div.absolute.w-px {
          background-color: ${resolvedLineColor};
        }
        .docs-styled-steps .steps > div:last-child > div.absolute.w-px::after {
          content: '';
          position: absolute;
          bottom: 0;
          left: 50%;
          transform: translateX(-50%);
          width: 6px;
          height: 6px;
          background-color: ${resolvedLineColor};
          transform: translateX(-50%) rotate(45deg);
        }
      `}</style>
      <div>
        <Steps>{children}</Steps>
      </div>
    </div>;
};

export const BorderedBox = ({children, variant = "default", padding = "var(--lp-spacing-4)", borderRadius = "var(--lp-spacing-px-8)", margin = "", accentBar = "", style = {}, className = "", ...rest}) => {
  const variants = {
    default: {
      border: "1px solid var(--lp-color-border-default)",
      backgroundColor: "var(--lp-color-bg-card)"
    },
    accent: {
      border: "1px solid var(--lp-color-accent)",
      backgroundColor: "var(--lp-color-bg-card)"
    },
    muted: {
      border: "1px solid var(--lp-color-border-default)",
      backgroundColor: "transparent"
    }
  };
  const accentBarColors = {
    accent: "var(--lp-color-accent)",
    positive: "var(--green-9)"
  };
  return <div data-docs-bordered-box="" data-accent-bar={accentBarColors[accentBar] ? "" : undefined} className={className} style={{
    ...variants[variant],
    padding: padding,
    borderRadius: borderRadius,
    ...margin ? {
      margin
    } : {},
    ...accentBarColors[accentBar] ? {
      position: "relative",
      '--accent-bar-color': accentBarColors[accentBar]
    } : {},
    ...style
  }} {...rest}>
      {children}
    </div>;
};

export const CustomDivider = ({color = "var(--lp-color-border-default)", middleText = "", spacing = "default", style = {}, className = "", ...rest}) => {
  const spacingPresets = {
    default: {
      margin: "24px 0"
    },
    overlap: {
      margin: "-1rem 0 -1rem 0"
    },
    tight: {
      margin: "0 0 -1rem 0"
    },
    section: {
      margin: "0 0 -2rem 0"
    },
    sectionOverlap: {
      margin: "-1rem 0 -2rem 0"
    },
    deepOverlap: {
      margin: "-1rem 0 -1.5rem 0"
    }
  };
  const spacingStyle = spacingPresets[spacing] || spacingPresets.default;
  return <div role="separator" aria-orientation="horizontal" className={className} style={{
    display: "flex",
    alignItems: "center",
    ...spacingStyle,
    fontSize: style?.fontSize || "16px",
    height: "fit-content",
    ...style
  }} {...rest}>
      <span style={{
    marginRight: "var(--lp-spacing-px-8)",
    opacity: 0.2
  }}>
        <Icon icon="/snippets/assets/logos/Livepeer-Logo-Symbol-Theme.svg" />
      </span>
      <div style={{
    flex: 1,
    height: "1px",
    background: "var(--lp-color-border-default)",
    opacity: 0.4
  }}></div>
      {middleText && <>
          <Icon icon="circle" size={2} />
          <span style={{
    margin: "0 8px",
    fontWeight: "bold",
    color: color,
    opacity: 0.7
  }}>
            {middleText}
          </span>
          <Icon icon="circle" size={2} />
        </>}
      <div style={{
    flex: 1,
    height: "1px",
    background: "var(--lp-color-border-default)",
    opacity: 0.4
  }}></div>
      <span style={{
    marginLeft: "var(--lp-spacing-px-8)",
    opacity: 0.2
  }}>
        <span style={{
    display: "inline-block",
    transform: "scaleX(-1)"
  }}>
          <Icon icon="/snippets/assets/logos/Livepeer-Logo-Symbol-Theme.svg" />
        </span>
      </span>
    </div>;
};

export const CustomCodeBlock = ({filename, icon, language, highlight, codeString = "", placeholderValue = "", wrap = true, lines = true, preNote = "", postNote = "", output = ""}) => {
  if (!codeString || codeString.trim() === "") {
    return null;
  }
  const renderedCode = codeString.replace(/\{PLACEHOLDER\}/g, placeholderValue);
  return <>
      {preNote && <div style={{
    marginBottom: "var(--lp-spacing-2)",
    fontSize: "0.875rem",
    color: "var(--lp-color-text-muted)"
  }}>
          {preNote}
        </div>}
      <CodeBlock filename={filename} icon={icon} language={language} lines highlight={highlight} wrap={wrap} line={lines}>
        {renderedCode}
      </CodeBlock>
      {postNote && <div style={{
    marginTop: "var(--lp-spacing-2)",
    fontSize: "0.875rem",
    color: "var(--lp-color-text-muted)",
    fontStyle: "italic"
  }}>
          {postNote}
        </div>}
      {output?.codeString && <>
          <Expandable title={<span style={{
    fontStyle: "italic",
    fontWeight: "bold"
  }}>
                Expected Output
              </span>}>
            <CodeBlock filename={output.filename || "Output Example"} icon={output.icon || "terminal"} language={output.language || "bash"} highlight={output.highlight} wrap={output.wrap || false} line={output.lines || false}>
              {output.codeString}
            </CodeBlock>
          </Expandable>
          <br />
        </>}
    </>;
};

export const DoubleIconLink = ({label = '', labelColor, href = '#', text = '', iconLeft = 'github', iconLeftColor, iconRight = 'arrow-up-right', iconRightColor = 'var(--lp-color-accent)', className = '', style = {}, ...rest}) => {
  return <span className={className} style={{
    whiteSpace: 'nowrap',
    display: 'inline-flex',
    alignItems: 'center',
    gap: "var(--lp-spacing-1)",
    marginLeft: '0.3rem',
    ...style
  }} {...rest}>
      {text && <span style={{
    marginRight: 8
  }}>{text}</span>}
      <Icon icon={iconLeft} color={iconLeftColor} />
      <a href={href} style={{
    color: {
      labelColor
    }
  }}>
        {label}
      </a>
      <div style={{
    marginRight: '0.3rem'
  }}>
        <Icon icon={iconRight} size={12} color={iconRightColor} />
      </div>
    </span>;
};

<CustomDivider style={{margin: "0 0 -1rem 0"}} />

# <Icon icon="face-grin-wink" size={26} /> Let's Go(-Livepeer) !

This guide will get you up & running with a Livepeer Gateway Node for {video()}, {ai()} Pipelines or {dual()} service routing.

*This guide includes:*

* Setup for {onChain()} and {offChain()} Livepeer Gateway nodes
* Installation guides for <span><Icon icon="docker" size={20} /> **Docker *(recommended)*** </span> and <span><Icon icon="code" size={20} /> **Pre-Built Binaries**. </span>

<Tip>
  <Icon icon="docker" size={20} /> [Docker](https://docs.docker.com/get-docker/) is the recommended way to install and run a Livepeer Gateway Node.

  <Icon icon="linux" size={20} /> [Linux OS](https://linux.org) is recommended for production use.
</Tip>

<CustomDivider />

<BorderedBox>
  <Tabs>
    <Tab title="Docker" icon="docker">
      ## <Icon icon="docker" iconType="solid" size={32} /> Docker Guide

      {dockerGroup()}

      <DockerSupport />

      <StyledSteps iconColor="var(--lp-color-accent-strong)" titleColor="var(--accent)" lineColor="var(--accent)" titleSize="h3">
        <StyledStep title="Prerequisites">
          <DockerUpdate />
        </StyledStep>

        <StyledStep title="Pull Docker Image">
          <DockerPull />
        </StyledStep>

        <StyledStep title="Quick Test">
          <DockerInstallCheck />
        </StyledStep>
      </StyledSteps>

      <Card title="Next Step: Configure the Gateway" icon="gear" href="/v2/gateways/setup/configure" horizontal arrow>
        View all available configuration options for the Gateway
      </Card>
    </Tab>

    <Tab title="Linux" icon="linux">
      ## <Icon icon="linux" iconType="solid" size={32} /> Linux & macOS Binary Guide

      {linuxGroup()}

      <LinuxSupport />

      <StyledSteps iconColor="var(--lp-color-accent-strong)" titleColor="var(--accent)" lineColor="var(--accent)" titleSize="h3">
        <StyledStep title="Prerequisites">
          <LinuxPrerequisites />
        </StyledStep>

        <StyledStep title="Download & Install Binary">
          <LinuxInstallBinary />
        </StyledStep>

        <StyledStep title="Quick Test">
          <LinuxInstallCheck />
        </StyledStep>
      </StyledSteps>

      <Card title="Next Step: Configure the Gateway" icon="gear" href="/v2/gateways/setup/configure" horizontal arrow>
        View all available configuration options for the Gateway
      </Card>
    </Tab>

    <Tab title="Windows" icon="windows">
      <Warning>
        This content is referenced from the [current docs windows install
        guide](https://docs.livepeer.org/gateways/guides/windows-install) **TODO** - \[
        ] UNVERIFIED INSTALL DOCS - VERIFY CONTENT - \[ ] MOVE ETH WALLET SETUP CONTENT
      </Warning>

      <Badge color="blue"> Video Only </Badge>

      <Icon icon="windows" />

      Latest go-livepeer version: <Badge color="green">{latestVersion_0}</Badge> (dynamically fetched)

      installing the Livepeer Gateway from source binary on Windows.

      <Note>This is a Linux distribution operating in WSL2</Note>

      <StyledSteps iconColor="var(--lp-color-accent-strong)" titleColor="var(--accent)" lineColor="var(--accent)">
        <StyledStep title="Prerequisites">
          Install WSL2 (Windows host)

          ```bash icon="terminal" lines In Powershell(Admin) theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          wsl --install
          # Reboot when prompted.
          ```

          ```bash icon="terminal" wrap lines Check theme={"theme":{"light":"github-light","dark":"dark-plus"}}
            wsl --status
            # Output: Version: WSL 2
            # Output:Default distro: Ubuntu
          ```

          ```bash icon="terminal" wrap lines Enter WSL theme={"theme":{"light":"github-light","dark":"dark-plus"}}
            wsl
          ```
        </StyledStep>

        <StyledStep title="Download & Unzip Binary">
          ## Download and unzip the Livepeer binary

          <CustomCodeBlock codeString="https://github.com/livepeer/go-livepeer/releases/download/{PLACEHOLDER}/livepeer-windows-amd64.zip" placeholderValue={latestVersion} language="bash" icon="terminal" />

          <Expandable title=">_ In case of version fetch issues">
            In case of fetch issues: Replace {'<VERSION>'} with the latest [go-livepeer release](https://github.com/livepeer/go-livepeer/releases) number

            ```bash icon="terminal" wrap lines theme={"theme":{"light":"github-light","dark":"dark-plus"}}
            https://github.com/livepeer/go-livepeer/releases/download/<VERSION>/livepeer-windows-amd64.zip
            ```
          </Expandable>
        </StyledStep>

        <StyledStep title="Create .bat File">
          ## Create a bat file to launch Livepeer.

          Create a file named Gateway.bat:

          ```bash icon="terminal" wrap lines theme={"theme":{"light":"github-light","dark":"dark-plus"}}
            touch gateway.bat
          ```

          Use the following as a template, adding your personal info where needed (on-chain) and save a .bat file
          in the same directory as the Livepeer executable.

          <Tabs>
            <Tab title="Off-Chain">
              ```bash icon="terminal" wrap lines theme={"theme":{"light":"github-light","dark":"dark-plus"}}
              livepeer.exe -network=offchain -gateway -cliAddr=127.0.0.1:5935 -monitor=true -v=6 -rtmpAddr=0.0.0.0:1935 -httpAddr=0.0.0.0:8935

              PAUSE
              ```
            </Tab>

            <Tab title="On-Chain">
              ```bash icon="terminal" wrap lines theme={"theme":{"light":"github-light","dark":"dark-plus"}}
                livepeer.exe  -network=arbitrum-one-mainnet -ethUrl=<YOUR_ARB_RPC_URL>  -ethAcctAddr=<YOUR_ETH_ADDRESS>  -ethPassword=<YOUR_PASSWORD>  -ethKeystorePath=<KEYSTORE_PATH> -gateway -cliAddr=127.0.0.1:5935 -rtmpAddr=0.0.0.0:1935 -httpAddr=0.0.0.0:8935 -maxPricePerUnit=300 -monitor=true -v=6

              PAUSE
              ```

              **Required On-Chain Parameters**

              Network Configuration

              * `-network`: Must be set to the blockchain network `arbitrum-one-mainnet`

              Ethereum Configuration

              * `-ethUrl`: Ethereum JSON-RPC URL (required for on-chain)
              * `-ethAcctAddr`: Your Ethereum account address
              * `-ethPassword`: Password for your ETH account or path to password file
              * `-ethKeystorePath`: Path to your keystore directory or keyfile
            </Tab>
          </Tabs>
        </StyledStep>

        <StyledStep title="Start Gateway">
          ## Start the Livepeer Gateway

          Start the Livepeer Gateway using the .bat file.

          ```bash icon="terminal" wrap lines theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          livepeer_cli.exe -host 127.0.0.1 -http 5935
          ```
        </StyledStep>

        <StyledStep title="Tip: Start with Windows">
          *If you'd like the Gateway to start with Windows you can create a System service
          using [NSSM](https://nssm.cc/) or the Windows Task Scheduler.*
        </StyledStep>
      </StyledSteps>

      {' '}

      <br />

      <Card title="Next Step: Configure the Gateway" icon="gear" href="/v2/gateways/setup/configure" horizontal arrow>
        Open the Livepeer CLI, then Jump to [Configuration
        Options](/v2/Gateways/setup/configure) to finish
        configuring the Gateway
      </Card>
    </Tab>
  </Tabs>
</BorderedBox>
