Skip to content

Commit

Permalink
feat: add separate image for nvidia gpu support (#1010)
Browse files Browse the repository at this point in the history
fixes #290

Co-authored-by: HoreaM <horea_manita@yahoo.com>
  • Loading branch information
MauriceNino and HoreaM authored Jan 20, 2024
1 parent bf88696 commit 319120d
Show file tree
Hide file tree
Showing 10 changed files with 219 additions and 25 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@
.dockerignore
Dockerfile
Dockerfile.dev
Dockerfile.nvidia
docker-compose.yml
37 changes: 37 additions & 0 deletions .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ jobs:
sudo rm -f /swapfile
sudo apt clean
df -h
# DEPLOY normal image
- uses: docker/metadata-action@v4
id: meta
with:
Expand Down Expand Up @@ -81,6 +82,42 @@ jobs:
tags: ${{ steps.meta.outputs.tags }}
cache-from: type=gha
cache-to: type=gha,mode=max
# DEPLOY GPU supported image
- uses: docker/metadata-action@v4
id: meta_nvidia
with:
flavor: |
latest=false
images: |
ghcr.io/mauricenino/dashdot
mauricenino/dashdot
labels: |
org.opencontainers.image.title="dash."
org.opencontainers.image.description="dash. - a modern server dashboard"
org.opencontainers.image.authors="MauriceNino <mauriceprivat98@gmail.com>"
org.opencontainers.image.url=https://github.com/MauriceNino/dashdot
org.opencontainers.image.source=https://github.com/MauriceNino/dashdot
org.opencontainers.image.licenses=MIT
tags: |
type=semver,pattern={{version}},value=${{ format('v{0}', env.package_version) }},enable=${{ github.ref_name == 'main' }},prefix=nvidia-
type=semver,pattern={{major}}.{{minor}},value=${{ format('v{0}', env.package_version) }},enable=${{ github.ref_name == 'main' }},prefix=nvidia-
type=semver,pattern={{major}},value=${{ format('v{0}', env.package_version) }},enable=${{ github.ref_name == 'main' }},prefix=nvidia-
type=ref,event=branch,enable=${{ github.ref_name != 'main' }},prefix=nvidia-
type=raw,value=nvidia,enable=${{ github.ref_name == 'main' }}
- uses: docker/build-push-action@v4
with:
context: .
file: Dockerfile.nvidia
platforms: linux/amd64,linux/arm64/v8
target: prod
push: true
build-args: |
VERSION=${{ github.ref_name == 'main' && env.package_version || format('0.0.0-{0}', github.ref_name) }}
BUILDHASH=${{ github.sha }}
labels: ${{ steps.meta_nvidia.outputs.labels }}
tags: ${{ steps.meta_nvidia.outputs.tags }}
cache-from: type=gha
cache-to: type=gha,mode=max
- if: ${{ github.ref_name == 'main' }}
env:
GIT_USER: github-actions
Expand Down
13 changes: 9 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ FROM node:20-alpine AS base

WORKDIR /app
ARG TARGETPLATFORM
ENV DASHDOT_IMAGE=base
ENV DASHDOT_RUNNING_IN_DOCKER=true

RUN \
Expand Down Expand Up @@ -69,18 +70,22 @@ COPY . ./

RUN \
yarn --immutable --immutable-cache &&\
yarn build:prod
yarn build:prod &&\
node scripts/strip_package_json.js

# PROD #
FROM base as prod

EXPOSE 3001

COPY --from=build /app/package.json .
COPY --from=build /app/version.json .
COPY --from=build /app/.yarn/releases/ .yarn/releases/
COPY --from=build /app/.yarn/releases .yarn/releases
COPY --from=build /app/.yarnrc.yml .yarnrc.yml
COPY --from=build /app/dist/apps/server dist/apps/server
COPY --from=build /app/dist/apps/cli dist/apps/cli
COPY --from=build /app/dist/apps/view dist/apps/view
COPY --from=build /app/dist/package.json package.json

CMD ["yarn", "start"]
RUN yarn

CMD ["node", "."]
97 changes: 97 additions & 0 deletions Dockerfile.nvidia
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# BASE #
FROM nvidia/cuda:12.2.0-base-ubuntu20.04 AS base

WORKDIR /app
ARG TARGETPLATFORM
ENV DASHDOT_IMAGE=nvidia
ENV DASHDOT_RUNNING_IN_DOCKER=true
ENV NVIDIA_VISIBLE_DEVICES=all
ENV NVIDIA_DRIVER_CAPABILITIES="compute,video,utility"

RUN \
/bin/echo ">> installing dependencies" &&\
apt-get update &&\
apt-get install -y \
curl \
wget \
mdadm \
dmidecode \
util-linux \
pciutils \
lm-sensors \
speedtest-cli &&\
curl -fsSL https://deb.nodesource.com/setup_20.x | bash - &&\
apt-get install -y nodejs &&\
corepack enable &&\
if [ "$TARGETPLATFORM" = "linux/amd64" ] || [ "$(uname -m)" = "x86_64" ]; \
then \
/bin/echo ">> installing dependencies (amd64)" &&\
wget -qO- https://install.speedtest.net/app/cli/ookla-speedtest-1.1.1-linux-x86_64.tgz \
| tar xmoz -C /usr/bin speedtest; \
elif [ "$TARGETPLATFORM" = "linux/arm64" ] || [ "$(uname -m)" = "aarch64" ]; \
then \
/bin/echo ">> installing dependencies (arm64)" &&\
wget -qO- https://install.speedtest.net/app/cli/ookla-speedtest-1.1.1-linux-aarch64.tgz \
| tar xmoz -C /usr/bin speedtest; \
elif [ "$TARGETPLATFORM" = "linux/arm/v7" ]; \
then \
/bin/echo ">> installing dependencies (arm/v7)" &&\
wget -qO- https://install.speedtest.net/app/cli/ookla-speedtest-1.1.1-linux-armhf.tgz \
| tar xmoz -C /usr/bin speedtest; \
else /bin/echo "Unsupported platform"; exit 1; \
fi &&\
/bin/echo -e ">> clean-up" &&\
apt-get clean && \
rm -rf /tmp/* /var/tmp/*

# DEV #
FROM base AS dev

EXPOSE 3001
EXPOSE 3000

RUN \
/bin/echo -e ">> installing dependencies (dev)" &&\
apt-get install -y \
git &&\
git config --global --add safe.directory /app

# BUILD #
FROM base as build

ARG BUILDHASH
ARG VERSION

RUN \
/bin/echo -e ">> installing dependencies (build)" &&\
apt-get install -y \
git \
make \
clang \
build-essential &&\
git config --global --add safe.directory /app &&\
/bin/echo -e "{\"version\":\"$VERSION\",\"buildhash\":\"$BUILDHASH\"}" > /app/version.json

COPY . ./

RUN \
yarn --immutable --immutable-cache &&\
yarn build:prod &&\
node scripts/strip_package_json.js

# PROD #
FROM base as prod

EXPOSE 3001

COPY --from=build /app/version.json .
COPY --from=build /app/.yarn/releases .yarn/releases
COPY --from=build /app/.yarnrc.yml .yarnrc.yml
COPY --from=build /app/dist/apps/server dist/apps/server
COPY --from=build /app/dist/apps/cli dist/apps/cli
COPY --from=build /app/dist/apps/view dist/apps/view
COPY --from=build /app/dist/package.json package.json

RUN yarn

CMD ["node", "."]
18 changes: 11 additions & 7 deletions apps/cli/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';

const execp = promisify(exec);
const execpnoerr = async (cmd: string): Promise<string | undefined> => {
const execpnoerr = async (cmd: string) => {
return execp(cmd)
.then(({ stdout }) => stdout)
.catch(() => undefined);
.then(({ stdout }) => stdout.trim())
.catch(() => '');
};

const inspectObj = (obj: unknown): string => {
Expand All @@ -35,10 +35,12 @@ yargs(hideBin(process.argv))
const nodeVersion = await execpnoerr('node --version');
const buildInfoJson = await execpnoerr('cat version.json');
const gitHash = await execpnoerr('git log -1 --format="%H"');
const platform = await execpnoerr('uname -a');

const runningInDocker = await execpnoerr(
'echo $DASHDOT_RUNNING_IN_DOCKER'
);
const image = await execpnoerr('echo $DASHDOT_IMAGE');
const buildInfo = JSON.parse(buildInfoJson ?? '{}');
const version = buildInfo.version ?? 'unknown';
const buildhash = buildInfo.buildhash ?? gitHash;
Expand All @@ -47,15 +49,17 @@ yargs(hideBin(process.argv))
removePad`
INFO
=========
Yarn: ${yarnVersion.trim()}
Node: ${nodeVersion.trim()}
Yarn: ${yarnVersion}
Node: ${nodeVersion}
Dash: ${version}
Cwd: ${process.cwd()}
Hash: ${buildhash}
Platform: ${platform}
Docker image: ${image}
In Docker: ${isDocker}
In Podman: ${isPodman}
In Docker (env): ${runningInDocker}`
In Docker (env): ${runningInDocker}
In Podman: ${isPodman}`
);
}
)
Expand Down
16 changes: 3 additions & 13 deletions apps/docs/docs/config/widget-specific/graphics.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,9 @@ title: Graphics

<!-- markdownlint-enable -->

To use the GPU widget, make sure to include it in the `DASHDOT_WIDGET_LIST`. One
limitation with the GPU widget is that it will **only run out of the box with from
source installations**. Docker images do not include the necessary tools (mainly,
because I don't want to bloat the image for everyone). If you absolutely need the
GPU widget running inside a docker container, you will need to create your own image.

These links might help you with that:

- <https://www.howtogeek.com/devops/how-to-use-an-nvidia-gpu-with-docker-containers/>
- <https://docs.docker.com/compose/gpu-support/>
- <https://towardsdatascience.com/how-to-properly-use-the-gpu-within-a-docker-container-4c699c78c6d1>
- <https://stackoverflow.com/q/25185405/9150652>
- <https://stackoverflow.com/q/63751883/9150652>
To use the GPU widget, make sure to include it in the `DASHDOT_WIDGET_LIST`.
Also, if you are running the docker image, make sure to use the `nvidia` tag
(see [Installation with Docker](/docs/install/docker#gpu-support)).

## `DASHDOT_GPU_WIDGET_GROW`

Expand Down
26 changes: 26 additions & 0 deletions apps/docs/docs/install/docker-compose.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,29 @@ services:
DASHDOT_ENABLE_CPU_TEMPS: 'true'
# ...
```

## GPU Support

GPU support is available with another image tag and a slightly different config.

```yml
version: '3.5'

services:
dash:
image: mauricenino/dashdot:nvidia
restart: unless-stopped
privileged: true
deploy:
resources:
reservations:
devices:
- capabilities:
- gpu
ports:
- '80:3001'
volumes:
- /:/mnt/host:ro
environment:
DASHDOT_WIDGET_LIST: 'os,cpu,storage,ram,network,gpu'
```
16 changes: 15 additions & 1 deletion apps/docs/docs/install/docker.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ tags:
```bash
docker container run -it \
-p 80:3001 \
--privileged \
-v /:/mnt/host:ro \
--privileged \
mauricenino/dashdot
```

Expand All @@ -28,3 +28,17 @@ docker container run -it \
--env DASHDOT_ENABLE_CPU_TEMPS="true" \
# ...
```

## GPU Support

GPU support is available with another image tag and a slightly different command.

```bash
docker container run -it \
-p 80:3001 \
-v /:/mnt/host:ro \
--privileged \
--gpus all \
--env DASHDOT_WIDGET_LIST="os,cpu,storage,ram,network,gpu"
mauricenino/dashdot:nvidia
```
5 changes: 5 additions & 0 deletions apps/server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,8 @@ process.on('unhandledRejection', e => {
tearDownHostSpecific();
process.exit(1);
});

process.on('SIGINT', () => {
console.info('SIGINT signal received.');
process.exit(0);
});
15 changes: 15 additions & 0 deletions scripts/strip_package_json.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const packageJson = require('../package.json')
const fs = require('fs')

const newPackageJson = {
name: packageJson.name,
version: packageJson.version,
description: packageJson.description,
packageManager: packageJson.packageManager,
main: packageJson.main,
scripts: {
cli: 'node dist/apps/cli/main.js',
}
}

fs.writeFileSync('dist/package.json', JSON.stringify(newPackageJson, null, 2))

0 comments on commit 319120d

Please sign in to comment.