Quickstart

Install Docker Compose

⚠️

Do not use docker-compose

Always use docker compose instead of docker-compose to avoid docker related issues.

LatticeFlow is deployed using docker compose. To check if Docker Compose is installed, run the following command on your machine:

docker compose version
How to install Docker Compose?

If you do not have docker compose installed yet, please follow the instructions below or the official docker documentation:

# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

# Install the latest version
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Manage Docker as a non-root user
# https://docs.docker.com/engine/install/linux-postinstall/

# Create the docker group.
sudo groupadd docker

# Add your user to the docker group.
sudo usermod -aG docker $USER

# Activate the changes to groups or log out/log in
newgrp docker
sudo yum install -y docker
# Start the Docker service.
sudo service docker start


# Manage Docker as a non-root user
# https://docs.docker.com/engine/install/linux-postinstall/
sudo usermod -a -G docker $USER

# Install docker compose plugin
DOCKER_CONFIG=/usr/local/lib/docker
sudo mkdir -p $DOCKER_CONFIG/cli-plugins
sudo curl -SL "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o $DOCKER_CONFIG/cli-plugins/docker-compose
sudo chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose

# Activate the changes to groups or log out/log in
newgrp docker
# Please follow the instructions at:
# https://docs.latticeflow.io/page/latticeflow-web-installation-on-windows

Step 1: Login to Docker Registry

LatticeFlow Web is a containerized application. To gain access to LatticeFlow Docker images, login into the LatticeFlow Docker registry.

To login, use your the Docker credentials in the command below and run it.

docker login registry.gitlab.com -u <username> -p <password>

Step 2: Configure Deployment

The LatticeFlow Web deployment is configured using environment variables.

Create an .env file, copy the contents below into it, and adjust the environment variables to your needs.

📘

Web Versions

LF_ASSESSMENT_VERSION defines the version of LatticeFlow Web to be deployed.

LF_ASSESSMENT_VERSION="0.13.0"

# Environment for which LatticeFlow is deployed
ENV="prod"
LF_DEPLOYMENT_NAME="prod"

# (Optional) Various secrets
OPENAI_API_KEY=""
OPENAI_ORG=""
TOGETHER_API_KEY=""
GEMINI_API_KEY=""
ANTHROPIC_API_KEY=""
NOVITA_API_KEY=""
FIREWORKS_API_KEY=""
SAMBANOVA_API_KEY=""

# (Optional) Adjust the port on which the LatticeFlow will be available.
LF_ASSESSMENT_PORT="5005"
LF_ASSESSMENT_JUPYTER_PORT="8888"

Step 3: Deploy LatticeFlow Web

⚠️

Warning

The default LatticeFlow deployment comes without SSL encryption. Please run it in a trusted environment or adapt it to add SSL encryption following your company's best practices.

Important: If you do not set SSL encryption, you need to add LF_OIDC_ALLOW_INSECURE_REDIRECT=True in your .env file to explicitly allow insecure connections.


In the directory with the .env file create a new file named docker-compose.yaml and paste the contents of the docker compose template:

Docker Compose Template Contents
name: assessment

