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

Add container support for Ibeji #62

Merged
merged 15 commits into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from 8 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
19 changes: 19 additions & 0 deletions .accepted_words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,20 @@ Chariott's
chariott
com
config
containerized
Ctrl
dev
digitaltwins
dir
Dockerfile
dockerfile
dockerfiles
dotnet
dt
dtdl
DTDL
en
env
fontconfig
gcc
gcc's
Expand All @@ -29,31 +36,42 @@ Ibeji
Ibeji's
intellectualproperty
invehicle
io
iot
js
json
JSON
kbd
ld
LD
libfontconfig
libsdl
localhost
loopback
microsoft
minimalistic
mosquitto
Mosquitto
mqtt
MQTT
netns
opendigitaltwins
plugandplay
Podman
podman
protobuf
Protobuf
ps
repo
Repo
rm
rustup
sdk
sdl
SDL
slirp
snapd
standalone
sudo
timothee
toml
Expand All @@ -62,4 +80,5 @@ toolchain
uri
URI
www
xargs
yaml
15 changes: 15 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.git
.gitattributes
.gitignore
.dockerignore

debug/
target/

.devcontainer/
.github/
devops/
docs/
tools/

Cargo.lock
78 changes: 78 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
# SPDX-License-Identifier: MIT

# syntax=docker/dockerfile:1

# Comments are provided throughout this file to help you get started.
# If you need more help, visit the Dockerfile reference guide at
# https://docs.docker.com/engine/reference/builder/

################################################################################
# Create a stage for building the application.

ARG RUST_VERSION=1.72.1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a way for this to be controlled by the rust-toolchain.toml file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not in a simple way, there may be a way to copy the value from the rust-toolchain.toml file or install rust manually but I am not sure it is worth it at this point.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this goes in as is, then let's make it a high priority follow-up to address this. I have some ideas on how to do this. Perhaps we can have a 15 min brainstorming on the best way to do it and to make sure that the solution gets into all of our software components.

FROM docker.io/library/rust:${RUST_VERSION}-slim-bullseye AS build
ARG APP_NAME=invehicle-digital-twin
WORKDIR /sdv
devkelley marked this conversation as resolved.
Show resolved Hide resolved

COPY ./ .

# Add Build dependencies.
RUN apt update && apt upgrade -y && apt install -y protobuf-compiler

# Check that APP_NAME argument is valid.
RUN sanitized=$(echo "${APP_NAME}" | tr -dc '^[a-zA-Z_0-9-]+$'); \
[ "$sanitized" = "${APP_NAME}" ] || { \
echo "ARG 'APP_NAME' is invalid. APP_NAME='${APP_NAME}' sanitized='${sanitized}'"; \
exit 1; \
}

# Build the application with the 'containerize' feature.
RUN cargo build --release -p "${APP_NAME}" --features "containerize"

# Copy the built application to working directory.
RUN cp ./target/release/"${APP_NAME}" /sdv/service

################################################################################
# Create a new stage for running the application that contains the minimal
# runtime dependencies for the application. This often uses a different base
# image from the build stage where the necessary files are copied from the build
# stage.
#
# The example below uses the debian bullseye image as the foundation for running the app.
# By specifying the "bullseye-slim" tag, it will also use whatever happens to be the
# most recent version of that tag when you build your Dockerfile. If
# reproducability is important, consider using a digest
# (e.g., debian@sha256:ac707220fbd7b67fc19b112cee8170b41a9e97f703f588b2cdbbcdcecdd8af57).
FROM docker.io/library/debian:bullseye-slim AS final

# Create a non-privileged user that the app will run under.
# See https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user
ARG UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${UID}" \
appuser
USER appuser

WORKDIR /sdv

# Set home environment variable.
ENV IBEJI_HOME=/sdv

# Copy the executable from the "build" stage.
COPY --from=build /sdv/service /sdv/

# Copy configuration for service.
COPY --from=build /sdv/container/config/standalone/ /sdv/

# Expose the port that the application listens on.
EXPOSE 5010

# What the container should run when it is started.
CMD ["/sdv/service"]
78 changes: 78 additions & 0 deletions Dockerfile.integrated
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
# SPDX-License-Identifier: MIT

