Production Deployment

Build / Integration Guide / Production Deployment

8. Production Deployment

📋 Production Ready: Deploying Tari in production requires careful planning, monitoring, and redundancy. This section covers Docker, Kubernetes, and monitoring setups.

🐳 Docker Deployment

Docker Compose

version: '3.8'

services:
  tari-node:
    # WARNING: Use specific version tags in production, not 'latest'
    image: tariproject/minotari_node:latest
    container_name: tari-node
    restart: unless-stopped
    ports:
      - "18141:18141"  # P2P port
      - "127.0.0.1:18142:18142"  # gRPC port (localhost only)
    volumes:
      - tari-node-data:/root/.tari
      - ./config/node-config.toml:/root/.tari/mainnet/config/config.toml:ro
    environment:
      - TARI_NETWORK=mainnet
      - RUST_LOG=info
    networks:
      - tari-network

  tari-wallet:
    image: tariproject/minotari_console_wallet:latest
    container_name: tari-wallet
    restart: unless-stopped
    ports:
      - "127.0.0.1:18143:18143"  # gRPC port (localhost only)
    volumes:
      - tari-wallet-data:/root/.tari
      - ./config/wallet-config.toml:/root/.tari/mainnet/config/config.toml:ro
    environment:
      - TARI_NETWORK=mainnet
      - TARI_WALLET__CUSTOM_BASE_NODE=tari-node:18142
    depends_on:
      - tari-node
    networks:
      - tari-network

  exchange-api:
    build: .
    container_name: tari-exchange-api
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - TARI_WALLET_GRPC=http://tari-wallet:18143
      - TARI_NODE_GRPC=http://tari-node:18142
    depends_on:
      - tari-node
      - tari-wallet
    networks:
      - tari-network

volumes:
  tari-node-data:
  tari-wallet-data:

networks:
  tari-network:
    driver: bridge

Dockerfile

# Multi-stage build for the exchange-api service referenced in docker-compose.yml
FROM node:18-slim AS build

WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev

COPY . .
RUN npm run build

FROM node:18-slim

WORKDIR /app
ENV NODE_ENV=production

COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
COPY --from=build /app/package.json ./

# Run as a non-root user
RUN useradd --uid 1001 --create-home appuser
USER appuser

EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=5s CMD node dist/healthcheck.js

CMD ["node", "dist/server.js"]

Kubernetes

apiVersion: apps/v1
kind: Deployment
metadata:
  name: tari-node
  labels:
    app: tari-node
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tari-node
  template:
    metadata:
      labels:
        app: tari-node
    spec:
      containers:
        - name: tari-node
          image: tariproject/minotari_node:1.0.0
          ports:
            - containerPort: 18141
            - containerPort: 18142
          env:
            - name: TARI_NETWORK
              value: "mainnet"
          volumeMounts:
            - name: tari-data
              mountPath: /root/.tari
          resources:
            requests:
              memory: "4Gi"
              cpu: "2"
            limits:
              memory: "8Gi"
              cpu: "4"
      volumes:
        - name: tari-data
          persistentVolumeClaim:
            claimName: tari-node-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: tari-node-grpc
spec:
  selector:
    app: tari-node
  ports:
    - port: 18142
      targetPort: 18142
  type: ClusterIP