图文并茂记录:Ubuntu上安装Ollama大模型提供Serve,前端调用实现AI对话功能

本文图文并茂,记录安装 Ollama过程,下载大模型,启动ollama大模型服务,然后通过nginx代理外部请求访问,实现一个前端问答效果

准备工作

  • 一台服务器,操作系统 Ubuntu,版本大于等于 20.04,笔者的是 Ubuntu 22.04 64 bit
  • 当然了 有域名最好
  • 一个图形可视化化链接服务器软件,笔者推荐 winscp
  • 一架梯子,笔者用的是,clash小猫

效果图

效果演示地址

请点击一下:ashuai.site/reactExampl...

第一步,试试ollama官方提供的命令

ollama官方:ollama.com/download/li...

第二步,网络不行,ollama下载不下来

文件太大了,有一个G多

第三步,到github上找对应ollama安装包资源,下载,再上传到乌班图服务器上

地址如下:github.com/ollama/olla...

然后,在浏览器中下载

下载完毕以后,在用winscp将其移动到服务器上

ollama安装包上传完毕

第四步,解压对应的这个文件

1. 解压 .tgz 压缩包并统一路径管理

当前我们是已在 /var/selfDownload 目录(通过 ls 能看到 ollama-linux-amd64.tgz),直接执行解压命令即可。.tgz.tar.gz 的简写,需用 tar 命令解压:

bash 复制代码
tar -zxvf ollama-linux-amd64.tgz
  • 命令说明:

    • z:处理 gzip 压缩格式(对应 .gz/.tgz);
    • x:执行 "解压" 操作;
    • v:显示解压过程(可选,方便查看文件是否正常解压);
    • f:指定要解压的文件名(必须放在命令最后,这里是 ollama-linux-amd64.tgz)。

解压成功 得到两个新的文件夹

在winscp中也能直观看到

把对应的文件移动走到对应位置,统一管理,注意下图的路径

然后跑起来服务

2. 安装大模型,使用curl命令进行对话

ollama服务 默认运行的端口是11434端口

然后,使用curl命令,在服务器内部的命令行中,发送给ollama发请求,调用通义千文大模型试试

js 复制代码
curl http://localhost:11434/api/generate -d '{
  "model": "qwen2.5:0.5b",
  "prompt": "你是什么模型",
  "stream": false
}'
  • 我们发现跑通了,至此,乌班图服务器上,安装Ollama就全部完成了
  • 但是,单单只有Ollama的上安装的模型服务还不太够,效果不明显
  • 接下,我们要让服务器上的大模型服务能够在外部调用

3. nginx代理外部请求到ollama

  • 笔者服务器上安装nginx,以便于代理外部的请求,而后把外部请求转发到服务器上的ollama的大模型服务
  • 以/ollama开头的请求,转到ollama这里使用11434端口上
bash 复制代码
# ollama服务
location /ollama/ {
    # 允许所有来源访问
    add_header 'Access-Control-Allow-Origin' '*' always;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
    add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
    add_header 'Access-Control-Max-Age' 1728000 always;

    # 代理到 Ollama
    proxy_pass http://localhost:11434/;

    # 完全清理所有头,只保留必要的
    proxy_pass_request_headers off;

    # 手动设置最基本的头信息 ollama的响应头过于复杂可能导致403报错
    proxy_set_header Host localhost;
    proxy_set_header Content-Type application/json;
    proxy_set_header Content-Length $content_length;
    proxy_set_header Connection close;
}

第五步,在外部访问请求服务器上的ollama大模型接口

写一个react页面,直接发请求即可

效果图

交互效果

接口请求返回

react代码

即分为对话区和输入区,前端代码倒是很简单

js 复制代码
import { useState } from 'react'
import axios from 'axios'
import { Input } from 'antd'
import styles from './Ollama.module.css'

