toolkitbox

~/ / AI articles / Local LLMs on a VPS / Put nginx in front of Ollama: basic authentication, HTTPS and streaming settings

Put nginx in front of Ollama: basic authentication, HTTPS and streaming settings

Ollama listens on the server itself by default, which is the safest place for it. When another machine has to reach it, the Ollama FAQ points to a proxy server such as nginx. This article builds that setup from the nginx documentation: a password, HTTPS, the settings that matter for streamed answers, and a firewall that closes the other doors.

Published: · 5 min read · Checked against the official Ollama and nginx documentation on 2026-10-26. Directive defaults depend on the nginx version, so check the version you run.

What the Ollama FAQ says

The Ollama FAQ says that Ollama runs an HTTP server and can be exposed using a proxy server such as Nginx. Its example listens on port 80, sets a server_name, forwards requests with proxy_pass http://localhost:11434 and sets the Host header to localhost:11434.

The FAQ page that we checked does not describe any authentication for the Ollama server. That is why the password has to come from the proxy in front of it. Ollama binds 127.0.0.1 port 11434 by default, so an nginx on the same server can reach it without changing that address.

A password with basic authentication

The ngx_http_auth_basic_module limits access by checking a user name and password. Two directives do the work: auth_basic, whose string is used as the realm and which is off by default, and auth_basic_user_file, which names the password file.

DirectiveDefaultWhat the documentation says
auth_basic string | off;offThe parameter is used as the authentication realm. The value off cancels a setting inherited from a previous level.
auth_basic_user_file file;noneThe file has one name:password entry per line, and lines starting with # are comments.
  • Supported password types: crypt()-encrypted passwords and apr1 hashes, both generated with the htpasswd utility from Apache or with openssl passwd.
  • The {SCHEME}data syntax is also supported. The page says PLAIN is an example only and should not be used, and that SHA, an unsalted SHA-1, should not be used either because it is vulnerable to rainbow table attacks. SSHA is salted SHA-1.
  • The documentation's example: location / { auth_basic "closed site"; auth_basic_user_file conf/htpasswd; }

The page names htpasswd and openssl passwd but gives no commands. Commonly used forms, which are ours and not from the page, are htpasswd -c /etc/nginx/ollama.htpasswd alice, which prompts for a password, and openssl passwd -apr1, which prints a hash to paste after the user name and a colon.

HTTPS

Our reading, not a statement from the documents: basic authentication sends the password with every request, so use it only behind HTTPS. According to the nginx documentation, a server needs the ssl parameter on its listening socket, and the locations of the certificate and the private key.

DirectiveExample from the documentation
listenlisten 443 ssl;
server_nameserver_name www.example.com;
ssl_certificatessl_certificate www.example.com.crt;
ssl_certificate_keyssl_certificate_key www.example.com.key;
  • By default nginx uses ssl_protocols TLSv1.2 TLSv1.3 and ssl_ciphers HIGH:!aNULL:!MD5, so configuring them explicitly is generally not needed.
  • The private key should be stored in a file with restricted access, but it must be readable by nginx's master process.
  • If browsers report errors for a certificate from a well-known authority, the server may need to send the intermediate certificates. The server certificate must appear before the chained certificates in the combined file, or nginx fails to start with a key values mismatch error.
  • Let's Encrypt's getting-started page says that if your provider does not obtain certificates for you and you can administer your server, you can run an ACME client, and that it recommends Certbot for most people.

Settings for streamed and slow answers

A model writes its answer piece by piece, and the first piece can take a while to arrive, for example while a large model is loaded into memory. Three nginx settings decide how this looks from the outside.

DirectiveDefaultWhat the documentation says
proxy_bufferingonWhen buffering is disabled, the response is passed to the client synchronously, immediately as it is received. When it is enabled, nginx saves the response into buffers first.
proxy_read_timeout60sThe timeout is set only between two successive read operations, not for the whole response. If the proxied server does not transmit anything within this time, the connection is closed.
proxy_http_version1.1 since nginx 1.29.7Before 1.29.7 the default was 1.0. Version 1.1 or 2 is recommended for keepalive connections.

Our reading, not a statement from the documents: to see an answer appear as it is written, turn proxy_buffering off for the Ollama location, and if the model can stay silent for more than a minute while it loads, raise proxy_read_timeout. Setting proxy_http_version 1.1 explicitly is harmless on every version.

Put it together

This configuration combines the directives above for one server name. It is our composition from the documented directives, so test it with nginx -t before you reload.

LineWhy
server {one server block for the Ollama name
listen 443 ssl;HTTPS
server_name ollama.example.com;your own name
ssl_certificate /etc/ssl/ollama.crt;the certificate, with intermediates after it
ssl_certificate_key /etc/ssl/ollama.key;the private key, readable only as needed
auth_basic "ollama";turns the password on
auth_basic_user_file /etc/nginx/ollama.htpasswd;where the users are kept
location / {everything goes to Ollama
proxy_pass http://localhost:11434;from the Ollama FAQ
proxy_set_header Host localhost:11434;from the Ollama FAQ
proxy_http_version 1.1;recommended for keepalive
proxy_buffering off;so the answer streams
proxy_read_timeout 300s;allows a slow first piece
}end of location
}end of server

Close the other doors

The proxy only helps if people cannot reach Ollama or the application behind it another way. Ollama stays on its default address, and a firewall admits only the addresses you use.

TaskCommand from the Ubuntu documentation
Turn the firewall onsudo ufw enable
Allow a portsudo ufw allow 22
Allow one address to one portsudo ufw allow proto tcp from 192.168.0.2 to any port 22
Allow a whole subnetreplace the address with 192.168.0.0/24
Check the statesudo ufw status

The Ubuntu page says UFW is initially disabled. It has no warning about locking yourself out over SSH. Our recommendation: allow your SSH port before you enable the firewall on a server that you reach remotely, and allow port 443 only from the addresses that need it.

Sources

Read next