Skip to content

Commit d1456c6

Browse files
committed
Update template to easier instructions
1 parent 2413fcd commit d1456c6

12 files changed

Lines changed: 307 additions & 104 deletions

File tree

.dockerignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Applies to build only, ignore everything by default
2+
**
3+
4+
# Keep only files needed for build
5+
!environment.yml
6+
!pyproject.toml
7+
!docker/
8+
!docker-compose.yml

.env

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,20 @@ XAUTH=/tmp/.docker.xauth
44
AVAILABLE_CORES=$(($(nproc) - 1))
55

66
DOCKER_USER=todo-docker-user
7+
BASE_IMAGE=todo-base-image
78
IMAGE_NAME=todo-image-name
9+
IMAGE_USER=todo-image-user
810
IMAGE_TAG=latest
11+
TIME_ZONE=$(cat /etc/timezone 2>/dev/null || readlink /etc/localtime | sed 's|.*/zoneinfo/||')
12+
TIME_ZONE=${TIME_ZONE:-UTC}
913

1014
CONTAINER_NAME=${IMAGE_NAME}
11-
CONTAINER_HOME_FOLDER=/root
15+
HOME_FOLDER=/home/${IMAGE_USER}
1216
CODE_FOLDER=${IMAGE_NAME}
1317

1418
HOST_UID=$(id -u)
1519
HOST_GID=$(id -g)
16-
HOSTNAME=${HOSTNAME}
20+
HOST=${HOST:-$(hostname)}
21+
HOSTNAME=${HOSTNAME:-$(hostname)}
22+
23+
BUILDER=multi-platform

README.md

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88

99
## Usage Guidelines
1010

11-
### Base Repo
11+
TLDR: Search for `todo` and update all occurrences to your desired name
12+
13+
### Base Repository
1214

1315
1. Change [LICENSE](LICENSE) if necessary
1416

@@ -18,19 +20,37 @@
1820

1921
### Docker Config
2022

21-
1. Modify **DOCKER_USER**, **IMAGE_NAME** in [.env](.env)
23+
1. Modify `todo-docker-user`, `todo-base-image`, `todo-image-name`, `todo-image-user` in [.env](.env)
24+
25+
- [.env](.env) will be loaded when you use docker compose for build/run/push
26+
- `todo-docker-user` refers to your docker hub account username
27+
- `todo-base-image` is the image dockerfile is based on, such as `nvidia/cuda:13.0.0-cudnn-devel-ubuntu24.04`
28+
- `todo-image-user` refers to the default user inside the image, which is used to determine home folder
2229

23-
1. Modify the service name from **default** to your service name in [docker-compose.yml](docker-compose.yml)
30+
1. Modify the service name from `todo-service-name` to your service name in [docker-compose.yml](docker-compose.yml), add additional volume mounting options such as dataset directories
2431

25-
1. Update [Dockerfile](docker/latest/Dockerfile)
32+
1. Update [Dockerfile](docker/latest/Dockerfile) and [.dockerignore](.dockerignore)
33+
34+
- Existing dockerfile has screen & tmux config, oh-my-zsh, cmake, and other basic goodies
35+
- Add any additional dependency installations at appropriate locations
2636

2737
1. [build.sh](scripts/build.sh) to build and test the image locally in your machine's architecture
2838

29-
1. [push.sh](scripts/push.sh) to push the multi-arch image to the registry
39+
- The scripts uses buildx to build multi-arch image, you can disable this by removing redundant archs in [docker-compose.yml](docker-compose.yml)
40+
- Building stage does not have GPU access, if some of your dependencies need GPU, build them inside a running container and commit to the final image
41+
42+
1. [run_container.sh](scripts/run_container.sh) or `docker compose up -d` to run and test a built image
43+
44+
- The service by default will mount the whole repository onto `CODE_FOLDER` inside the container so any modification inside also takes effect outside, which is useful when you use vscode remote extension to develop inside a running container with remote docker context
45+
- You should be able to run and see GUI applications inside the container if `DISPLAY` is set correctly when you run the script
46+
47+
1. [push.sh](scripts/push.sh) to push the multi-arch image to docker hub
48+
49+
- You should have the docker hub repository set up before pushing
3050

3151
## Developer Quick Start
3252

33-
- Run [scripts/dev-setup.sh](scripts/dev-setup.sh) to setup the development environment
53+
- Run [scripts/dev_setup.sh](scripts/dev_setup.sh) to setup the development environment
3454

