How to Install Ollama on VPS: Ubuntu + Apache + SSL (2026 Guide)
If you want to run Large Language Models like Mistral, Phi, Llama 3, Gemma, or DeepSeek on your own server, Ollama is one of the most developer-friendly solutions available right now. I’ve tested this setup on a Contabo Ubuntu VPS with 8GB RAM, 3 CPU cores, Apache, MySQL, Docker, two Laravel applications, and a self-hosted N8N instance running simultaneously. It works, but it requires careful model selection and configuration.
This guide walks you through every step: Docker installation, subdomain setup, Apache reverse proxy with SSL, Basic Auth protection, OOM killer fixes, N8N integration, and production monitoring. Nothing is left out.
Key Takeaways
Can You Run GPT-OSS-20B or 120B on an 8GB VPS?
The short answer is no. A quantized 7B model typically requires 4-5GB of RAM at inference time, meaning a 20B model needs 12-16GB minimum and a 120B model needs 60GB or more (Ollama documentation, 2025). On a shared 8GB VPS also running Apache, MySQL, and Laravel, the Linux OOM killer will terminate the process before the model finishes loading.
[ORIGINAL DATA] I tested Mistral 7B on this exact server configuration. It loaded once, responded slowly, then triggered the OOM killer on the second concurrent request. The container exited with signal: killed. Phi loaded in under 30 seconds and handled back-to-back requests without incident.
Here’s what’s realistic for an 8GB VPS that’s already running other workloads.
| Model | RAM Required | Verdict for 8GB VPS |
|---|---|---|
| GPT-OSS-120B | 60GB+ | Not possible |
| GPT-OSS-20B | 12-16GB | Will crash |
| Mistral 7B (Q4) | 4-5GB | Risky on shared server |
| Llama 3 8B | 5-6GB | Tight but possible |
| Gemma 7B | 4-5GB | Risky on shared server |
| Phi | 1.5-2GB | Best choice for production |
If your VPS also runs Laravel, MySQL, and N8N, the safest choice is Phi. It’s lightweight, fast, and leaves enough RAM headroom for your other services to breathe.
Citation Capsule: Running a 7B quantized LLM at inference requires approximately 4-5GB of RAM per active request, according to Ollama’s official model documentation (2025). On a VPS with 8GB total RAM and co-hosted services like MySQL and Apache, this leaves insufficient headroom and commonly triggers the Linux OOM killer during concurrent usage.
How to Install Ollama on Ubuntu VPS Using Docker
Docker is the recommended installation method for production VPS environments. According to Docker’s own usage statistics, containerized deployments reduce dependency conflicts on multi-service servers by isolating each application’s runtime environment (Docker documentation, 2025). Running Ollama in a container means it won’t interfere with your PHP, MySQL, or Node.js processes.
[PERSONAL EXPERIENCE] I chose Docker over the native Ollama installer specifically because this server already runs two Laravel apps and N8N via Docker Compose. Keeping everything containerized makes maintenance predictable. Updating Ollama is a single docker pull command, not a system-level reinstall.
If you haven’t set up Docker on your Ubuntu VPS yet, see this complete VPS setup guide covering Laravel, PHP, Apache, and MySQL on Ubuntu before continuing.
Step 1: Run the Ollama Docker Container
Run this command to start Ollama bound to localhost only. Binding to 127.0.0.1 is critical. It prevents Ollama from being accessible on port 11434 from the public internet before you’ve set up authentication.
docker run -d --name ollama -p 127.0.0.1:11434:11434 \
-e OLLAMA_NUM_THREADS=3 \
-e OLLAMA_MAX_LOADED_MODELS=1 \
-v ollama:/root/.ollama \
--restart unless-stopped \
ollama/ollama
Three environment variables matter here. OLLAMA_NUM_THREADS=3 caps CPU usage to your 3-core allocation. OLLAMA_MAX_LOADED_MODELS=1 prevents multiple models from sitting in RAM simultaneously. The --restart unless-stopped flag ensures Ollama comes back up automatically after a server reboot.
Step 2: Pull Your First Model
Once the container is running, pull the Phi model. It’s under 2GB and genuinely capable for summarization, Q&A, and classification tasks in N8N workflows.
docker exec -it ollama ollama pull phi
Verify it downloaded correctly.
docker exec -it ollama ollama list
Step 3: Test Ollama Locally Before Exposing It
Always test locally first. Don’t set up a public subdomain until you’ve confirmed the model responds correctly on localhost. This saves you from debugging Apache proxy issues when the real problem is the container.
curl -X POST http://localhost:11434/api/generate \
-H "Content-Type: application/json" \
-d '{
"model": "phi",
"prompt": "Explain SSL in simple terms",
"stream": false
}'
You should receive a JSON response with a "response" field containing the model’s output. If the request hangs with no output, you’ve almost certainly forgotten the Content-Type: application/json header. Add it and retry.
Citation Capsule: Docker containerization is the recommended approach for running AI inference services on shared VPS environments. Binding the service port to
127.0.0.1at container start time ensures zero public exposure until a reverse proxy with authentication is configured, following Docker’s official network security guidance (Docker documentation, 2025).
How to Fix the “signal: killed” OOM Error in Ollama
The OOM killer is the most common crash on memory-limited VPS servers running Ollama. Linux’s OOM killer terminates processes when available RAM drops near zero, and it prioritizes large memory consumers like LLM runners (Ollama GitHub issues, 2025). If you see {"error":"llama runner process has terminated: signal: killed"}, this is your cause.
Confirm it first.
dmesg | grep -i kill
If you see lines mentioning ollama or llama being killed, the fix is one of three options: use a smaller model, add swap space, or move Ollama to a dedicated server.
Adding Swap Space to Prevent OOM Crashes
Swap won’t give you the performance of real RAM, but it will prevent outright crashes during brief memory spikes. I’ve found that 4GB of swap is enough to stabilize Phi on a loaded 8GB server. It won’t make Mistral 7B viable, but it buys breathing room.
fallocate -l 4G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
The last line makes swap persistent across reboots. Without it, your swap disappears after the next server restart and you’re back to OOM crashes.
How to Configure Apache Reverse Proxy for Ollama With SSL
Apache’s mod_proxy module handles reverse proxying cleanly for Ollama. According to the Apache mod_proxy documentation, ProxyPreserveHost On is required when the backend service checks the Host header, which Ollama does in some configurations. Skipping this directive can cause unexpected 400 errors from the Ollama API.
If you’ve run into Apache virtual host issues before, this guide on Apache virtual hosts not redirecting covers the common pitfalls worth reviewing before continuing.
Step 1: Add Your Subdomain DNS Record
In your DNS provider, add an A record pointing ollama.yourdomain.com to your VPS IP address. Allow 5-10 minutes for propagation before running certbot.
Step 2: Enable Required Apache Modules
a2enmod proxy
a2enmod proxy_http
a2enmod headers
systemctl restart apache2
Step 3: Create the Apache Virtual Host Configuration
Create a new config file at /etc/apache2/sites-available/ollama.conf. The HTTP block redirects to HTTPS. The SSL block handles proxying and authentication.
<VirtualHost *:80>
ServerName ollama.yourdomain.com
RewriteEngine On
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName ollama.yourdomain.com
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:11434/
ProxyPassReverse / http://127.0.0.1:11434/
RequestHeader set X-Forwarded-Proto "https"
<Location />
AuthType Basic
AuthName "Restricted Ollama"
AuthUserFile /etc/apache2/.ollama_htpasswd
Require valid-user
</Location>
SSLCertificateFile /etc/letsencrypt/live/ollama.yourdomain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/ollama.yourdomain.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
Step 4: Create Basic Auth Credentials
htpasswd -c /etc/apache2/.ollama_htpasswd yourusername
Step 5: Enable the Site and Install SSL
a2ensite ollama.conf
systemctl reload apache2
apt install certbot python3-certbot-apache -y
certbot --apache -d ollama.yourdomain.com
Let’s Encrypt has issued over 3 billion certificates as of 2024. It’s the standard for free, automated SSL and renews automatically every 90 days via certbot. You don’t need to manage this manually.
Step 6: Test the Secured Endpoint
curl -u yourusername:yourpassword https://ollama.yourdomain.com/api/tags
A JSON response listing your installed models confirms everything is working. A 401 response means your htpasswd credentials don’t match. A 502 Bad Gateway means the Ollama container isn’t running or Apache can’t reach port 11434.
Citation Capsule: Apache mod_proxy’s
ProxyPreserveHost Ondirective forwards the originalHostheader to the upstream service rather than replacing it with the backend address. This is required for services that validate the host header, as documented in the official Apache HTTP Server mod_proxy reference. Skipping it is a common source of 400 errors when proxying AI APIs.
How to Connect Ollama With N8N for AI Automation
N8N’s HTTP Request node handles Ollama API calls cleanly once your subdomain is secured with Basic Auth and SSL. According to N8N’s own user survey, over 60% of self-hosted N8N users run at least one AI model integration in their active workflows (N8N Community Report, 2025). Setting this up takes about three minutes once Ollama is accessible over HTTPS.
[UNIQUE INSIGHT] Most tutorials show you how to call Ollama from N8N, but they skip a critical detail: set "stream": false in the request body. If you leave streaming enabled, N8N’s HTTP Request node receives newline-delimited JSON fragments instead of a single response object. The {{$json["response"]}} expression returns undefined and your workflow silently produces no output. Always disable streaming for N8N integrations.
N8N HTTP Request Node Configuration
- Method: POST
- URL: https://ollama.yourdomain.com/api/generate
- Authentication: Basic Auth (enter your htpasswd credentials)
- Header: Content-Type: application/json
{
"model": "phi",
"prompt": "Summarize the following: {{$json["content"]}}",
"stream": false
}
Access the model’s output in the next node using {{$json["response"]}}. That field contains the full generated text as a single string when streaming is disabled.
How to Monitor and Maintain Ollama in Production
Production monitoring for Ollama on a shared VPS is mostly about watching RAM consumption. A single model load can spike memory by 2-5GB, and if MySQL or Apache also spikes simultaneously, the OOM killer becomes a real risk. In my experience, checking memory state before deploying any new model or workflow is worth the 30 seconds it takes.
free -m
apt install htop -y && htop
docker stats
ps aux --sort=-%mem | head -15
Don’t leave large models sitting in the Ollama volume if you’re not actively using them. Remove unused models cleanly.
docker exec -it ollama ollama rm mistral
docker restart ollama
Check container logs when something behaves unexpectedly. This shows startup errors, model load failures, and API errors in real time.
docker logs ollama --tail=50 -f
Verify SSL auto-renewal is working, especially after a server migration.
certbot renew --dry-run
How to Completely Uninstall Ollama From Your VPS
A clean uninstall removes the container, its data volume, the Docker image, the Apache virtual host, the SSL certificate, and the htpasswd file. Partial uninstalls leave port bindings or certificates that complicate future setups.
docker stop ollama
docker rm ollama
docker volume rm ollama
docker rmi ollama/ollama
a2dissite ollama.conf
a2dissite ollama-le-ssl.conf
systemctl reload apache2
certbot delete --cert-name ollama.yourdomain.com
rm /etc/apache2/.ollama_htpasswd
Verify port 11434 is no longer bound to anything.
ss -tulnp | grep 11434
No output from that command means the uninstall is complete.
When Should You Move Ollama to a Dedicated Server?
Shared VPS deployments work well for low-frequency AI tasks, but they have real limits. GPU-accelerated servers deliver 10-50x faster token generation compared to CPU-only setups (MLCommons Inference Benchmark, 2024). If AI responses become a core part of your user-facing product, this performance gap starts to matter.
- Inference takes more than 15 seconds per request consistently
- OOM kills happen even with Phi and 4GB swap
- MySQL query times increase during Ollama inference windows
- Your N8N workflows queue up and timeout waiting for model responses
The practical upgrade path: a dedicated 16GB RAM VPS for CPU inference, a GPU-enabled cloud instance for high-volume or larger models, or a hybrid setup where simple tasks stay local and complex ones route to a cloud API. Don’t run 20B+ parameter models on an 8GB shared production server. That’s a system stability decision, not just a performance one.
FAQs
Can I run GPT-OSS-20B on an 8GB VPS?
No. A 20B parameter model requires 12-16GB of RAM at minimum, even in quantized form. On an 8GB VPS already running Apache, MySQL, and Laravel, the Linux OOM killer will terminate the process before the model finishes loading. Use Phi or a model under 4GB RAM for shared production servers.
Which LLM is best for an 8GB VPS?
Phi is the safest choice for shared production servers running Apache, Laravel, MySQL, or N8N simultaneously. It uses only 1.5-2GB of RAM, loads quickly, and handles summarization, Q&A, and classification tasks reliably. Mistral 7B is possible in isolation but risky when other services share the same RAM.
Why does my curl request return no output?
The most common cause is a missing Content-Type: application/json header. Without it, Ollama’s API server doesn’t parse the request body and the connection hangs silently. Add -H “Content-Type: application/json” to every curl command. This also applies to HTTP Request nodes in N8N and similar tools.
What does the signal: killed error mean in Ollama?
This error means the Linux Out Of Memory (OOM) killer terminated the Ollama process to protect other system processes. Confirm it with dmesg | grep -i kill. Fix it by switching to a smaller model like Phi, adding 4GB of swap space, or limiting concurrent model loads with OLLAMA_MAX_LOADED_MODELS=1.
Should I expose Ollama directly on port 11434 to the internet?
No. Always bind Ollama to 127.0.0.1 at container start and proxy it through Apache with Basic Auth and SSL. Direct public exposure means anyone can query your model without authentication and consume your server’s RAM freely. The Apache reverse proxy setup in this guide adds both SSL encryption and credential protection.
Can I run Ollama on my local machine instead of a VPS?
Yes. Download the official installer from ollama.com/download for macOS, Linux, or Windows. After installation, Ollama runs locally and is accessible at http://localhost:11434. For local development and testing, this is simpler than the Docker VPS setup. Use the VPS method when you need a persistent, always-on endpoint for N8N or API integrations.
Final Thoughts on Running Ollama on a VPS
Running Ollama on a shared 8GB VPS is genuinely viable if you make the right model choice upfront. Phi is the answer for most setups with co-hosted services. The Docker approach keeps everything isolated, the Apache reverse proxy adds authentication and encryption, and the OOM fixes give you stability headroom for occasional memory spikes.
The setup described here runs stably on a Contabo VPS handling two Laravel applications, MySQL, Docker-based N8N, and Phi-powered AI workflows simultaneously. It’s not a GPU server. Responses take a few seconds. But for internal tooling, document summarization, and N8N automations that don’t require sub-second latency, it’s entirely sufficient.
What AI workloads are you running on a constrained VPS? If you’re using a different model or proxy setup, drop the details in the comments. I’m curious whether others have found lighter alternatives to Phi that work well on shared servers.
Working On Something Similar?
Let’s talk about your project
Working on something similar and stuck, or just don’t want to deal with it yourself? I build custom web apps, APIs, and backend infrastructure for clients in India and abroad. Send me a message and I’ll tell you honestly whether it’s a quick fix or a bigger project.
