Website feature removed
problem description
I recently did a complete reinstall on my Respberry Pi and wanted to reinstall Cobalt via Docker compose.
After the installation, I noticed that the website no longer exists and the image URL no longer exists in docker-compose.yml.
How can I fix this?
Many thanks in advance.
your instance configuration
services:
cobalt-api:
image: ghcr.io/imputnet/cobalt:10
restart: unless-stopped
container_name: cobalt-api
init: true
ports:
- 9000:9000/tcp
# if you're using a reverse proxy, uncomment the next line and remove the one above (9000:9000/tcp):
#- 127.0.0.1:9000:9000
environment:
# replace https://api.cobalt.tools/ with your instance's target url in same format
API_URL: "https://api.cobalt.tools"
# if you want to use cookies when fetching data from services, uncomment the next line and the lines under > # COOKIE_PATH: "/cookies.json"
# see docs/run-an-instance.md for more information
labels:
- com.centurylinklabs.watchtower.scope=cobalt
# if you want to use cookies when fetching data from services, uncomment volumes and next line
#volumes:
#- ./cookies.json:/cookies.json
# update the cobalt image automatically with watchtower
watchtower:
image: ghcr.io/containrrr/watchtower
restart: unless-stopped
command: --cleanup --scope cobalt --interval 900 --include-restarting
volumes:
- /var/run/docker.sock:/var/run/docker.sock
You don't need to host the frontend anymore, you can use your own instance on cobalt.tools.
https://cobalt.tools/settings/instances
You don't need to host the frontend anymore, you can use your own instance on cobalt.tools.
https://cobalt.tools/settings/instances
Ah lol. Thanks for the tip. Unfortunately, I only have one problem: I don't have a public (static) IP address. That means that the entire local docker setup is pointless now. Which is a shame.
How do you enable it without web interface ?
enable what? (selfhosted) cobalt?
by 'enable' do you mean 'use'?
Yes, web interface disappear between version 7 and 10. After update, i can't reach my self hosted website
you can use your api instance with main frontend instance: https://cobalt.tools/settings/instances#community
Thanks i read it a bit more up in this discussion, but it's that part i don't understand what to do with
just paste the instance url there
Just go it. I paste my URL there One last question. Do i also have to replace the url in docker-compose.yml or do i leave api.cobalt.tools ?
For the moment i let api.cobalt.tools but i only see that when i load my URL
cobalt":{"version":"10.1.0","url":"https://api.cobalt.tools/","startTime":"1728801652969","durationLimit":10800,"services":["bilibili","bluesky","dailymotion","facebook","instagram","loom","ok","pinterest","reddit","rutube","snapchat","soundcloud","streamable","tiktok","tumblr","twitch","twitter","vine","vimeo","vk","youtube"]},"git":{"branch":"main","commit":"c33017283d20ee9a998b7c19ad5f24fc17bdede7","remote":"imputnet/cobalt"}}
Do i also have to replace the url in docker-compose.yml
yes, you have to replace it or else tunnels (youtube & etc) won’t work
Ok, i replace API URL with my domain name. I'm also under a reverse proxy, i uncomment line 127.0.0.1:9000:9000 and comment 9000:9000/tcp but it leads me to a bad gateway 502 error
I managed to build and serve both the website and API with minor tweaks to the Dockerfile.
It's probably still a better idea to just replace the instance in https://cobalt.tools/, but hey, if really wants to host the frontend, see below (requires two arguments WEB_HOST and WEB_DEFAULT_API which turn into env vars, see docs):
FROM node:23-alpine AS base
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
FROM base AS build
WORKDIR /app
COPY . /app
RUN corepack enable && pnpm add -g serve
RUN apk add --no-cache python3 alpine-sdk
# Build backend (cobalt-api)
FROM build AS build-api
WORKDIR /app
RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
pnpm install --prod --frozen-lockfile
RUN pnpm deploy --filter=@imput/cobalt-api --prod /prod/api
# Build frontend (cobalt-web)
FROM build AS build-web
WORKDIR /app/web
RUN --mount=type=cache,id=pnpm-web,target=/pnpm/store \
pnpm install --prod=false --frozen-lockfile
ARG WEB_HOST
ARG WEB_DEFAULT_API
ENV WEB_HOST=${WEB_HOST}
ENV WEB_DEFAULT_API=${WEB_DEFAULT_API}
RUN pnpm run build
# Merge api+web results
FROM base AS final
WORKDIR /app
RUN apk add --no-cache python3
COPY --from=build-api --chown=node:node /prod/api /app
COPY --from=build-web --chown=node:node /app/web /app/web
COPY .git /app/.git
USER node
EXPOSE 9000
EXPOSE 9001
CMD [ "sh", "-c", "python3 -m http.server 9001 --directory /app/web/build & node src/cobalt" ]
For those using docker-compose here's the an example docker-compose.yml file:
services:
cobalt:
container_name: cobalt
build:
context: ./cobalt
dockerfile: Dockerfile
args:
WEB_HOST: "https://cobalt.example.com/"
WEB_DEFAULT_API: "https://cobalt-api.example.com/"
init: true
read_only: true
restart: unless-stopped
ports:
- 127.0.0.1:8000:9000 # api
- 127.0.0.1:8001:9001 # web
environment:
API_URL: "https://cobalt-api.example.com/"
API_AUTH_REQUIRED: 0
DURATION_LIMIT: 86400 # 24 hours
Not very elegant, but does its job.
You don't need to host the frontend anymore, you can use your own instance on cobalt.tools.
https://cobalt.tools/settings/instances
That's not how it works. If someone decides to bring up their own instance, there are reasons why they don't want to use the official site
That's not how it works. If someone decides to bring up their own instance, there are reasons why they don't want to use the official site
what are the reasons though? and they're still able to host it just fine, just without docker because it's a static build: https://github.com/imputnet/cobalt/tree/main/web
what are the reasons though?
Developers can change the code of the official web page at will and these changes will not be public, for example metrics for commercial purposes.
And some just physically can not use selfhosted backend, because they are behind NAT.
I could also mention the problem of foreign sites being blocked in Russia, which can accidentally cause another site to be blocked (once all sites hosted on Hetzner didn't work), but I think that's a local problem
you can't use cobalt for commercial purposes (see https://github.com/imputnet/cobalt/blob/main/web/LICENSE)
Another thread to track that feature suggestion: https://github.com/imputnet/cobalt/issues/1095
Throwing my hat in the ring - I made another container that uses BusyBox's httpd, available here. Using BusyBox's httpd means it's incredibly light (it's using 500KB of RAM as I write this). It also references the source code of cobalt as a build context, so the Dockerfile can depend on the cobalt source tree without having to maintain a fork! (Of course, I haven't tested it much, so no stability guarantees for the present or future).
You don't need to host the frontend anymore, you can use your own instance on cobalt.tools.
I made this container for a friend whose ISP is blocking access to cobalt.tools. They literally cannot use cobalt without self-hosting the frontend, because otherwise there's no frontend to connect to their self-hosted API. Please consider the users who can't use your hosted frontend.
and they're still able to host it just fine, just without docker because it's a static build
This makes sense (it's just building static files and that's not really what Docker is meant to do), but there is the arguable convenience factor. Using a Docker container keeps the instance up to date, so people don't have to continually git pull && pnpm i && pnpm run build. This is a lot easier to set and forget (especially when the sample compose for the API uses watchtower!).
The documentation to run an instance is clearly aimed at beginners - it tells you where to install Docker, tells you that nano might not exist, etc. Meanwhile, the README in the web directory just says "run pnpm run build", which might not be enough info for someone who doesn't write a lot of JavaScript. At the minimum, even if self-hosting via Docker is discouraged, it's probably a good idea to link to where to install Node.js/pnpm and how to host the built folder (e.g. a cobalt-blessed web server).
Would really like to see this added back or atleast an environment variable we can say true or false to.
you can use your api instance with main frontend instance: https://cobalt.tools/settings/instances#community
You're not able to provide a .local domain to the field, just says "unable to connect"
Honestly, this is a very strange decision to exclude the frontend and force the users to use your instance. Even weirder, given your own statement:
we believe that the future of the internet is open, which is why cobalt is source first and easily self-hostable.
That doesn't make any sense.
This is only partial self-hosting. I want to use API and frontend as one on my own server, completely disconnected with any official resources. What happens when your instance is gone? Then everyone trying to use Cobalt is out of luck?
What's even the point of hosting our own API and using your frontend? Why not just use your API as well?
I don't get it.
This is my docker compose via traefik with @NotNite solution
services:
cobalt-web:
build:
context: https://github.com/NotNite/cobalt-web-docker.git
dockerfile: Dockerfile
additional_contexts:
cobalt-src: https://github.com/imputnet/cobalt.git
args:
WEB_HOST: "https://cobalt.acme.com"
WEB_DEFAULT_API: "https://cobaltapi.acme.com"
container_name: cobalt-web
labels:
- traefik.enable=true
- traefik.http.routers.cobalt.entrypoints=web,websecure
- traefik.http.routers.cobalt.rule=Host(`cobalt.acme.com`)
- traefik.http.routers.cobalt.tls=true
- traefik.http.routers.cobalt.tls.certresolver=production
- traefik.docker.network=traefik_default # Specify the correct network
- traefik.http.services.cobalt.loadbalancer.server.port=3000
networks:
- traefik_default
cobalt:
image: ghcr.io/imputnet/cobalt:11
init: true
read_only: true
restart: unless-stopped
container_name: cobalt
environment:
# replace https://api.url.example/ with your instance's url
# or else tunneling functionality won't work properly
API_URL: "https://cobaltapi.acme.com"
labels:
- traefik.enable=true
- traefik.http.routers.cobaltapi.entrypoints=web,websecure
- traefik.http.routers.cobaltapi.rule=Host(`cobaltapi.acme.com`)
- traefik.http.routers.cobaltapi.tls=true
- traefik.http.routers.cobaltapi.tls.certresolver=production
- traefik.docker.network=traefik_default # Specify the correct network
- traefik.http.services.cobaltapi.loadbalancer.server.port=9000
networks:
- traefik_default
networks:
traefik_default:
external: true