Skip to content

Commit f28b9ff

Browse files
authored
Dev/hshami/udate wiki (#527)
* update documentation
1 parent 2fab5ab commit f28b9ff

6 files changed

Lines changed: 297 additions & 51 deletions

File tree

.devcontainer/Dockerfile

Lines changed: 43 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,75 @@
11
# Dependencies versions
2-
ARG PYTHON_VERSION="3.9.10"
2+
ARG PYTHON_VERSION="3.9"
33

4-
# see https://hub.docker.com/_/python/?tab=tag
5-
FROM python:${PYTHON_VERSION}-buster
4+
FROM mcr.microsoft.com/vscode/devcontainers/python:0-${PYTHON_VERSION}
65

76
# Dependencies versions
8-
ARG AZURE_CLI_VERSION="2.24.0-1~buster"
9-
ARG NODE_VERSION="15.x"
7+
ARG AZURE_CLI_VERSION="2.34.1-1~bullseye"
8+
ARG NODE_VERSION="17.x"
109
ARG DOTNET_VERSION="5.0"
11-
ARG JDK_VERSION="2:1.11-71"
12-
ARG MAVEN_VERSION="3.6.0-1"
10+
ARG JDK_VERSION="2:1.11-72"
11+
ARG MAVEN_VERSION="3.6.3-5"
1312

14-
RUN apt-get update && \
15-
apt-get upgrade -y && \
16-
apt-get install -y --no-install-recommends build-essential && \
17-
apt-get install -y libffi-dev libssl-dev vim
13+
# Bring in utility scripts
14+
COPY .devcontainer/library-scripts/*.sh /tmp/library-scripts/
1815

19-
# Install python development dependencies
20-
ADD requirements_dev.txt requirements.txt /tmp/
21-
RUN python -m pip install --upgrade pip
22-
RUN pip install -r /tmp/requirements_dev.txt
16+
RUN \
17+
# Install some basics
18+
apt-get update && \
19+
apt-get upgrade -y && \
20+
apt-get install -y --no-install-recommends build-essential apt-utils && \
21+
apt-get install -y libffi-dev libssl-dev vim sudo && \
22+
apt-get upgrade -y
2323

2424
RUN \
25-
# Install the Azure CLI and IoT extension
25+
# Upgrade to latest pip
26+
python -m pip install --upgrade pip && \
27+
# Install node, npm
28+
curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION} | bash - && \
29+
apt-get install -y nodejs && \
30+
npm install npm@latest -g && \
31+
# Install azure-cli
2632
apt-get install -y ca-certificates curl apt-transport-https lsb-release gnupg && \
2733
curl -sL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor | tee /etc/apt/trusted.gpg.d/microsoft.gpg > /dev/null && \
2834
echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/azure-cli.list && \
2935
apt-get update && apt-get install -y azure-cli=${AZURE_CLI_VERSION} && \
3036
az extension add --name azure-iot --system && \
3137
az extension update --name azure-iot && \
32-
# Install Docker CE CLI
33-
apt-get install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common lsb-release && \
34-
curl -fsSL https://download.docker.com/linux/$(lsb_release -is | tr '[:upper:]' '[:lower:]')/gpg | apt-key add - 2>/dev/null && \
35-
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/$(lsb_release -is | tr '[:upper:]' '[:lower:]') $(lsb_release -cs) stable" && \
36-
apt-get update && \
37-
apt-get install -y docker-ce-cli && \
38-
# Install node, npm, Yoeman, node.js modules
39-
curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION} | bash - && \
40-
apt-get install -y nodejs && \
38+
# Use Docker script from script library to set things up - enable non-root docker, user vscode, using moby
39+
/bin/bash /tmp/library-scripts/docker-in-docker-debian.sh "true" "vscode" "true" \
40+
# Install Yoeman, node.js modules
4141
npm install -g yo && \
4242
npm i -g yo generator-azure-iot-edge-module && \
43-
cd ~ && \
4443
# Install dotnet SDK
45-
wget https://packages.microsoft.com/config/debian/10/packages-microsoft-prod.deb -O packages-microsoft-prod.deb && \
44+
cd ~ && \
45+
wget https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb -O packages-microsoft-prod.deb && \
4646
dpkg -i packages-microsoft-prod.deb && \
4747
rm packages-microsoft-prod.deb && \
4848
apt-get update && apt-get install -y apt-transport-https && \
4949
apt-get update && apt-get install -y dotnet-sdk-${DOTNET_VERSION} && \
5050
# Install Java JDK, Maven
5151
apt-get install -y default-jdk=${JDK_VERSION} && \
5252
apt-get install -y maven=${MAVEN_VERSION} && \
53-
#
53+
# Install bash completion
54+
apt-get update && apt-get -y install bash-completion && \
5455
# Clean up
5556
apt-get autoremove -y && \
5657
apt-get clean -y && \
5758
rm -rf /tmp/* && \
5859
rm -rf /var/lib/apt/lists/*
5960

60-
# Customize bash
61+
# customize vscode environmnet
62+
USER vscode
6163
RUN \
62-
# Git command prompt
63-
git clone https://github.com/magicmonty/bash-git-prompt.git ~/.bash-git-prompt --depth=1 && \
64-
echo "if [ -f \"$HOME/.bash-git-prompt/gitprompt.sh\" ]; then GIT_PROMPT_ONLY_IN_REPO=1 && source $HOME/.bash-git-prompt/gitprompt.sh; fi" >> "/root/.bashrc" && \
65-
# Install bash completion
66-
apt-get update && \
67-
apt-get -y install bash-completion && \
68-
echo "source /usr/share/bash-completion/bash_completion" >> ~/.bashrc
64+
git clone https://github.com/magicmonty/bash-git-prompt.git $HOME/.bash-git-prompt --depth=1 && \
65+
echo "\n# setup GIT prompt and completion\nif [ -f \"$HOME/.bash-git-prompt/gitprompt.sh\" ]; then\n GIT_PROMPT_ONLY_IN_REPO=1 && source $HOME/.bash-git-prompt/gitprompt.sh;\nfi" >> $HOME/.bashrc && \
66+
echo "source /usr/share/bash-completion/bash_completion" >> $HOME/.bashrc && \
67+
echo "\n# add local python programs to PATH\nexport PATH=$PATH:$HOME/.local/bin\n" >> $HOME/.bashrc && \
68+
# enable some useful aliases
69+
sed -i -e "s/#alias/alias/" $HOME/.bashrc && \
70+
# add the cookiecutter
71+
pip install cookiecutter
72+
73+
# launch docker-ce
74+
ENTRYPOINT [ "/usr/local/share/docker-init.sh" ]
75+
CMD [ "sleep", "infinity" ]

.devcontainer/devcontainer.json

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,23 @@
44
"name": "iotedgedev",
55
"build": {
66
"dockerfile": "Dockerfile",
7-
"context": "..",
7+
"context": ".."
88
},
99

10-
"runArgs": [
11-
"--network",
12-
"host"
13-
],
14-
15-
"postCreateCommand": "pip install -e .",
10+
"runArgs": ["--init", "--privileged"],
1611
"mounts": [
1712
// Keep command history
1813
"source=ostf-bashhistory,target=/commandhistory,type=volume",
19-
// Use hosts docker socket
20-
"source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind",
14+
// Use docker-in-docker socket
15+
"source=dind-var-lib-docker,target=/var/lib/docker,type=volume"
2116
],
2217

18+
"overrideCommand": false,
19+
"postCreateCommand": "docker image prune -a -f && sudo chown vscode:users -R /home/vscode/Dev && pip install -r requirements_dev.txt && pip install -e .",
20+
2321
// Set *default* container specific settings.json values on container create.
2422
"settings": {
25-
"#terminal.integrated.defaultProfile.linux#": "/bin/bash",
23+
"#terminal.integrated.defaultProfile.linux#": "/bin/bash"
2624
},
2725

2826
// Add the IDs of extensions you want installed when the container is created.
@@ -34,5 +32,9 @@
3432
"streetsidesoftware.code-spell-checker",
3533
"yzhang.markdown-all-in-one",
3634
"davidanson.vscode-markdownlint"
37-
]
35+
],
36+
37+
"workspaceMount": "source=${localWorkspaceFolder},target=/home/vscode/Dev,type=bind,consistency=cached",
38+
"workspaceFolder": "/home/vscode/Dev",
39+
"remoteUser": "vscode"
3840
}
Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
#!/usr/bin/env bash
2+
#-------------------------------------------------------------------------------------------------------------
3+
# Copyright (c) Microsoft Corporation. All rights reserved.
4+
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
5+
#-------------------------------------------------------------------------------------------------------------
6+
#
7+
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/docker-in-docker.md
8+
# Maintainer: The VS Code and Codespaces Teams
9+
#
10+
# Syntax: ./docker-in-docker-debian.sh [enable non-root docker access flag] [non-root user] [use moby]
11+
12+
ENABLE_NONROOT_DOCKER=${1:-"true"}
13+
USERNAME=${2:-"automatic"}
14+
USE_MOBY=${3:-"true"}
15+
MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc"
16+
17+
set -e
18+
19+
if [ "$(id -u)" -ne 0 ]; then
20+
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
21+
exit 1
22+
fi
23+
24+
# Determine the appropriate non-root user
25+
if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then
26+
USERNAME=""
27+
POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)")
28+
for CURRENT_USER in ${POSSIBLE_USERS[@]}; do
29+
if id -u ${CURRENT_USER} > /dev/null 2>&1; then
30+
USERNAME=${CURRENT_USER}
31+
break
32+
fi
33+
done
34+
if [ "${USERNAME}" = "" ]; then
35+
USERNAME=root
36+
fi
37+
elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then
38+
USERNAME=root
39+
fi
40+
41+
# Get central common setting
42+
get_common_setting() {
43+
if [ "${common_settings_file_loaded}" != "true" ]; then
44+
curl -sfL "https://aka.ms/vscode-dev-containers/script-library/settings.env" 2>/dev/null -o /tmp/vsdc-settings.env || echo "Could not download settings file. Skipping."
45+
common_settings_file_loaded=true
46+
fi
47+
if [ -f "/tmp/vsdc-settings.env" ]; then
48+
local multi_line=""
49+
if [ "$2" = "true" ]; then multi_line="-z"; fi
50+
local result="$(grep ${multi_line} -oP "$1=\"?\K[^\"]+" /tmp/vsdc-settings.env | tr -d '\0')"
51+
if [ ! -z "${result}" ]; then declare -g $1="${result}"; fi
52+
fi
53+
echo "$1=${!1}"
54+
}
55+
56+
# Function to run apt-get if needed
57+
apt_get_update_if_needed()
58+
{
59+
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
60+
echo "Running apt-get update..."
61+
apt-get update
62+
else
63+
echo "Skipping apt-get update."
64+
fi
65+
}
66+
67+
# Checks if packages are installed and installs them if not
68+
check_packages() {
69+
if ! dpkg -s "$@" > /dev/null 2>&1; then
70+
apt_get_update_if_needed
71+
apt-get -y install --no-install-recommends "$@"
72+
fi
73+
}
74+
75+
# Ensure apt is in non-interactive to avoid prompts
76+
export DEBIAN_FRONTEND=noninteractive
77+
78+
# Install dependencies
79+
check_packages apt-transport-https curl ca-certificates lxc pigz iptables gnupg2 dirmngr
80+
81+
# Swap to legacy iptables for compatibility
82+
if type iptables-legacy > /dev/null 2>&1; then
83+
update-alternatives --set iptables /usr/sbin/iptables-legacy
84+
update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
85+
fi
86+
87+
# Install Docker / Moby CLI if not already installed
88+
architecture="$(dpkg --print-architecture)"
89+
if type docker > /dev/null 2>&1 && type dockerd > /dev/null 2>&1; then
90+
echo "Docker / Moby CLI and Engine already installed."
91+
else
92+
# Source /etc/os-release to get OS info
93+
. /etc/os-release
94+
if [ "${USE_MOBY}" = "true" ]; then
95+
# Import key safely (new 'signed-by' method rather than deprecated apt-key approach) and install
96+
get_common_setting MICROSOFT_GPG_KEYS_URI
97+
curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg
98+
echo "deb [arch=${architecture} signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/repos/microsoft-${ID}-${VERSION_CODENAME}-prod ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/microsoft.list
99+
apt-get update
100+
apt-get -y install --no-install-recommends moby-cli moby-buildx moby-engine
101+
apt-get -y install --no-install-recommends moby-compose || echo "(*) Package moby-compose (Docker Compose v2) not available for ${VERSION_CODENAME} ${architecture}. Skipping."
102+
else
103+
# Import key safely (new 'signed-by' method rather than deprecated apt-key approach) and install
104+
curl -fsSL https://download.docker.com/linux/${ID}/gpg | gpg --dearmor > /usr/share/keyrings/docker-archive-keyring.gpg
105+
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/${ID} ${VERSION_CODENAME} stable" > /etc/apt/sources.list.d/docker.list
106+
apt-get update
107+
apt-get -y install --no-install-recommends docker-ce-cli docker-ce
108+
fi
109+
fi
110+
111+
echo "Finished installing docker / moby"
112+
113+
# Install Docker Compose if not already installed and is on a supported architecture
114+
if type docker-compose > /dev/null 2>&1; then
115+
echo "Docker Compose already installed."
116+
else
117+
target_compose_arch="${architecture}"
118+
if [ "${target_compose_arch}" != "x86_64" ]; then
119+
# Use pip to get a version that runns on this architecture
120+
if ! dpkg -s python3-minimal python3-pip libffi-dev python3-venv > /dev/null 2>&1; then
121+
apt_get_update_if_needed
122+
apt-get -y install python3-minimal python3-pip libffi-dev python3-venv
123+
fi
124+
export PIPX_HOME=/usr/local/pipx
125+
mkdir -p ${PIPX_HOME}
126+
export PIPX_BIN_DIR=/usr/local/bin
127+
export PYTHONUSERBASE=/tmp/pip-tmp
128+
export PIP_CACHE_DIR=/tmp/pip-tmp/cache
129+
pipx_bin=pipx
130+
if ! type pipx > /dev/null 2>&1; then
131+
pip3 install --disable-pip-version-check --no-warn-script-location --no-cache-dir --user pipx
132+
pipx_bin=/tmp/pip-tmp/bin/pipx
133+
fi
134+
${pipx_bin} install --system-site-packages --pip-args '--no-cache-dir --force-reinstall' docker-compose
135+
rm -rf /tmp/pip-tmp
136+
else
137+
latest_compose_version=$(basename "$(curl -fsSL -o /dev/null -w "%{url_effective}" https://github.com/docker/compose/releases/latest)")
138+
curl -fsSL "https://github.com/docker/compose/releases/download/${latest_compose_version}/docker-compose-$(uname -s)-${target_compose_arch}" -o /usr/local/bin/docker-compose
139+
chmod +x /usr/local/bin/docker-compose
140+
fi
141+
fi
142+
143+
# If init file already exists, exit
144+
if [ -f "/usr/local/share/docker-init.sh" ]; then
145+
echo "/usr/local/share/docker-init.sh already exists, so exiting."
146+
exit 0
147+
fi
148+
echo "docker-init doesnt exist..."
149+
150+
# Add user to the docker group
151+
if [ "${ENABLE_NONROOT_DOCKER}" = "true" ]; then
152+
if ! getent group docker > /dev/null 2>&1; then
153+
groupadd docker
154+
fi
155+
156+
usermod -aG docker ${USERNAME}
157+
fi
158+
159+
tee /usr/local/share/docker-init.sh > /dev/null \
160+
<< 'EOF'
161+
#!/usr/bin/env bash
162+
#-------------------------------------------------------------------------------------------------------------
163+
# Copyright (c) Microsoft Corporation. All rights reserved.
164+
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
165+
#-------------------------------------------------------------------------------------------------------------
166+
167+
sudoIf()
168+
{
169+
if [ "$(id -u)" -ne 0 ]; then
170+
sudo "$@"
171+
else
172+
"$@"
173+
fi
174+
}
175+
176+
# explicitly remove dockerd and containerd PID file to ensure that it can start properly if it was stopped uncleanly
177+
# ie: docker kill <ID>
178+
sudoIf find /run /var/run -iname 'docker*.pid' -delete || :
179+
sudoIf find /run /var/run -iname 'container*.pid' -delete || :
180+
181+
set -e
182+
183+
## Dind wrapper script from docker team
184+
# Maintained: https://github.com/moby/moby/blob/master/hack/dind
185+
186+
export container=docker
187+
188+
if [ -d /sys/kernel/security ] && ! sudoIf mountpoint -q /sys/kernel/security; then
189+
sudoIf mount -t securityfs none /sys/kernel/security || {
190+
echo >&2 'Could not mount /sys/kernel/security.'
191+
echo >&2 'AppArmor detection and --privileged mode might break.'
192+
}
193+
fi
194+
195+
# Mount /tmp (conditionally)
196+
if ! sudoIf mountpoint -q /tmp; then
197+
sudoIf mount -t tmpfs none /tmp
198+
fi
199+
200+
# cgroup v2: enable nesting
201+
if [ -f /sys/fs/cgroup/cgroup.controllers ]; then
202+
# move the init process (PID 1) from the root group to the /init group,
203+
# otherwise writing subtree_control fails with EBUSY.
204+
sudoIf mkdir -p /sys/fs/cgroup/init
205+
sudoIf echo 1 > /sys/fs/cgroup/init/cgroup.procs
206+
# enable controllers
207+
sudoIf sed -e 's/ / +/g' -e 's/^/+/' < /sys/fs/cgroup/cgroup.controllers \
208+
> /sys/fs/cgroup/cgroup.subtree_control
209+
fi
210+
## Dind wrapper over.
211+
212+
# Handle DNS
213+
set +e
214+
cat /etc/resolv.conf | grep -i 'internal.cloudapp.net'
215+
if [ $? -eq 0 ]
216+
then
217+
echo "Setting dockerd Azure DNS."
218+
CUSTOMDNS="--dns 168.63.129.16"
219+
else
220+
echo "Not setting dockerd DNS manually."
221+
CUSTOMDNS=""
222+
fi
223+
set -e
224+
225+
# Start docker/moby engine
226+
( sudoIf dockerd $CUSTOMDNS > /tmp/dockerd.log 2>&1 ) &
227+
228+
set +e
229+
230+
# Execute whatever commands were passed in (if any). This allows us
231+
# to set this script to ENTRYPOINT while still executing the default CMD.
232+
exec "$@"
233+
EOF
234+
235+
chmod +x /usr/local/share/docker-init.sh
236+
chown ${USERNAME}:root /usr/local/share/docker-init.sh

0 commit comments

Comments
 (0)