Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# # Build and push distributed-secrets-vault to Docker Hub on version tags or manual dispatch.
# name: Publish Docker image

on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
image_tag:
description: "Docker image tag (e.g. latest or v1.0.0)"
required: true
default: "latest"

env:
DSV_IMAGE_NAME: distributed-secrets-vault

jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Set up JDK 25
uses: actions/setup-java@v5.2.0
with:
java-version: "25"
distribution: "temurin"
cache: maven

- name: Build application JAR
run: |
./mvnw -B clean package -DskipTests
mkdir -p target/dependency
(cd target/dependency && jar -xf ../*.jar)

- name: Resolve image tag
id: meta
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
echo "tag=${{ inputs.image_tag }}" >> "$GITHUB_OUTPUT"
else
echo "tag=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
fi

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: docker.io/${{ secrets.DOCKERHUB_USERNAME }}/${{ env.DSV_IMAGE_NAME }}:${{ steps.meta.outputs.tag }}
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,5 @@ build/
### Environment Variables ###
.env
.env.local
.env.*.local
.env.*.local
k8s/image.env
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ The Distributed Secrets Vault is a leaderless cluster system where secrets are s
## Installation and Usage Guide

- [Installation Instructions](docker/README.md)
- [Docker Hub image & Kubernetes deploy](docs/docker-hub.md)
- [API and Usage Documentation](docs/api.md)
- [DSV Client Repository](https://github.com/S26-Distributed-Capstone/DSVClient)
83 changes: 83 additions & 0 deletions docs/docker-hub.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Docker Hub image for Kubernetes

Production and testing manifests pull the DSV backend from Docker Hub. Workers do not need a local `ctr import`.

## Image

Published at [noambensim/distributed-secrets-vault](https://hub.docker.com/r/noambensim/distributed-secrets-vault) on Docker Hub:

```text
docker.io/noambensim/distributed-secrets-vault:latest
```

Pull manually:

```bash
docker pull noambensim/distributed-secrets-vault:latest
```

To change the repository, edit:

- `k8s/image.env` (for build/push scripts)
- `k8s/production/kustomization.yaml` and `k8s/testing/kustomization.yaml` (`images.newName` / `newTag`)

## One-time Docker Hub setup

1. Repository: [noambensim/distributed-secrets-vault](https://hub.docker.com/r/noambensim/distributed-secrets-vault).
2. Create an access token: Docker Hub → Account Settings → Security → New Access Token.
3. For GitHub Actions, add repository secrets:
- `DOCKERHUB_USERNAME`
- `DOCKERHUB_TOKEN` (the access token, not your account password)

## Build and push (local)

```bash
cp k8s/image.env.example k8s/image.env
# Edit DOCKERHUB_USERNAME if needed

docker login
chmod +x scripts/docker-build-push.sh
./scripts/docker-build-push.sh
```

Or publish via GitHub Actions: **Actions → Publish Docker image → Run workflow**, or push a tag `v1.0.0`.

## Deploy to the cluster

```bash
kubectl apply -k k8s/production/ --dry-run=client
kubectl apply -k k8s/production/
kubectl get pods -n dsv -w
```

Each node pulls `docker.io/noambensim/distributed-secrets-vault:latest` when a pod starts (`imagePullPolicy: IfNotPresent`).

## Private repository

If the image is private, create a pull secret in the `dsv` namespace:

```bash
kubectl create secret docker-registry dockerhub-credentials \
--docker-server=https://index.docker.io/v1/ \
--docker-username=YOUR_USER \
--docker-password=YOUR_TOKEN \
-n dsv
```

Add to `k8s/production/app-statefulset.yaml` under `spec.template.spec`:

```yaml
imagePullSecrets:
- name: dockerhub-credentials
```

See `k8s/production/dockerhub-pull-secret.yaml.example`.

## Pin a release

Set the same tag in `k8s/image.env` (`DSV_IMAGE_TAG`) and in both kustomization files (`images.newTag`), then push and redeploy:

```bash
kubectl apply -k k8s/production/
kubectl rollout restart statefulset/dsv-app -n dsv
```
10 changes: 5 additions & 5 deletions docs/kubernetes.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ KAFKA_BOOTSTRAP_SERVERS=kafka.dsv.svc.cluster.local:9092
`k8s/testing` is intended for Docker Desktop, Minikube, or K3d. It runs three DSV app replicas without production node-affinity constraints.

```bash
kubectl apply -f k8s/testing/
kubectl get pods -w
kubectl apply -k k8s/testing/
kubectl get pods -n dsv -w
```

## Production Environment
Expand All @@ -77,9 +77,9 @@ kubectl get pods -w
- app pods use pod anti-affinity (one DSV pod per worker)
- **10 replicas** with `cluster.totalNodes=10`, `thresholdK=6`, `quorumM=6`

Full steps (scp manifests, import image on all workers, verify): [production-kubernetes-deploy.md](production-kubernetes-deploy.md).
Image is pulled from Docker Hub on each node. Build/push: [docker-hub.md](docker-hub.md). Deploy steps: [production-kubernetes-deploy.md](production-kubernetes-deploy.md).

```bash
kubectl apply -f k8s/production/ --dry-run=client
kubectl apply -f k8s/production/
kubectl apply -k k8s/production/ --dry-run=client
kubectl apply -k k8s/production/
```
Loading
Loading