Dockerfile 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. FROM debian:trixie-slim
  2. # Metadata
  3. LABEL maintainer="jmbatto"
  4. LABEL description="Julia 1.12 (Source Build) on Debian Trixie with PDI/GTK - Optimized for stability"
  5. # Build Arguments
  6. ARG USER_ID=1001
  7. ARG GROUP_ID=1001
  8. ARG USER_NAME=coder
  9. ARG JULIA_VERSION=v1.12.4
  10. ARG PDI_VERSION=1.10.0
  11. # -----------------------------------------------------------------------------
  12. # 1. System Dependencies Installation
  13. # -----------------------------------------------------------------------------
  14. # Rationale:
  15. # - 'neowofetch': Replaces 'neofetch' which has been removed from Debian Trixie repos.
  16. # - 'python3-setuptools': REQUIRED for PDI compilation. Python 3.12+ (shipped with Trixie)
  17. # removed 'distutils', causing CMake/PDI detection scripts to fail without setuptools.
  18. # - 'dbus-x11' & 'xvfb': Essential for running GTK applications in a headless Docker environment.
  19. RUN apt-get update && apt-get install -y --no-install-recommends \
  20. # Build tools and base utilities
  21. build-essential cmake git pkg-config \
  22. gfortran which perl gawk m4 vim libatomic1 \
  23. nano sudo lsof jq neowofetch curl wget \
  24. gdb valgrind clang-format \
  25. ca-certificates iputils-ping colordiff \
  26. # Python Environment (with setuptools fix for Py3.12)
  27. python3 python3-dev python3-numpy python3-pandas python3-matplotlib python3-pip python3-h5py python3-termcolor python3-setuptools \
  28. # Scientific Libraries (MPI/PDI/HDF5)
  29. mpi-default-dev libhdf5-dev libz-dev hdf5-tools \
  30. # Graphics Stack (X11, GTK4, OpenGL, DBus)
  31. libx11-6 libxext6 libxrender1 libxtst6 xauth xvfb dbus-x11 \
  32. libgl1-mesa-dri libgl1 \
  33. libgtk-4-1 libgtk-3-0 libglib2.0-0 libcairo2 \
  34. libpango-1.0-0 libharfbuzz0b \
  35. libgdk-pixbuf-2.0-0 libgdk-pixbuf2.0-bin \
  36. libgraphene-1.0-0 librsvg2-common \
  37. shared-mime-info \
  38. adwaita-icon-theme-full hicolor-icon-theme fonts-liberation \
  39. graphviz \
  40. && rm -rf /var/lib/apt/lists/*
  41. # Fix: Generate machine-id to prevent GLib/GTK runtime errors regarding missing D-Bus UUID.
  42. RUN dbus-uuidgen > /etc/machine-id
  43. # Fix: Update GDK pixbuf loaders cache.
  44. # Prevents runtime warnings/errors about missing image format loaders.
  45. RUN LOADER_PATH=$(find /usr/lib -name gdk-pixbuf-query-loaders | head -n 1) && \
  46. ln -s $LOADER_PATH /usr/bin/gdk-pixbuf-query-loaders && \
  47. gdk-pixbuf-query-loaders --update-cache
  48. # -----------------------------------------------------------------------------
  49. # 2. JULIA COMPILATION
  50. # -----------------------------------------------------------------------------
  51. WORKDIR /tmp/julia-build
  52. RUN git clone --depth 1 --branch ${JULIA_VERSION} https://github.com/JuliaLang/julia.git .
  53. # Build Configuration (Make.user) - CRITICAL FIXES FOR DEBIAN TRIXIE
  54. # 1. USE_SYSTEM_LIBUNWIND=0: Forces internal libunwind. System libunwind on Trixie causes Segfaults.
  55. # 2. noexecstack: Security flag required by modern Linux kernels.
  56. # 3. -gdwarf-4: CRITICAL FIX. GCC 13+ defaults to DWARF-5 debug format, which is incompatible
  57. # with Julia's current unwinder, leading to immediate Segfaults on startup.
  58. RUN echo "prefix=/usr/local/julia" > Make.user && \
  59. echo "MARCH=x86-64" >> Make.user && \
  60. echo "USE_SYSTEM_LIBUNWIND=0" >> Make.user && \
  61. echo "LDFLAGS=-Wl,-z,noexecstack" >> Make.user && \
  62. echo "CFLAGS=-Wa,--noexecstack -gdwarf-4" >> Make.user && \
  63. echo "CXXFLAGS=-Wa,--noexecstack -gdwarf-4" >> Make.user
  64. # Compile, Install, and Cleanup
  65. # Cleanup is performed immediately to reduce final image size (~1GB saved).
  66. ENV JULIA_PATH=/usr/local/julia
  67. ENV PATH=$JULIA_PATH/bin:$PATH
  68. RUN make -j$(nproc) && \
  69. make install && \
  70. rm -rf /tmp/julia-build
  71. # -----------------------------------------------------------------------------
  72. # 3. PDI INSTALLATION
  73. # -----------------------------------------------------------------------------
  74. ENV PDI_DIR=/usr/local
  75. ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/lib/x86_64-linux-gnu
  76. ENV CPATH=/usr/local/include
  77. ENV PREFIX=/usr/local
  78. WORKDIR /tmp/pdi-build
  79. # Build Configuration:
  80. # - BUILD_PYTHON=ON & BUILD_PYCALL_PLUGIN=ON: Explicitly enabled to generate
  81. # 'libpdi_pycall_plugin.so'. Required to prevent 'plugin not found' errors
  82. # when interacting with Python from Julia/PDI.
  83. RUN git clone --depth 1 --branch ${PDI_VERSION} https://github.com/pdidev/pdi.git . && \
  84. mkdir build && cd build && \
  85. cmake \
  86. -DBUILD_MPI=OFF \
  87. -DBUILD_DECL_HDF5_PLUGIN=ON \
  88. -DBUILD_SHARED_LIBS=ON \
  89. -DBUILD_FORTRAN=OFF \
  90. -DBUILD_HDF5_PARALLEL=OFF \
  91. -DBUILD_PYTHON=ON \
  92. -DBUILD_PYCALL_PLUGIN=ON \
  93. -DBUILD_NETCDF_PARALLEL=OFF \
  94. -DCMAKE_INSTALL_PREFIX=/usr/local \
  95. .. && \
  96. make -j$(nproc) && \
  97. make install && \
  98. ldconfig && \
  99. cd / && rm -rf /tmp/pdi-build
  100. # -----------------------------------------------------------------------------
  101. # 4. USER CONFIGURATION & RUNTIME ENVIRONMENT
  102. # -----------------------------------------------------------------------------
  103. RUN groupadd -g ${GROUP_ID} ${USER_NAME} && \
  104. useradd -m -u ${USER_ID} -g ${USER_NAME} -s /bin/bash ${USER_NAME} && \
  105. echo "${USER_NAME} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
  106. # RUNTIME ENVIRONMENT VARIABLES - CRITICAL SETTINGS
  107. # 1. LD_LIBRARY_PATH: STRICTLY excludes '/usr/lib/x86_64-linux-gnu'.
  108. # Reason: Preventing "DLL Hell". Including system paths forces Julia to load system
  109. # libraries (e.g., system libglib) instead of its own Artifacts, causing undefined
  110. # symbol errors (e.g., 'g_string_copy'). We prioritize Julia and PDI libs.
  111. ENV LD_LIBRARY_PATH=/usr/local/julia/lib:/usr/local/julia/lib/julia:/usr/local/lib
  112. # 2. GTK_A11Y=none: Disables GTK Accessibility Bus to suppress "org.a11y.Bus" warnings in logs.
  113. ENV GTK_A11Y=none
  114. # 3. Graphics & Julia settings
  115. ENV GKSwstype=100
  116. ENV JULIA_PKG_PRECOMPILE_AUTO=0
  117. ENV JULIA_PKG_USE_CLI_GIT=true
  118. ENV DISPLAY=host.docker.internal:0.0
  119. ENV PYTHONPATH=/usr/local/lib/python3/dist-packages
  120. # Switch to non-root user for Package Installation
  121. # Ensures ~/.julia permissions are correctly set for the user 'coder'.
  122. USER ${USER_NAME}
  123. WORKDIR /home/${USER_NAME}/project
  124. # -----------------------------------------------------------------------------
  125. # 5. JULIA PACKAGES INSTALLATION
  126. # -----------------------------------------------------------------------------
  127. # Optimization:
  128. # - Operations are consolidated into a single RUN instruction to reduce Docker layer count.
  129. # - xvfb-run: Executes in a virtual framebuffer. Essential for 'Pkg.precompile()'
  130. # of Gtk4 and ProfileView, which require a display server even during installation.
  131. ENV LD_LIBRARY_PATH=/usr/local/julia/lib:/usr/local/julia/lib/julia:/usr/local/lib
  132. RUN julia -e 'import Pkg; \
  133. Pkg.add([ \
  134. "Pkg", \
  135. "AbstractTrees", \
  136. "BenchmarkTools", \
  137. "Cairo_jll", \
  138. "Documenter", \
  139. "GeoInterface", \
  140. "GeometryBasics", \
  141. "HDF5", \
  142. "Interpolations", \
  143. "IterativeSolvers", \
  144. "JLD", \
  145. "LibGEOS", \
  146. "LinearAlgebra", \
  147. "LsqFit", \
  148. "MPI", \
  149. "MUMPS", \
  150. "MethodAnalysis", \
  151. "OffsetArrays", \
  152. "PProf", \
  153. "PackageCompiler", \
  154. "Parameters", \
  155. "Peaks", \
  156. "Polynomials", \
  157. "Printf", \
  158. "Profile", \
  159. "PropertyDicts", \
  160. "Revise", \
  161. "Roots", \
  162. "SnoopCompileCore", \
  163. "SparseArrays", \
  164. "SpecialFunctions", \
  165. "StaticArrays", \
  166. "Statistics", \
  167. "Test", \
  168. "YAML" \
  169. ])'
  170. RUN xvfb-run --auto-servernum --server-args="-screen 0 1920x1080x24 -nolisten tcp" \
  171. julia -e 'import Pkg; \
  172. Pkg.add([ \
  173. "DataFrames", \
  174. "Gtk4", \
  175. "Gtk", \
  176. "ProfileView", \
  177. "PProf", \
  178. "Reexport" \
  179. ])'
  180. ENV LD_LIBRARY_PATH=""
  181. # hack to install julia package
  182. RUN xvfb-run --auto-servernum --server-args="-screen 0 1920x1080x24 -nolisten tcp" \
  183. julia -e 'import Pkg; Pkg.precompile()'
  184. RUN xvfb-run --auto-servernum --server-args="-screen 0 1920x1080x24 -nolisten tcp" \
  185. julia -e 'import Pkg; Pkg.update(); Pkg.precompile()'
  186. ENV LD_LIBRARY_PATH=/usr/local/julia/lib:/usr/local/julia/lib/julia:/usr/local/lib
  187. CMD ["/bin/bash"]