Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ref!: enable static builds #10

Merged
merged 8 commits into from
Oct 22, 2023
Merged

ref!: enable static builds #10

merged 8 commits into from
Oct 22, 2023

Conversation

coolaj86
Copy link
Contributor

@coolaj86 coolaj86 commented Oct 21, 2023

  • switch from adapter-node to adapter-static
  • rename ENDPOINT to API_BASE_URL to follow common convention and avoid confusing with webserver vs api server
  • match on /api prefix to more easily allow control of Reverse Proxy routes from Web Server to API Server

Preview Documentation

https://github.com/coolaj86/ollama-webui/tree/feat-static#how-to-build-for-static-deployment

How to build

git clone git@github.com:ollama-webui/ollama-webui.git
pushd ./ollama-webui/
npm run build

Example Caddyfile

  • Reverse Proxy to localhost:11434
  • Serve ./build/
# replace localhost with example.com or whatever
localhost {
    handle /api/* {
        reverse_proxy localhost:11434
    }

    file_server {
        root ./build/
    }
}
caddy run --config ./Caddyfile

with Working CORS Snippet

# CORS Preflight (OPTIONS) + Request (GET, POST, PATCH, PUT, DELETE)
(cors-api) {
	@match-cors-api-preflight method OPTIONS
	handle @match-cors-api-preflight {
		header {
			Access-Control-Allow-Origin "{http.request.header.origin}"
			Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE, OPTIONS"
			Access-Control-Allow-Headers "Origin, Accept, Authorization, Content-Type, X-Requested-With"
			Access-Control-Allow-Credentials "true"
			Access-Control-Max-Age "3600"
			defer
		}
		respond "" 204
	}

	@match-cors-api-request {
		not {
			header Origin "{http.request.scheme}://{http.request.host}"
		}
		header Origin "{http.request.header.origin}"
	}
	handle @match-cors-api-request {
		header {
			Access-Control-Allow-Origin "{http.request.header.origin}"
			Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE, OPTIONS"
			Access-Control-Allow-Headers "Origin, Accept, Authorization, Content-Type, X-Requested-With"
			Access-Control-Allow-Credentials "true"
			Access-Control-Max-Age "3600"
			defer
		}
	}
}

# replace localhost with example.com or whatever
localhost {
	## HTTP Basic Auth
	## (uncomment to enable)
	# basicauth {
	# 	# see .example.env for how to generate tokens
	# 	{env.OLLAMA_API_ID} {env.OLLAMA_API_TOKEN_DIGEST}
	# }

	handle /api/* {
		# Comment to disable CORS
		import cors-api

		reverse_proxy localhost:11434
	}

	# Same-Origin Static Web Server
	file_server {
		root ./build/
	}
}

@tjbck
Copy link
Contributor

tjbck commented Oct 21, 2023

Looking good! Great work on enabling the static build. Could you also please verify that it functions seamlessly with Docker? It would be beneficial to ensure compatibility across different environments. Thanks!

@tjbck
Copy link
Contributor

tjbck commented Oct 21, 2023

Additionally, I also suggest providing users with the option to bypass the reverse proxy, allowing direct usage of the ollama API_ENDPOINT (https://localhost:11434/api). This will ensure flexibility for users while maintaining a straightforward setup process. Thank you for your efforts on this!

@coolaj86
Copy link
Contributor Author

I don't use Docker, but I can verify that both npm run dev and npm run build are working, which means that the docker bits should still be working since it's just a node image, which I believe is just an ubuntu image.

Help Needed

Here's where I need help:

I don't understand how the svelte environment system works and it seems to behave differently between adaptor-node and adapter-static as well as between npm run dev and npm run build.

This is what should happen:

# this should build from `src/lib/constants.ts`
npm run build
# this should use the ENV
API_SERVER=https://localhost/api npm run build
# this should have access to `${location.protocol}` and `${location.host}`
npm run dev

I'm not sure how to get that behavior. That needs someone with Svelte expertise, which I absolutely am not.

I'm very familiar with Linux and Node and JavaScript, but this is doing proprietary things, not following any normal conventions. (I believe Svelte is is completely its own language that just happens to use JS syntax)

@tjbck
Copy link
Contributor

tjbck commented Oct 21, 2023

@coolaj86

I've just pushed a few commits and attempted to align the behaviour as per your requirements. If there are any discrepancies or if I've misunderstood any part of your request, please don't hesitate to let me know.

@tjbck
Copy link
Contributor

tjbck commented Oct 21, 2023

Forgot to mention, to build with the environment variable, please run:

OLLAMA_API_ENDPOINT="http://[Your Ollama URL]/api" npm run build

This should run with the specified environment variable. Let me know if you have any questions.

.gitignore Outdated Show resolved Hide resolved
README.md Outdated
- 💻 **Code Syntax Highlighting**: Enjoy enhanced code readability with our syntax highlighting feature.
- 🔗 **External Ollama Server Connection**: Link to the model when Ollama is hosted on a different server via the environment variable -e OLLAMA_ENDPOINT="http://[insert your Ollama address]".

- 🔗 **External Ollama Server Connection**: You can seamlessly connect to an external Ollama server hosted on a different address by setting the environment variable during the Docker build process. Execute the following command to include the Ollama API endpoint in the Docker image: `docker build --build-arg OLLAMA_API_ENDPOINT="http://[Your Ollama URL]/api" -t ollama-webui .`.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding is that there is no Ollama API, but rather Ollama uses the ChatGPT API, so calling it OLLAMA may be a bit of a misnomer.

That said, I may be wrong, and I could see a future in which OLLAMA begins to add its own features to create a separate API (maybe that's already the case with /api/tags? Or maybe that's how GPT distinguishes between 3, 3.5, 4, etc too?)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm uncertain about your point regarding Ollama's use of the ChatGPT API. Could you please provide further clarification? Ollama functions locally and relies on API calls to access the downloaded models.

Copy link
Contributor Author

@coolaj86 coolaj86 Oct 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My point is that it's like S3. Whether you're using Amazon or Digital Ocean or Minio, the ENVs are always named according to S3 because S3 is a protocol more than it is a specific product.

S3_REGION=...
S3_BUCKET=...
S3_PREFIX=...
S3_KEY=...

It would be more confusing to do something like

DIGITAL_OCEAN_BUCKET=...

Because everyone just knows it as "S3" regardless of who is actually providing the service.

Likewise, the GPT is generic. Lots and lots of tools are being built that either provide as a service or consume as a client the GPT API.

So naming it OLLAMA_API_ENDPOINT is actually confusing - it makes it sound like it's NOT compatible with GPT, but actually it is.

So if someone had another client product that works with GPT and they wanted to try it with ollama, it would be much more consistent for it to either not carry the protocol name at all API_ENDPOINT, or to carry the generic protocol name GPT_API_ENDPOINT.

# confusing, sounds like there's a new API that's incompatible with GPT
OLLAMA_API_ENDPOINT=...

# clear, this is a generic, GPT-compatible Chat UI that relies on the GPT API
GPT_API_ENDPOINT=...

# not as clear, but at least not confusing
API_ENDPOINT

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had seen is some of the ollama or mistral documentation that they use the GPT API, but in looking at https://platform.openai.com/docs/api-reference/fine-tuning, it doesn't appear to be the case from what I can see.

Copy link
Contributor

@tjbck tjbck Oct 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see what you mean but I think you might be misunderstanding what Ollama is offering. FYI, Ollama does not make any requests to proprietary OpenAI GPT-related APIs and everything is processed on a local machine, hence needing to download LLMs locally beforehand (it can also be operated offline!). Additionally, Ollama WebUI only supports Ollama APIs at the moment, so I believe it's appropriate to use the name "OLLAMA_API_ENDPOINT" for the env variable.

If you have any other questions regarding Ollama to help you understand how it works, feel free to ask, I'll do my best to answer to the best of my ability! (discord [at]timbk) Thanks for the explanation though!

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tjbck your discord handle appears to be my GitHub account name. If you tag it with the @ I automatically get notifications for this whole discussion. Just wanted to make you aware and commenting here was the only option I saw.
Cool project btw and have a nice Sunday guys!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, so sorry 😅. Thanks for your understanding. Have a good day as well!

Copy link
Contributor Author

@coolaj86 coolaj86 Oct 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it doesn't make requests to OpenAI's GPT, but I was under the impression that it used the same API signatures.

After checking the documentation and API calls, it looks like that was not correct, or I misunderstood what I had read.

Agreed, OLLAMA_* is the best way to go.

@tjbck
Copy link
Contributor

tjbck commented Oct 22, 2023

@coolaj86 Is everything working as it should? everything lgtm! Will merge this branch once you confirm everything is working as intended for you.

@coolaj86
Copy link
Contributor Author

I'm just now taking a look at this again.

@coolaj86 coolaj86 force-pushed the feat-static branch 7 times, most recently from bc8f80a to 49443f7 Compare October 22, 2023 07:05
@tjbck tjbck requested review from tjbck and removed request for tjbck October 22, 2023 07:20
@coolaj86
Copy link
Contributor Author

coolaj86 commented Oct 22, 2023

Okay, I believe I've adequately tested and documented everything.

Also:

  • renamed .env.example to example.env so that it is immediately visible to all users
  • renamed *_API_ENDPOINT to *_API_BASE_URL to match the common convention
    (this is also what's documented in the Svelte documentation on ENVs)
  • added caddy example with HTTP Basic Auth for GitHub-style API Tokens

@coolaj86 coolaj86 changed the title WIP: enable static builds ref!: enable static builds Oct 22, 2023
@coolaj86
Copy link
Contributor Author

coolaj86 commented Oct 22, 2023

One last thing I didn't test or check:

  • if API_BASE_URL='' (empty) it should default to http://localhost:11434/api
  • if API_BASE_URL='/api' (path only) then it should be relative to the current scheme/host/port

Then the main release could be built for '' and embedded releases could be built for '/api'

It would also be nice (in another iteration) to have a setting to change it at runtime.

src/lib/constants.ts Outdated Show resolved Hide resolved
README.md Outdated
@@ -48,9 +48,10 @@ OLLAMA_HOST=0.0.0.0 OLLAMA_ORIGINS=* ollama serve

### Using Docker 🐳

```bash
docker build --build-arg OLLAMA_API_BASE_URL='http://localhost:11434/api' -t ollama-webui .
Copy link
Contributor Author

@coolaj86 coolaj86 Oct 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"explicit is better than implicit" - it means users have to reference less documentation, and have to hold less in their heads.

https://github.com/ewjoachim/zen-of-python/blob/master/zen.png

It looks "cool" to copy and paste fewer characters, but it's much more frustrating to have to reference documentation for things that aren't intuitive.

That said, now that we know that '' will work correctly, showing OLLAMA_API_BASE_URL='' would both be fewer characters and still be mostly self-documenting.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed!

@coolaj86
Copy link
Contributor Author

I just rebased this on the current main and squashed both of our most recent doc commits into one.

I think this is ready for your final review.

@tjbck
Copy link
Contributor

tjbck commented Oct 22, 2023

LGTM! Great work, Thanks a lot!

@tjbck tjbck merged commit f2bdbfa into open-webui:main Oct 22, 2023
1 check passed
@tjbck tjbck mentioned this pull request Oct 22, 2023
explorigin pushed a commit to explorigin/open-webui that referenced this pull request Feb 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants