11# ─────────────────────────────
2- # Stage 1: Base
2+ # Stage 1: Base (System Dependencies)
33# ─────────────────────────────
44FROM nvidia/cuda:13.0.1-cudnn-runtime-ubuntu24.04 AS base
55
66SHELL ["/bin/bash" , "-o" , "pipefail" , "-c" ]
77
8+ ARG DEBIAN_FRONTEND=noninteractive
9+
810ENV TZ="Asia/Seoul" \
9- DEBIAN_FRONTEND=noninteractive \
11+ LANG=ko_KR.UTF-8 \
12+ LC_ALL=ko_KR.UTF-8 \
1013 USER=code \
1114 UID=1001 \
1215 GID=1001 \
1316 GOSU_VERSION=1.17 \
1417 TINI_VERSION=v0.19.0
1518
16- ENV LANG=ko_KR.UTF-8
17- ENV LC_ALL=ko_KR.UTF-8
18-
1919RUN set -eux; \
2020 rm -rf /etc/apt/sources.list.d/cuda.list; \
2121 apt-get update -yq; \
@@ -38,58 +38,46 @@ RUN set -eux; \
3838 \
3939 dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')" ; \
4040 wget -O /usr/bin/tini "https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-$dpkgArch" ; \
41- wget -O /usr/bin/tini.asc "https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-$dpkgArch.asc" ; \
42- export GNUPGHOME="$(mktemp -d)" ; \
43- gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys 595E85A6B1B4779EA4DAAEC70B588DFF0527A9B7; \
44- gpg --batch --verify /usr/bin/tini.asc /usr/bin/tini; \
45- gpgconf --kill all; \
46- rm -rf "$GNUPGHOME" /usr/bin/tini.asc; \
4741 chmod +x /usr/bin/tini; \
4842 tini --version; \
4943 \
5044 wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch" ; \
51- wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc" ; \
52- export GNUPGHOME="$(mktemp -d)" ; \
53- gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \
54- gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \
55- gpgconf --kill all; \
56- rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \
5745 chmod +x /usr/local/bin/gosu; \
58- gosu --version; gosu nobody true; \
46+ gosu --version; \
47+ \
48+ curl -fsSL https://code-server.dev/install.sh | sh; \
5949 \
6050 apt-get clean; \
61- rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*; \
62- groupadd --gid ${GID} ${USER}; \
63- useradd --uid ${UID} --gid ${GID} --create-home --shell /bin/bash ${USER}; \
64- echo "code ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/nopasswd
51+ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
52+
53+ RUN groupadd --gid ${GID} ${USER} && \
54+ useradd --uid ${UID} --gid ${GID} --create-home --shell /bin/bash ${USER} && \
55+ echo "${USER} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/nopasswd && \
56+ chmod 0440 /etc/sudoers.d/nopasswd
6557
6658USER ${USER}
6759WORKDIR /home/${USER}
68- ENV BASH_ENV="/home/${USER}/.bash_env"
60+ ENV BASH_ENV="/home/${USER}/.bash_env" \
61+ PNPM_HOME="/home/${USER}/.pnpm/store" \
62+ PATH="/home/${USER}/.local/bin:/home/${USER}/.pnpm/store:${PATH}"
6963
70- RUN touch "${BASH_ENV}" && echo '. "${BASH_ENV}"' >> ~/.bashrc
64+ RUN touch "${BASH_ENV}" && \
65+ echo '. "${BASH_ENV}"' >> ~/.bashrc
7166
7267RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.2/install.sh | PROFILE="${BASH_ENV}" bash && \
73- source ${BASH_ENV} && nvm install --lts && nvm use --lts && \
74- npm install -g pnpm@latest-10 && npm cache clean --force
68+ source ${BASH_ENV} && \
69+ nvm install --lts && \
70+ nvm use --lts && \
71+ npm install -g pnpm@latest-10 && \
72+ npm cache clean --force
7573
7674RUN curl -LsSf https://astral.sh/uv/install.sh | sh && \
77- export PATH= "$HOME/.local/bin:$PATH" && \
75+ source ${BASH_ENV} && \
7876 uv python install 3.12.9 --default --preview && \
7977 uv tool update-shell
8078
81- ENV PNPM_HOME="/home/${USER}/.pnpm/store"
82- ENV PATH="/home/${USER}/.local/bin:${PNPM_HOME}:${PATH}"
83-
84- RUN python --version && \
85- which python && \
86- python -c "import sys; print(sys.executable, sys.version, sys.platform)"
87-
88- RUN curl -fsSL https://code-server.dev/install.sh | sh && \
89- rm -rf ~/.cache/code-server
90-
9179# ─────────────────────────────
92- # Stage 2: Fonts (root )
80+ # Stage 2: Fonts (Resource Only )
9381# ─────────────────────────────
9482FROM base AS fonts
9583USER root
@@ -102,31 +90,32 @@ RUN set -eux; \
10290 install_google_font() { \
10391 local relative_path="$1" ; local font_name="$2" ; \
10492 local font_dir="/usr/share/fonts/truetype/${relative_path}" ; \
105- mkdir -p "${font_dir}" && \
93+ mkdir -p "${font_dir}" ; \
10694 local encoded_font_name=$(printf "%s" "${font_name}" | jq -sRr @uri); \
10795 wget --quiet -O "${font_dir}/${font_name}" \
10896 "https://raw.githubusercontent.com/google/fonts/17216f1645a133dbbeaa506f0f63f701861b6c7b/ofl/${relative_path}/${encoded_font_name}" ; \
10997 }; \
110- \
98+ # D2Coding
11199 mkdir -p /usr/share/fonts/truetype/D2Coding && \
112- wget --quiet -O /usr/share/fonts/truetype/ D2Coding.zip \
113- "https://github.com/naver/d2codingfont/releases/download/VER${D2CODING_VERSION}/D2Coding-Ver${D2CODING_VERSION}-${D2CODING_DATE}.zip" && \
114- unzip /usr/share/fonts/truetype/D2Coding.zip -d /usr/share/fonts/truetype/ && \
115- rm /usr/share/fonts/truetype/ D2Coding.zip; \
100+ wget --quiet -O /tmp/D2Coding.zip "https://github.com/naver/d2codingfont/releases/download/VER${D2CODING_VERSION}/ D2Coding-Ver${D2CODING_VERSION}-${D2CODING_DATE} .zip" && \
101+ unzip -q /tmp/D2Coding.zip -d /usr/share/fonts/truetype/ && \
102+ \
103+ # D2Coding Nerd
116104 mkdir -p /usr/share/fonts/truetype/D2CodingNerd && \
117- wget --quiet -O /usr/share/fonts/truetype/D2CodingNerd/D2CodingNerd.ttf \
118- "https://github.com/kelvinks/D2Coding_Nerd/raw/master/D2Coding%20v.${D2CODING_NERD_VERSION}%20Nerd%20Font%20Complete.ttf" ; \
105+ wget --quiet -O /usr/share/fonts/truetype/D2CodingNerd/D2CodingNerd.ttf \
106+ "https://github.com/kelvinks/D2Coding_Nerd/raw/master/D2Coding%20v.${D2CODING_NERD_VERSION}%20Nerd%20Font%20Complete.ttf" ; \
107+ \
108+ # Pretendard
119109 mkdir -p /usr/share/fonts/truetype/Pretendard && \
120- wget --quiet -O /usr/share/fonts/truetype/ Pretendard.zip \
121- "https://github.com/orioncactus/pretendard/releases/download/v${PRETENDARD_VERSION}/ Pretendard-${PRETENDARD_VERSION}.zip" && \
122- unzip /usr/share/fonts/truetype/Pretendard.zip -d /usr/share/fonts/truetype/Pretendard/ && \
123- rm /usr/share/fonts/truetype/ Pretendard.zip; \
110+ wget --quiet -O /tmp/Pretendard.zip "https://github.com/orioncactus/pretendard/releases/download/v${PRETENDARD_VERSION}/ Pretendard-${PRETENDARD_VERSION} .zip" && \
111+ unzip -q /tmp/Pretendard.zip -d /usr/share/fonts/truetype/ Pretendard/ && \
112+ \
113+ # Pretendard JP
124114 mkdir -p /usr/share/fonts/truetype/PretendardJP && \
125- wget --quiet -O /usr/share/fonts/truetype/PretendardJP.zip \
126- "https://github.com/orioncactus/pretendard/releases/download/v${PRETENDARD_VERSION}/PretendardJP-${PRETENDARD_VERSION}.zip" && \
127- unzip /usr/share/fonts/truetype/PretendardJP.zip -d /usr/share/fonts/truetype/PretendardJP/ && \
128- rm /usr/share/fonts/truetype/PretendardJP.zip; \
115+ wget --quiet -O /tmp/PretendardJP.zip "https://github.com/orioncactus/pretendard/releases/download/v${PRETENDARD_VERSION}/PretendardJP-${PRETENDARD_VERSION}.zip" && \
116+ unzip -q /tmp/PretendardJP.zip -d /usr/share/fonts/truetype/PretendardJP/ && \
129117 \
118+ # Google Fonts
130119 install_google_font "notosans" "NotoSans[wdth,wght].ttf" ; \
131120 install_google_font "notosans" "NotoSans-Italic[wdth,wght].ttf" ; \
132121 install_google_font "notoserif" "NotoSerif[wdth,wght].ttf" ; \
@@ -137,7 +126,6 @@ RUN set -eux; \
137126 install_google_font "notoserifjp" "NotoSerifJP[wght].ttf" ; \
138127 install_google_font "notoemoji" "NotoEmoji[wght].ttf" ; \
139128 install_google_font "notocoloremoji" "NotoColorEmoji-Regular.ttf" ; \
140- \
141129 install_google_font "nanumbrushscript" "NanumBrushScript-Regular.ttf" ; \
142130 install_google_font "nanumgothic" "NanumGothic-Bold.ttf" ; \
143131 install_google_font "nanumgothic" "NanumGothic-ExtraBold.ttf" ; \
@@ -147,23 +135,20 @@ RUN set -eux; \
147135 install_google_font "nanummyeongjo" "NanumMyeongjo-Bold.ttf" ; \
148136 install_google_font "nanummyeongjo" "NanumMyeongjo-ExtraBold.ttf" ; \
149137 install_google_font "nanummyeongjo" "NanumMyeongjo-Regular.ttf" ; \
150- \
151138 install_google_font "ibmplexmono" "IBMPlexMono-Bold.ttf" ; \
152139 install_google_font "ibmplexmono" "IBMPlexMono-Regular.ttf" ; \
153140 install_google_font "ibmplexsanskr" "IBMPlexSansKR-Bold.ttf" ; \
154141 install_google_font "ibmplexsanskr" "IBMPlexSansKR-Regular.ttf" ; \
155142 \
156- chmod -R 644 /usr/share/fonts/truetype/* && \
157- find /usr/share/fonts/truetype/ -type d -exec chmod 755 {} + && \
143+ chmod -R 644 /usr/share/fonts/truetype/*; \
144+ find /usr/share/fonts/truetype/ -type d -exec chmod 755 {} +; \
158145 fc-cache -f -v
159146
160147# ─────────────────────────────
161- # Stage 3: Builder
148+ # Stage 3: Builder (User Environment Construction)
162149# ─────────────────────────────
163150FROM base AS builder
164- USER root
165- COPY --chmod=775 fix-permissions /usr/local/bin/fix-permissions
166- USER ${UID}
151+ USER ${USER}
167152
168153RUN uv init --python 3.12.9 --bare && \
169154 uv venv --python 3.12.9 --seed
@@ -185,15 +170,11 @@ RUN uv add \
185170 jupyterlab-language-pack-ko-KR \
186171 https://github.com/AISFlow/nbconvert.git
187172
188- RUN set -eux; \
189- EXTENSIONS="ms-python.python ms-python.pylint ms-toolsai.jupyter charliermarsh.ruff esbenp.prettier-vscode anwar.papyrus-pdf mechatroner.rainbow-csv cweijan.vscode-office" ; \
173+ RUN mkdir -p /home/${USER}/.local/share/code-server && \
174+ EXTENSIONS="ms-python.python ms-python.pylint ms-toolsai.jupyter charliermarsh.ruff esbenp.prettier-vscode anwar.papyrus-pdf mechatroner.rainbow-csv cweijan.vscode-office" && \
190175 for EXT in $EXTENSIONS; do \
191176 for i in $(seq 1 5); do \
192- if code-server --install-extension "${EXT}" ; then \
193- break; \
194- else \
195- sleep 10; \
196- fi; \
177+ if code-server --install-extension "${EXT}" ; then break; else sleep 5; fi; \
197178 done; \
198179 done
199180
@@ -218,22 +199,20 @@ FROM base AS runtime
218199
219200ENV NODE_ENV=production
220201
221- COPY --link --chown=${UID}:${GID} presettings/vscode-settings.json /home/${ USER}/.local/share/code-server/User/settings.json
202+ USER root
222203
223- COPY --link --chown=${UID}:${GID} presettings/matplotlibrc /home/${USER}/.config/matplotlib/matplotlibrc
204+ COPY --link --chmod=755 --from=fonts /usr/share/fonts/ /usr/share/fonts/
205+ COPY --link --chmod=755 --from=ghcr.io/aisflow/dockerised-mecab-ko:20250319-190826 /opt/mecab/ /opt/mecab/
224206
225207COPY --link --chown=${UID}:${GID} --from=builder /home/${USER}/ /home/${USER}/
226208
227- COPY --link --chown=${UID}:${GID} endeavour /usr/bin/endeavour
228-
229- COPY --link --chmod=775 --from=builder /usr/local/bin/fix-permissions /usr/local/bin/fix-permissions
230-
231- COPY --link --chmod=775 --from=ghcr.io/aisflow/dockerised-mecab-ko:20250319-190826 /opt/mecab/ /opt/mecab/
232-
233- COPY --link --chmod=775 --from=fonts /usr/share/fonts/ /usr/share/fonts/
209+ COPY --link --chown=${UID}:${GID} presettings/vscode-settings.json /home/${USER}/.local/share/code-server/User/settings.json
210+ COPY --link --chown=${UID}:${GID} presettings/matplotlibrc /home/${USER}/.config/matplotlib/matplotlibrc
234211
235- USER root
212+ COPY --link --chmod=755 --from=builder /usr/local/bin/fix-permissions /usr/local/bin/fix-permissions
213+ COPY --link --chmod=755 endeavour /usr/bin/endeavour
236214
237215EXPOSE 8080
216+
238217ENTRYPOINT [ "tini" , "--" , "/opt/nvidia/nvidia_entrypoint.sh" ]
239- CMD [ "endeavour" ]
218+ CMD [ "endeavour" ]
0 commit comments