|
| 1 | +Ddoc |
| 2 | + |
| 3 | +$(D_S $(TITLE), |
| 4 | + |
| 5 | +$(P |
| 6 | +$(B dlang-dockerized) is a $(EM community project) that packages D compilers as OCI images. |
| 7 | +These can be used with OCI-compliant container engines — such as |
| 8 | +$(LINK2 https://docs.docker.com/engine/install/, Docker) |
| 9 | +$(LINK2 https://podman.io/get-started, Podman) or |
| 10 | +$(LINK2 https://kubernetes.io/docs/concepts/overview/, Kubernetes). |
| 11 | +) |
| 12 | + |
| 13 | +$(NOTE |
| 14 | +OCI stands for $(STRONG $(LINK2 https://opencontainers.org/, Open Container Initiative)). |
| 15 | +) |
| 16 | + |
| 17 | + |
| 18 | +$(H2 Quick Start) |
| 19 | + |
| 20 | +$(H3 Docker) |
| 21 | +$(CONSOLE docker run --init --rm -it -v .:/src ghcr.io/dlang-dockerized/dmd:latest dmd) |
| 22 | + |
| 23 | +$(H3 Podman) |
| 24 | +$(CONSOLE podman run --init --rm -it -v .:/src ghcr.io/dlang-dockerized/dmd:latest dmd) |
| 25 | + |
| 26 | +$(H3 Common CLI flags) |
| 27 | + |
| 28 | +$(P |
| 29 | +The provided command runs the container image for $(CODE dmd) from $(CODE ghcr.io). |
| 30 | +It mounts the current working directory $(CODE .) as volume $(LPAREN)$(ARG -v)$(RPAREN) under $(CODE /src) in the container. |
| 31 | +) |
| 32 | + |
| 33 | +$(P |
| 34 | +$(ARG --rm) instructs the container engine to automatically remove the container |
| 35 | +and any anonymous unnamed volume associated with the container when it exits. |
| 36 | +) |
| 37 | + |
| 38 | +$(P |
| 39 | +$(ARG -it) is actually a combination of the flags $(ARG -i) and $(ARG) |
| 40 | +and requests an interactive session — even if detached — with a pseudo-TTY. |
| 41 | +) |
| 42 | + |
| 43 | +$(P |
| 44 | +Given that most applications are not designed to be run as PID $(CODE 1), |
| 45 | +using $(ARG --init) the container engine can be instructed to inject a tiny $(EM init system) |
| 46 | +which takes care of the $(EM signal handling) requirements for PID $(CODE 1) of the Linux kernel |
| 47 | +as well as $(EM reaping orphaned zombie processes). |
| 48 | +) |
| 49 | + |
| 50 | +Further information can be found in the corresponding manuals: |
| 51 | +$(UL |
| 52 | +$(LI $(LINK https://docs.docker.com/reference/cli/docker/container/run/)) |
| 53 | +$(LI $(LINK https://docs.podman.io/en/latest/markdown/podman-run.1.html)) |
| 54 | +) |
| 55 | + |
| 56 | + |
| 57 | +$(H2 Containerfiles) |
| 58 | + |
| 59 | +$(UL |
| 60 | +$(LI $(CODE $(NBSP)$(NBSP)ghcr.io/dlang-dockerized/dmd)) |
| 61 | +$(LI $(CODE $(NBSP)$(NBSP)ghcr.io/dlang-dockerized/ldc)) |
| 62 | +$(LI $(CODE docker.io/dlangdockerized/dmd)) |
| 63 | +$(LI $(CODE docker.io/dlangdockerized/ldc)) |
| 64 | +) |
| 65 | + |
| 66 | +$(P |
| 67 | +Container images are built from so-called $(EM Containerfile)s — |
| 68 | +also known as $(EM Dockerfile)s when used with $(EM Docker). |
| 69 | +) |
| 70 | + |
| 71 | +$(P |
| 72 | +These Containerfiles are compiled from templates and meta data. |
| 73 | +) |
| 74 | + |
| 75 | +$(P |
| 76 | +A repository providing pre-rendered Containerfiles can be found at: |
| 77 | +$(LINK https://github.com/dlang-dockerized/containerfiles) |
| 78 | +) |
| 79 | + |
| 80 | +$(P |
| 81 | +The source template files as well as the template engine are located in the $(EM packaging) repository: |
| 82 | +$(LINK https://github.com/dlang-dockerized/packaging) |
| 83 | +) |
| 84 | + |
| 85 | +$(P |
| 86 | +Documentation for the format of Containerfiles can be found over there: |
| 87 | +$(LINK https://github.com/podman-container-tools/container-libs/blob/main/common/docs/Containerfile.5.md) |
| 88 | +) |
| 89 | + |
| 90 | + |
| 91 | +$(H3 Packaged software) |
| 92 | + |
| 93 | +$(UL |
| 94 | +$(LI $(H4 DMD — Digital Mars D Compiler) |
| 95 | + $(UL |
| 96 | + $(LI DUB — official package manager for the D programming language) |
| 97 | + $(LI rdmd — rapid edit-run cycle companion) |
| 98 | + ) |
| 99 | +) |
| 100 | +$(LI $(H4 LDC — LLVM-based D Compiler) |
| 101 | + $(UL |
| 102 | + $(LI DUB — official package manager for the D programming language) |
| 103 | + $(LI LLD — Linker of the LLVM project) |
| 104 | + $(LI LLDB — Debugger of the LLVM project) |
| 105 | + $(LI rdmd — rapid edit-run cycle companion) |
| 106 | + ) |
| 107 | +) |
| 108 | +) |
| 109 | + |
| 110 | +$(NOTE |
| 111 | +Please note that not all software listed above is available across all image versions. |
| 112 | +This applies to images providing legacy compiler versions in particular. |
| 113 | +) |
| 114 | + |
| 115 | + |
| 116 | +$(H3 Compiler versions) |
| 117 | + |
| 118 | +$(P |
| 119 | +$(I dlang-dockerized) aims to package the latest compilers as well as “relevant” legacy versions. |
| 120 | +) |
| 121 | + |
| 122 | +$(P |
| 123 | +To select a specific version of a container image, append a version prefix to the image name. |
| 124 | +) |
| 125 | + |
| 126 | +$(NOTE |
| 127 | +The prefix $(CODE latest) refers to the latest stable release of the corresponding image. |
| 128 | +) |
| 129 | + |
| 130 | +$(CONSOLE $(SHE) Containerfile |
| 131 | + |
| 132 | +$(SHE) latest stable release |
| 133 | +FROM ghcr.io/dlang-dockerized/dmd:latest |
| 134 | + |
| 135 | +$(SHE) latest release of the 2.100.x branch (→ 2.100.2) |
| 136 | +FROM ghcr.io/dlang-dockerized/dmd:2.100 |
| 137 | + |
| 138 | +$(SHE) 2.100.0 release |
| 139 | +FROM ghcr.io/dlang-dockerized/dmd:2.100.0 |
| 140 | +) |
| 141 | + |
| 142 | +$(P |
| 143 | +Images are rebuilt from time to time in order to ship dependency updates and similar. |
| 144 | +) |
| 145 | + |
| 146 | +$(P |
| 147 | +For legacy versions of the bundled software it may be necessary to apply |
| 148 | +custom patches and/or backports in order prior to building. |
| 149 | +These modifications can be found in the |
| 150 | +$(LINK2 https://github.com/dlang-dockerized/packaging/tree/main/resources/patches, $(CODE patches) subfolder) |
| 151 | +in the $(EM packaging) repository. |
| 152 | +) |
| 153 | + |
| 154 | + |
| 155 | +$(H3 Base images) |
| 156 | + |
| 157 | +$(P |
| 158 | +A base image is the start of all Containerfiles. |
| 159 | +It serves as the base of the container and as such provides a runtime environment. |
| 160 | +) |
| 161 | + |
| 162 | +$(P |
| 163 | +A common convention is to append a suffix to the tag of the container image |
| 164 | +that consists of an alias referring to the base image. |
| 165 | +) |
| 166 | + |
| 167 | +$(UL |
| 168 | +$(LI $(CODE ghcr.io/dlang-dockerized/dmd:$(EM baseimage))) |
| 169 | +$(LI $(CODE ghcr.io/dlang-dockerized/dmd:latest-$(EM baseimage))) |
| 170 | +$(LI $(CODE ghcr.io/dlang-dockerized/dmd:2-$(EM baseimage))) |
| 171 | +$(LI $(CODE ghcr.io/dlang-dockerized/dmd:2.100.2-$(EM baseimage))) |
| 172 | +$(LI $(SMALL and so on)) |
| 173 | +) |
| 174 | + |
| 175 | + |
| 176 | +$(H3 Maintained versions and images) |
| 177 | + |
| 178 | +$(P |
| 179 | +The $(STRONG maintenance policy) of $(I dlang-dockerized) is outlined in the MAINTENANCE document of the project. |
| 180 | +It can be found at $(LINK https://github.com/dlang-dockerized/packaging/blob/main/MAINTENANCE.md). |
| 181 | +) |
| 182 | + |
| 183 | +$(NOTE: |
| 184 | +Keep in mind, this is work done by volunteers. |
| 185 | +) |
| 186 | + |
| 187 | + |
| 188 | +$(H2 Container registries) |
| 189 | + |
| 190 | +Container images are pushed to two container registries: |
| 191 | +$(UL |
| 192 | +$(LI GitHub Container Registry: $(LINK https://github.com/orgs/dlang-dockerized/packages/container/package/dmd)) |
| 193 | +$(LI Docker Hub: $(LINK https://hub.docker.com/r/dlangdockerized/dmd/tags)) |
| 194 | +) |
| 195 | + |
| 196 | +The registry to pull an image from is selected |
| 197 | +by prepending the corresponding registry host and vendor name to the image name: |
| 198 | +$(UL |
| 199 | +$(LI GitHub Container Registry: $(CODE $(EM ghcr.io/dlang-dockerized/)dmd)) |
| 200 | +$(LI Docker Hub: $(CODE $(EM docker.io/dlangdockerized/)dmd)) |
| 201 | +) |
| 202 | + |
| 203 | +$(NOTE |
| 204 | +At the time of writing, $(STRONG $(EM ghcr.io)) is the $(STRONG recommended registry) to pull these images from. |
| 205 | +) |
| 206 | + |
| 207 | +$(NOTE |
| 208 | +$(EM Docker) defaults to $(CODE docker.io); |
| 209 | +allowing users to omit that prefix. |
| 210 | +$(BR) |
| 211 | +Best practice is, however, to explicitly specify the source registry of an image. |
| 212 | +This ensures compatibility across container engines and user configurations. |
| 213 | +) |
| 214 | + |
| 215 | + |
| 216 | +$(H2 Tips and tricks) |
| 217 | + |
| 218 | +$(H3 Debugging with LLDB) |
| 219 | + |
| 220 | +$(P |
| 221 | +At the time of writing, due to a limitation in LLDB, |
| 222 | +$(EM seccomp confinement) needs to be turned off for the debugger to work. |
| 223 | +$(CONSOLE docker run --security-opt seccomp=unconfined -it dlang-dockerized/ldc:latest lldb /src/my-app) |
| 224 | +) |
| 225 | + |
| 226 | +$(P |
| 227 | +For further information check out: $(LINK https://github.com/llvm/llvm-project/issues/61899) |
| 228 | +) |
| 229 | + |
| 230 | + |
| 231 | +$(H2 Issue tracker) |
| 232 | + |
| 233 | +See: $(LINK https://github.com/dlang-dockerized/packaging/issues) |
| 234 | + |
| 235 | + |
| 236 | +$(H2 Packaging your own app as container image) |
| 237 | + |
| 238 | +$(P |
| 239 | +The following examples outline how one can build and package their own application using OCI containers. |
| 240 | +They are meant to be used as a starting point only. |
| 241 | +Downstream users are expected to adjust them accordingly to fit their requirements and tune them to their liking. |
| 242 | +) |
| 243 | + |
| 244 | +$(NOTE |
| 245 | +The D community is usually more than happy to help you with getting your Containerfile set up and running. |
| 246 | +) |
| 247 | + |
| 248 | + |
| 249 | +$(H3 No build system) |
| 250 | + |
| 251 | +$(OL |
| 252 | +$(LI Navigate into the root folder of your project.) |
| 253 | +$(LI Create a file named $(CODE Dockerfile) $(LPAREN)no file extension$(RPAREN) in that directory.) |
| 254 | +$(LI Copy and paste the following template: |
| 255 | +$(CONSOLE $(SHE) build stage |
| 256 | +FROM ghcr.io/dlang-dockerized/dmd:latest AS build-stage |
| 257 | +COPY . /d-project |
| 258 | +RUN dmd -inline -O -i -I=/d-project/src /d-project/src/app.d -of=/my-d-app |
| 259 | + |
| 260 | +$(SHE) runtime stage |
| 261 | +FROM docker.io/debian:latest |
| 262 | +COPY --from=build-stage /my-d-app /usr/local/bin/my-d-app |
| 263 | +CMD ["/usr/local/bin/my-d-app"] |
| 264 | +) |
| 265 | +) |
| 266 | +$(LI Adjust as needed.) |
| 267 | +$(LI Run $(ICODE docker build . --tag my-d-app:v1.0.0) to build the container image.) |
| 268 | +) |
| 269 | + |
| 270 | + |
| 271 | +$(H3 Using DUB) |
| 272 | +$(OL |
| 273 | +$(LI Navigate into the folder of your project |
| 274 | + where your $(I DUB recipe) $(LPAREN)i.e. $(CODE dub.json) or $(CODE dub.sdl)$(RPAREN) is located.) |
| 275 | +$(LI Specify a $(CODE targetPath) and a $(CODE targetName) in your DUB recipe. |
| 276 | +$(SMALL While this step is optional, |
| 277 | +it will make it easier to copy the right binary into the runtime stage later.) |
| 278 | +) |
| 279 | +$(LI Create a file named $(CODE Dockerfile) $(LPAREN)no file extension$(RPAREN) in that directory.) |
| 280 | +$(LI Copy and paste the following template: |
| 281 | +$(CONSOLE $(SHE) build stage |
| 282 | +FROM ghcr.io/dlang-dockerized/dmd:latest AS build-stage |
| 283 | +COPY . /d-project |
| 284 | +RUN dub build --build=plain |
| 285 | + |
| 286 | +$(SHE) runtime stage |
| 287 | +FROM docker.io/debian:latest |
| 288 | +COPY --from=build-stage /targetPath/targetName /usr/local/bin/my-d-app |
| 289 | +CMD ["/usr/local/bin/my-d-app"] |
| 290 | +) |
| 291 | +) |
| 292 | +$(LI Adjust as needed.) |
| 293 | +$(LI Run $(ICODE docker build . --tag my-d-app:v1.0.0) to build the container image.) |
| 294 | +) |
| 295 | + |
| 296 | +) |
| 297 | + |
| 298 | + |
| 299 | +Macros: |
| 300 | + TITLE=Docker and OCI images |
| 301 | + |
| 302 | + ARG=$(TC code, arg, $0) |
| 303 | + CODE=$(T code, $0) |
| 304 | + CONSOLE=$(PRE $(CODE $1)) |
| 305 | + ICODE=$(T code, $(T b, $1)) |
| 306 | + SHE=# |
0 commit comments