cobalt
cobalt copied to clipboard
Add a Docker image for the web instance
problem description
Information about selfhosting a web app has been removed from the manual. https://github.com/imputnet/cobalt/blob/main/docs/run-an-instance.md The old configuration now runs 2 instances of cobalt-api.
How to selfhost new version of web app?
your instance configuration
cobalt_api:
image: ghcr.io/imputnet/cobalt:latest
container_name: cobalt_api
ports:
- 9002:9000/tcp
environment:
- API_URL=https://api.cobalt.${DOMAIN}/
restart: unless-stopped
cobalt:
image: ghcr.io/imputnet/cobalt:latest
container_name: cobalt
ports:
- 9003:9001/tcp
environment:
- WEB_URL=https://cobalt.${DOMAIN}/
- API_URL=https://api.cobalt.${DOMAIN}/
restart: unless-stopped
They answered me in Discord: You can't as of right now.
You'd have to set your own instances (API) in this : https://cobalt.tools/settings/instances
I personally stay on v7 for now, waiting (hopefully) to have someone create a docker-compose for the web facing interface.
Web must be run manually right now, but it does exist in the web directory, it's just not containerized.
You can't as of right now.
who said that? you can host it as a static build (the same way we do). you can read everything you need to know in web's readme file: https://github.com/imputnet/cobalt/blob/main/web/README.md
You can't as of right now.
who said that? you can host it as a static build (the same way we do). you can read everything you need to know in the web's readme file.
Not as a docker compose, I meant.
it is also indeed better to use the main web app with your api instance: https://cobalt.tools/settings/instances
we don't track anything and it's one less thing for you to take care of.
Not as a docker compose, I meant.
i don't think we'll be providing a docker image for frontend for now. if that ever changes, i'll try to remember to let you know.
I'm unsure why it was appropiate to go this route especially considering that this was provided before without issue.
Would you consider a PR adding this back?
Would you consider a PR adding this back?
hey, sure! if you would like to work on it, here is a general outline of how i'd envision for it to look:
- the dockerfile would be configurable during build time using the same environment variables as listed in the web readme. it wouldn't have any runtime environment variables (since they wouldn't have any effect anyways)
- the final docker image would ideally have no node.js runtime, and would just contain the build output + some lightweight web server like nginx:alpine
- it would use the same dockerfile for caching as recommended in pnpm documentation
Would you consider a PR adding this back?
hey, sure! if you would like to work on it, here is a general outline of how i'd envision for it to look:
- the dockerfile would be configurable during build time using the same environment variables as listed in the web readme. it wouldn't have any runtime environment variables (since they wouldn't have any effect anyways)
- the final docker image would ideally have no node.js runtime, and would just contain the build output + some lightweight web server like nginx:alpine
- it would use the same dockerfile for caching as recommended in pnpm documentation
The last two points should be straightforward to implement.
The first point, however, could be tricky. It’s inconvenient to have to republish a self-built variant to another registry—especially if you're using Kubernetes or Docker Swarm. Keeping it up-to-date would also be a hassle, and it rules out tools like Watchtower unless you're hosting your own fork with changes.
I'm unsure of the best approach here, but maybe providing an additional image variant alongside the static web server image or just going the node image route with a reverse proxy like NGINX in front of node could work better.
If we do want to go with the static webserver route I might take inspiration from how Piped handles this in their frontend, but this wouldn't solve issues with environment variables other than WEB_HOST and WEB_DEFAULT_API for users who want to integrate Plausible or Turnstile. This would also be the most jank approach.
@spectrapulse
[...] or just going the node image route with a reverse proxy like NGINX in front of node could work better.
one of the goals when rewriting the frontend was for it to be relatively small and simple to host from the server perspective (no processing required to serve frontend pages post-build), which unfortunately comes at the cost of runtime customizability (and i guess is also one of the reasons why there is no "official" dockerfile for it right now).
but if we once again bundle the entirety of the node project with the image (node_modules for web is ~100 MB on my machine) we are basically back to square 1, so that's why i wouldn't really consider this option to be "right" (in comparison, the static build output is just under 30 MB, and also vite mentions in their documentation explicitly not to use preview as a production server)
If we do want to go with the static webserver route I might take inspiration from how Piped handles this in their frontend, but this wouldn't solve issues with environment variables other than
WEB_HOSTandWEB_DEFAULT_APIfor users who want to integrate Plausible or Turnstile. This would also be the most jank approach.
i don't think this would work here since cobalt also uses these envs to include/omit certain parts of components (like hiding text that is not relevant if plausible is not enabled).
maybe one approach (that i'm not sure how feasible would be) would be to build the frontend at startup and then get rid of the whole build environment and just serve the static files, which isn't really ideal, but it would work i guess
In case anyone needs a docker image right now, I've made a basic one here: https://github.com/ggtylerr/globe/blob/master/services/cobalt-template/Dockerfile Do note that the copy paths would need to be changed if you aren't using the repo. It's just a matter of changing two lines.
It's probably not suitable for a PR but in case it's used as a base, I've addressed some of the points @dumbmoron made:
- It simply uses ARG instead of environment variables. While this isn't suitable for any published images, it's straightforward when building (which we'll have to do anyways at this time.)
- For simplicity's sake this Dockerfile uses
http-serverbut it could probably be modified for nginx. - It's only for the web app at the moment but it could very easily be merged with the existing app Dockerfile.
In case anyone needs a docker image right now, I've made a basic one here: https://github.com/ggtylerr/globe/blob/master/services/cobalt-template/Dockerfile Do note that the copy paths would need to be changed if you aren't using the repo. It's just a matter of changing two lines.
It's probably not suitable for a PR but in case it's used as a base, I've addressed some of the points @dumbmoron made:
- It simply uses ARG instead of environment variables. While this isn't suitable for any published images, it's straightforward when building (which we'll have to do anyways at this time.)
- For simplicity's sake this Dockerfile uses
http-serverbut it could probably be modified for nginx.- It's only for the web app at the moment but it could very easily be merged with the existing app Dockerfile.
Yeah I've pretty much already made a local branch with the changes needed for the original requirements into the existing Dockerfile it's just that I'm still looking for a possible solution that would fit better with published images. I'm probably going to end up making a small pr that just adds this functionality which would require build-time args for plausible and turnstile but where u can still patch the domain without needing to make and host your image.
I think people who have the need for that "advanced usage" might be less bothered by having to host their own image but people who simply want to self-host cobalt for themselves won't be affected much by the current state of the project with these changes.
In case anyone needs a docker image right now, I've made a basic one here: https://github.com/ggtylerr/globe/blob/master/services/cobalt-template/Dockerfile Do note that the copy paths would need to be changed if you aren't using the repo. It's just a matter of changing two lines.
It's probably not suitable for a PR but in case it's used as a base, I've addressed some of the points @dumbmoron made:
* It simply uses ARG instead of environment variables. While this isn't suitable for any published images, it's straightforward when building (which we'll have to do anyways at this time.) * For simplicity's sake this Dockerfile uses `http-server` but it could probably be modified for nginx. * It's only for the web app at the moment but it could very easily be merged with the existing app Dockerfile.
This was super handy, thanks for sharing.
I have automated the build for this image in a GitHub Actions workflow. At an interval, the workflow checks for updates to the version number inside of web/package.json within this repository, if it has changed, a new image is built and published to the GitHub container repository - tagged with the version number from package.json.
This makes it very easy to reference within a docker compose file, and image version monitoring software like renovate and watchtower will of course pick these up as normal:
cobalt-web:
container_name: cobalt-web
depends_on:
- cobalt-api
image: ghcr.io/[your-github-user]/cobalt-web:10.4.4
restart: unless-stopped
I hope at some point we can get an official image as it was a breeze back on v7.
In this comment, I give a modified Dockerfile and a docker-compose.yml to self-host the frontend (works on latest 10.5.4): https://github.com/imputnet/cobalt/issues/768#issuecomment-2585195207.
Could this thread be re-opened to keep track of docker-composerizing a self-hostable cobalt-web instance? Thanks!
Or should we rename issue https://github.com/imputnet/cobalt/issues/768 to a more explicit title like Create docker-compose GHCR image for cobalt-web?
Unsure why this was the choice that was made, considering a lot of people want to host both the api and the web instance on their own server.
you can still self-host the web instance, it's simply no longer a docker image, because it's a static web app: https://github.com/imputnet/cobalt/tree/main/web#cobalt-web
we're open to contributions of a docker image that has dynamic env variables and doesn't bake defaults into the image
I gave it a try with the following PR https://github.com/imputnet/cobalt/pull/1366
The image runs fine, so it's already going in the right direction. ~~Cloudflare challenges fail though, probably because I have to use my own instance as per this comment https://github.com/imputnet/cobalt/issues/811#issuecomment-2751005075.~~ Would love some input, it's not yet parsing docker container env variables at runtime, & I could not find these variables already used in the frontend code.
Currently, vite still uses process.env env-vars at build time, so the docker container is not using those defined via placeholders in runtime-config.js
EDIT: running and linking my own cobalt:11 API instance to the web container image worked, no more cloudflare turnstile error! Should be good to go, please tell me if you want to handle env-vars differently and directions on how to do it.