Self-Hosting AI Workflows on Mac: DeepSeek-R1 + Ollama + n8n powered by Docker

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • MyrinNew
    Senior Member
    • Feb 2024
    • 5175

    #1

    Self-Hosting AI Workflows on Mac: DeepSeek-R1 + Ollama + n8n powered by Docker

    I’ll walk through the process of setting up a local environment on a MacBook Pro M3 (18GB) to test the DeepSeek model using Ollama, n8n, and Docker via Docker Desktop. This setup is suitable ONLY for performing PoCs and development environments.


    Prerequisites

    Before we begin, make sure you have the following (or similar setup):

    1. MacBook Pro M3 with 18GB RAM
    2. Docker installed (via Docker desktop - https://www.docker.com/products/docker-desktop)
    3. Ollama installed (https://ollama.com)
    4. n8n installed (https://docs.n8n.io/hosting — for automating workflows, we’ll use this to test DeepSeek)


    Setting Up DeepSeek-R1 with Ollama

    DeepSeek-R1 is a powerful open-source AI model optimized for complex reasoning, coding, mathematics, and problem-solving. Running it locally ensures privacy, performance, and customization.


    Let’s dive into the steps!

    Step:1:

    1: Install n8n Using Docker Compose

    We’ll use Docker Compose to spin up n8n.


    Create a folder for the n8n setup:






    mkdir ~/n8n-docker && cd ~/n8n-docker








    2. Create a simple docker-compose.yml file for n8n:






    version: '3.9'

    services:
    n8n:
    image: n8nio/n8n:latest
    container_name: n8n
    ports:
    - "5678:5678"
    volumes:
    - ./n8n_data:/home/node/.n8n # Persistent storage for workflows and data
    restart: unless-stopped







    3. Start the n8n service:






    docker-compose up -d







    4. Open n8n in your browser: http://localhost:5678. Setup an owner account and Log in using the credentials.





    You can request a free n8n license key (emailed to you) to unlock selected paid features on your community edition of n8n. You can enter and activate your key as shown below.





    Step 2: Install Ollama






    ~/Doc/AI-Projects brew install ollama
    Warning: ollama 0.5.7 is already installed and up-to-date.
    To reinstall 0.5.7, run:
    brew reinstall ollama







    Step 3: Download the DeepSeek 7B model using Ollama:






    ~/Doc/AI-Projects ollama run deepseek-r1:7b
    pulling manifest
    pulling 96c415656d37... 100% ▕████████████████▏ 4.7 GB
    pulling 369ca498f347... 100% ▕████████████████▏ 387 B
    pulling 6e4c38e1172f... 100% ▕████████████████▏ 1.1 KB
    pulling f4d24e9138dd... 100% ▕████████████████▏ 148 B
    pulling 40fb844194b2... 100% ▕████████████████▏ 487 B
    verifying sha256 digest
    writing manifest
    success
    >>> /bye

    ~/Doc/AI-Projects ollama list
    NAME ID SIZE MODIFIED
    deepseek-r1:7b 0a8c26691023 4.7 GB 26 hours ago







    Step 4: Integrate DeepSeek with n8n


    Let’s set up a workflow in n8n to interact with the DeepSeek model.


    4.1: Create Chat Trigger, Basic LLM Chain and Ollama Chat Model nodes





    4.2: Configure Ollama Chat Model and test the connectivity


    Double-click on the Ollama Chat Model node and configure the Ollama Base URL.


    Instead of using localhost, set it to host.docker.internal with the appropriate Ollama port number (11434). Using localhost will result in a connection refused error, as Docker containers require host.docker.internal to access services running on the host machine.





    Once the connection is tested successfully, select the Deepseek model we have downloaded deepseek-r1:7b under parameters.





    Step 5: Test DeepSeek 7B Model


    Now that everything is set up:


    Test more complex queries using the DeepSeek 7B model.

    Create workflows in n8n to automate LLM-based tasks, such as summarisation, Q&A, or sentiment analysis.


    Simple test:









    Madhu: who are you





    Greetings! I'm DeepSeek-R1, an artificial intelligence assistant created by DeepSeek. I'm at your service and would be delighted to assist you with any inquiries or tasks you may have.



    Madhu: create terraform code to deploy eks cluster in aws


    Okay, I need to create a Terraform code to deploy an EKS cluster on AWS. Let me think about how to approach this.

    First, I should outline the main components needed for deploying EKS using AWS. The key parts are the master node and worker nodes. So, I'll probably use Terraform modules like ec2 for general EC2 setup, ebs for adding storage, rds for the database, elb for the load balancer, and autoscaling groups to manage scaling.

    I remember that EKS requires a cluster name which should be unique, so using a random string would make sense. I'll include a list of required modules at the top of my file to ensure they're loaded first.

    Next, I need to define resources for each node type. The master will have an instance type like t2.micro, and workers can use r5.micro with a higher vpc_id for better performance since workers are in the same subnet as the master.

    For storage, using ProvisionedS3Bucket makes sense because it's easy to manage and provides persistent storage. I'll set up both a default bucket and maybe an object store for EKS secrets or logs.

    The database should be RDS, so I'll configure a MySQL or PostgreSQL instance in the same subnet as the master for consistency.

    The load balancer is crucial for traffic distribution. I'll create an ELB that directs traffic to the EKS cluster nodes. The LB needs to be in the same VPC and Security Group as the master to ensure all nodes are reachable.

    Autoscaling groups will help manage scaling based on load and temperature. I'll set up two groups, one for scaling out and another for scaling back, with appropriate policies so they don't interfere with each other.

    I should also include environment variables in the Infrastructure Block for easy deployment from different environments like dev, staging, or prod.

    It's important to note that EKS requires specific IAM roles for each resource. I might need to create these roles in a separate Terraform file or handle them within this code using assume_iam_role statements.

    Wait, does the worker node need its own storage? Maybe using an S3 bucket per node isn't efficient, so perhaps using a shared storage solution like EFS or a persistent volume would be better. Or maybe I can use the same storage as the master for simplicity since they're in the same subnet.

    I'm also thinking about security groups. They need to allow SSH access and connect all nodes (including ELB) to each other. So, I'll define a security group that includes both nodes and the ELB.

    Another consideration is network interfaces. Each node's VPC ID should match so they're in the same subnet for communication.

    I should make sure all necessary modules are imported at the top of the file, like module 'ec2', 'ebs', etc., to avoid any undefined variable errors.

    Also, I need to define a list of parameter values that can be overridden or changed between environments. This way, each deployment environment can have its own configuration without rebuilding the entire code.

    Putting it all together, I'll structure the code with modules at the top, then define variables and resources in order. Each node type (master and worker) will be defined using their respective modules. The EKS cluster will include all these components plus the autoscaling groups for scaling management.

    I should also ensure that the output includes all necessary information like cluster name, master IP, etc., so users can easily deploy without manual input.

    Finally, I'll include a note about how to apply the changes and test the deployment, as well as mentioning the IAM roles required. This will help the user understand what steps to take next after running the Terraform code.

    To deploy an EKS cluster using Terraform on AWS, you can follow these steps with the provided code:

    Define Required Modules: Ensure all necessary modules are imported first.

    Set Up Variables: Create a variable list for deployment configuration.

    Define Resources:

    Master Node
    Worker Nodes
    Storage Solutions (S3, RDS)
    Load Balancer
    Autoscaling Groups
    Create Infrastructure Block: Manage environment-specific configurations.

    Define Tags and Output: Include useful metadata for deployment.

    Write Terraform Code:

    # Top of the file with required modules
    module "ec2"
    define "parameters" = [
    "region",
    "cluster_name",
    "vpc_id",
    "security_group",
    "KeyName",
    "efs_size",
    "s3_bucket_name",
    "rds_db_name",
    "master BootTime",
    "worker BootTime"
    ]

    # Infrastructure configuration

    module = "ec2"

    var Parameters = parameters()

    # Define CloudFormation stack variables
    var Region = Parameters.region
    var ClusterName = Parameters.cluster_name
    var VpcId = Parameters.vpc_id
    var SecurityGroup = Parameters.security_group
    var KeyName = Parameters.KeyName
    var EfSSize = Parameters.efs_size
    var S3BucketName = Parameters.s3_bucket_name
    var RdsDbName = Parameters.rds_db_name

    var Master = "t2.micro"
    var Worker = "r5.micro"

    # Define storage solutions
    var StorageSolution = {
    type: "provisioned_s3_bucket",
    bucket_name: S3BucketName,
    region: Region
    }

    var EksClusterStorage = {
    type: "efs",
    root_size_in_gigabytes: EfSSize,
    region: Region
    }

    # Define database solution
    var Rds = {
    type: "rds",
    engine: "mysql",
    name: RdsDbName,
    region: Region,
    key_name: KeyName,
    storage_type: "persistent",
    availability_zone: VpcId[0].Availability_Zone
    }

    # Define load balancer configuration
    var LoadBalancer = {
    type: "elastic_load_balancer",
    name: ClusterName LoadBalancer,
    region: Region,
    load_balancer subnet_id: VpcId[0].Subnet_id,
    security_groups: [SecurityGroup],
    inboundrules: [{
    destination_port: 80,
    protocol: "TCP"
    }]
    }

    # Define autoscaling groups
    var AutoscalingOut = {
    type: "autoscaling",
    scaling_out enabled: true,
    min_count: 2,
    max_count: 6,
    policy: { target_arn: "arn:aws:elasticloadbalancing:Region::app:elb/LoadBalancer/Status" }
    }

    var AutoscalingIn = {
    type: "autoscaling",
    scaling_in enabled: true,
    min_count: 2,
    max_count: 6,
    policy: { target_arn: "arn:aws:elasticloadbalancing:Region::app:elb/LoadBalancer/Status" }
    }

    # Apply changes
    apply {
    # Define the master node
    ec2.master(InstanceType = Master, KeyName = KeyName, AvailabilityZone = VpcId[0].Availability_Zone,
    SecurityGroupIds = [SecurityGroup], SubnetId = VpcId[0].Subnet_id,
    Storage = StorageSolution, EnableNetworking: true)

    # Define the worker nodes
    map "workers" {
    Worker,
    KeyName = KeyName,
    AvailabilityZone = VpcId[0].Availability_Zone,
    SecurityGroupIds = [SecurityGroup],
    SubnetId = VpcId[0].Subnet_id,
    Storage = StorageSolution,
    EnableNetworking: true
    }

    # Define the EKS cluster with master and worker nodes
    eks(Storage = EksClusterStorage, LoadBalancer = LoadBalancer, AutoscalingGroups = [AutoscalingOut, AutoscalingIn])

    # Infrastructure blocks
    infrastructureBlock "parameters" {
    parameters
    }

    infrastructureBlock "environment" {
    environment = Parameters.environment
    }
    }

    # Output information for deployment confirmation
    output "cluster_name" = ClusterName
    output "master_ip" = ec2.master.ip_address
    output "workers_count" = (number of workers)
    This code provides a comprehensive configuration to deploy an EKS cluster using Terraform on AWS. It includes:

    Master Node: Uses a T2.micro instance with RDS for storage and networking.
    Worker Nodes: Utilizes R5.micro instances, providing better performance compared to master nodes.
    Storage: Both S3 and EFS are configured to provide redundancy and in-cluster storage solutions.
    Load Balancer: Ensures traffic is distributed efficiently among all cluster nodes.
    Autoscaling Groups: Manages scaling based on load and temperature, with two groups for scaling out/in.
    To use this code:

    Ensure Terraform Installation: Confirm that Terraform is installed and configured correctly.
    Define Parameters: Create a YAML configuration file for your specific environment (dev, staging, prod).
    Apply Changes: Use terraform apply to deploy the EKS cluster based on your configurations.
    Note: The code assumes you have IAM roles set up with appropriate permissions for EKS operations, including RDS, S3, and ELB access. Ensure these roles are available before running the deployment.







    Conclusion

    The DeepSeek R1 LLM stands out for its ability to run locally within a Docker-powered environment, ensuring a privacy-first, efficient, and cost-effective alternative to cloud-based LLMs. By leveraging Docker alongside Ollama and n8n, DeepSeek offers a seamless workflow for testing and automation without the need for extensive infrastructure or internet connectivity.


    Feel free to experiment with different workflows and use cases!


    Learning continues.!




    More...
Working...