services:
  latticeflow-assessment-redis:
    restart: unless-stopped
    image: redis:7.2.5
    command: redis-server --save ""
    volumes:
      - lf-data-redis:/data
    networks:
      - internal
    healthcheck:
      test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
      interval: 1s
      timeout: 3s
      retries: 5
    labels:
      - ai.latticeflow.product=ai-assessments

  latticeflow-assessment-db:
    restart: unless-stopped
    image: postgres:15.2
    shm_size: 1024mb
    networks:
      - internal
    volumes:
      - lf-persistence:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=${LF_DB_NAME:-assessment}
      - POSTGRES_USER=${LF_DB_USER:-latticeflow}
      - POSTGRES_PASSWORD=${LF_DB_PASSWORD:-Uplifted8}
    healthcheck:
      test:
        [
          "CMD-SHELL",
          "pg_isready -d ${LF_DB_NAME:-assessment} -U ${LF_DB_USER:-latticeflow}",
        ]
      interval: 30s
      timeout: 60s
      retries: 5
      start_period: 80s
    labels:
      - ai.latticeflow.product=ai-assessments

  latticeflow-assessment-app:
    user: "assessment:assessment"
    security_opt:
      - no-new-privileges:true
    restart: unless-stopped
    image: registry.gitlab.com/latticeflow/cloud/cloud/latticeflow-assessment:${LF_ASSESSMENT_VERSION:?error}
    working_dir: /app/latticeflow-assessment
    entrypoint: "lf_start_assessment"
    ports:
      - "${LF_ASSESSMENT_PORT:-5005}:5005"
    volumes:
      - lf-data-logs:/app/latticeflow-assessment/lf_data/data/logs
      - lf-data-static-persistence:/app/latticeflow-assessment/lf_data/static/persistence
      - lf-data-local-datasets:/app/latticeflow-assessment/lf_data/data/datasets/local_datasets
    environment:
      - POSTGRES_DB=${LF_DB_NAME:-assessment}
      - POSTGRES_USER=${LF_DB_USER:-latticeflow}
      - POSTGRES_PASSWORD=${LF_DB_PASSWORD:-Uplifted8}
      - POSTGRES_HOST=latticeflow-assessment-db
      - LF_ENVIRONMENT=${LF_ENVIRONMENT:-production}
      - LF_ERROR_MONITORING_ENABLED=${LF_ERROR_MONITORING_ENABLED:-True}
      - LF_JOB_QUEUE_BROKER=redis://latticeflow-assessment-redis:6379
      - LF_LOAD_USER_PROVIDED_INTEGRATIONS=${LF_LOAD_USER_PROVIDED_INTEGRATIONS:-False}
      - LF_KC_URL=http://latticeflow-assessment-keycloak:8080
      - LF_KC_EXTERNAL_PORT=${LF_KEYCLOAK_PORT:-8080}
      - LF_OIDC_ALLOW_INSECURE_REDIRECT_URI=${LF_OIDC_ALLOW_INSECURE_REDIRECT_URI:-False}
      - OPENAI_API_KEY=${OPENAI_API_KEY}
      - OPENAI_ORG=${OPENAI_ORG}
      - TOGETHER_API_KEY=${TOGETHER_API_KEY}
      - GEMINI_API_KEY=${GEMINI_API_KEY}
      - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
      - NOVITA_API_KEY=${NOVITA_API_KEY}
      - FIREWORKS_API_KEY=${FIREWORKS_API_KEY}
      - SAMBANOVA_API_KEY=${SAMBANOVA_API_KEY}
    networks:
      - external
      - internal
    depends_on:
      latticeflow-assessment-redis:
        condition: service_healthy
      latticeflow-assessment-db:
        condition: service_healthy
      latticeflow-assessment-keycloak:
        condition: service_healthy
    healthcheck:
      test: ["CMD-SHELL", "python -c \"import requests; print(requests.get('http://localhost:5005/api/ping').text)\" | grep pong"]
      interval: 10s
      timeout: 5s
      retries: 120
    labels:
      - ai.latticeflow.product=ai-assessments
  latticeflow-assessment-jupyter:
    user: "assessment:assessment"
    security_opt:
      - no-new-privileges:true
    restart: unless-stopped
    image: registry.gitlab.com/latticeflow/cloud/cloud/latticeflow-assessment:${LF_ASSESSMENT_VERSION:?error}
    working_dir: /app/latticeflow-assessment
    entrypoint: "python -m jupyter notebook --ip 0.0.0.0 --port 8888"
    ports:
      - "${LF_ASSESSMENT_JUPYTER_PORT:-8888}:8888"
    environment:
      - POSTGRES_DB=${LF_DB_NAME:-assessment}
      - POSTGRES_USER=${LF_DB_USER:-latticeflow}
      - POSTGRES_PASSWORD=${LF_DB_PASSWORD:-Uplifted8}
      - POSTGRES_HOST=latticeflow-assessment-db
      - LF_ENVIRONMENT=${LF_ENVIRONMENT:-production}
      - LF_ERROR_MONITORING_ENABLED=${LF_ERROR_MONITORING_ENABLED:-True}
      - LF_JOB_QUEUE_BROKER=redis://latticeflow-assessment-redis:6379
      - LF_LOAD_USER_PROVIDED_INTEGRATIONS=${LF_LOAD_USER_PROVIDED_INTEGRATIONS:-False}
      - OPENAI_API_KEY=${OPENAI_API_KEY}
      - OPENAI_ORG=${OPENAI_ORG}
      - TOGETHER_API_KEY=${TOGETHER_API_KEY}
      - GEMINI_API_KEY=${GEMINI_API_KEY}
      - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
      - NOVITA_API_KEY=${NOVITA_API_KEY}
      - FIREWORKS_API_KEY=${FIREWORKS_API_KEY}
      - SAMBANOVA_API_KEY=${SAMBANOVA_API_KEY}
    networks:
      - external
      - internal
    depends_on:
      - latticeflow-assessment-app
      - latticeflow-assessment-redis
      - latticeflow-assessment-db
    labels:
      - ai.latticeflow.product=ai-assessments

  latticeflow-assessment-workers:
    user: "assessment:assessment"
    security_opt:
      - no-new-privileges:true
    restart: unless-stopped
    image: registry.gitlab.com/latticeflow/cloud/cloud/latticeflow-assessment:${LF_ASSESSMENT_VERSION:?error}
    working_dir: /app/latticeflow-assessment
    entrypoint: "lf_start_workers"
    command:
      - "--disable_error_monitoring"
      - "--disable_analytics"
    environment:
      - POSTGRES_DB=${LF_DB_NAME:-assessment}
      - POSTGRES_USER=${LF_DB_USER:-latticeflow}
      - POSTGRES_PASSWORD=${LF_DB_PASSWORD:-Uplifted8}
      - POSTGRES_HOST=latticeflow-assessment-db
      - LF_JOB_QUEUE_BROKER=redis://latticeflow-assessment-redis:6379
      - LF_LOAD_USER_PROVIDED_INTEGRATIONS=${LF_LOAD_USER_PROVIDED_INTEGRATIONS:-False}
      - LF_KC_URL=http://latticeflow-assessment-keycloak:8080
      - OPENAI_API_KEY=${OPENAI_API_KEY}
      - OPENAI_ORG=${OPENAI_ORG}
      - TOGETHER_API_KEY=${TOGETHER_API_KEY}
      - GEMINI_API_KEY=${GEMINI_API_KEY}
      - HF_TOKEN=${HF_TOKEN}
      - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
      - NOVITA_API_KEY=${NOVITA_API_KEY}
      - FIREWORKS_API_KEY=${FIREWORKS_API_KEY}
      - SAMBANOVA_API_KEY=${SAMBANOVA_API_KEY}
    volumes:
      - lf-data-logs:/app/latticeflow-assessment/lf_data/data/logs
      - lf-data-static-persistence:/app/latticeflow-assessment/lf_data/static/persistence
      - lf-data-local-datasets:/app/latticeflow-assessment/lf_data/data/datasets/local_datasets
    networks:
      - internal
      - external
    depends_on:
      - latticeflow-assessment-app
      - latticeflow-assessment-db
      - latticeflow-assessment-redis
    labels:
      - ai.latticeflow.product=ai-assessments
    healthcheck:
      test: ["CMD-SHELL", "/home/assessment/venv/bin/python", "-m", "celery", "-A", "latticeflow.assessment.job_queue", "inspect", "ping"]
      start_period: 20s
      interval: 5s
      timeout: 10s
      retries: 3

  latticeflow-assessment-logrotate:
    image: blacklabelops/logrotate
    restart: unless-stopped
    volumes:
      - lf-data-logs:/app/latticeflow-assessment/lf_data/data/logs
    environment:
      - LOGS_DIRECTORIES=/app/latticeflow-assessment/lf_data/data/logs
      - LOGROTATE_SIZE=10M
      - LOGROTATE_COPIES=3

  latticeflow-assessment-keycloak:
    user: "assessment:assessment"
    restart: unless-stopped
    image: registry.gitlab.com/latticeflow/cloud/cloud/latticeflow-assessment-keycloak:${LF_ASSESSMENT_VERSION:?error}
    ports:
      - "${LF_KEYCLOAK_PORT:-8080}:8080"
    networks:
      - internal
      - external
    depends_on:
      latticeflow-assessment-db:
        condition: service_healthy
    healthcheck:
      test: ["CMD-SHELL", "/healthcheck.sh"]
      start_period: 10s
      interval: 5s
      timeout: 2s
      retries: 20
    environment:
      - KC_BOOTSTRAP_ADMIN_USERNAME=${KC_BOOTSTRAP_ADMIN_USERNAME:-admin}
      - KC_BOOTSTRAP_ADMIN_PASSWORD=${KC_BOOTSTRAP_ADMIN_PASSWORD:-admin}
      - KC_DB=postgres
      - KC_DB_URL=jdbc:postgresql://latticeflow-assessment-db/${LF_DB_NAME:-assessment}
      - KC_DB_USERNAME=${LF_DB_USER:-latticeflow}
      - KC_DB_PASSWORD=${LF_DB_PASSWORD:-Uplifted8}
      # Allow Keycloak to be addressed with a different hostname than its own.
      - KC_HOSTNAME_STRICT=false
      # Allow plain HTTP.
      - KC_HTTP_ENABLED=true
      # Tell KC to infer routing and redirect info from the XFF headers.
      - KC_PROXY_HEADERS=xforwarded
    entrypoint: [
      "/opt/keycloak/bin/kc.sh",
      "start",
      # Pass this flag to prevent keycloak from doing another build and overriding our config.
      "--optimized",
    ]