3555
## Note
3656

docker-compose.yml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
version: "3"
2-
31
services:
4-
default:
2+
todo-service-name:
53
build:
64
dockerfile: ./docker/${IMAGE_TAG}/Dockerfile
75
x-bake:
@@ -17,7 +15,8 @@ services:
1715
pull_policy: missing
1816
container_name: ${CONTAINER_NAME}
1917
privileged: true
20-
hostname: ${HOSTNAME}
18+
user: root
19+
hostname: ${HOST}
2120
network_mode: host
2221
ipc: host
2322
pid: host
@@ -34,8 +33,8 @@ services:
3433
- /var/lib/systemd/coredump/:/cores
3534
- /tmp/.X11-unix/:/tmp/.X11-unix/:rw
3635
- ${XAUTH}:${XAUTH}
37-
- .:${CONTAINER_HOME_FOLDER}/${CODE_FOLDER}
38-
working_dir: ${CONTAINER_HOME_FOLDER}/${CODE_FOLDER}
36+
- .:${HOME_FOLDER}/${CODE_FOLDER}
37+
working_dir: ${HOME_FOLDER}/${CODE_FOLDER}
3938
stdin_open: true # for -it
4039
tty: true # for -it
4140
# command: /bin/zsh

docker/latest/Dockerfile

Lines changed: 120 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,137 @@
11
# Do not add --platform=linux/blabla since this is intended for multiplatform builds
2-
FROM tomnotch/bipvrobotics-base-image:latest
3-
ENV HOME_FOLDER=/root
4-
WORKDIR $HOME_FOLDER/
2+
FROM ${BASE_IMAGE}
3+
ENV HOME=${HOME_FOLDER}
4+
WORKDIR ${HOME_FOLDER}/
5+
6+
# Make home folder if not exists
7+
RUN mkdir -p ${HOME_FOLDER}
58

69
# Fix apt install stuck problem
710
ENV DEBIAN_FRONTEND=noninteractive
811
RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
912

13+
# Copy home folder config
14+
COPY --from=home-folder-config . ${HOME_FOLDER}/
15+
1016
# update all obsolete packages to latest, install sudo, and cleanup
1117
RUN apt update -o Acquire::Check-Valid-Until=false -o Acquire::AllowInsecureRepositories=true -o Acquire::AllowDowngradeToInsecureRepositories=true && \
1218
apt full-upgrade -y && \
1319
apt install -y sudo ca-certificates && \
1420
apt autoremove -y && \
1521
apt autoclean -y
1622

23+
# fix local time problem
24+
RUN apt-get install -y --no-install-recommends tzdata && \
25+
ln -fs /usr/share/zoneinfo/${TIME_ZONE} /etc/localtime && \
26+
echo "${TIME_ZONE}" > /etc/timezone && \
27+
dpkg-reconfigure --frontend noninteractive tzdata
28+
29+
# update all obsolete packages to latest, install sudo, and cleanup
30+
RUN apt update -o Acquire::Check-Valid-Until=false -o Acquire::AllowInsecureRepositories=true -o Acquire::AllowDowngradeToInsecureRepositories=true && \
31+
apt full-upgrade -y && \
32+
apt install -y sudo ca-certificates && \
33+
apt autoremove -y && \
34+
apt autoclean -y
35+
36+
# Install some goodies
37+
RUN apt-get install -y --no-install-recommends \
38+
build-essential \
39+
clang-format \
40+
curl \
41+
dirmngr \
42+
git \
43+
gnupg \
44+
htop \
45+
less \
46+
locate \
47+
lsb-release \
48+
nano \
49+
ncdu \
50+
net-tools \
51+
perl \
52+
screen \
53+
software-properties-common \
54+
tmux \
55+
tmuxp \
56+
tree \
57+
unzip \
58+
valgrind \
59+
vim \
60+
wget \
61+
zsh
62+
63+
# upgrade cmake to kitware official apt-get repo release version
64+
RUN wget https://apt-get.kitware.com/kitware-archive.sh -O- | sh -s && \
65+
apt-get upgrade -y cmake && \
66+
apt-get autoremove -y
67+
1768
# # Add a new group and user
18-
# RUN addgroup --gid 1000 $USER && \
19-
# adduser --uid 1000 --ingroup $USER --home $HOME_FOLDER --shell /bin/zsh --disabled-password --gecos "" $USER && \
20-
# echo "$USER ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
69+
# RUN addgroup --gid 1000 $IMAGE_USER && \
70+
# adduser --uid 1000 --ingroup $IMAGE_USER --home ${HOME_FOLDER} --shell /bin/zsh --disabled-password --gecos "" $IMAGE_USER && \
71+
# echo "$IMAGE_USER ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
2172