# syntax=docker/dockerfile:1

# Comments are provided throughout this file to help you get started.
# If you need more help, visit the Dockerfile reference guide at
# https://docs.docker.com/engine/reference/builder/

################################################################################
# Create a stage for building the application.

ARG RUST_VERSION=1.72.1
FROM docker.io/library/rust:${RUST_VERSION}-slim-bullseye AS build
ARG APP_NAME=invehicle-digital-twin
WORKDIR /sdv

COPY ./ .

# Add Build dependencies.
RUN apt update && apt upgrade -y && apt install -y protobuf-compiler

# Check that APP_NAME argument is valid.
RUN sanitized=$(echo "${APP_NAME}" | tr -dc '^[a-zA-Z_0-9-]+$'); \
[ "$sanitized" = "${APP_NAME}" ] || { \
echo "ARG 'APP_NAME' is invalid. APP_NAME='${APP_NAME}' sanitized='${sanitized}'"; \
exit 1; \
}

# Build the application with the 'containerize' feature.
RUN cargo build --release -p "${APP_NAME}" --features "containerize managed_subscribe"

# Copy the built application to working directory.
RUN cp ./target/release/"${APP_NAME}" /sdv/service

################################################################################
# Create a new stage for running the application that contains the minimal
# runtime dependencies for the application. This often uses a different base
# image from the build stage where the necessary files are copied from the build
# stage.
#
# The example below uses the debian bullseye image as the foundation for running the app.
# By specifying the "bullseye-slim" tag, it will also use whatever happens to be the
# most recent version of that tag when you build your Dockerfile. If
# reproducability is important, consider using a digest
# (e.g., debian@sha256:ac707220fbd7b67fc19b112cee8170b41a9e97f703f588b2cdbbcdcecdd8af57).
FROM docker.io/library/debian:bullseye-slim AS final

# Create a non-privileged user that the app will run under.
# See https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user
ARG UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${UID}" \
appuser
USER appuser

WORKDIR /sdv

# Set home environment variable.
ENV IBEJI_HOME=/sdv

# Copy the executable from the "build" stage.
COPY --from=build /sdv/service /sdv/

# Copy configuration for service.
COPY --from=build /sdv/container/config/integrated/ /sdv/

# Expose the port that the application listens on.
EXPOSE 5010

