diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
new file mode 100644
index 0000000..fdcd432
--- /dev/null
+++ b/.github/workflows/publish.yml
@@ -0,0 +1,53 @@
+name: Build and Publish Docker Image
+
+on:
+ push:
+ branches:
+ - develop
+ tags:
+ - 'v*'
+ pull_request:
+ branches:
+ - develop
+
+env:
+ REGISTRY: ghcr.io
+ IMAGE_NAME: ${{ github.repository }}
+
+jobs:
+ build-and-publish:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ packages: write
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Log in to the Container registry
+ uses: docker/login-action@v3
+ with:
+ registry: ghcr.io
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Extract metadata for Docker
+ id: meta
+ uses: docker/metadata-action@v5
+ with:
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
+ tags: |
+ type=ref,event=branch
+ type=ref,event=pr
+ type=semver,pattern={{version}}
+ type=semver,pattern={{major}}.{{minor}}
+ type=sha
+
+ - name: Build and push Docker image
+ uses: docker/build-push-action@v5
+ with:
+ context: .
+ push: ${{ github.event_name != 'pull_request' }}
+ tags: ${{ steps.meta.outputs.tags }}
+ labels: ${{ steps.meta.outputs.labels }}
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..29ea677
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,34 @@
+ARG PROMETHEUS_VERSION=v3.0.1
+ARG SUPERCRONIC_VERSION=0.2.33
+
+FROM ghcr.io/lumeweb/promster:develop AS promster
+FROM debian:bookworm-slim AS certs
+RUN apt-get update && apt-get install -y curl ca-certificates
+RUN mkdir -p /rootfs/bin /rootfs/usr/bin /rootfs/etc/ssl/certs /rootfs/lib/x86_64-linux-gnu && \
+ cp /usr/bin/curl /rootfs/bin/ && \
+ cp -r /etc/ssl/certs/* /rootfs/etc/ssl/certs/ && \
+ cp -L /lib/x86_64-linux-gnu/lib*.so* /rootfs/lib/x86_64-linux-gnu/
+
+FROM prom/prometheus:${PROMETHEUS_VERSION}
+COPY --from=promster /bin/promster /usr/bin/promster
+COPY --from=certs /rootfs/ /
+
+RUN echo $PATH && \
+ ls -l /bin/curl && \
+ /bin/curl -Lo /usr/local/bin/mc https://dl.min.io/client/mc/release/linux-amd64/mc && \
+ chmod +x /usr/local/bin/mc && \
+ /bin/curl -Lo /usr/local/bin/supercronic https://github.com/aptible/supercronic/releases/download/v${SUPERCRONIC_VERSION}/supercronic-linux-amd64 && \
+ chmod +x /usr/local/bin/supercronic
+
+COPY entrypoint.sh /entrypoint.sh
+COPY bin/config-validator /bin/config-validator
+COPY bin/backup-manager /bin/backup-manager
+COPY bin/storage-manager /bin/storage-manager
+
+RUN chmod +x /entrypoint.sh \
+ /bin/config-validator \
+ /bin/backup-manager \
+ /bin/storage-manager
+
+USER root
+ENTRYPOINT [ "/entrypoint.sh" ]
\ No newline at end of file
diff --git a/bin/backup-manager b/bin/backup-manager
new file mode 100644
index 0000000..d5c07ce
--- /dev/null
+++ b/bin/backup-manager
@@ -0,0 +1,69 @@
+#!/bin/bash
+
+# Perform backup
+backup() {
+ # Use mc CLI to upload TSDB files to S3
+ mc --endpoint=${AWS_S3_ENDPOINT} mirror --overwrite /data ${AWS_BUCKET_NAME}/
+}
+
+# Restore from S3
+restore() {
+ # Check available disk space
+ available_disk_space=$(df -h "/data" | awk '{print $4}' | sed 's/%//g')
+ available_disk_space_bytes=$(echo "$available_disk_space * 1024 * 1024" | bc)
+
+ # Calculate total size of data to be restored
+ total_size=$(mc --endpoint=${AWS_S3_ENDPOINT} du --recursive ${AWS_BUCKET_NAME}/ | awk '{print $1}')
+
+ # Calculate max safe threshold
+ max_safe_threshold=$(echo "$available_disk_space_bytes * $MAX_DISK_USAGE_PERCENT / 100" | bc)
+
+ # Check if there is enough disk space
+ if [ $total_size -gt $max_safe_threshold ]; then
+ # Restore only the data that fits within the available disk space
+ mc --endpoint=${AWS_S3_ENDPOINT} mirror --overwrite ${AWS_BUCKET_NAME}/ /data --max-size $max_safe_threshold
+ else
+ # Restore all data
+ mc --endpoint=${AWS_S3_ENDPOINT} mirror --overwrite ${AWS_BUCKET_NAME}/ /data
+ fi
+}
+
+# Verify backup integrity
+verify() {
+ # Use mc CLI to verify backup integrity
+ mc --endpoint=${AWS_S3_ENDPOINT} ls ${AWS_BUCKET_NAME}/
+}
+
+# List available backups
+list() {
+ # Use mc CLI to list available backups
+ mc --endpoint=${AWS_S3_ENDPOINT} ls ${AWS_BUCKET_NAME}/
+}
+
+# Show backup system status
+status() {
+ # mc CLI does not support get-bucket-status command
+ echo "mc CLI does not support get-bucket-status command"
+}
+
+case $1 in
+ --backup)
+ backup
+ ;;
+ --restore)
+ restore
+ ;;
+ --verify)
+ verify
+ ;;
+ --list)
+ list
+ ;;
+ --status)
+ status
+ ;;
+ *)
+ echo "Usage: backup-manager