Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add separate image for gpu support #1010

Merged
merged 9 commits into from
Jan 20, 2024
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
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 <[email protected]>"
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))
Loading