2273
# # Fix UID/GID when mounting from host using this: https://github.com/boxboat/fixuid
2374
# RUN curl -SsL https://github.com/boxboat/fixuid/releases/download/v0.6.0/fixuid-0.6.0-linux-amd64.tar.gz | tar -C /usr/local/bin -xzf - && \
2475
# chown root:root /usr/local/bin/fixuid && \
2576
# chmod 4755 /usr/local/bin/fixuid && \
2677
# mkdir -p /etc/fixuid
2778

28-
# # Switch to the new user
29-
# USER $USER:$USER
30-
31-
#! Install OpenCV 4.2.0 with QUIRC support from source
32-
ENV OPENCV_VERSION=4.2.0
33-
RUN pip3 uninstall -y opencv && \
34-
apt install -y --no-install-recommends libavcodec-dev libavformat-dev libswscale-dev libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev libgtk-3-dev libpng-dev libjpeg-dev && \
35-
git clone --depth 1 --recursive https://github.com/opencv/opencv.git $HOME_FOLDER/opencv -b $OPENCV_VERSION && \
36-
# follow the error information,replace all the “ipcp-unit-growth” with “ipa-cp-unit-growth” in 3rdparty/carotene/CMakeLists.txt and 3rdparty/carotene/hal/CMakeLists.txt
37-
perl -pi -e 's/ipcp-unit-growth/ipa-cp-unit-growth/g' $HOME_FOLDER/opencv/3rdparty/carotene/CMakeLists.txt $HOME_FOLDER/opencv/3rdparty/carotene/hal/CMakeLists.txt && \
38-
git clone --depth 1 --recursive https://github.com/opencv/opencv_contrib.git $HOME_FOLDER/opencv_contrib -b $OPENCV_VERSION && \
39-
mkdir -p $HOME_FOLDER/opencv/build && \
40-
cd $HOME_FOLDER/opencv/build && \
41-
cmake \
42-
-D CMAKE_CXX_STANDARD=20 \
43-
-D EIGEN_INCLUDE_PATH=/usr/include/eigen3 \
44-
-D OPENCV_GENERATE_PKGCONFIG=ON \
45-
-D BUILD_opencv_python3=ON \
46-
-D OPENCV_PYTHON3_INSTALL_PATH=/usr/local/lib/python3.8/dist-packages \
47-
# -D OPENCV_ENABLE_NONFREE=ON \
48-
-D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules \
49-
# -D WITH_LAPACK=ON \
50-
-D WITH_GTK=ON \
51-
-D WITH_TBB=ON \
52-
# -D WITH_QUIRC=ON \
53-
-D WITH_GSTREAMER=ON \
54-
-D WITH_V4L=ON \
55-
# -D WITH_OPENGL=ON \
56-
-D BUILD_TESTS=OFF \
57-
-D BUILD_PERF_TESTS=OFF \
58-
-D BUILD_EXAMPLES=OFF \
59-
-D CMAKE_BUILD_TYPE=RELEASE \
60-
-D CMAKE_INSTALL_PREFIX=/usr/local .. && \
61-
make install -j$(($(nproc)-1)) && \
62-
echo "export OpenCV_DIR=/usr/local/lib/cmake/opencv4/" >> ${HOME_FOLDER}/.zshrc && \
63-
echo "export OpenCV_DIR=/usr/local/lib/cmake/opencv4/" >> ${HOME_FOLDER}/.bashrc && \
64-
rm -rf $HOME_FOLDER/opencv && \
65-
rm -rf $HOME_FOLDER/opencv_contrib
79+
# install zsh, Oh-My-Zsh, and plugins
80+
RUN sh -c "$(wget -O- https://github.com/deluan/zsh-in-docker/releases/latest/download/zsh-in-docker.sh)" -- \
81+
-t https://github.com/romkatv/powerlevel10k \
82+
-p git \
83+
-p https://github.com/zsh-users/zsh-autosuggestions \
84+
-p https://github.com/zsh-users/zsh-completions \
85+
-p https://github.com/zsh-users/zsh-syntax-highlighting \
86+
-a "[[ ! -f ${HOME_FOLDER}/.p10k.zsh ]] || source ${HOME_FOLDER}/.p10k.zsh" \
87+
-a "POWERLEVEL9K_DISABLE_GITSTATUS=true" \
88+
-a "bindkey -M emacs '^[[3;5~' kill-word" \
89+
-a "bindkey '^H' backward-kill-word" \
90+
-a "autoload -U compinit && compinit" \
91+
-a "export PATH=~/.local/bin:${PATH}"
92+
93+
# change default shell for the ${IMAGE_USER} in the image building process for extra environment safety
94+
RUN chsh -s $(which zsh)
95+
96+
#! Examples of actual dependency install:
97+
# #! Install OpenCV 4.2.0 with QUIRC support from source
98+
# ENV OPENCV_VERSION=4.2.0
99+
# RUN pip3 uninstall -y opencv && \
100+
# apt install -y --no-install-recommends libavcodec-dev libavformat-dev libswscale-dev libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev libgtk-3-dev libpng-dev libjpeg-dev && \
101+
# git clone --depth 1 --recursive https://github.com/opencv/opencv.git ${HOME_FOLDER}/opencv -b $OPENCV_VERSION && \
102+
# # follow the error information,replace all the “ipcp-unit-growth” with “ipa-cp-unit-growth” in 3rdparty/carotene/CMakeLists.txt and 3rdparty/carotene/hal/CMakeLists.txt
103+
# perl -pi -e 's/ipcp-unit-growth/ipa-cp-unit-growth/g' ${HOME_FOLDER}/opencv/3rdparty/carotene/CMakeLists.txt ${HOME_FOLDER}/opencv/3rdparty/carotene/hal/CMakeLists.txt && \
104+
# git clone --depth 1 --recursive https://github.com/opencv/opencv_contrib.git ${HOME_FOLDER}/opencv_contrib -b $OPENCV_VERSION && \
105+
# mkdir -p ${HOME_FOLDER}/opencv/build && \
106+
# cd ${HOME_FOLDER}/opencv/build && \
107+
# cmake \
108+
# -D CMAKE_CXX_STANDARD=20 \
109+
# -D EIGEN_INCLUDE_PATH=/usr/include/eigen3 \
110+
# -D OPENCV_GENERATE_PKGCONFIG=ON \
111+
# -D BUILD_opencv_python3=ON \
112+
# -D OPENCV_PYTHON3_INSTALL_PATH=/usr/local/lib/python3.8/dist-packages \
113+
# # -D OPENCV_ENABLE_NONFREE=ON \
114+
# -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules \
115+
# # -D WITH_LAPACK=ON \
116+
# -D WITH_GTK=ON \
117+
# -D WITH_TBB=ON \
118+
# # -D WITH_QUIRC=ON \
119+
# -D WITH_GSTREAMER=ON \
120+
# -D WITH_V4L=ON \
121+
# # -D WITH_OPENGL=ON \
122+
# -D BUILD_TESTS=OFF \
123+
# -D BUILD_PERF_TESTS=OFF \
124+
# -D BUILD_EXAMPLES=OFF \
125+
# -D CMAKE_BUILD_TYPE=RELEASE \
126+
# -D CMAKE_INSTALL_PREFIX=/usr/local .. && \
127+
# make install -j$(($(nproc)-1)) && \
128+
# echo "export OpenCV_DIR=/usr/local/lib/cmake/opencv4/" >> ${HOME_FOLDER}/.zshrc && \
129+
# echo "export OpenCV_DIR=/usr/local/lib/cmake/opencv4/" >> ${HOME_FOLDER}/.bashrc && \
130+
# rm -rf ${HOME_FOLDER}/opencv && \
131+
# rm -rf ${HOME_FOLDER}/opencv_contrib
132+
133+
# Add git safe directory
134+
RUN git config --global --add safe.directory "*"
66135

