Ollama server
Overview
Setting up an old school Self-Hosted Server Stack: Mattermost, OpenWebUI, and Monitoring
This is how Claude and I installed an Ollama server from scratch.
Part 1: Installing Ollama and OpenWebUI
Installing Ollama
First, we installed Ollama, which is the backend for our AI operations:
After installation, we created a systemd service to manage Ollama:
Added this configuration:
1[Unit]
2Description=Ollama Service
3After=network-online.target
4
5[Service]
6ExecStart=/usr/local/bin/ollama serve
7User=root
8Restart=always
9
10[Install]
11WantedBy=multi-user.target
Started and enabled the service:
To verify the installation, we pulled a model:
Setting up OpenWebUI with Ollama
OpenWebUI serves as our frontend interface for Ollama. We installed it using Python's virtual environment:
1# Install required packages
2sudo apt install python3-full python3-pip python3-venv
3
4# Create and activate virtual environment
5mkdir open-webui && cd open-webui
6python3 -m venv openwebui-env
7source openwebui-env/bin/activate
8
9# Install OpenWebUI
10pip install open-webui
Created a systemd service for OpenWebUI:
Added the configuration (change 'username' to your username):
1[Unit]
2Description=OpenWebUI
3After=network.target
4
5[Service]
6Type=simple
7User=username
8WorkingDirectory=/home/username
9Environment=PATH=/home/username/open-webui/openwebui-env/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
10ExecStart=/home/username/open-webui/openwebui-env/bin/open-webui serve
11Restart=always
12
13[Install]
14WantedBy=multi-user.target
Then start it.
Part 2: Setting up Mattermost
Initial Installation
We started by installing Mattermost on our Ubuntu server. Mattermost runs on port 8065 by default.
Troubleshooting WebSocket Issues
Initially, we encountered the error: "Please check connection, Mattermost unreachable. If issue persists, ask administrator to check WebSocket port." This is a common issue when setting up Mattermost, especially before configuring Nginx properly.
The solution involved:
- Checking if port 8065 was accessible:
- Ensuring the WebSocket configuration in
config.json
matched our setup:
1{
2 "ServiceSettings": {
3 "SiteURL": "http://your-server-ip:8065",
4 "WebsocketURL": "", // Empty to use SiteURL
5 "TLSStrictTransport": false
6 }
7}
- Most importantly, properly configuring Nginx to handle WebSocket connections. The critical part in the Nginx configuration is:
1location ~ /api/v[0-9]+/(users/)?websocket$ {
2 proxy_set_header Upgrade $http_upgrade;
3 proxy_set_header Connection "upgrade";
4 proxy_set_header Host $http_host;
5 # ... other proxy settings ...
6}
Adding SSL with Nginx
To secure our Mattermost instance, we set up Nginx as a reverse proxy and added SSL certificates:
- Created Nginx configuration:
Added:
1upstream backend {
2 server 127.0.0.1:8065;
3 keepalive 32;
4}
5
6proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mattermost_cache:10m max_size=3g inactive=120m use_temp_path=off;
7
8server {
9 server_name mattermost.yourdomain.com;
10
11 location ~ /api/v[0-9]+/(users/)?websocket$ {
12 proxy_set_header Upgrade $http_upgrade;
13 proxy_set_header Connection "upgrade";
14 client_max_body_size 50M;
15 proxy_set_header Host $http_host;
16 proxy_set_header X-Real-IP $remote_addr;
17 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
18 proxy_set_header X-Forwarded-Proto $scheme;
19 proxy_set_header X-Frame-Options SAMEORIGIN;
20 proxy_buffers 256 16k;
21 proxy_buffer_size 16k;
22 proxy_read_timeout 600s;
23 proxy_pass http://backend;
24 }
25
26 location / {
27 client_max_body_size 50M;
28 proxy_set_header Connection "";
29 proxy_set_header Host $http_host;
30 proxy_set_header X-Real-IP $remote_addr;
31 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
32 proxy_set_header X-Forwarded-Proto $scheme;
33 proxy_set_header X-Frame-Options SAMEORIGIN;
34 proxy_buffers 256 16k;
35 proxy_buffer_size 16k;
36 proxy_read_timeout 600s;
37 proxy_cache mattermost_cache;
38 proxy_cache_use_stale error timeout invalid_header http_500;
39 proxy_cache_revalidate on;
40 proxy_cache_min_uses 2;
41 proxy_cache_lock on;
42 proxy_cache_valid 200 7d;
43 proxy_pass http://backend;
44 }
45}
Securing Mattermost
We implemented several security measures:
- Disabled open registration by modifying config.json:
Added:
1{
2 "ServiceSettings": {
3 "EnableOpenServer": false
4 },
5 "TeamSettings": {
6 "EnableUserCreation": false,
7 "EnableTeamCreation": false
8 }
9}
- Enabled Multi-Factor Authentication:
1{
2 "ServiceSettings": {
3 "EnforceMultifactorAuthentication": true,
4 "EnableMultifactorAuthentication": true
5 }
6}
- Set up email notifications using SendGrid:
1{
2 "EmailSettings": {
3 "EnableSignUpWithEmail": true,
4 "EnableSignInWithEmail": true,
5 "EnableSMTPAuth": true,
6 "SMTPUsername": "apikey",
7 "SMTPPassword": "your-sendgrid-api-key-here",
8 "SMTPServer": "smtp.sendgrid.net",
9 "SMTPPort": 587,
10 "ConnectionSecurity": "STARTTLS",
11 "SendEmailNotifications": true,
12 "FeedbackName": "Mattermost",
13 "FeedbackEmail": "your-verified-sender@yourdomain.com",
14 "ReplyToAddress": "your-verified-sender@yourdomain.com"
15 }
16}
Part 3: Setting up Monitoring
Installing Prometheus
- Created necessary users and directories:
1sudo useradd --no-create-home --shell /bin/false prometheus
2sudo mkdir /etc/prometheus
3sudo mkdir /var/lib/prometheus
- Downloaded and installed Prometheus:
1wget https://github.com/prometheus/prometheus/releases/download/v2.49.1/prometheus-2.49.1.linux-amd64.tar.gz
2tar xvf prometheus-*.tar.gz
3cd prometheus-*/
4sudo cp prometheus /usr/local/bin/
5sudo cp promtool /usr/local/bin/
6sudo cp -r consoles/ /etc/prometheus
7sudo cp -r console_libraries/ /etc/prometheus
- Created Prometheus configuration:
Added basic configuration:
1global:
2 scrape_interval: 15s
3
4scrape_configs:
5 - job_name: 'prometheus'
6 static_configs:
7 - targets: ['localhost:9090']
8
9 - job_name: 'node'
10 static_configs:
11 - targets: ['localhost:9100']
Installing Node Exporter
- Set up Node Exporter for system metrics:
1wget https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gz
2tar xvf node_exporter-*.tar.gz
3sudo cp node_exporter-*/node_exporter /usr/local/bin/
4sudo useradd --no-create-home --shell /bin/false node_exporter
5sudo chown node_exporter:node_exporter /usr/local/bin/node_exporter
- Created systemd service for Node Exporter:
Added:
1[Unit]
2Description=Node Exporter
3Wants=network-online.target
4After=network-online.target
5
6[Service]
7User=node_exporter
8Group=node_exporter
9Type=simple
10ExecStart=/usr/local/bin/node_exporter
11
12[Install]
13WantedBy=multi-user.target
Installing Grafana
- Added Grafana repository and installed:
1sudo apt-get install -y apt-transport-https software-properties-common
2wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
3echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee -a /etc/sources.list.d/grafana.list
4sudo apt-get update
5sudo apt-get install grafana
- Set up Nginx as reverse proxy for Grafana:
Added:
1server {
2 server_name grafana.yourdomain.com;
3
4 location / {
5 proxy_pass http://localhost:3000;
6 proxy_http_version 1.1;
7 proxy_set_header Upgrade $http_upgrade;
8 proxy_set_header Connection 'upgrade';
9 proxy_set_header Host $host;
10 proxy_cache_bypass $http_upgrade;
11 }
12}
Useful Shell Aliases
If you're using bash/zsh, you might want to add these helpful aliases to your .bashrc
or .zshrc
:
1# Service management
2alias mm-restart='sudo systemctl restart mattermost'
3alias mm-status='sudo systemctl status mattermost'
4alias mm-logs='sudo journalctl -u mattermost -f'
5
6# Quick edits
7alias mm-config='sudo vim /opt/mattermost/config/config.json'
8alias ng-edit='cd /etc/nginx/sites-available'
9
10# Monitoring
11alias prom-status='sudo systemctl status prometheus'
12alias graf-status='sudo systemctl status grafana-server'
Conclusion
We now have a fully functional, secure server stack with:
- Mattermost for team communication
- OpenWebUI for AI interactions
- Comprehensive system monitoring with Prometheus and Grafana
- Everything secured with SSL certificates
- Basic monitoring dashboards set up
Next steps could include:
- Setting up specific Mattermost monitoring
- Adding Ollama monitoring
- Creating custom Grafana dashboards
- Setting up alerting rules
- Implementing backup solutions
- Monitor token per second
Remember to regularly update all components and monitor system resources to ensure everything runs smoothly. Setting up a Self-Hosted Server Stack: Mattermost, OpenWebUI, and Monitoring