# What the container should run when it is started.
CMD ["/sdv/service"]
96 changes: 96 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- [Install Rust](#install-rust)
- [Install Protobuf Compiler](#install-protobuf-compiler)
- [Install SDL2 library](#install-sdl2-library)
- [Install dotnet-sdk library](#install-dotnet-sdk-library)
- [Install MQTT Broker](#install-mqtt-broker)
- [Cloning the Repo](#cloning-the-repo)
- [Building](#building)
Expand All @@ -18,6 +19,10 @@
- [Seat Massager Sample](#seat-massager-sample)
- [Streaming Sample](#streaming-sample)
- [Using Chariott](#using-chariott)
- [Running in a Container](#running-in-a-container)
- [Docker](#docker)
- [Podman](#podman)
- [Dockerfile](#dockerfile)
- [Trademarks](#trademarks)

## <a name="introduction">Introduction</a>
Expand All @@ -35,6 +40,10 @@ the nature of the capability, how to work with it and how it can be remotely acc

## <a name="prerequisites">Prerequisites</a>

We recommend the use of Ubuntu 22.04 for running the In-Vehicle Digital Twin Service. Other
operating systems or versions of Ubuntu may encounter issues. We invite others to help us find and
resolve any compatibility issues.

### <a name="install-gcc">Install gcc</a>

Rust needs gcc's linker, so you will need to install it. To install gcc, do the following:
Expand Down Expand Up @@ -72,6 +81,14 @@ You will need to install the libsdl2-dev library. This can be done by executing:
sudo apt install -y libsdl2-dev
```

### <a name="install-dotnet-sdk-library">Install dotnet-sdk library</a>
devkelley marked this conversation as resolved.
Show resolved Hide resolved

You will need to install dotnet-sdk for the dtdl-tools crate. This can be done by executing:

```shell
sudo apt install -y dotnet-sdk-7.0
```

### <a name="install-mqtt-broker">Install MQTT Broker</a>

If you plan to run any of the samples that use MQTT, then you will need to install a MQTT Broker, like [Mosquitto](https://github.com/eclipse/mosquitto).
Expand Down Expand Up @@ -270,6 +287,85 @@ rather than having it statically provided in their respective config file, then
`chariott_uri: "http://0.0.0.0:50000"`<br>
1. In the consumer's config file and the provider's config file, remove the setting for invehicle_digital_twin_uri, so that the chariott_uri will be used to find the In-vehicle Digital Twin URI.<br>

## <a name="running-in-a-container">Running in a Container</a>

Below are the steps for running the service in a container. Note that the configuration files used
by the containerized service are cloned from [container/config](./container/config/) defined in the
project's root.

### <a name="docker">Docker</a>

<b>Prerequisites</b>

[Install Docker](https://docs.docker.com/engine/install/)

<b>Running in Docker</b>

To run the service in a Docker container:

1. Run the following command in the project's root directory to build the docker container from the
Dockerfile:

```shell
docker build -t invehicle_digital_twin -f Dockerfile .
```

1. Once the container has been built, start the container in interactive mode with the following
command in the project's root directory:

```shell
docker run --name invehicle_digital_twin -p 5010:5010 --env-file=./container/config/docker.env --add-host=host.docker.internal:host-gateway -it --rm invehicle_digital_twin
```

1. To detach from the container, enter:

<kbd>Ctrl</kbd> + <kbd>p</kbd>, <kbd>Ctrl</kbd> + <kbd>q</kbd>

1. To stop the container, enter:

```shell
docker stop invehicle_digital_twin
```

### <a name="podman">Podman</a>

<b>Prerequisites</b>

[Install Podman](https://podman.io/docs/installation)

<b>Running in Podman</b>

To run the service in a Podman container:

1. Run the following command in the project's root directory to build the podman container from the
Dockerfile:

```shell
podman build -t invehicle_digital_twin:latest -f Dockerfile .
```

1. Once the container has been built, start the container with the following command in the
project's root directory:

```shell
podman run -p 5010:5010 --env-file=./container/config/podman.env --network=slirp4netns:allow_host_loopback=true localhost/invehicle_digital_twin
```

1. To stop the container, run:

```shell
podman ps -f ancestor=localhost/invehicle_digital_twin:latest --format="{{.Names}}" | xargs podman stop
```

### <a name="dockerfile">Dockerfile</a>
devkelley marked this conversation as resolved.
Show resolved Hide resolved

There are currently two dockerfiles provided in the root directory of the project that can be built:

- Dockerfile - A standalone version of the In-Vehicle Digital Twin Service
- Dockerfile.integrated - A version of the In-Vehicle Digital Twin Service that communicates with
devkelley marked this conversation as resolved.
Show resolved Hide resolved
the [Chariott Service](https://github.com/eclipse-chariott/chariott) and the
[Agemo Service](https://github.com/eclipse-chariott/Agemo).

## <a name="trademarks">Trademarks</a>

This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft
Expand Down
9 changes: 9 additions & 0 deletions container/config/docker.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
# SPDX-License-Identifier: MIT

# DNS name used by the container to communicate with host.
HOST_GATEWAY=host.docker.internal

# Alias for localhost to be replaced by HOST_GATEWAY if run in a container.
LOCALHOST_ALIAS=0.0.0.0
11 changes: 11 additions & 0 deletions container/config/integrated/invehicle_digital_twin_settings.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#
# In-Vehicle Digital Twin Service Settings
#

# The IP address and port number that the in-vehicle digital twin service listens on for digital twin requests.
# Example: "0.0.0.0:5010"
invehicle_digital_twin_authority: "0.0.0.0:5010"

# The URL that the Chariott service listens on for requests.
# If you wish to use Chariott, then uncomment this setting.
chariott_uri: "http://0.0.0.0:50000" # DevSkim: ignore DS137138
Loading
Loading