67136
# end of sudo apt installs
68137
RUN apt full-upgrade -y && \
@@ -71,11 +140,17 @@ RUN apt full-upgrade -y && \
71140
apt clean -y && \
72141
rm -rf /var/lib/apt/lists/*
73142

143+
# change owner of home folder
144+
RUN chown -R ${IMAGE_USER}:${IMAGE_USER} ${HOME_FOLDER}
145+
146+
# change user
147+
USER ${IMAGE_USER}
148+
74149
# Set the default shell to zsh
75150
SHELL [ "/bin/zsh", "-c" ]
76151

77152
# # move fixuid config
78-
# RUN mv $HOME_FOLDER/fixuid-config.yml /etc/fixuid/config.yml
153+
# RUN mv ${HOME_FOLDER}/fixuid-config.yml /etc/fixuid/config.yml
79154

80155
# Entrypoint command
81156
# ENTRYPOINT [ "/bin/sh" , "-c", "fixuid; /bin/zsh" ]

scripts/build.sh

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,33 @@
88
# Copyright Ⓒ 2024 Mukai (Tom Notch) Yu
99
#
1010

11+
set -euo pipefail
12+
13+
before_env="$(mktemp)"
14+
after_env="$(mktemp)"
15+
tmp_dockerfile="$(mktemp)"
16+
cleanup() { rm -f "${before_env}" "${after_env}" "${tmp_dockerfile}"; }
17+
trap cleanup EXIT
18+
19+
env | sort >"${before_env}"
20+
21+
set -a
1122
. "$(dirname "$0")"/variables.sh
23+
set +a
24+
25+
env | sort >"${after_env}"
26+
27+
diff_env="$(
28+
awk -F= '
29+
NR==FNR { before[$1]=$0; next }
30+
{
31+
name=$1
32+
if (!(name in before) || before[name] != $0)
33+
printf " ${%s}", name
34+
}
35+
' "${before_env}" "${after_env}"
36+
)"
37+
diff_env="${diff_env# }" # trim leading space
1238

1339
# Determine the local platform
1440
if [[ "$(uname -m)" == "x86_64" ]]; then
@@ -20,19 +46,25 @@ else
2046
exit 1
2147
fi
2248

23-
# Desired builder name
24-
BUILDER_NAME="multi-platform"
25-
2649
# Check if the builder already exists
27-
if ! docker buildx ls | grep -q "^${BUILDER_NAME} "; then
28-
echo "Creating Docker Buildx builder '${BUILDER_NAME}'..."
50+
if ! docker buildx inspect "${BUILDER}" &>/dev/null; then
51+
echo "Creating Docker Buildx builder '${BUILDER}'..."
2952
docker buildx create \
30-
--name "${BUILDER_NAME}" \
53+
--name "${BUILDER}" \
3154
--use --platform linux/amd64,linux/arm64 \
3255
--driver docker-container
3356
else
34-
echo "Docker Buildx builder '${BUILDER_NAME}' already exists."
57+
echo "Docker Buildx builder '${BUILDER}' already exists."
58+
docker buildx use "${BUILDER}"
3559
fi
3660

61+
# environment variable substitution trick
62+
envsubst "${diff_env}" <"$(dirname "$0")/../docker/${IMAGE_TAG}/Dockerfile" >"${tmp_dockerfile}"
63+
64+
echo ">>> Substituted dockerfile:"
65+
echo "----------------------------------------"
66+
cat "${tmp_dockerfile}"
67+
echo "----------------------------------------"
68+
3769
# Build the Docker image for only the local platform, push.sh will push multi-platform version
38-
docker buildx bake --file "$(dirname "$0")"/../docker-compose.yml --load --set "*.platform=$LOCAL_PLATFORM"
70+
docker buildx bake --file "$(dirname "$0")"/../docker-compose.yml --load --set "*.platform=${LOCAL_PLATFORM}" --set "*.dockerfile=${tmp_dockerfile}"

scripts/kill.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@
1010

1111
. "$(dirname "$0")"/variables.sh
1212

13-
docker exec --privileged -it "$CONTAINER_NAME" pkill -f zsh
13+
docker exec --privileged -it "${CONTAINER_NAME}" pkill -f zsh
1414

15-
docker rm -f "$CONTAINER_NAME"
15+
docker rm -f "${CONTAINER_NAME}"

scripts/pull.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@
1010

1111
. "$(dirname "$0")"/variables.sh
1212

13-
docker pull "$DOCKER_USER"/"$IMAGE_NAME":"$IMAGE_TAG"
13+
docker pull "${DOCKER_USER}"/"${IMAGE_NAME}":"${IMAGE_TAG}"

0 commit comments

Comments
 (0)