# Dockerfile Specification, Style & Best Practices This document defines the quality standards, coding styles, and build optimizations for all Dockerfiles in the LabNow container ecosystem. --- ## 1. Structure & Layout Standards All Dockerfiles must follow a clean, standardized structure: 1. **Header**: Licensing, author, maintainer. 2. **Global ARGs**: Define `BASE_NAMESPACE` and `BASE_IMG` variables at the top of the file, before the `FROM` declaration: ```dockerfile ARG BASE_NAMESPACE ARG BASE_IMG="base" FROM ${BASE_NAMESPACE:+$BASE_NAMESPACE/}${BASE_IMG} ``` 3. **Labels**: Add descriptive labels (`LABEL maintainer="postmaster@labnow.ai"`). 4. **Environment Variables**: Use `ENV` declarations grouped together. 5. **SHELL Configuration**: Override default `/bin/sh` to enforce Bash login shell behavior: ```dockerfile SHELL ["/bin/bash", "--login", "-o", "pipefail", "-c"] ``` 6. **Command Layers**: Put complex shell operations under a unified `RUN` block using `&& \`. 7. **WORKDIR**: Set appropriate workspace context. --- ## 2. Command Formatting and Clean Code - **Instruction Casing**: Instruction names (`FROM`, `RUN`, `ENV`, `ARG`, `SHELL`, `COPY`, `WORKDIR`) must be capitalized. - **Multiline Chains**: Chain shell commands using `&& \` and align them vertically for readability. - **Self-contained execution**: Group logic that installs libraries, compiles source, and configures environments into a single `RUN` instruction. --- ## 3. Layer Optimization & Bloat Prevention To keep final images lightweight: 1. **No Residual Cache**: Package installation caches (such as apt, pip, npm, conda) must be purged in the *same* `RUN` layer they are created in. Suffix every major `RUN` block with `install__clean`. 2. **Temporary Dev Header Purging**: If compilation requires development libraries (e.g. `*-dev`, `ninja-build`), uninstall them in the same layer after compiling binary targets. 3. **No NVIDIA Wheel Bloat**: For GPU-enabled images, strip redundant python cuda-wheels (`nvidia-*`) using pip and utilize lightweight C++ runtime packages instead. 4. **Permission Rectification**: Set correct permissions at the end of the build block: ```dockerfile && fix_permission 0 /opt ``` --- ## 4. Environment & Dependency Rules - **No Hardcoded Package Names**: Do not list package names directly in the `RUN` command block (e.g., avoid `apt-get install -y git curl`). Write them to dedicated external text files (e.g., `install_list_base.apt`, `install_list_PY_nlp.pip`) and ingest them using `install_apt` or `install_pip`. - **In-File Comments**: Package index files should document why each dependency is installed using comment blocks (preceded by `%`): ```text python-docx % For parsing Word documentation files rpy2 % Integration between Python and R ``` - **Loop-Based Customization**: Enable optional profile installations by looping over arguments: ```bash for profile in $(echo $ARG_PROFILE_JAVA | tr "," "\n") ; do ( setup_java_${profile} ) ; done ```