14 Commits

7 changed files with 114 additions and 41 deletions

53
.github/workflows/docker.yml vendored Normal file
View File

@@ -0,0 +1,53 @@
name: ci
on:
push:
branches: [ "*" ]
tags: [ "*" ]
pull_request:
jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
# list of Docker images to use as base name for tags
images: |
${{ github.repository }}
ghcr.io/${{ github.repository }}
# generate Docker tags based on the following events/attributes
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
- name: Login to Docker Hub
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GHCR
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push
uses: docker/build-push-action@v6
with:
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

View File

@@ -1,36 +0,0 @@
---
stages:
- linting
- release
variables:
EXECUTABLE_NAME: dockup
IMAGE_NAME: ${CI_REGISTRY_IMAGE}
linting:
stage: linting
image: python:latest
script:
- pip install -r requirements.txt
- pip install isort black flake8 pylint
- isort ${EXECUTABLE_NAME} --check-only
- black ${EXECUTABLE_NAME} --check --diff --line-length 79
- flake8 ${EXECUTABLE_NAME}
# - pylint ${EXECUTABLE_NAME} --disable=C0111
release:
image: docker:latest
services:
- docker:dind
stage: release
script:
- echo "$CI_REGISTRY_PASSWORD" | docker login $CI_REGISTRY -u $CI_REGISTRY_USER --password-stdin
- export TAG="${CI_COMMIT_TAG:-latest}" && echo $TAG
- docker build -t ${IMAGE_NAME}:${TAG} .
- docker push ${IMAGE_NAME}:${TAG}
rules:
- if: $CI_COMMIT_BRANCH == "master"
when: on_success
- if: $CI_COMMIT_TAG
when: on_success
...

View File

@@ -1,11 +1,16 @@
# Init image
FROM python:3
FROM python:slim
WORKDIR /app
# Install requirements
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
RUN wget -O /usr/bin/regctl https://github.com/regclient/regclient/releases/latest/download/regctl-linux-amd64
RUN python - <<EOF
from urllib.request import urlopen;
from pathlib import Path;
Path("/usr/bin/regctl").write_bytes(urlopen("https://github.com/regclient/regclient/releases/latest/download/regctl-linux-amd64").read())
EOF
RUN chmod 755 /usr/bin/regctl
# Import app

View File

@@ -10,6 +10,34 @@ Get the provided `compose.yaml`.
docker compose up -d
```
All images are exposed to `http://0.0.0.0:8000/all` in JSON format.
If you want to get only images needing update, look at `http://0.0.0.0:8000/updates`.
Here is a quick example of what you get on the `/all` endpoint (dockup don't have local tag because it is a locally built image):
```json
[
{
"name": "dockup",
"repo": "dockup-dockup",
"local_tag": "latest",
"remote_tag": null
},
{
"name": "wikijs-wiki-1",
"repo": "ghcr.io/requarks/wiki",
"local_tag": "2.5.307",
"remote_tag": "2.5.307"
},
{
"name": "wikijs-db-1",
"repo": "postgres",
"local_tag": "17.4-alpine",
"remote_tag": "17.5-alpine"
}
]
```
# Requirements
This program needs [regctl](https://github.com/regclient/regclient.git).
It is shipped with container image by default, however you'll need to install it by yourself if running script directly.

View File

@@ -2,7 +2,8 @@
name: dockup
services:
dockup:
image: registry.gitlab.com/ramiuslr/dockup:latest
image: ramiuslr/dockup:latest # You should set a fixed tag
# build: . # Use this for local development setup
container_name: dockup
restart: always
ports:

25
dockup
View File

@@ -4,15 +4,31 @@ import http.server
import json
import logging
import os
import signal
import socketserver
import subprocess
import sys
import time
from threading import Lock, Thread
import docker
from dotenv import load_dotenv
from fastapi import FastAPI
from packaging.version import InvalidVersion, Version, parse
# Enable quick restart in docker
app = FastAPI()
def shutdown_handler(signum, frame):
logging.info("Received shutdown signal")
sys.exit(0)
signal.signal(signal.SIGTERM, shutdown_handler)
signal.signal(signal.SIGINT, shutdown_handler)
# Global variables
data_lock = Lock()
g_data = []
@@ -120,8 +136,13 @@ def get_remote_tags(images):
for tag in tags:
# Skip mismatched suffixes
if local_suffix and not tag.endswith(local_suffix):
continue
if local_suffix:
if not tag.endswith(local_suffix):
continue
else:
# Skip tags with suffixes if local has none
if "-" in tag:
continue
# Validate version structure
if is_valid_semver(

View File

@@ -1,3 +1,4 @@
docker
packaging
dotenv
fastapi