mirror of
https://github.com/sergi0g/cup.git
synced 2025-11-08 13:13:49 -05:00
Add documentation
This commit is contained in:
20
.github/workflows/docs.yml
vendored
Normal file
20
.github/workflows/docs.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
name: Deploy github pages
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- 'docs/**'
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- run: cd docs/
|
||||||
|
- name: Install dependencies
|
||||||
|
run: pnpm install
|
||||||
|
- name: Build
|
||||||
|
run: pnpm build
|
||||||
|
- name: Publish
|
||||||
|
uses: actions/upload-pages-artifact@v3
|
||||||
|
with:
|
||||||
|
path: out/
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1 +1,4 @@
|
|||||||
/target
|
/target
|
||||||
|
/docs/.next
|
||||||
|
/docs/node_modules
|
||||||
|
/docs/out
|
||||||
BIN
docs/assets/blue_theme.png
Normal file
BIN
docs/assets/blue_theme.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 83 KiB |
BIN
docs/assets/cup.gif
Normal file
BIN
docs/assets/cup.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 136 KiB |
BIN
docs/assets/gray_theme.png
Normal file
BIN
docs/assets/gray_theme.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 87 KiB |
BIN
docs/assets/old_cup.png
Normal file
BIN
docs/assets/old_cup.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 64 KiB |
16
docs/next.config.js
Normal file
16
docs/next.config.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
const withNextra = require("nextra")({
|
||||||
|
theme: "nextra-theme-docs",
|
||||||
|
themeConfig: "./theme.config.jsx",
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = withNextra(
|
||||||
|
{
|
||||||
|
output: "export",
|
||||||
|
images: {
|
||||||
|
unoptimized: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// If you have other Next.js configurations, you can pass them as the parameter:
|
||||||
|
// module.exports = withNextra({ /* other next.js config */ })
|
||||||
20
docs/package.json
Normal file
20
docs/package.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"dev": "next",
|
||||||
|
"build": "next build",
|
||||||
|
"start": "next start"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@tabler/icons-react": "^3.11.0",
|
||||||
|
"next": "^14.2.5",
|
||||||
|
"nextra": "^2.13.4",
|
||||||
|
"nextra-theme-docs": "^2.13.4",
|
||||||
|
"react": "^18.3.1",
|
||||||
|
"react-dom": "^18.3.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"autoprefixer": "^10.4.19",
|
||||||
|
"postcss": "^8.4.39",
|
||||||
|
"tailwindcss": "^3.4.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
10
docs/pages/_app.mdx
Normal file
10
docs/pages/_app.mdx
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import '../styles.css';
|
||||||
|
import 'nextra-theme-docs/style.css';
|
||||||
|
|
||||||
|
export default function App({ Component, pageProps }) {
|
||||||
|
return (
|
||||||
|
<main>
|
||||||
|
<Component {...pageProps} />
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
17
docs/pages/_meta.json
Normal file
17
docs/pages/_meta.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"docs": {
|
||||||
|
"title": "Documentation",
|
||||||
|
"type": "page"
|
||||||
|
},
|
||||||
|
"about": {
|
||||||
|
"title": "About",
|
||||||
|
"type": "page",
|
||||||
|
"theme": {
|
||||||
|
"typesetting": "article"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"index": {
|
||||||
|
"title": "Home",
|
||||||
|
"display": "hidden"
|
||||||
|
}
|
||||||
|
}
|
||||||
110
docs/pages/about.mdx
Normal file
110
docs/pages/about.mdx
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
import Image from "next/image";
|
||||||
|
import old_cup from "../assets/old_cup.png"
|
||||||
|
import web_ui from "../assets/blue_theme.png"
|
||||||
|
|
||||||
|
# About
|
||||||
|
Cup is a small utility that checks for updates to Docker containers. The logic is simple: Cup checks the locally pulled images' digests against the latest ones in their registry. It then presents the results in a pretty interface. Here's the story:
|
||||||
|
|
||||||
|
## How it started
|
||||||
|
|
||||||
|
I got the basic idea for Cup a long time ago. I was looking at [Homepage's list of widgets](https://gethomepage.dev/latest/widgets/) when I discovered [What's Up Docker?](https://github.com/fmartinou/whats-up-docker) (referred to as WUD from now on).
|
||||||
|
|
||||||
|
According to the docs:
|
||||||
|
|
||||||
|
> What's up Docker ( aka WUD ) gets you notified when a new version of your Docker Container is available.
|
||||||
|
|
||||||
|
It supports the most common registries, has integrations with IFTTT, Slack, Telegram and other apps/services for notifications or triggering workflows and also has the option to automatically update containers, like [Watchtower](https://github.com/containrrr/watchtower).
|
||||||
|
|
||||||
|
I was managing my homelab myself at that time and the only way to check if I had updates was log in to the server and manually try to pull the images for *every single compose file*. WUD seemed to solve the problem nicely, so I decided to give it a try. I never used automatic updates or notifications, but I configured it and let it run.
|
||||||
|
|
||||||
|
After deploying it and setting up my reverse proxy, I was greeted with this dashboard:
|
||||||
|
<Image src="https://github.com/fmartinou/whats-up-docker/blob/master/docs/ui/ui.png?raw=true" alt="A screenshot of WUD's web UI, from the docs" />
|
||||||
|
It was working fine, but... the UI was not what I expected. It really reminds me of some really old Android app (I hope I didn't offend anyone). That was strike one. Nevertheless, I left it running. It was useful after all.
|
||||||
|
|
||||||
|
A few days later I was pulling some docker images, when I got this error message:
|
||||||
|
|
||||||
|
> You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limits.
|
||||||
|
|
||||||
|
Wait a minute. What was that? I'd never encountered a message like this before. I thought "Weird. Maybe I pulled too many images today?". So I decided to finish those updates another day.
|
||||||
|
|
||||||
|
Next time I tried, same issue. "What the heck is happening?" I thought. The only change I'd made to my homelab at that time was installing WUD. So I stopped it. And that's where the problems ended.
|
||||||
|
|
||||||
|
The problem was clearly related to WUD, so I started trying to find what was going wrong. That was when I came upon [this page from Docker's documentation](https://docs.docker.com/docker-hub/download-rate-limit/). I noticed 2 things:
|
||||||
|
|
||||||
|
> A pull request is defined as up to two `GET` requests on registry manifest URLs (`/v2/*/manifests/*`)
|
||||||
|
|
||||||
|
> `HEAD` requests aren't counted.
|
||||||
|
|
||||||
|
There were also helpful instructions on how to check the rate limit:
|
||||||
|
|
||||||
|
```
|
||||||
|
sergio@desktop:~ $ TOKEN=$(curl "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimitpreview/test:pull" | jq -r .token)
|
||||||
|
% Total % Received % Xferd Average Speed Time Time Time Current
|
||||||
|
Dload Upload Total Spent Left Speed
|
||||||
|
100 5429 0 5429 0 0 7431 0 --:--:-- --:--:-- --:--:-- 7426
|
||||||
|
|
||||||
|
sergio@desktop:~ $ curl --head -H "Authorization: Bearer $TOKEN" https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/latest
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
content-length: 2782
|
||||||
|
content-type: application/vnd.docker.distribution.manifest.v1+prettyjws
|
||||||
|
docker-content-digest: sha256:767a3815c34823b355bed31760d5fa3daca0aec2ce15b217c9cd83229e0e2020
|
||||||
|
docker-distribution-api-version: registry/2.0
|
||||||
|
etag: "sha256:767a3815c34823b355bed31760d5fa3daca0aec2ce15b217c9cd83229e0e2020"
|
||||||
|
date: Tue, 16 Jul 2024 12:13:17 GMT
|
||||||
|
strict-transport-security: max-age=31536000
|
||||||
|
ratelimit-limit: 100;w=21600
|
||||||
|
ratelimit-remaining: 100;w=21600
|
||||||
|
docker-ratelimit-source: <REDACTED>
|
||||||
|
```
|
||||||
|
|
||||||
|
The rate limit is there, just like in the docs, but do you see something else interesting? Look at this header: `docker-content-digest: sha256:767a3815c34823b355bed31760d5fa3daca0aec2ce15b217c9cd83229e0e2020`
|
||||||
|
|
||||||
|
This is an image's digest. Can we check for updates by making `HEAD` requests to Docker Hub?
|
||||||
|
|
||||||
|
The answer is yes:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ set TOKEN $(curl -H "Accept: application/vnd.docker.distribution.manifest.list.v2+json" "https://auth.docker.io/token?service=registry.docker.io&scope=repository:library/busybox:pull" | jq -r .token)
|
||||||
|
$ curl --head -H "Authorization: Bearer $TOKEN" -H "Accept: application/vnd.docker.distribution.manifest.v2.list+json" https://registry-1.docker.io/v2/library/busybox/manifests/latest
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
content-length: 6761
|
||||||
|
content-type: application/vnd.oci.image.index.v1+json
|
||||||
|
docker-content-digest: sha256:9ae97d36d26566ff84e8893c64a6dc4fe8ca6d1144bf5b87b2b85a32def253c7
|
||||||
|
docker-distribution-api-version: registry/2.0
|
||||||
|
etag: "sha256:9ae97d36d26566ff84e8893c64a6dc4fe8ca6d1144bf5b87b2b85a32def253c7"
|
||||||
|
date: Tue, 16 Jul 2024 12:17:49 GMT
|
||||||
|
strict-transport-security: max-age=31536000
|
||||||
|
ratelimit-limit: 100;w=21600
|
||||||
|
ratelimit-remaining: 100;w=21600
|
||||||
|
docker-ratelimit-source: <REDACTED>
|
||||||
|
```
|
||||||
|
|
||||||
|
And then we can compare that with the digest of the image stored locally:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ docker inspect busybox:latest | jq -r '.[0].RepoDigests[0]'
|
||||||
|
busybox@sha256:9ae97d36d26566ff84e8893c64a6dc4fe8ca6d1144bf5b87b2b85a32def253c7
|
||||||
|
```
|
||||||
|
|
||||||
|
Notice how the 2 digests are the same. We can check for image updates without using up the rate limit!
|
||||||
|
|
||||||
|
That's when I got the idea of writing a program to do this automatically.
|
||||||
|
|
||||||
|
## The birth of Cup
|
||||||
|
|
||||||
|
I initially intended to write a simple bash script but I chose not to for the following reasons:
|
||||||
|
|
||||||
|
- I wanted something more than a simple script. WUD has a web UI and support for so many integrations! I had to match that some way!
|
||||||
|
- Bash is slow and I was learning Rust at the time, so I wanted to practice (and make a proper project)
|
||||||
|
|
||||||
|
It started out as a small CLI that could either check a single image, or check all the images.
|
||||||
|
<Image src={old_cup} alt="The initial version of Cup" />
|
||||||
|
It also couldn't check for updates to images not from Docker Hub, lacked a web UI and generally had many limitations. But it proved it could be done, quickly and efficiently. The binary was just 5 MB and took about 5 seconds for ~90 images on my development machine. That's insane!
|
||||||
|
|
||||||
|
A few days later, I decided to completely rewrite it. I tried to write clean code, split it in files and fix every limitation from the previous version. I'm quite close. Here's what it looks like now:
|
||||||
|
<Image src="https://github.com/sergi0g/cup/blob/main/screenshots/cup.gif?raw=true" alt="Cup's old CLI" />
|
||||||
|
It also has a statically rendered web UI making it ideal for self hosting.
|
||||||
|
<Image src={web_ui} alt="Cup's web UI"/>
|
||||||
|
With some optimization (well ok, maybe a lot), the binary is 5 MB and that means I finally don't have to wait forever to pull the Docker image! Finally something that works nicely with my 1.5 MB/s internet connection! (Thank you powerline!)
|
||||||
|
|
||||||
|
Now go ahead and try it out!
|
||||||
8
docs/pages/docs/_meta.json
Normal file
8
docs/pages/docs/_meta.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"index": {
|
||||||
|
"title": "Introduction"
|
||||||
|
},
|
||||||
|
"nightly": {
|
||||||
|
"title": "Using the latest version"
|
||||||
|
}
|
||||||
|
}
|
||||||
98
docs/pages/docs/configuration.mdx
Normal file
98
docs/pages/docs/configuration.mdx
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
import Image from "next/image";
|
||||||
|
import { Steps, Callout } from "nextra-theme-docs";
|
||||||
|
import blue from "../../assets/blue_theme.png"
|
||||||
|
import gray from "../../assets/gray_theme.png"
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
|
||||||
|
## Custom docker socket
|
||||||
|
|
||||||
|
Sometimes, there may be a need to specify a custom docker socket. Cup provides the `-s` option for this.
|
||||||
|
|
||||||
|
For example, if using Podman, you might do
|
||||||
|
|
||||||
|
```
|
||||||
|
$ cup -s /run/user/1000/podman/podman.sock check
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration file
|
||||||
|
|
||||||
|
Cup has an option to be configured from a configuration file named `cup.json`.
|
||||||
|
|
||||||
|
<Steps>
|
||||||
|
### Create the configuration file
|
||||||
|
Create a `cup.json` file somewhere on your system. For binary installs, a path like `~/.config/cup.json` is recommended.
|
||||||
|
If you're running with Docker, you can create a `cup.json` in the directory you're running cup and mount it into the container. _In the next section you will need to use the path where you **mounted** the file_
|
||||||
|
|
||||||
|
### Configure Cup from the configuration file
|
||||||
|
Follow the guides below (Theme and Authentication) to make your `cup.json`
|
||||||
|
|
||||||
|
Here's a full example:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
authentication: {
|
||||||
|
"ghcr.io": "<YOUR_TOKEN_HERE>",
|
||||||
|
"registry-1.docker.io": "<YOUR_TOKEN_HERE>"
|
||||||
|
},
|
||||||
|
theme: "blue"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Run Cup with the new configuration file
|
||||||
|
To let Cup know that you'd like it to use a custom configuration file, you can use the `-c` flag, followed by the _absolute_ path of the file.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ cup -c /home/sergio/.config/cup.json check
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker run -tv /var/run/docker.sock:/var/run/docker.sock -v /home/sergio/.config/cup.json:/config/cup.json ghcr.io/sergi0g/cup -c /config/cup.json serve
|
||||||
|
```
|
||||||
|
</Steps>
|
||||||
|
|
||||||
|
## Theme (server only)
|
||||||
|
|
||||||
|
Cup initially had a blue theme which looked like this:
|
||||||
|
|
||||||
|
<Image alt="Screenshot of blue theme" src={blue} />
|
||||||
|
|
||||||
|
This was replaced by a more neutral theme which is now the default:
|
||||||
|
|
||||||
|
<Image alt="Screenshot of neutral theme" src={gray} />
|
||||||
|
|
||||||
|
However, you can get the old theme back by adding the `theme` key to your `cup.json`
|
||||||
|
Available values are `default` and `blue`.
|
||||||
|
|
||||||
|
Here's an example:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"theme": "blue",
|
||||||
|
// Other options
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Authentication
|
||||||
|
|
||||||
|
<Callout emoji="⛔">
|
||||||
|
The features described in this section have not been implemented yet.
|
||||||
|
</Callout>
|
||||||
|
|
||||||
|
Some registries (or specific images) may require you to be authenticated. For those, you can modify `cup.json` like this:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"authentication": {
|
||||||
|
"<YOUR_REGISTRY_DOMAIN_1>": "<YOUR_TOKEN_1>",
|
||||||
|
"<YOUR_REGISTRY_DOMAIN_2>": "<YOUR_TOKEN_2>"
|
||||||
|
// ...
|
||||||
|
},
|
||||||
|
// Other options
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
You can use any registry, like `ghcr.io`, `quay.io`, `gcr.io`, etc.
|
||||||
|
|
||||||
|
<Callout emoji="⚠️">
|
||||||
|
For Docker Hub, use `registry-1.docker.io`
|
||||||
|
</Callout>
|
||||||
26
docs/pages/docs/index.mdx
Normal file
26
docs/pages/docs/index.mdx
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import Image from "next/image";
|
||||||
|
import cup from "../../assets/cup.gif";
|
||||||
|
import { Cards, Card } from "nextra-theme-docs";
|
||||||
|
import { IconBrandDocker, IconPackage } from "@tabler/icons-react";
|
||||||
|
|
||||||
|
# Introduction
|
||||||
|
|
||||||
|
<Image src={cup} unoptimized />
|
||||||
|
|
||||||
|
Cup is a lightweight alternative to [What's up Docker?](https://github.com/fmartinou/whats-up-docker) written in Rust.
|
||||||
|
|
||||||
|
# Features ✨
|
||||||
|
|
||||||
|
- 🚀 Extremely fast. Cup takes full advantage of your CPU and is hightly optimized, resulting in lightning fast speed. On my test machine, it took ~6 seconds for 70 images.
|
||||||
|
- Supports most registries, including Docker Hub, ghcr.io, Quay, lscr.io and even Gitea (or derivatives)
|
||||||
|
- Doesn't exhaust any rate limits. This is the original reason I created Cup. It was inspired by What's up docker? which would always use it up.
|
||||||
|
- Beautiful CLI and web interface for checking on your containers any time.
|
||||||
|
- The binary is tiny! At the time of writing it's just 4.7 MB. No more pulling 100+ MB docker images for a such a simple program.
|
||||||
|
- JSON output for both the CLI and web interface so you can connect Cup to integrations. It's easy to parse and makes webhooks and pretty dashboards simple to set up!
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
|
||||||
|
<Cards>
|
||||||
|
<Card icon={<IconBrandDocker />} title="With Docker" href="/docs/installation/docker" />
|
||||||
|
<Card icon={<IconPackage />} title="As a binary" href="/docs/installation/binary" />
|
||||||
|
</Cards>
|
||||||
8
docs/pages/docs/installation/_meta.json
Normal file
8
docs/pages/docs/installation/_meta.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"docker": {
|
||||||
|
"title": "With Docker"
|
||||||
|
},
|
||||||
|
"binary": {
|
||||||
|
"title": "As a binary"
|
||||||
|
}
|
||||||
|
}
|
||||||
25
docs/pages/docs/installation/binary.mdx
Normal file
25
docs/pages/docs/installation/binary.mdx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { Callout, Card, Steps } from "nextra-theme-docs";
|
||||||
|
import { IconFileDescription } from "@tabler/icons-react";
|
||||||
|
|
||||||
|
# As a binary
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
This guide will help you install Cup from a binary.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
<Steps>
|
||||||
|
### Download binary
|
||||||
|
Go to https://github.com/sergi0g/cup/releases/latest.
|
||||||
|
|
||||||
|
Depending on your system's architecture, choose the binary for your system. For example, for an `x86_64` machine, you should download `cup-x86_64-unknown-linux-musl`
|
||||||
|
<Callout>
|
||||||
|
You can use the command `uname -i` to find this
|
||||||
|
</Callout>
|
||||||
|
### Add binary to path
|
||||||
|
Move the binary you downloaded to a directory in your path. You can usually get a list those directories by running `echo $PATH`. On most Linux systems, moving it to `~/.local/bin` is usually enough.
|
||||||
|
</Steps>
|
||||||
|
|
||||||
|
That's it! Cup is ready to be used. Head over to the Usage page to get started.
|
||||||
|
<br />
|
||||||
|
<Card icon={<IconFileDescription />} title="Usage" href="/docs/usage" />
|
||||||
21
docs/pages/docs/installation/docker.mdx
Normal file
21
docs/pages/docs/installation/docker.mdx
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { Callout, Card } from "nextra-theme-docs";
|
||||||
|
import { IconFileDescription } from "@tabler/icons-react";
|
||||||
|
|
||||||
|
# With Docker
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
This guide will help you install Cup as a Docker container. It is the easiest installation method and also makes updating Cup very easy.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
To get started, open up a terminal and run the following command.
|
||||||
|
```bash
|
||||||
|
$ docker pull ghcr.io/sergi0g/cup
|
||||||
|
```
|
||||||
|
<Callout emoji="⚠️">
|
||||||
|
If you aren't in the `docker` group, please ensure you run all commands as a user who does. In most cases, you'll just need to prefix the `docker` commands with `sudo`
|
||||||
|
</Callout>
|
||||||
|
|
||||||
|
That's it! Cup is ready to be used. Head over to the Usage page to get started.
|
||||||
|
<br />
|
||||||
|
<Card icon={<IconFileDescription />} title="Usage" href="/docs/usage" />
|
||||||
21
docs/pages/docs/nightly.mdx
Normal file
21
docs/pages/docs/nightly.mdx
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { Callout } from "nextra-theme-docs"
|
||||||
|
|
||||||
|
# Using the latest version
|
||||||
|
|
||||||
|
The installation instructions you previously followed describe how to install Cup's stable version.
|
||||||
|
|
||||||
|
However, it is only updated when a new release is created, so if you want the latest features, you'll need to install Cup's nightly version.
|
||||||
|
|
||||||
|
Cup's nightly version always contains the latest changes in the main branch.
|
||||||
|
|
||||||
|
<Callout emoji="⚠️">
|
||||||
|
There is no guarantee that the nightly version will always work. There may be breaking changes or a bad commit and it may not work properly. Install nightly only if you know what you are doing. These instructions will assume you have the technical know-how to follow them. If you do not, please use the stable release
|
||||||
|
</Callout>
|
||||||
|
|
||||||
|
## With Docker
|
||||||
|
|
||||||
|
Instead of `ghcr.io/sergi0g/cup`, use `ghcr.io/sergi0g/cup:nightly`
|
||||||
|
|
||||||
|
## As a binary
|
||||||
|
|
||||||
|
Go to a [nightly workflow run](https://github.com/sergi0g/cup/actions/workflows/nightly.yml) and download the artifact for your system.
|
||||||
11
docs/pages/docs/usage.mdx
Normal file
11
docs/pages/docs/usage.mdx
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { IconServer, IconTerminal } from "@tabler/icons-react";
|
||||||
|
import { Cards, Card } from "nextra-theme-docs";
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
You can use Cup in 2 different ways. As a CLI or as a server. You can learn more about each mode in its corresponding page
|
||||||
|
|
||||||
|
<Cards>
|
||||||
|
<Card icon={<IconTerminal />} title="CLI" href="/docs/usage/cli" />
|
||||||
|
<Card icon={<IconServer />} title="Server" href="/docs/usage/server" />
|
||||||
|
</Cards>
|
||||||
73
docs/pages/docs/usage/cli.mdx
Normal file
73
docs/pages/docs/usage/cli.mdx
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
import Image from "next/image";
|
||||||
|
import cup from "../../../assets/cup.gif";
|
||||||
|
|
||||||
|
# CLI
|
||||||
|
|
||||||
|
Cup's CLI provides the `cup check` command.
|
||||||
|
|
||||||
|
## Basic Usage
|
||||||
|
|
||||||
|
### Check for all updates
|
||||||
|
```ansi
|
||||||
|
$ cup check
|
||||||
|
[32mnginx:alpine Update available
|
||||||
|
redis:7 Update available
|
||||||
|
redis:alpine Update available
|
||||||
|
[0m...
|
||||||
|
[34mcentos:7 Up to date
|
||||||
|
mcr.microsoft.com/devcontainers/go:0-1.19-bullseye Up to date
|
||||||
|
rockylinux:9-minimal Up to date
|
||||||
|
rabbitmq:3.11.9-management Up to date
|
||||||
|
[0m...
|
||||||
|
[90msome/deleted:image Unknown
|
||||||
|
```
|
||||||
|
|
||||||
|
### Check for updates to a specific image
|
||||||
|
```
|
||||||
|
$ cup check node:latest
|
||||||
|
node:latest has an update available
|
||||||
|
```
|
||||||
|
|
||||||
|
## Enable icons
|
||||||
|
You can also enable icons if you have a [Nerd Font](https://nerdfonts.com) installed.
|
||||||
|
|
||||||
|
<Image src={cup} unoptimized />
|
||||||
|
|
||||||
|
## JSON output
|
||||||
|
When integrating Cup with other services (e.g. webhooks or a dashboard), you may find Cup's JSON output functionality useful.
|
||||||
|
|
||||||
|
It provides some useful metrics (see [server](/docs/usage/server) for more information), along with a list of images and whether they have an update or not.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ cup check -r
|
||||||
|
{"metrics":{"update_available":4,"monitored_images":25,"unknown":1,"up_to_date":20},"images":{"ghcr.io/immich-app/immich-server:v1.106.4":false,"portainer/portainer-ce:2.20.3-alpine":false,"ghcr.io/runtipi/runtipi:v3.4.1":false,...}}
|
||||||
|
```
|
||||||
|
|
||||||
|
Here is how it would look in Typescript:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
type CupData = {
|
||||||
|
metrics: {
|
||||||
|
monitored_images: number,
|
||||||
|
up_to_date: number,
|
||||||
|
update_available: number,
|
||||||
|
unknown: number
|
||||||
|
},
|
||||||
|
images: {
|
||||||
|
[image: string]: boolean | null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage with Docker
|
||||||
|
|
||||||
|
If you're using the Docker image, just replace all occurences of `cup` in the examples with `docker run -tv /var/run/docker.sock:/var/run/docker.sock ghcr.io/sergi0g/cup`.
|
||||||
|
|
||||||
|
For example, this:
|
||||||
|
```bash /check node:latest/
|
||||||
|
$ cup check node:latest
|
||||||
|
```
|
||||||
|
becomes:
|
||||||
|
```bash /check node:latest/
|
||||||
|
$ docker run -tv /var/run/docker.sock:/var/run/docker.sock ghcr.io/sergi0g/cup check node:latest
|
||||||
|
```
|
||||||
53
docs/pages/docs/usage/server.mdx
Normal file
53
docs/pages/docs/usage/server.mdx
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import { Callout } from "nextra-theme-docs";
|
||||||
|
|
||||||
|
# Server
|
||||||
|
|
||||||
|
The server provides the `cup serve` command.
|
||||||
|
|
||||||
|
## Basic usage
|
||||||
|
|
||||||
|
```ansi
|
||||||
|
$ cup serve
|
||||||
|
[2m2024-07-17T09:08:38.724922Z [0m [32m INFO [0m [2mxitca_server::net [0m [2m: [0m Started Tcp listening on: Some(0.0.0.0:8000)
|
||||||
|
[2m2024-07-17T09:08:38.725076Z [0m [33m WARN [0m [2mxitca_server::server::future [0m [2m: [0m ServerFuture::wait is called from within tokio context. It would block current thread from handling async tasks
|
||||||
|
[2m2024-07-17T09:08:38.725248Z [0m [32m INFO [0m [2mxitca_server::worker [0m [2m: [0m Started xitca-server-worker-0
|
||||||
|
[2m2024-07-17T09:08:38.725343Z [0m [32m INFO [0m [2mxitca_server::worker [0m [2m: [0m Started xitca-server-worker-1
|
||||||
|
[2m2024-07-17T09:08:38.725580Z [0m [32m INFO [0m [2mxitca_server::worker [0m [2m: [0m Started xitca-server-worker-2
|
||||||
|
[2m2024-07-17T09:08:38.725607Z [0m [32m INFO [0m [2mxitca_server::worker [0m [2m: [0m Started xitca-server-worker-3
|
||||||
|
[2m2024-07-17T09:08:41.390783Z [0m [32m INFO [0m [1mrequest [0m [1m{ [0m [3mmethod [0m [2m= [0mGET [3muri [0m [2m= [0m/ [1m} [0m [2m: [0m [2mon_request [0m [2m: [0m serving request
|
||||||
|
[2m2024-07-17T09:08:41.390905Z [0m [32m INFO [0m [1mrequest [0m [1m{ [0m [3mmethod [0m [2m= [0mGET [3muri [0m [2m= [0m/ [1m} [0m [2m: [0m [2mon_response [0m [2m: [0m sending response
|
||||||
|
```
|
||||||
|
|
||||||
|
This will launch the server on port `8000`. To access it, visit `http://<YOUR_IP>:8000` (replace `<YOUR_IP>` with the IP address of the machine running Cup.)
|
||||||
|
|
||||||
|
<Callout>
|
||||||
|
The URL `http://<YOUR_IP>:8000/json` is also available for usage with integrations.
|
||||||
|
</Callout>
|
||||||
|
|
||||||
|
## Use a different port
|
||||||
|
|
||||||
|
Pass the `-p` argument with the port you want to use
|
||||||
|
|
||||||
|
```ansi
|
||||||
|
$ cup serve -p 9000
|
||||||
|
[2m2024-07-17T09:08:38.724922Z [0m [32m INFO [0m [2mxitca_server::net [0m [2m: [0m Started Tcp listening on: Some(0.0.0.0:9000)
|
||||||
|
[2m2024-07-17T09:08:38.725076Z [0m [33m WARN [0m [2mxitca_server::server::future [0m [2m: [0m ServerFuture::wait is called from within tokio context. It would block current thread from handling async tasks
|
||||||
|
[2m2024-07-17T09:08:38.725248Z [0m [32m INFO [0m [2mxitca_server::worker [0m [2m: [0m Started xitca-server-worker-0
|
||||||
|
[2m2024-07-17T09:08:38.725343Z [0m [32m INFO [0m [2mxitca_server::worker [0m [2m: [0m Started xitca-server-worker-1
|
||||||
|
[2m2024-07-17T09:08:38.725580Z [0m [32m INFO [0m [2mxitca_server::worker [0m [2m: [0m Started xitca-server-worker-2
|
||||||
|
[2m2024-07-17T09:08:38.725607Z [0m [32m INFO [0m [2mxitca_server::worker [0m [2m: [0m Started xitca-server-worker-3
|
||||||
|
[2m2024-07-17T09:08:41.390783Z [0m [32m INFO [0m [1mrequest [0m [1m{ [0m [3mmethod [0m [2m= [0mGET [3muri [0m [2m= [0m/ [1m} [0m [2m: [0m [2mon_request [0m [2m: [0m serving request
|
||||||
|
[2m2024-07-17T09:08:41.390905Z [0m [32m INFO [0m [1mrequest [0m [1m{ [0m [3mmethod [0m [2m= [0mGET [3muri [0m [2m= [0m/ [1m} [0m [2m: [0m [2mon_response [0m [2m: [0m sending response
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage with Docker
|
||||||
|
If you're using the Docker image, just replace all occurences of `cup` in the examples with `docker run -tv /var/run/docker.sock:/var/run/docker.sock -p <PORT>:<PORT> ghcr.io/sergi0g/cup`, where `<PORT>` is the port Cup will be using.
|
||||||
|
|
||||||
|
For example, this:
|
||||||
|
```bash /serve -p 9000/
|
||||||
|
$ cup serve -p 9000
|
||||||
|
```
|
||||||
|
becomes:
|
||||||
|
```bash /serve -p 9000/
|
||||||
|
$ docker run -tv /var/run/docker.sock:/var/run/docker.sock -p 9000:9000 ghcr.io/sergi0g/cup serve -p 9000
|
||||||
|
```
|
||||||
3
docs/pages/index.mdx
Normal file
3
docs/pages/index.mdx
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Welcome to Cup
|
||||||
|
|
||||||
|
Hello world!
|
||||||
4089
docs/pnpm-lock.yaml
generated
Normal file
4089
docs/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
6
docs/postcss.config.js
Normal file
6
docs/postcss.config.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
}
|
||||||
7
docs/styles.css
Normal file
7
docs/styles.css
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
.tabler-icon {
|
||||||
|
color: rgb(250 250 250 / var(--tw-text-opacity)) !important
|
||||||
|
}
|
||||||
11
docs/tailwind.config.js
Normal file
11
docs/tailwind.config.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
module.exports = {
|
||||||
|
content: [
|
||||||
|
"theme.config.jsx"
|
||||||
|
],
|
||||||
|
theme: {
|
||||||
|
extend: {},
|
||||||
|
},
|
||||||
|
plugins: [],
|
||||||
|
}
|
||||||
|
|
||||||
111
docs/theme.config.jsx
Normal file
111
docs/theme.config.jsx
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
import { ThemeSwitch } from "nextra-theme-docs";
|
||||||
|
import { useRouter } from "next/router";
|
||||||
|
import { useConfig } from "nextra-theme-docs";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
docsRepositoryBase: "https://github.com/sergi0g/cup/tree/main/docs",
|
||||||
|
useNextSeoProps() {
|
||||||
|
const { asPath } = useRouter()
|
||||||
|
if (asPath !== '/') {
|
||||||
|
return {
|
||||||
|
titleTemplate: '%s – Cup'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
head: () => {
|
||||||
|
const { asPath } = useRouter()
|
||||||
|
const { frontMatter } = useConfig()
|
||||||
|
const url =
|
||||||
|
'https://sergi0g.github.io/cup' +
|
||||||
|
(`/${asPath}`);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<meta property="og:url" content={url} />
|
||||||
|
<meta property="og:title" content={frontMatter.title || 'Cup'} />
|
||||||
|
<meta
|
||||||
|
property="og:description"
|
||||||
|
content={frontMatter.description || 'The easiest way to manage your container updates'}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
logo: (
|
||||||
|
<div className="flex items-center">
|
||||||
|
<Logo />
|
||||||
|
<h1 className="font-bold ml-2">Cup</h1>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
logoLink: "sergi0g.github.io/cup",
|
||||||
|
project: {
|
||||||
|
link: "https://github.com/sergi0g/cup",
|
||||||
|
},
|
||||||
|
navbar: {
|
||||||
|
extraContent: <ThemeSwitch lite className="[&_span]:hidden" />,
|
||||||
|
},
|
||||||
|
toc: {
|
||||||
|
backToTop: true,
|
||||||
|
},
|
||||||
|
footer: {
|
||||||
|
text: null,
|
||||||
|
},
|
||||||
|
navigation: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
function Logo() {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 128 128"
|
||||||
|
style={{ height: "calc(var(--nextra-navbar-height) * 0.6)" }}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
style={{ fill: "#A6CFD6" }}
|
||||||
|
d="M65.12,17.55c-17.6-0.53-34.75,5.6-34.83,14.36c-0.04,5.2,1.37,18.6,3.62,48.68s2.25,33.58,3.5,34.95
|
||||||
|
c1.25,1.37,10.02,8.8,25.75,8.8s25.93-6.43,26.93-8.05c0.48-0.78,1.83-17.89,3.5-37.07c1.81-20.84,3.91-43.9,3.99-45.06
|
||||||
|
C97.82,30.66,94.2,18.43,65.12,17.55z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
style={{ fill: "#DCEDF6" }}
|
||||||
|
d="M41.4,45.29c-0.12,0.62,1.23,24.16,2.32,27.94c1.99,6.92,9.29,7.38,10.23,4.16
|
||||||
|
c0.9-3.07-0.38-29.29-0.38-29.29s-3.66-0.3-6.43-0.84C44,46.63,41.4,45.29,41.4,45.29z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
style={{ fill: "#6CA4AE" }}
|
||||||
|
d="M33.74,32.61c-0.26,8.83,20.02,12.28,30.19,12.22c13.56-0.09,29.48-4.29,29.8-11.7
|
||||||
|
S79.53,21.1,63.35,21.1C49.6,21.1,33.96,25.19,33.74,32.61z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
style={{ fill: "#DC0D27" }}
|
||||||
|
d="M84.85,13.1c-0.58,0.64-9.67,30.75-9.67,30.75s2.01-0.33,4-0.79c2.63-0.61,3.76-1.06,3.76-1.06
|
||||||
|
s7.19-22.19,7.64-23.09c0.45-0.9,21.61-7.61,22.31-7.93c0.7-0.32,1.39-0.4,1.46-0.78c0.06-0.38-2.34-6.73-3.11-6.73
|
||||||
|
C110.47,3.47,86.08,11.74,84.85,13.1z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
style={{ fill: "#8A1F0F" }}
|
||||||
|
d="M110.55,7.79c1.04,2.73,2.8,3.09,3.55,2.77c0.45-0.19,1.25-1.84,0.01-4.47
|
||||||
|
c-0.99-2.09-2.17-2.74-2.93-2.61C110.42,3.6,109.69,5.53,110.55,7.79z"
|
||||||
|
/>
|
||||||
|
<g>
|
||||||
|
<path
|
||||||
|
style={{ fill: "#8A1F0F" }}
|
||||||
|
d="M91.94,18.34c-0.22,0-0.44-0.11-0.58-0.3l-3.99-5.77c-0.22-0.32-0.14-0.75,0.18-0.97
|
||||||
|
c0.32-0.22,0.76-0.14,0.97,0.18l3.99,5.77c0.22,0.32,0.14,0.75-0.18,0.97C92.21,18.3,92.07,18.34,91.94,18.34z"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path
|
||||||
|
style={{ fill: "#8A1F0F" }}
|
||||||
|
d="M90.28,19.43c-0.18,0-0.35-0.07-0.49-0.2l-5.26-5.12c-0.28-0.27-0.28-0.71-0.01-0.99
|
||||||
|
c0.27-0.28,0.71-0.28,0.99-0.01l5.26,5.12c0.28,0.27,0.28,0.71,0.01,0.99C90.64,19.36,90.46,19.43,90.28,19.43z"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path
|
||||||
|
style={{ fill: "#8A1F0F" }}
|
||||||
|
d="M89.35,21.22c-0.12,0-0.25-0.03-0.36-0.1l-5.6-3.39c-0.33-0.2-0.44-0.63-0.24-0.96
|
||||||
|
c0.2-0.33,0.63-0.44,0.96-0.24l5.6,3.39c0.33,0.2,0.44,0.63,0.24,0.96C89.82,21.1,89.59,21.22,89.35,21.22z"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user