networks:
  external:
    driver: bridge
  internal:
    driver: bridge
    internal: true

volumes:
  lf-data-redis:
    driver: local
  lf-persistence:
    driver: local
  lf-data-logs:
    driver: local
  lf-data-static-persistence:
    driver: local
  lf-data-local-datasets:
    driver: local

In the directory with the .env file, run the following commands to fetch LatticeFlow Web Docker images and deploy LatticeFlow Web.

source .env  # If using `/bin/sh` shell, then use: . $PWD/.env
docker compose up --detach

If everything started successfully, you should see an output similar to the one below.

[+] Running 11/11
 ✔ Network external                	 						Created                     0.1s
 ✔ Network internal                 						Created                     0.1s
 ✔ Volume "lf-data-redis"  											Created                     0.0s
 ✔ Volume "lf-persistence"  										Created                     0.0s
 ✔ Volume "lf-data-data"  											Created                     0.0s
 ✔ Volume "lf-data-reports" 										Created                     0.0s
 ✔ Container latticeflow-assessment-redis-1    	Healthy                    22.6s
 ✔ Container latticeflow-assessment-db-1       	Healthy                    22.6s
 ✔ Container latticeflow-assessment-app-1      	Healthy                    51.2s
 ✔ Container latticeflow-assessment-jupyter-1   Started                     6.2s
 ✔ Container latticeflow-assessment-workers-1  	Started                    52.0s

Step 4: Setup LatticeFlow Web

After successfully starting the deployment, LatticeFlow Web should be accessible at [http://localhost:5005].If a different port than 5005 was picked in Step 2, adapt the URL.