Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

Commit ee0a77f

Browse files
authored
Merge pull request #66 from microsoftgraph/chore/docker_image
Add docker build config
2 parents 1efafbb + cb4bdf5 commit ee0a77f

File tree

12 files changed

+214
-12
lines changed

12 files changed

+214
-12
lines changed

.dockerignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
**/.git/
2+
**/.github/
3+
**/.vs/
4+
**/.vscode/
5+
**/[Bb]in/
6+
**/[Oo]bj/
7+
**/*.sample.*
8+
tmp/
9+
**/.env
10+
**/*.md
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: Publish Docker image
2+
on:
3+
workflow_dispatch:
4+
inputs:
5+
tag:
6+
description: 'The tag to build'
7+
required: true
8+
type: string
9+
push:
10+
branches: [main]
11+
tags: ['v*']
12+
paths: ['src/**', '.github/workflows/**']
13+
jobs:
14+
push_to_registry:
15+
name: Push Docker image to GitHub Packages
16+
runs-on: ubuntu-latest
17+
env:
18+
MSGRAPH_DOCKER_REGISTRY_URL: docker.pkg.github.com
19+
PACKAGE_VERSION: ${{github.event.inputs.tag || github.ref_name || 'v0.1.0'}}
20+
steps:
21+
- id: get-version
22+
run: |
23+
PACKAGE_VERSION=$(echo $PACKAGE_VERSION | sed s/^v//)
24+
echo "::set-output name=version::$PACKAGE_VERSION"
25+
- name: Check out the repo
26+
uses: actions/checkout@v3
27+
with:
28+
submodules: true
29+
ref: ${{github.event.inputs.tag || ''}}
30+
- name: Login to GitHub package feed
31+
uses: docker/[email protected]
32+
with:
33+
username: ${{ github.actor }}
34+
password: ${{ secrets.GITHUB_TOKEN }}
35+
registry: docker.pkg.github.com
36+
- name: Push to GitHub Packages - Nightly
37+
if: contains(github.ref, 'refs/head/main')
38+
uses: docker/[email protected]
39+
with:
40+
push: true
41+
tags: docker.pkg.github.com/microsoftgraph/msgraph-cli/msgraph-cli:nightly
42+
secrets: |
43+
"user=${{ secrets.NUGET_USER }}"
44+
"token=${{ secrets.NUGET_PASSWORD }}"
45+
- name: Push to GitHub Packages - Release
46+
if: contains(github.ref, 'refs/tags/v')
47+
uses: docker/[email protected]
48+
with:
49+
push: true
50+
tags: docker.pkg.github.com/microsoftgraph/msgraph-cli/msgraph-cli:latest,docker.pkg.github.com/microsoftgraph/msgraph-cli/msgraph-cli:${{ steps.get-version.outputs.version }}
51+
secrets: |
52+
"user=${{ secrets.NUGET_USER }}"
53+
"token=${{ secrets.NUGET_PASSWORD }}"

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,4 +573,7 @@ FodyWeavers.xsd
573573
# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,visualstudio,intellij+all,dotnetcore,windows,macos,linux
574574

575575
app-settings.*.json
576-
!app-settings.sample.json
576+
!app-settings.sample.json
577+
578+
# docker compose mounts
579+
tmp/

Dockerfile

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# To get around the bug in https://github.com/moby/buildkit/issues/1366 on windows hosts, you can either:
2+
# 1. Enable long file path support in windows
3+
# 2. Use the \\?\ prefix when specifying the path in the docker build command. e.g.
4+
# docker build \\?\C:\path -f .\Dockerfile
5+
# See https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation
6+
FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine AS build-env
7+
8+
ARG MS_NUGET_URL=https://nuget.pkg.github.com/microsoft/index.json
9+
ARG MSGRAPH_NUGET_URL=https://nuget.pkg.github.com/microsoftgraph/index.json
10+
11+
WORKDIR /app
12+
13+
COPY ./src ./msgraph-cli/src
14+
COPY ./msgraph-cli-core ./msgraph-cli/msgraph-cli-core
15+
WORKDIR /app/msgraph-cli
16+
17+
RUN --mount=type=secret,id=user,required=true --mount=type=secret,id=token,required=true \
18+
dotnet nuget add source ${MS_NUGET_URL} -n ms-gh -u $(cat /run/secrets/user) -p $(cat /run/secrets/token) --store-password-in-clear-text &&\
19+
dotnet nuget add source ${MSGRAPH_NUGET_URL} -n msgraph-gh -u $(cat /run/secrets/user) -p $(cat /run/secrets/token) --store-password-in-clear-text
20+
21+
RUN dotnet publish -p:PublishSingleFile=false -p:PublishReadyToRun=true -p:PublishReadyToRunShowWarnings=true ./src/msgraph-cli.csproj --configuration Release --no-self-contained --runtime linux-musl-x64 --output /app/output
22+
23+
FROM mcr.microsoft.com/dotnet/runtime:6.0-alpine as runtime
24+
25+
# Change this password by providing a different value when running the container
26+
ENV KEYRING_PASSWORD="password"
27+
28+
RUN apk add --no-cache libsecret dbus gnome-keyring libcap &&\
29+
dbus-uuidgen > /var/lib/dbus/machine-id &&\
30+
setcap cap_ipc_lock=+ep $(which gnome-keyring-daemon)
31+
32+
RUN addgroup mgc &&\
33+
adduser -D -G mgc -h /app mgc
34+
35+
WORKDIR /app
36+
37+
COPY --from=build-env /app/output ./dist
38+
39+
RUN ln -s /app/dist/mgc /usr/bin/mgc
40+
41+
USER mgc
42+
43+
COPY --chown=mgc:mgc ./docker/* ./dist/
44+
45+
RUN mkdir -p /app/.mgc /app/.local/share/.IdentityService /app/.local/share/keyrings &&\
46+
chmod +x /app/dist/init.sh
47+
48+
VOLUME [ "/app/.mgc", "/app/.local/share/.IdentityService", "/app/.local/share/keyrings" ]
49+
50+
ENTRYPOINT ["./dist/init.sh"]
51+
52+
LABEL description="# Welcome to the Microsoft Graph CLI \
53+
[Source dockerfile](https://github.com/microsoftgraph/msgraph-cli/blob/main/Dockerfile)"

docker-compose.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
version: '2'
2+
services:
3+
mgc:
4+
image: msgraph-cli
5+
cap_add:
6+
# https://man7.org/linux/man-pages/man7/capabilities.7.html
7+
#
8+
- IPC_LOCK # Required by gnome-keyring daemon, the dbus secret service
9+
environment:
10+
- KEYRING_PASSWORD=changeit
11+
volumes:
12+
- ./tmp/.mgc:/app/.mgc
13+
- ./tmp/.IdentityService:/app/.local/share/.IdentityService
14+
- ./tmp/keyrings:/app/.local/share/keyrings

docker/README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Microsoft Graph CLI
2+
## Docker Image Help
3+
4+
### Quick start
5+
#### Running the container
6+
If you are using docker-compose:
7+
```sh
8+
$ docker-compose run -it mgc sh
9+
```
10+
11+
Otherwise use docker to run the container.
12+
```sh
13+
$ docker run -it --cap-add=IPC_LOCK --rm msgraph-cli sh
14+
```
15+
16+
> The IPC_LOCK capability is required by the `gnome-keyring-daemon` process which
17+
> performs token encryption.
18+
19+
#### Building an image
20+
Ensure you have a docker engine with API access [1.39+](https://docs.docker.com/engine/api/v1.39/) and BuildKit enabled.
21+
Create 2 files `nuget_user.txt` and `nuget_token.txt` and set their content to a username and a matching personal access token
22+
that has pull access to both the [microsoft](https://github.com/microsoft) and [microsoftgraph](https://github.com/microsoftgraph)
23+
GitHub organizations' package registries.
24+
25+
To build an image in windows powershell:
26+
```powershell
27+
$ docker build \\?\$(Get-Location) -f . -t msgraph-cli --secret id=user,src=./tmp/nuget_user.txt --secret id=token,src=./tmp/nuget_token.txt
28+
```
29+
30+
> The `\\?\$(Get-Location)` section of the command is used to get around the 260 character
31+
> limitation on windows systems that could cause issues when copying files to the docker
32+
> context. This issue impacts buildkit builds. For more information, check
33+
> [this issue](https://github.com/moby/buildkit/issues/1366).
34+
35+
To build an image in linux or WSL:
36+
```sh
37+
$ docker build -t msgraph-cli --secret id=user,src=./tmp/nuget_user.txt --secret id=token,src=./tmp/nuget_token.txt .
38+
```

docker/app-settings.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Debug"
5+
}
6+
}
7+
}

docker/init.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/usr/bin/env sh
2+
3+
set -e
4+
5+
script="$0"
6+
DIR="$(dirname $script)"
7+
8+
capabilities=$(capsh --print | grep -e "Current: .*ipc_lock" | sed s/\n// | sed s/\ //)
9+
ipc_error="IPC_LOCK capability is not enabled. If you are running a docker container, add the capability using the '--cap-add' option."
10+
11+
if [ -z "$capabilities" ]; then
12+
echo "$ipc_error"
13+
exit 2
14+
fi
15+
16+
if ! pgrep -x "dbus-daemon" > /dev/null
17+
then
18+
export DBUS_SESSION_BUS_ADDRESS=$(dbus-daemon --session --fork --print-address)
19+
else
20+
echo "dbus-daemon already running"
21+
fi
22+
23+
dbus-run-session -- echo "$KEYRING_PASSWORD" | gnome-keyring-daemon --daemonize --components=secrets --unlock && "$@"

msgraph-cli-core

src/Program.cs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,14 @@
88
using Microsoft.Graph.Cli.Core.Commands.Authentication;
99
using Microsoft.Graph.Cli.Core.Configuration;
1010
using Microsoft.Graph.Cli.Core.IO;
11-
using Microsoft.Graph.Cli.Core.Utils;
12-
using Microsoft.Kiota.Abstractions;
1311
using Microsoft.Kiota.Authentication.Azure;
1412
using Microsoft.Kiota.Cli.Commons.IO;
1513
using Microsoft.Kiota.Http.HttpClientLibrary;
16-
using Microsoft.Kiota.Http.HttpClientLibrary.Middleware;
17-
using Microsoft.Kiota.Http.HttpClientLibrary.Middleware.Options;
1814
using System.CommandLine;
1915
using System.CommandLine.Builder;
2016
using System.CommandLine.Hosting;
2117
using System.CommandLine.Parsing;
2218
using System.IO;
23-
using System.Linq;
24-
using System.Net.Http;
2519
using System.Reflection;
2620
using System.Threading.Tasks;
2721
using System.Collections.Generic;
@@ -123,7 +117,7 @@ static IHostBuilder CreateHostBuilder(string[] args) =>
123117

124118
static void ConfigureAppConfiguration(IConfigurationBuilder builder) {
125119
builder.Sources.Clear();
126-
builder.AddJsonFile("app-settings.json", optional: false);
120+
builder.AddJsonFile(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "app-settings.json"), optional: false);
127121
var pathUtil = new PathUtility();
128122
var authCache = new AuthenticationCacheUtility(pathUtil);
129123
var dataDir = pathUtil.GetApplicationDataDirectory();

0 commit comments

Comments
 (0)