export default function Ollama() {
    const [messages, setMessages] = useState([]) // 存储对话数据
    const [inputValue, setInputValue] = useState('') // 输入框内容
    const [isLoading, setIsLoading] = useState(false) // 加载状态

    // 发请求
    const sendApiRequest = () => {
        if (!inputValue.trim()) return // 如果输入为空,不发送请求

        const userMessage = inputValue.trim()
        setIsLoading(true)

        // 添加用户消息到对话数据
        setMessages(prev => [...prev, { type: 'user', content: userMessage }])
        setInputValue('') // 清空输入框

        axios.post('/ollama/api/generate', {
            model: "qwen2.5:0.5b",
            prompt: userMessage,
            stream: false
        }).then((response) => {
            const { response: aiResponse } = response.data
            // 添加AI回复到对话数据
            setMessages(prev => [...prev, { type: 'ai', content: aiResponse }])
            setIsLoading(false)
        }).catch((error) => {
            setMessages(prev => [...prev, { type: 'error', content: JSON.stringify(error) }])
            setIsLoading(false)
        })
    }

    // 处理输入框按键事件
    const handleKeyPress = (e) => {
        if (e.key === 'Enter' && !isLoading) {
            sendApiRequest()
        }
    }

    return (
        <div>
            <h3>Ollama调用大模型</h3>

            {/* 对话区 */}
            <div className={styles.chatContainer}>
                <div className={styles.messages}>
                    {messages.length === 0 ? (
                        <div className={styles.emptyMessage}>
                            暂无数据,请开始与AI对话吧!🤔🤔🤔
                        </div>
                    ) : (
                        messages.map((message, index) => (
                            <div
                                key={index}
                                className={`${styles.message} ${styles[message.type]}`}
                            >
                                <div className={styles.messageContent}>
                                    {message.content}
                                </div>
                            </div>
                        ))
                    )}
                </div>
            </div>

            {/* 输入区 */}
            <Input
                value={inputValue}
                onChange={(e) => setInputValue(e.target.value)}
                onPressEnter={handleKeyPress}
                placeholder="输入问题,回车发送"
                disabled={isLoading}
            />
        </div>
    )
}

样式css代码

css 复制代码
.chatContainer {
    border: 1px solid #dee2e6;
    border-radius: 8px;
    height: 400px;
    margin-bottom: 20px;
    overflow-y: auto;
    background-color: #fafafa;
}

.messages {
    padding: 15px;
}

.message {
    margin-bottom: 15px;
    display: flex;
}

/* 用户输入的在右侧,ai回复的在左侧,报错居中 */
.user { justify-content: flex-end; }
.ai { justify-content: flex-start; }
.error { justify-content: center; }

.messageContent {
    max-width: 70%;
    padding: 10px 15px;
    word-wrap: break-word;
}

.user .messageContent {
    background-color: #1890ff;
    color: white;
    border-radius: 18px 18px 4px 18px;
}

.ai .messageContent {
    background-color: #f0f0f0;
    color: #333;
    border-radius: 18px 18px 18px 4px;
}

.error .messageContent {
    background-color: #fff2f0;
    color: #ff4d4f;
    border: 1px solid #ffccc7;
    border-radius: 8px;
}

.emptyMessage {
    text-align: center;
    color: #999;
    font-style: italic;
    padding: 40px;
}

完整github代码地址

请点击 github.com/shuirongshu...

创造不易,感谢关注、点赞、评论支持 🙏🙏🙏

A good memory is better than a bad pen. Record it down...

相关推荐
hkj880816 小时前
Ubuntu 20.04 安装 OpenJDK 17
linux·运维·ubuntu
sulikey16 小时前
服务器安装Docker教程。如何在云服务器安装Docker容器?
运维·服务器·ubuntu·docker·安装教程·云服务器
郝亚军1 天前
使用Vue 3和Nginx打包和部署Vue.js项目的一般步骤
前端·vue.js·nginx
IT曙光2 天前
在Ubuntu上本地部署Dify?
linux·ubuntu
默默提升实验室2 天前
Ubuntu 22.04.5 配置静态IP,手动安装SSH
ubuntu
難釋懷2 天前
Nginx代理https请求
redis·nginx·https
初圣魔门首席弟子2 天前
TypeScript 类型系统完全指南:从基础到高级工具类型(知识库版)
linux·运维·ubuntu
TARDIS_20202 天前
VMware配置ubuntu26.04虚拟机桥接
ubuntu
雷工笔记2 天前
什么是Ubuntu?
linux·运维·ubuntu