Skip to content

Commit 3519865

Browse files
committed
first commit
0 parents  commit 3519865

File tree

7 files changed

+298
-0
lines changed

7 files changed

+298
-0
lines changed

.github/workflows/build.yml

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
name: Build and publish
2+
3+
on:
4+
workflow_dispatch:
5+
schedule:
6+
- cron: "0 1 * * *"
7+
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- name: Checkout
14+
uses: actions/checkout@v5
15+
16+
- name: AWS CLI v2
17+
uses: imehedi/actions-awscli-v2@latest
18+
continue-on-error: true
19+
with:
20+
args: s3 cp s3://${{ vars.SC_ARTIFACTS_BUCKET }}/bitwarden-cli-docker/REVISION . --endpoint-url ${{ vars.SC_AMS_AWS_ENDPOINT }}
21+
env:
22+
AWS_ACCESS_KEY_ID: ${{ secrets.SC_AWS_KEY_ID }}
23+
AWS_SECRET_ACCESS_KEY: ${{ secrets.SC_AWS_SECRET_ACCESS_KEY }}
24+
AWS_DEFAULT_REGION: "nl-ams"
25+
26+
- name: Tag
27+
id: tag
28+
env:
29+
GITHUB_TOKEN: ${{ github.token }}
30+
run: |
31+
set -euo pipefail
32+
# Find latest stable Bitwarden CLI (cli-v*) using GitHub API (authenticated)
33+
REPO_TAG=$(curl -sS \
34+
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
35+
-H "Accept: application/vnd.github+json" \
36+
"https://api.github.com/repos/bitwarden/clients/releases?per_page=100" \
37+
| jq -r '
38+
[ .[]
39+
| select(.tag_name | startswith("cli-v"))
40+
| select(.draft==false and .prerelease==false)
41+
| .tag_name ]
42+
| sort_by( sub("^cli-v"; "") | split(".") | map(tonumber) )
43+
| last
44+
| sub("^cli-v"; "")
45+
')
46+
if [ -z "${REPO_TAG:-}" ] || ! echo "$REPO_TAG" | grep -Eq '^[0-9]+(\.[0-9]+){2}$'; then
47+
echo "Failed to resolve latest Bitwarden CLI version" >&2
48+
exit 1
49+
fi
50+
echo "Latest Bitwarden CLI: $REPO_TAG"
51+
PREVIOUS_TAG=$(cat REVISION || echo "")
52+
mkdir -p temp/
53+
if [ "$REPO_TAG" = "$PREVIOUS_TAG" ]; then
54+
echo "No new tags. Skipping."
55+
echo "skipped=true" >> $GITHUB_OUTPUT
56+
echo $REPO_TAG > temp/REVISION
57+
exit 0
58+
fi
59+
VERSION="$REPO_TAG"
60+
echo "VERSION=$VERSION" >> $GITHUB_ENV
61+
echo $REPO_TAG > temp/REVISION
62+
63+
- name: AWS CLI v2
64+
uses: imehedi/actions-awscli-v2@latest
65+
with:
66+
args: s3 cp temp/REVISION s3://${{ vars.SC_ARTIFACTS_BUCKET }}/bitwarden-cli-docker/REVISION --endpoint-url ${{ vars.SC_AMS_AWS_ENDPOINT }}
67+
env:
68+
AWS_ACCESS_KEY_ID: ${{ secrets.SC_AWS_KEY_ID }}
69+
AWS_SECRET_ACCESS_KEY: ${{ secrets.SC_AWS_SECRET_ACCESS_KEY }}
70+
AWS_DEFAULT_REGION: "nl-ams"
71+
72+
# Buildx explicit setup not required for single-arch; build-push-action
73+
# provisions a builder automatically.
74+
75+
- name: Extract metadata (tags, labels) for Docker
76+
id: meta
77+
if: ${{ steps.tag.outputs.skipped != 'true' }}
78+
uses: docker/metadata-action@v5
79+
with:
80+
images: ghcr.io/icoretech/bitwarden-cli-docker
81+
labels: |
82+
org.opencontainers.image.description=Bitwarden CLI
83+
org.opencontainers.image.source=https://github.com/icoretech/bitwarden-cli-docker
84+
org.opencontainers.image.title=bitwarden-cli
85+
org.opencontainers.image.vendor=iCoreTech, Inc.
86+
tags: |
87+
type=raw,value=${{ env.VERSION }}
88+
89+
- name: Login to GitHub Container Registry
90+
uses: docker/login-action@v3
91+
if: ${{ steps.tag.outputs.skipped != 'true' }}
92+
with:
93+
registry: ghcr.io
94+
username: ${{ github.actor }}
95+
password: ${{ secrets.PACKAGES_PAT }}
96+
97+
- name: Build and push Docker image
98+
uses: docker/build-push-action@v6
99+
if: ${{ steps.tag.outputs.skipped != 'true' }}
100+
with:
101+
platforms: linux/amd64
102+
push: ${{ github.event_name != 'pull_request' }}
103+
tags: ${{ steps.meta.outputs.tags }}
104+
labels: ${{ steps.meta.outputs.labels }}
105+
# No provenance attestation for simplicity and max compatibility
106+
build-args: BW_VERSION=${{ env.VERSION }}

.github/workflows/keepalive.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Keep Repository Active
2+
3+
on:
4+
# Run weekly to ensure we never hit GitHub's 60‑day inactivity window.
5+
schedule:
6+
- cron: "23 5 * * 1" # Mondays at 05:23 UTC
7+
workflow_dispatch: {}
8+
9+
permissions:
10+
contents: write
11+
12+
jobs:
13+
keepalive:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Checkout
17+
uses: actions/checkout@v5
18+
with:
19+
fetch-depth: 0
20+
21+
- name: Create keepalive commit if idle
22+
shell: bash
23+
run: |
24+
set -euo pipefail
25+
now=$(date +%s)
26+
last=$(git log -1 --format=%ct || echo 0)
27+
days=$(( ( now - last ) / 86400 ))
28+
threshold_days=${THRESHOLD_DAYS:-50}
29+
30+
echo "Last commit: ${days} days ago; threshold: ${threshold_days} days"
31+
32+
if (( days > threshold_days )); then
33+
echo "Creating keepalive commit to maintain repository activity..."
34+
mkdir -p .github
35+
date -u +%Y-%m-%dT%H:%M:%SZ > .github/.keepalive
36+
git config user.name "github-actions[bot]"
37+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
38+
git add .github/.keepalive
39+
git commit -m "chore(keepalive): repository activity"
40+
git push
41+
else
42+
echo "No keepalive commit needed."
43+
fi

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/bw
2+
.DS_Store
3+
push.sh
4+
scripts/

Dockerfile

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Local build and run
2+
#
3+
# Build (choose Bitwarden CLI version via BW_VERSION):
4+
# docker build -t bitwarden-cli-docker:local --build-arg BW_VERSION=2025.10.0 .
5+
#
6+
# Run (interactive):
7+
# docker run --rm -it --name bw bitwarden-cli-docker:local --version
8+
# docker run --rm -it --name bw bitwarden-cli-docker:local login --apikey
9+
10+
# Downloader stage: fetch and verify Bitwarden CLI binary
11+
FROM alpine:3.22 AS downloader
12+
13+
# Require the version from build args; do not auto-resolve
14+
ARG BW_VERSION
15+
16+
RUN apk update --no-cache \
17+
&& apk add --no-cache curl jq unzip ca-certificates \
18+
&& VERSION="${BW_VERSION}" \
19+
&& if [ -z "$VERSION" ]; then echo "BW_VERSION build-arg is required" >&2; exit 1; fi \
20+
&& curl -sLo /tmp/bw.zip "https://github.com/bitwarden/clients/releases/download/cli-v${VERSION}/bw-oss-linux-${VERSION}.zip" \
21+
&& echo $( \
22+
curl -sL "https://api.github.com/repos/bitwarden/clients/releases/tags/cli-v${VERSION}" | jq -r ".assets[] | select(.name == \"bw-oss-linux-${VERSION}.zip\") .digest" | cut -f2 -d: \
23+
) /tmp/bw.zip > /tmp/sum.txt \
24+
&& sha256sum -sc /tmp/sum.txt \
25+
&& unzip -d /tmp /tmp/bw.zip \
26+
&& chmod +x /tmp/bw
27+
28+
# Runtime stage
29+
FROM debian:stable-slim
30+
31+
RUN apt-get update \
32+
&& apt-get install -y --no-install-recommends ca-certificates wget \
33+
&& rm -rf /var/lib/apt/lists/*
34+
35+
COPY --from=downloader /tmp/bw /usr/local/bin/bw
36+
37+
# Non-root execution setup
38+
USER 1000
39+
WORKDIR /bw
40+
ENV HOME=/bw
41+
42+
# Entrypoint wraps the CLI so `docker run ... <args>` becomes `bw <args>`
43+
COPY entrypoint.sh /entrypoint.sh
44+
ENTRYPOINT ["/entrypoint.sh"]

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2025 iCoreTech, Inc.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# 🔐 Bitwarden CLI Docker Image
2+
3+
This repository hosts an automated build system for creating 🐳 Docker images of the [Bitwarden CLI](https://help.bitwarden.com/article/cli/).
4+
The built AMD64 Docker images are published to GHCR with semantic tagging. amd64-only.
5+
6+
## 📖 Overview
7+
8+
The build system tracks upstream Bitwarden CLI releases (tags like `cli-v2025.10.0`). When a new CLI release is available, an image is built and published to GHCR. Image tags mirror the CLI version (for example, `2025.10.0`).
9+
10+
## 💡 Usage
11+
12+
Pull the image:
13+
14+
```bash
15+
docker pull ghcr.io/icoretech/bitwarden-cli-docker:<tag>
16+
```
17+
18+
Replace `<tag>` with a Bitwarden CLI version (for example, `2025.10.0`).
19+
20+
You can find available tags on the [GitHub Packages page](https://github.com/icoretech/bitwarden-cli-docker/pkgs/container/bitwarden-cli-docker).
21+
22+
This image runs the `bw` binary as a non‑root user (`uid 1000`) with `HOME` set to `/bw`. The entrypoint transparently proxies arguments to `bw`.
23+
24+
```bash
25+
# Persist CLI config/session between runs
26+
mkdir -p ./bw
27+
28+
docker run --rm -it \
29+
-e BW_HOST=https://vault.bitwarden.com \
30+
31+
-e BW_PASSWORD='your-master-password' \
32+
-v $PWD/bw:/bw \
33+
ghcr.io/icoretech/bitwarden-cli-docker:2025.10.0
34+
```
35+
36+
## 📄 License
37+
38+
The Docker images and the code in this repository are released under [MIT License](LICENSE).
39+
40+
Please note that the Bitwarden project has its own license and terms, which you should review if you plan to use, distribute, or modify the software.

entrypoint.sh

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/usr/bin/env sh
2+
set -eu
3+
4+
# If arguments are provided, run bw with them (passthrough mode)
5+
if [ "$#" -gt 0 ]; then
6+
exec bw "$@"
7+
fi
8+
9+
# Server mode
10+
11+
if [ -z "${BW_HOST:-}" ]; then
12+
echo "BW_HOST is required" >&2
13+
exit 2
14+
fi
15+
16+
# Point CLI to the desired server (US/EU/self-hosted)
17+
bw config server "${BW_HOST}"
18+
19+
# Login/unlock
20+
if [ -n "${BW_CLIENTID:-}" ] && [ -n "${BW_CLIENTSECRET:-}" ]; then
21+
echo "Using API key to log in"
22+
# bw reads BW_CLIENTID and BW_CLIENTSECRET from env
23+
bw login --apikey --raw >/dev/null 2>&1 || true
24+
if [ -n "${BW_PASSWORD:-}" ]; then
25+
export BW_SESSION="$(bw unlock --passwordenv BW_PASSWORD --raw)"
26+
fi
27+
else
28+
if [ -z "${BW_USER:-}" ] || [ -z "${BW_PASSWORD:-}" ]; then
29+
echo "BW_USER and BW_PASSWORD are required when not using API key" >&2
30+
exit 2
31+
fi
32+
echo "Using username/password to log in"
33+
export BW_SESSION="$(bw login "${BW_USER}" --passwordenv BW_PASSWORD --raw)"
34+
fi
35+
36+
# Ensure session is valid if possible
37+
bw unlock --check >/dev/null 2>&1 || true
38+
39+
echo 'Running `bw serve` on 0.0.0.0:8087'
40+
exec bw serve --hostname 0.0.0.0

0 commit comments

Comments
 (0)