From 7bd2b738a8bbef331e8ba20159a28960a44e262f Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Mon, 13 Jan 2025 17:01:24 +0100 Subject: [PATCH 1/9] build: replace absolute /tmp with runner context temp dir Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com> --- .../manuals/build/ci/github-actions/cache.md | 10 +++--- .../build/ci/github-actions/multi-platform.md | 34 +++++++++---------- .../ci/github-actions/share-image-jobs.md | 8 ++--- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/content/manuals/build/ci/github-actions/cache.md b/content/manuals/build/ci/github-actions/cache.md index bb12ba8b660e..d0e8ffcf0767 100644 --- a/content/manuals/build/ci/github-actions/cache.md +++ b/content/manuals/build/ci/github-actions/cache.md @@ -248,7 +248,7 @@ jobs: - name: Cache Docker layers uses: actions/cache@v4 with: - path: /tmp/.buildx-cache + path: ${{ runner.temp }}/.buildx-cache key: ${{ runner.os }}-buildx-${{ github.sha }} restore-keys: | ${{ runner.os }}-buildx- @@ -258,14 +258,14 @@ jobs: with: push: true tags: user/app:latest - cache-from: type=local,src=/tmp/.buildx-cache - cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max + cache-from: type=local,src=${{ runner.temp }}/.buildx-cache + cache-to: type=local,dest=${{ runner.temp }}/.buildx-cache-new,mode=max - # Temp fix # https://github.com/docker/build-push-action/issues/252 # https://github.com/moby/buildkit/issues/1896 name: Move cache run: | - rm -rf /tmp/.buildx-cache - mv /tmp/.buildx-cache-new /tmp/.buildx-cache + rm -rf ${{ runner.temp }}/.buildx-cache + mv ${{ runner.temp }}/.buildx-cache-new ${{ runner.temp }}/.buildx-cache ``` diff --git a/content/manuals/build/ci/github-actions/multi-platform.md b/content/manuals/build/ci/github-actions/multi-platform.md index 86d5349eddd4..71b48d32267e 100644 --- a/content/manuals/build/ci/github-actions/multi-platform.md +++ b/content/manuals/build/ci/github-actions/multi-platform.md @@ -179,15 +179,15 @@ jobs: - name: Export digest run: | - mkdir -p /tmp/digests + mkdir -p ${{ runner.temp }}/digests digest="${{ steps.build.outputs.digest }}" - touch "/tmp/digests/${digest#sha256:}" + touch "${{ runner.temp }}/digests/${digest#sha256:}" - name: Upload digest uses: actions/upload-artifact@v4 with: name: digests-${{ env.PLATFORM_PAIR }} - path: /tmp/digests/* + path: ${{ runner.temp }}/digests/* if-no-files-found: error retention-days: 1 @@ -199,7 +199,7 @@ jobs: - name: Download digests uses: actions/download-artifact@v4 with: - path: /tmp/digests + path: ${{ runner.temp }}/digests pattern: digests-* merge-multiple: true @@ -233,7 +233,7 @@ jobs: type=semver,pattern={{major}}.{{minor}} - name: Create manifest list and push - working-directory: /tmp/digests + working-directory: ${{ runner.temp }}/digests run: | docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ $(printf '${{ env.DOCKERHUB_REPO }}@sha256:%s ' *) @@ -326,13 +326,13 @@ jobs: - name: Rename meta bake definition file run: | - mv "${{ steps.meta.outputs.bake-file }}" "/tmp/bake-meta.json" + mv "${{ steps.meta.outputs.bake-file }}" "${{ runner.temp }}/bake-meta.json" - name: Upload meta bake definition uses: actions/upload-artifact@v4 with: name: bake-meta - path: /tmp/bake-meta.json + path: ${{ runner.temp }}/bake-meta.json if-no-files-found: error retention-days: 1 @@ -354,7 +354,7 @@ jobs: uses: actions/download-artifact@v4 with: name: bake-meta - path: /tmp + path: ${{ runner.temp }} - name: Login to Docker Hub uses: docker/login-action@v3 @@ -374,7 +374,7 @@ jobs: with: files: | ./docker-bake.hcl - cwd:///tmp/bake-meta.json + cwd://${{ runner.temp }}/bake-meta.json targets: image set: | *.tags= @@ -383,15 +383,15 @@ jobs: - name: Export digest run: | - mkdir -p /tmp/digests + mkdir -p ${{ runner.temp }}/digests digest="${{ fromJSON(steps.bake.outputs.metadata).image['containerimage.digest'] }}" - touch "/tmp/digests/${digest#sha256:}" + touch "${{ runner.temp }}/digests/${digest#sha256:}" - name: Upload digest uses: actions/upload-artifact@v4 with: name: digests-${{ env.PLATFORM_PAIR }} - path: /tmp/digests/* + path: ${{ runner.temp }}/digests/* if-no-files-found: error retention-days: 1 @@ -404,12 +404,12 @@ jobs: uses: actions/download-artifact@v4 with: name: bake-meta - path: /tmp + path: ${{ runner.temp }} - name: Download digests uses: actions/download-artifact@v4 with: - path: /tmp/digests + path: ${{ runner.temp }}/digests pattern: digests-* merge-multiple: true @@ -423,12 +423,12 @@ jobs: uses: docker/setup-buildx-action@v3 - name: Create manifest list and push - working-directory: /tmp/digests + working-directory: ${{ runner.temp }}/digests run: | - docker buildx imagetools create $(jq -cr '.target."docker-metadata-action".tags | map(select(startswith("${{ env.REGISTRY_IMAGE }}")) | "-t " + .) | join(" ")' /tmp/bake-meta.json) \ + docker buildx imagetools create $(jq -cr '.target."docker-metadata-action".tags | map(select(startswith("${{ env.REGISTRY_IMAGE }}")) | "-t " + .) | join(" ")' ${{ runner.temp }}/bake-meta.json) \ $(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *) - name: Inspect image run: | - docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:$(jq -r '.target."docker-metadata-action".args.DOCKER_META_VERSION' /tmp/bake-meta.json) + docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:$(jq -r '.target."docker-metadata-action".args.DOCKER_META_VERSION' ${{ runner.temp }}/bake-meta.json) ``` diff --git a/content/manuals/build/ci/github-actions/share-image-jobs.md b/content/manuals/build/ci/github-actions/share-image-jobs.md index 17cb2d29c18d..747dfe591bd7 100644 --- a/content/manuals/build/ci/github-actions/share-image-jobs.md +++ b/content/manuals/build/ci/github-actions/share-image-jobs.md @@ -29,13 +29,13 @@ jobs: uses: docker/build-push-action@v6 with: tags: myimage:latest - outputs: type=docker,dest=/tmp/myimage.tar + outputs: type=docker,dest=${{ runner.temp }}/myimage.tar - name: Upload artifact uses: actions/upload-artifact@v4 with: name: myimage - path: /tmp/myimage.tar + path: ${{ runner.temp }}/myimage.tar use: runs-on: ubuntu-latest @@ -45,10 +45,10 @@ jobs: uses: actions/download-artifact@v4 with: name: myimage - path: /tmp + path: ${{ runner.temp }} - name: Load image run: | - docker load --input /tmp/myimage.tar + docker load --input ${{ runner.temp }}/myimage.tar docker image ls -a ``` From 8dc92f238b56e7441490982683b58e769ab4a61b Mon Sep 17 00:00:00 2001 From: Sarah Sanders Date: Mon, 13 Jan 2025 13:52:50 -0800 Subject: [PATCH 2/9] admin: access to insights (#21804) ## Description - The support team requested that we add clarifying information to the Insights guide that customers need to request access to Insights from their CSM. Insights is not auto-enabled by default when a customer meets the criteria (business subscription + require sign-in). Support receives a lot of tickets where customers assume this is the case. ## Related issues or tickets [ENGDOCS-2373](https://docker.atlassian.net/browse/ENGDOCS-2373) ## Reviews - [ ] Technical review - [ ] Editorial review - [ ] Product review [ENGDOCS-2373]: https://docker.atlassian.net/browse/ENGDOCS-2373?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ --- content/manuals/admin/organization/insights.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/content/manuals/admin/organization/insights.md b/content/manuals/admin/organization/insights.md index 478f8101b471..a66f77fa4698 100644 --- a/content/manuals/admin/organization/insights.md +++ b/content/manuals/admin/organization/insights.md @@ -28,6 +28,10 @@ Key benefits include: {{< include "admin-early-access.md" >}} +To access Insights, you must contact your Customer Success Manager to have the +feature enabled. Once the feature is enabled, access Insights using the following +steps: + 1. Go to the [Admin Console](https://app.docker.com/admin/) and sign in to an account that is an organization owner. 2. Select your company on the **Choose profile** page. From 587b827a4d70288caa23adb1312bf4f2fc5513a2 Mon Sep 17 00:00:00 2001 From: Craig Osterhout <103533812+craig-osterhout@users.noreply.github.com> Date: Mon, 13 Jan 2025 15:13:31 -0800 Subject: [PATCH 3/9] get-started: cheat sheet update (#21806) ## Description Edited cheat sheet pdf directly to add the context "." at the end of docker build example. https://deploy-preview-21806--docsdocker.netlify.app/get-started/docker_cheatsheet.pdf ## Related issues or tickets Closes #18575 ## Reviews - [ ] Editorial review Signed-off-by: Craig --- static/get-started/docker_cheatsheet.pdf | Bin 558081 -> 535161 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/static/get-started/docker_cheatsheet.pdf b/static/get-started/docker_cheatsheet.pdf index f21c1057650cc2213345580e43849883cae786c4..13436e65523090e3ade96f650ccf1d722a427c2e 100644 GIT binary patch delta 24972 zcma&OWpo`$vNdX17F)8InVFfH(PCz1W|f$kSr%K&j21JK#f%oSEO>VJ%-p`;^vt_I zs@BO|l{+J%D)Q{C6}$XG2_NV10TOv(Q5ptX7HE>4 zzNxVzKHHxSMJESmLnkE%W8=@Zwodr$fA%T??smrbbV9#ytZYr8=~T>(U5y>&9gIzk z9gJ-Ze+}pO^Fjeb2U}5F2Wxx=`ae5Vj2#?*&qc>T#3;f7&C3gIY-9A>^55qC(*s3k z1E)VGP?M2{rc?Uk=RfU+rV}-{asrGU@aaUY^qq`_jSX#$jDLA;Y-8$VhR?xB{~OfN z$-!9P8W!3uvruIvdRr9UJEy9;oh~fVrOEbz@WO(nE+2=&O0-UV*s`VV;{tlqEGy_( z)gD1kqV5u_9(Z+{6|xcas`5c%nXI$oPD}>$0~4!g_;q_`>f7^elld-SVDNe-_r1Qg zU*vU9d8=u$is|)fj7Z-{+GZfbt*$(I$+t!w)fmT?loT?}pd4r#onv;P9l!2-p2Ljf zD~cJYP%`_FEW>U%21!We#MB*kAF)M0m^+r+D5r*Ahwp;3bHR{+<&8%b*DvRKAL908 zZa|w}6i%UCwYad{P>>ENa)sw557>v^;omk|=?RTI^=23BwDhKzwOcr-W1cbQ>hT%UR5wcUG{tDzIY|t%d*cg1GTUUXS3$aj zI`L2K3;E;q(St&Lh-AZOX0Ys(sB$#EoC4=}nT|5WmqO}n@(y0jQYvLyee@$GTXvc(s(fGCRgi=7ZT#(^oPVPSuRi2!<@p5v*c<(zQtQ-3D zeBM0`?xgurnII{V)_}95Pxs@6O(?1BOS7s&3l}1#JWC^hWn|#OwOg;PxoJ~1@Th6* zO3}~*`Hg;D3o-Y?Nj42X_Y`_tSRppJB;~1*uZZUXzU|O*n;*Q>8q~fg(fke)atQ=} zt8n%9*^K!8LQO<&ct_3XTiLU6dal{A)_XsU^6(-e1y!&-o}i~I?_tXh+eS2dO@gki zoP)Bg+#vvvKQu&q5{~j~I#0Dz@BCt6ry7uOd%}+cal=Pc$~nAD8c<5<07nyUBd!zv z(lRx~G+G(p`C&1Cj?r@A%f+nL$;G+p1pFZkXQ%9OGL?kl*FlZ|JuVFT-&Us9x+cr*7cVQY9yKH$XDsH$!26 zXaAqM`p03LT@ za^xl^Lk8t&<#4q>FRISnF7$2f9}BUex+2PK^MYIUvPS7YIC)-Bb*)v_aNR*c0qY0nd>pM>seugU+X%p zBIIZbm@~guKsiao7NR$@Mj1Bh1I-@5)!}G3N${O3de4`i+^r>!>6DX8cS{Z7Yik(G zti2nZp7zc!S50!+us401xG|f(vEEDIIZ(PjSdQqc&9^&hgLR;9gP{*Z+J=lm5-WOw z7!GzT2JMEMkHbHa2n$Knj^rRg0K!+~^G7+_xC2{7+)CMp9upg}oxM-hK!V~HpJCrP z1DMaEbqQWmgZ(Za3EJxpq4!x+XFY1iQBywDsri@U5^szTu?tjjRrLfrtR!G$4wl5w z43Xcj%gj%3_T~L?zM@2=JaX9VVYe8YfxEdDWTQjeSgfb-rsag9)$2EXi+(n+j)wET zQjLzyu}EQ_{gQv}mfej50f6=YGKea(&t_pH(hZT>5*Krph+y+^XzoZi;Qj-hAFpgc z9yQ`~GbdMyR+cOsFx3m_YVu z^9kS=u)h&Llq~vlnnS7V!H70N1n6WfRZR9x&4povQB{0VPY+g42CybBitTsNrt|T_ z=EE?G{LEE4E!h`EP3i}?aOB950%C8(>_*w+)uymI2|r_giDYQuB|?n8QE1eI$0fEg zd>;&bC`l+0$%2Ta*%NzN$clL`p5RQTz~5!SXm>wD5=Vsu3V9vD z+%LAJ`EJfi=p~wz66hiGo>2;#i{#&q$b1(Owfxo20%pjQtpS}kPplHs6hv82ezJfo zk>4dl@@qjx+--Q`#W`moGos+bnzAItMB?XGWs1Enx>Mk$JSr4S zB#G9Gm`7d`MboIFs%6a!;?6jpM*M14UBsK1V>3e%iK;C!Ji^=Et}jtN)D+rVlS|;+MNNQ!p5!K@XgdzFunp;}2B~~T zs>PYj(AdhLe{!XxfCiSagA-#*J!Rc!>fn2$>bDFyfi*qvhk)rqgxG1!{(6@>9%% z1$Nba@1TIb!_5GOVX)wVBq{m!1%4rn0GkewlN#3GS32-?z7@hw<=APdqogS!-(J?`Sjz5SiV_Z#xu8@N(^d| z+w5gyTV`*=;9tiz*wR{YnLim}Bq%Bkv1m5d%%KkTJaLzlUahKsv}pP+#1u*wHf9(6 zV7LfqtkxjKNNAIY)#l;V66N0Y_U;V{JjR3&n^VzGe*7500JieJm^Bqsn#Ou&PK{kc z6e@zz^3K~I)CTc6%is|Ko8rpFKL>MyOuz}XEAorck;`^%uFx4_Ps1h}jz;FvW*4dj zd(wiQk`QtURE5=+7{{lwUk=IYym| zU2Tr<%l{}}4SVSSzNSE}!^WbiLNz0Sw{Y+J~fYwefcy@fml zUZ8B5vg3c!X~&a_Lir-fSdcGFH^SMgI=1aieEZgLYKW*=V11UU0TK_jEaaJRrc4Jg zGhzfnvlc?Df=950G7Sp`v~+V#R}F;%!Iff&d|x1{YEo4E%xJ(7=<;M-2HqK2*C}s* zm45PrmFkRsf1Pscco{2>hBn07J2S;E#R@I;hqjDK(5Wa&V_HJrb@wfX}|M zF<+e6i`+nLx_^~V$sGBV%1=DBq&BayyIuv+)lHH|Tzc#&_BAx%Lk5jM{k99Pz=#4j z8at=xkG6XJuM&MCIikMukr({QHf7{y6$9av7FND7|BAQ(a>Yi$Y~(16iBqe41Bsjra5&WIIsUFuihh-(mQV;FD>1K!t# z0Yw^|xf%Li1#a~U3gq2*>^=rIHOq?egO(RnH`mr6k$+(%B#MgMT!4_=7|xG8`h#g_ zeYBuQk;?C~k+hZ(c@!r%5xzrtcOr07<@vFNj4BW@p`ui3Qw7kr?7XY zI=-iMW2%)TkQFpN?Pa?3T+1_@Lg1wI4$8`&>=9$;GwhbrX^rYu!dpz5_F&x$viieF zp`)O+4`>6JO45Q0g1&R$z=gGyb*=e89Y4TGsKeR;?_pt*x+k6)-&751^}uv+Sm@W( z0~tc7=79(j=lU!V9-rv5TY`K#Uk&Y6NIo;$6|<0*8RKvJdWvz=e(ze|a6YL=PLm zWRJsoK)$q!n_c5WQR+xs7$0ggK8LdG6nI^yb0=$<7cK{diVwB;A^gaCxSYgGIQ=$D z3aAkxED|w^ex@`=OD;82*u|52f!bs(pr9O1LNKu3or3TBOdee` zD~%myVr4&yCDVjK-3Q||LPn@$`1$EI2IpH*3w|(j2i=gXtVj?S)R<^Sjo=Dgjd#Ne z0>hTh7mKyo0&e_8qNqG*oN!Nw+)i*|?N~f^C;NfeP3C5;xRjLT$ShYfoQCOreJyJT z+&t-mrgVAOPW`j;iP8aB{Dg`fKhL6Xu#tY9`z&eb)3F{w*WoN=^!OKc{$~1qVWe$i zi5%_3O*CSI>kG2#eRguG9L0m6GpGu4iHqP`A~lO505V>{H-?mg+D&d_1iV@b)a1xs zMn;)G4tq!Qq^>UWRKJ<+?#gE-)s^`9U#r+ zd1)Y*jVqi)?dIrH%FK@yW^q&>z)AQ}1vigI3w#%+4jD9xjThAx*NB{BSjA~3+8qiz z?}1|%qZP?t`%pLWd7?6M$*Amm+?GB_Ml|Bbi^PBdmh_LOc%;o7RY2;2nyr12mam33Tq64c$*%8p?>@n(^AWVg!3 zZ9onDaiLc%4tFoTuFQc1HzFNo6cEVA!p}BQh#mb zp4&C$9}gcL2ga^d$+S2(-H{$Zd_GhDc#q-n@VdJpN7wb_(Cp>-V!))vl<9-p>FMbG z;(ndedkyfoKWT|>Xd_C!W);)NGf~oFl-#rHR6HGFPHuv>_M6%`i96EpN@2u}Zv#x2 zleD*wk_(GEKE;l2XIEI!5yRH6VQ96SIz!8k3b0q~m!Ui25nnIYR`*JgT7D|Ck%EW2 z<#=hVz@!m$H+|dh&7l_*Jva@wCB3N#3AImObfrUP&->}?bhdmZ&}Z06_Wt2^ZN&-3 z81LmS7V?o&keI(uI@*10V!?;6)d_eb;#G9tmbZ1Io#4@ab|Nf!V!XJz_@=nKtA3^4 z+(}QWm6`A+hcMI~nFHOqv@P#W10k@n90S81PL7siK`ChbMuT zkmcs~t9PW?rcWH5H%H1B__Y>CS~yzWASn<+SzFO|bL%q#cL!jC!U^LX z+g`_P=c3fshTD@`_rZJwu5QQHgz^BtrYBRawRT-^D^Wz}n?iXJ<`io|x>* z{CKZz>o%ulM+iULomN&+3wR*#&ivvOY0=k2TJzLF34M`(12;L8i1?e)gwQh}!LEYn zR8I}+gwDwMW*1#bi>n3MjdRmESRIETI3>HM$mfmuP76ob^mB322d^eRu@_cclC~oO zwFCh4N8 z&rf1V`ryPr1p&vA`EOzaZ4hdB?{t&ZIk+;jt?`AS>ZG1|ZjT<7>&=(gKEQhfP36F4 zIQI>Q7&vu_ixk zVd&Tra_^89ftaqA7cM=(BS(ZS#!&WW`$G0fEefL+&kldYMVJ7FkqQ@K?Aq+eZM<6e zo0E`g_I<+rvQNgu;qQmgs*}A5@ysQ1b&_y%lsK9Tm>l5(9Wnf`C5EJkz1|wvh-LWS zYq5ZYj=X25WWgzOLNF(P=Os(-pd*r$L>0leGwm32FsH9hSF})B;9;XQ`BTYM)<)@# zhhIPIGP@+(mskq;@&YBC@+eP--x_LVG}bZORv;8*!NICp%(rgGR{mY*7|V8}E*f#Y z`Z{@m3_ghQPkKLAdVrQ{Tt>nDKT7r0DPI8cyh3DC(hq_v=#v zjLI0ckAqPF{q)vlv&`B9!e9}!xbl8Uqcy~yTW;S6Yte@|%k8AIt_l@g516}SPv4KH zbRdy-!lgdA1i>bk;BfxR!iQL;G}bI&oVSb1JGU2UHN9S-(E?vd$oGAPS83q*QwgK+ zA*(`3yW+BYu@{n-o=D<`Bg>%m&$Fd(g(4&%qfqmJ%YEF)I&97A428`HZo(KiEeZyi zPE~0pT!u4A#PUeKI}FzA?VyqB4Fc}Z@3eN9E(mr$e&%AB$uMrj(3w}|vth>L|Ii8{ zR+aVKL5TKaJnpbRkmn`&Jzeo32ZM^NlPm{=l5C_*dgNwU_9wPQH^z~%p#WoQEpxpK z@ZF|u06}wwdt1$Z8>e#=1+S$RK?cHVSH?JhW{F&t^{TQ)fg?Oh1ze;NBM5`;a$r1Q zgsx;JKDANQa9Z;ByQOxp2xrcUwE^vj@2;!5mmw9Q2%_h937UOIpV$zw6xZK=E^4a{zf zPsp_-P>eZ0+&wfqPP%65)X#fL1LKg3Yw_7!f@HY^``WV-aZ)vx=aP!pRJpE)LY8#G zZ7#J`j22!N$GMeQ7d+jKXctaubkBvCGaz;X8`Z^BvA0OlFdn9jX7A+Hj_T~#^0*lU zdg%EnQxprkC~DO&H)xSBlzDWefuS54yQRgrACseQlMBa95KV%2H5A5qPnLafxh*SVL1$4>gzFf@1ckcU0>|X9Z>gYgJ~`Qb*J6+a zI{x@}D5xrWVG0)Gr40^#^fUMF8SG%`yT6k5mA>uQrYsqOtmv()M&NOt1;O?N6J_J- zqH=GG1-2^xb&$djomq}%V0V@-hvQD96?lSVH)^eL#U{$hKo*n4=}%_7Kq~5AaJAU^~fh9 zv~8+Z^XZ~Vn2vqNR3PE|AUtC#E6Rw1pA2>6RdbK7hA)u0`uKAJ$tH=5%YkudRq9Nw zxq0*E)s~o+>e5AO`4}?8h^fU#Us6>>WvabL+fB^LYI(8dTHc;bXIXLF*_!n|t!4^6 zospZ#x6GSmj4zm_<_0EYVlJ+vRvHhhW3$wEKhMpYpFzp|r~xog{dQf%!`6-$Qx`)= z$3``erEgRM^G=0r8U4_|DzyYVNjW3Quc$CD8T;W84Ettb%1qJE zZ>RZ0p6>{)DBMyvhxnvv`!F+Qz1w2f)3TeG9#`lV3u%EMMk=8Ri|X;>wYdDemQQOI zWV%|fl!5IaFv7U1&Nuhk?q(+=z4p4RV!T|PlL_pz$+!md%ky}BL-U1J3bpt|3rMAE zcr|o=RWX;ghK89Y3t$iWeydG()S<3YMg<}@p69qP8TLutG5!g&{0~vjfsFbY_UMAw`k2k|e4mGR=eyqF zPb;A=Pu6{6UG@+Xv+qSS8x840X=$%pyGCw*hNr=)=tHS3p|;3R@(qIuK9A1YX1~5} zmu&&HgnKJhU7Zj6!>*PjPGmz@J(R|-lPPGa<tY8)a}c*xg_OIZbR;r+OT<;3JwiIuyYmp3AgNhhiWQtdChbRlDu}}=KL)_q2eXSDG)DhFwJ`} zYqhc<@4R4wF<|TjF21!z*dT5)X=7u7M*0Dh3l!c=u?u?#W}o*8Y^@z6-AGp;Hmq}= zCZ7%Oq~OM~iS!d-yX-3zytIl@mc;RkJz11@hM z2HcB5OZj@{sh)Bc7f%#cHt!gwn5(R#R+e9>Ub}6D<7VqH(_7}p(mltt7)Rt_hM~P> z%H)8vd3sw{cqlo4K-$kv#4QflVQ9LSHT;W=@qaajv#Y>+O`9g`X7&PYBx z)2%tr2W?08Tr9*LPE3Xw_mPw_mr^l6YsoBzPo+Eb^LmWhwOxJ_S+q?kj?T$?ZWARB zfCxK-ZvT}sZ#bl&7TR%)M0$LU2`9yLiwP`u61<20i8#`uTgbwhs2R5!oYrd}Q`&U_GxiR^hVpd} zcd;nj@*sTUHvB<$K3zrJ;@17my!r9#dlWK1kCNpx!+>YQ!lwftM$V7|$LfUJa4G5M zgmrgNfowhGC{S9i0_vxAvVKkTl(~1{aVHI4>Tp-a6F9mqobS~0Gs3jvM;;1(2rP4M zfl+p*!7odhn^3%LVDU!QC|YF!g~+ld$$iVkXckQwcf+t?VG4HnW)@%9lh$;tB2qPQ z1gJJt+53*i)nUSI|gan^$dqB>O?b+Aw)JuaPj^;`X{pOE72gwaQ-hy#G zfcE2A3PqX4z_5H^eCiE25Zp3Hv&bY-MlgV_(pwh$R;P&K4&L}&Feru0VG7Ykxw+I- zo4BE};uG9U988Q(=BmjH;M}H?kSKHIZA)*jtaV0O~ zf183|AX+LRb4Rs|EcnT?z}Umh^UWQsMB;PZZafO=(u7WZ;(Q5717Zu ztW4uO%Tqyr5nokfk~R^9UV*Lp>3GL0|779A4boSt=lkyY`PWX`gY#nFhU~gB@6=K1 zq>=oAbkWKq)~tpVKpTDTqRUeZv7AN3)t*-CtGVr1x9v)LeO|atJ+ddf>c_^XUUyu7v`}YB}x_ zepn_CPO(Mx)2M{gZgXVZClrJ#5_6t!o$K#uX&2QjL9DlOoQx%NcpvYs0N$6EiwwZC z9V7c~1Esv4a@<88WqFKmb2b^g=7%Z{s|%)l{nS!8e}g!OBB93>1>K&~DS|uNobWwuu1YAQQV-NN|}1b(2b=qX)2 zlW)MhT;_7NmGiI~PpN7$YEGT%e2uqHqk(NSb$p3FISlrIcuk?n z!ZkNLA2Zg8_9%r!=|X_r<$RMF(b@rOsd2A@@Y_xAp zvr#9s3V`;R8mDa;Z83z(!02`E*9iT|My*FSAhj7!nmo<%IvYy zY!m0PFuHbR>^9mt)nlVN==BMmQBCPRw}KLGrONH*xU#4#MFd1x;ODqw?Y)!z&u18sUzP<+^NR9*wQ^74BLQ z3i_ZwF^^bY_feu&+sCqen^#fcW12qn#WC5VNEt&&Ih%-Wn$rZG)*k6U6|zsC7e{@) zooza2UMveSm+`AjKyH~HsljfU=U&NHX@!^_cG333jy9hX9#da(90YxSfYnOIG?Z%Q z0}v{BeM-vUikn;auvx9A`^73W+cg4<25AtNs!BomIMzZZJi!IOL0s?lh6f=@@l>@3 zROLTtFjhcqrkPB$rPov%BrxHg&^u{DwXq09!1eB4C_(6*P2LUr^G;+gNS%I29$%Q` z*1JV1ata{7Z8!oi@2b)fHC^C}oU0Qo1tveMHoLa?vs!|(pXRk`X_xOQ%n8+x+m`qY z+T2I6Qenq*RN4D@iU7{yCKK~;!3(d*zI^3W{#lo62#;Au=|^dti7a}SaL2Tqu0ta}+$iJ!qH9V07V%qbK%O+tS%frl)s|@7AJ365n#7kc_ytfw{w4 zp&8!OdH>dq%mrjRI}waIt@gF%bk1ptTnjI9YE>SLM=i)7h{b-q2N z6r(D6+I-O}`uzKv0k&{{2QOcEiO(iOT31^;OW zfU~{5wUDDdvmcoidUlJiyB#7pt^N7^E2x;>kILaihlz=+tpH2E-qriIP2TD(E3is~ zkg~O)rxTZtO6a7;mIq5^04^ZK^}dfKY3bm8vFCI_dADMH{7&C?!B|FDIwFd-mQ=^PE8#8%3N^IiTNu zxWLJw9h%G>k;@#|Dt@dA4m5a7!Q#a0aD@(Fk~d zOc-=vM@suyFqMTd1gQ5%r;K2^lp2kXux&^@)sW(KJsk^HW&@9>Y?i=o`J^}Ymm5Dv z18pvB6FM3kQ9h96-4-stLTjtZ1mT{Uvjz3{&-h(;y5Suonn|t01%&2_?u8gS z&Jt?nDrwTM%OFbYMQSp@*I&gLYn*bL=wA)KN5)y8wj;RI0|IH^m{1sqNKsl5$cW9M zYO)_Oi(y%vaZjZ)Fxex5>Md&V?pYU{6uiGrKu2GGFVMO3pv_VqQv|COEqH{)N^^xv zhioe{G=?HZZfdaEZV2KOYvawE*s>l4oj>kZ3O|faE9X;esokEoZfmpc7gG5kt0yaz z3?1M3^Mgvg4AAL>tAG*_(J;rkZ4^p$^TGD=#4M!3u4M)4fb4)<1umgHbDC(C^nTol zm8)!3Cv#EqF`jtjT4MaGMbApg_4H&ZDST_ak?c6hLZW&qq6Jz9vujxMQWOP6RVUoC z(_Z2Rx1?%ip{W=C5mE765JU>E>Mh4=Y8Zi*YTXS|HlT_^m||3FKNc;08va_^V=V0u z#cNTCAWE!~Q?qy5di%-q%9}OfKCxoUTVsWWPdzj2%8Bc1QIyl_r`i4dD{zx<2$_yh z{bW&6%@&l-d2Cp5@a*2=a9Y+k#d5Fo;!zU|(4WW*_wTD|HR8#f4`PucDp|KbWv+j$ z;$0Bba|XyAd6t6CoaNYBQ}(@S`a2%V%Puz-$V)n&^$%%*a;QP9OB-z-Ez(6C3@^K= z=SUeIRb>;tac831aE*hep@)VTUNp2A84%M1<&tn1}5ujpQ z?ub$8;sMvsYA1Dg3an7Pyd(9(ZTuS-82;kHpS9$21{R7=*3fjaziLS7e;1THI6C38 zv9tYITmH8Nr@w1MIsUAP|6N`V{Hwk^OU+sis}1p$DtRJg_W0Q7<@Hw`ga7Unp=1Q) zdcWShW3aSO&>DuL|L-Ffp2%%3C z#e3Mv5|K&y$@L479}X3fq0e_E1*e}pp!B8eJHK!9sU@P5pX zlMr*)pyvzDMSLC5147r2kFC(dCzdz^c|ZVi%wK4LNZSMU0ZOPAQxaDRQy_SBL2pV& z2)sQ26L!nbRR6&5VDlsCq{mnkL^ebygif~?K>@2T+MAW|1?YuYHa!X}fjD!0BK}rs zpB}tJ2oxenB}FWFv#gKbvbonsyLtQ}1fg%fB7O2(q5NNgtloCeWra)x1IPmK3+`?r zSd;{*T*!x9d4*N8Lnt4jdRhWC$dZ(y@<8kabmY(dL=3{UvG{V3Q3J$1##On2N*CbY zisTiti9h0ieAyMULav3Bb(jB)Nhq1f2iaB3p^W&2z?4!xpjghgu-@&y60`Bvh{YB) zf4CIYR`hKF_-qN4lNk5#Q)-#7@cEjijHSY@j?J=jaodieH062}47Hm-!qzsLZ1&M$ zo*MA+{MpE9W1?vWnZih^Hg?ceU{IgXn6@Ts*`4NxtrzFzxdUzi-_?O)TUO`d;HWq$ z>`dRHv2ebTkTRHXhv!tWyfVXpc#!HsA)CvptF2@RD0rJqV7{_j*`QJ7mgYZNwJfxK zoj9|xP{@*|Juy~jOQ-%d5=-M~>T9%Fh2oCU%tFMxy5?g254=0CN}wY8m`lHGcE5CD zfwqkP8J$+PZrgmeJiO|anzj{ZD#nv!bxL!Gu| zTc0q%kt5b0ml(=NsOMay0Z?A7JK+12(GM-F_`x7LQBvJ(_!7NweEfO=Z+ZVN_!zUr zUTbnc;lP=L(_fo6ZE^O=?lM2uKpdy|wzkE(_%^=O;LJ=V5x4e3L`8}lpXI^gWS!N1 zmGH=C_i+UWB|XPc#jrgLMJ3~wl9DNhS@{ZJuc**rR7MQt-UlxF>)A|*Tta`LnVm1RuVI1ogE%eR>_?67%y|^`YEjtE-pN;F;<)1?rJDt|i+_6Zjmm#g?A{ zSAZ-?_~KZ2jw8|%jx0pNj$NE;PpV5eBYSyQ|5Y%lv4^UEc7k74m+qqrm0s_DsrevV zg1HRW$F1iV%Uk`-;_p`lc=%Z6ZNrx~8Ar`JVb{k-PVWS%DHL#Y3{67NZZ3;N17qou z$!@!JJKsJ96ptTeU(R|d0ObcMd^Hn59L_vidBw1{W1Gj5`s={KkI}E$tk$&Q+)q_7 zV*@DC+3151jU4Yh`Bc7I>f`5-hxqXQa8zpqJ&9YSGe0?~KN9j;s{)v&)JW%OuvywD`4k8eD;@JKyjsBDD%H^8rMop8)ZrXOlc>z zvRk+v-5amR_P%ph5Be#*&;K9_6^V#WLNBS8*iG)IK$tHq8WxF&LBc3$lsH5l_eY0B zWIQ?vgQP)XA9+lV6y{L_2bxjkyb+QxZI%z?c?Oqsl+H3qTBrY zp5h-=#+PC!fYPODhfEUSEqT;a1rtNt-g!x)_Cy7ag(=<+ti{`9+2U>ui zJjQo_R28`z3|I_uiH2nPYz`=LUC-HkTGPV1A2f4VTd~zZ#$8swa8>X|o;S5BA`d(m zFx0GvU|9fNxo}l^cOLN6+Mdt8 zm7vYFAH6)JD|Cf$*yfIu=LX;i7r2T-*6T5ZZ&R0U5OY*RdbeJU!mbOpwdsmSJmmPW z!(1T%JZy0c!b%q+af-rMEbCQhdybKrA6wIAv$vCV%y2Q=A?vrH&L6j86ANSPE(~Tw zC(*c&8lSAD=S6^x3(tMOic1kP_&ZPHWrv`;`{zMyAu7Xa%}zuh`J{0p-XcoTE!@fT z{K)IN!=~%`Oa9_kX{Qb@?bom!t;e}tIre%L-Q~wUFNT(7f>Z~lRBU<0_dlAw@rV`u zD_OsdHD-f)R~54%#oroWq%Lpnht2HS@8$CT?9}*lcd`W>mOsu(FQybo@LpYSkx}jK zAhJ%Ll-qNwH(cxH>`N_A-*zC%OXjqk|D5z{d{Xx~T~N2keEWo720LisO^+4bAn)~F z5UYuEop`#@Y%uC2#A?#=2=oVv?RT@;HfRZJgK_tjkls3DBhMj=9>|I9zneIUM(u+&V&Awhgd-m{{C|>&b?z<#y^i8^X(zosN+GvOmdjy_NG&{z z?67nr>0d^R@<#EGg5lPpR~C~?ijaS>?M18-ai&;r(>ir-)F;pyWz@rH|6n^UkTOEr zqji$JTXDIfNQ#=14Q$DxE9EvpZ7g%>VCxqX+JT{g{)`Ec131L zV#kF5n5*4rOpte+dB}ov?y_bhARCuu5nb_Fu@RI_&nk_)`#n07nQI;c=cjcWl;cc6 z7G+f2OJi0bDVfZ2$qf41FQn82(o-e#$kV1%(lLnymr~||KV~YB;8Mm!`aO)p{8y*S zFZ&QRexXuE&A&9tLBe88_q74h?r&euS?;MR_J{9q%AUU=ggL+19tLkrMbRC;;u)%7 z;Qt*H`-4IKW|NFe3{3x0{4oDL$NUS$l*MQIm%@*cg^d{+^cM-M%l?c8t@bwxBG$j+ z2@2Y};cL><(&MvnF#bBTGW_u1Id*4g2=q>+)~ zAEL&8$rFDo8~>?KRQp9LjSZdtWhV0APT$ZN|Brk4YuC|w>Eataxgdii#U~$@%P-n@MQI^e+f<1{^F2?^)G$uzeQcu+~_w&XQTf$ z$v>o^j4Vtn91Oob40#L$`E|Vib$~WK27dUm{M*;W`VfZ5o|KqcazN6(Y+r^X z%EZHdEP6&NnTCwzgZ(|rOzeN8Or2(7)ZYRz{556%`JDZ)82`f}CKk5eKG!`A+5A1wUvKn(1!DU{3)obH z0OI@iNPkr=|5qgXKT@rUj~0aY?~(qm;bvm{L-yDdtpMT)@;8q$K@xXMsXmg-7` zcY${h$`UbpfMJ_?u}n&YG&|>ptCN!tF@sHqHZkM|0%_!sHGD%q@b)T({Jx9kRsV*c z?kHB`;?*zyTkkwP->Uu~+J*;NMNnHRsbWuTb!xD}G3_$p)eeIF<6D{qa7N9wY*T%LM z(ZKV%fJzogQkge);OJgC%+R5%G-%I=2}x2(P&gWz8-!eFt3nJWmr{@l4h6Fqy0`A`XZb5gU}`jg)>4+3DnapRY85CN^-Xr2Zu^fFJ4W z;tFhrtYsWU8^O-nkW;gCsDsdqn<&H9vF&l##QApu;e&fG9E%cv`pm*eLeyE0p7@?h z5{x@rSGiD%Ve8&fr+_2g2|E_VLT;QH4Y>#6_0yt~rkn>@hAmL+B8nLEG-IGBX3bu@ zIMkh7qUT*cH6PP_@)dJ^$>e)fMB846?9F0=l|)of{aBfCScSetCxS<#ND~624hiXi zkW^JE@^LZ{A{ygD?JbqY;p<`LgXwLm{W~|j3j`tUzEB813#slnCF`#iv`X6A3BG6V zr#?42m2ubLMW%SxaGR^Jb0z|IN4(f1o z!&M|bELI6Mi;i^piMfyoqm^tKV4Y=;ec0;Bv}w_XQmy$|@vzo}Al8vJ76>0B6=d7O z*0xUv+>%+yc?ZC1CrfIW2ss;B!t`(?pCC06ix1{XWxrIU??WDfIYR-RBHl8foeE#7 z3likk4h8kN(B(R7+$Z#3hh8RD>K!Q)R)-bKao3HDJey|nIm7{tUx zOA>WXe6;>3ed^XCV|(}zVKlsr(qWN+58y3Z(L8@R>J&RV7r=}Zbnuoli^sU5l~0ZL+Lys>a|=cmp^(!? z+%hJb51wINQN~+~pHsw(v;5X*@`E==wq-^gC-J!rA_(mWHc@M)=B?& z_ZNLuY7ER)(6Qd0a?Fr^^|vebw|7xB*RxIi6P8tIhZp(5hPWDZ`}%tZW*e@WUbp(J zewo%jrOs-pxjuTDbGnY2)Y{-a$tFwYT=ItvG(r!n3xS_b2Lsu^evWRJ!~rfx&o$w+ zl9u99=z-Ct@~Hqi{be-mo-d?akJp4v^jmvKy(5T1qllmveed{Wb<|GUr=mw;WHvsI zy`^09bbUX2KwOk$FOV|?f}ym5urpV>Kzeiq;S~S$c>}5MQ=AkTR4)^Rcxn>1t!V2| zP1?_afnD6MkU_#eng!dM=X^veKfC|2xd48D<>NPb`At+9IR5(SfdBHQm!0hwN&IjB z){LxwvgltV;(xvaFt4F$yCRDEN(H)G=nc zV3z;+{GN-cKwKiRu=%u?G&UrYALK>SDa23_ z(PA5jFukOIfd7Auopn@H-TKGr79=DD2}zY07+^r@P7$TMOL`FLL$~Ar4hH`=G*0p zLTx1rqs)8rujF|j_k@*?>k$-URx-0Q(vPdh(Zz{kW9xumUjAE(!MLuB41pu>@os`* zm{o(dJ+kQn<705U17i({uJaAVbHnWJKip|UV+R(*(LK4R>Ek3LDF_vquKL=_CPnYY5oW`Pdxq_b2lMDQ>p)>_ZsC_V-Qqt#A&y`dc5ce2pT|-r!LcRS zW~uEPVZgWcjId|tYK9&9Ym9?r&F*_pc}vh`=gUw8$>b{t-BF-E-nSI9LPiV#rgxVa z%mI6$#y;^`#*n3v;FZKiGvtP*^jXCNMnSp`h3Fg8kV<*Q@~k++?mI8?y@gsds=BCF z&l?)NXDD+cSm{_h%7xBY<3URW-a=1u}9kG0*7%hj1X3$$M&(EJ7Rv;k_+cF{>CN1K}-mzB*dRjp;LHrZ?6RPD@X z#k%!eadeW3r*r||Y-ddanE0-Ed@Gme%3A$Is_+pSn46s$JsZI!MPuFVe<|p?*g;l` z!KHPEnMayDoSxijZgT6~&V=$x>wB9?~@>i&@H&8WhW2QD5qMb(C}ccuzFVogXsC(C?5Y_tLgyJ6wO6D^9_C0Nag;i@vP-paw) za=+}QyFC|zftYf!G2$KMVkm0W3ts7d@#N57?B-8#S(JUc{)E2%6)iCnJocdVMCFAZ z-L1Z-vetna8dLLVxASurIXWX+kEEIE2Iw>kRQcY&nW9C+zgKz3ixvJH2qd^Bbc<%q zG>l^e#yF8JcVi*%8Y|KJr+Jv9%&i>t=$}WFDy}UESViN_q~=7<^*?80yOFOnz!IcN zo5-F~Xgk*j)1IlD<@@NiRi`QMLo+d5s<{}h$)}euOPO7$sNllqUSq!SejzsiHf~MN zUKCFx0&aXi!ZOZZBFg8J3XE()#k{60X?OVh?XEUQU`{&wLCA5Eo>1~{7^nIho$`y< zfYXopnw;jWLZKg=vz%XPmrabb4cJQC%ntWTI6_{Jq_br}8v2u4E}vCCz6|3}qzHbO z(OjM%b0vA*>)t0)dznbFdN)-Zh|5TePHt;&fzQL)YsI;l+RDiV{lK@7We&T&;}V^V zfYqZS4;gUF$uSSl=aX0Fnl!O6n}RdYtS01IYVSnBjWDkSX2qn8<&jS5`YSoH{?ud+ zWDGY3XYWq}k)6KqETi&s-|7Y~O5{nfK?-m(N#uLt(Iz7%Y1QZ20Bmr(2+FsL@_B?xL-9`Gf#X|UinKKx&EG891f+6L2luYWv*8zX z`g$61Jx;##b4Q*nw-b7Lq0D%WPQ@#t7~bjwt0c8ZT~EM}+q$!oZTif^LGtC-!QM?f zL1Wb6rR@@f@q_D%-e1|WM0^Tg*bn=!X^)AgK(8jxL!0$7f%2H)#mXj69g1RffphQ} z-k|ym7diIrTI9Zkr?}I-{R8Ai3q8Q4rP70^Oz?X3>67Zn}pG7A=!2WO7`n<5n=?<^QvvRtg*Ta-AA99 zRLH3eIt#ZtZnBOnzEstddgA4X;if*`S@Md|zvELOKEn3sneTPe%Q22+xWL_@P0oyC zb>l|=WMHXpH=yk}c1$`0Frb)NaZn5pGt3^{XwT+!eGI3dd@lUql$Y!|;BkrBlaxL%~%k4&q44&-PEtl8n39Qz&ILwDz4h{eg)cb!82 zOgX=Pw%4(u$9*hn(6X{W*FHAWVTOLM`^d3{a}IWp_FCY@W-xcqFv!;>p=G+F=*k<7 z8(X^a$z&a=F)BpyFPkdLm=mQf#NtC@RIbFmZ1hgvnI?zR-&AI+%fz<|=Y-FDu}v~n zS^$BY@cGd01pG4VKnBKx9;`Vq6Hz=XxsP=qePo~-+sOcyCIp>uX8Zkw0^RhJ5tNN9vTTiGU|5*X?>;sVscT zKe&i?nqJmC=aGEZ!7mQz7>(SJm^rlkCYE`dCu&7ik^0k1mDd?!x3s7?Z6&*5M5!MR zi0-AiZhT4Ztv^WhbH})**E77Bb%x*?5A^$r7VFKR9m^?${q1^vR-UbsZ=NkT;AGR7 zKLUL=Wxwy@GQl~*QIZOM(l0l>f9|6`GgDh_s$b(lkGqb0Clf8-<*=zPgNJ^KL|eP0 zP-5yH#s%-Q0V>vu2KIiXjU3;_^(p~%)eTKuW596k>4P~ZMcppXZ#CSM2b+m2{kaxG zbz>{ruQ|Jou&2kWkZ-Rut7iyY1C;qRoEf~tB(9AjB@Tv8C60YfO!2M=ic?{{%O_8L zw4T51p0&MA^VPr2E4FPXyUncKB(`-YsvbcFCC5#Bz9iAYv$`GcFyi)9WpbjR8Pl&E zh0~rK_%m-=EjLen!Rw2Xl&|wpbedkC+YDDdyWss=+f}`m-^R3wXkyTg0_+6prAgI{ zedPMbj{^^{={|ixqn3JxICp>^ohW;IE3&tmc>>xcA6AacnUP0DUUit8muTS(UU&XL zCw{K_zwac#Ae1fS*RJAcCHi+E^l$aFpKTETe`~`3R8SM*`AeJM0^YFPPvk7WY#|PSZPn;Ed{UB)>=1IA^_Y!jr{6}3 z-QhC?2+IcrJv)ypm|?m$j+c<$ZggCQ3jz1CG^+W7bLQvI9|oCxmWtrTk>n>@e`u4{ zjEzMe2$C$rb?J6#y@lSD1r`& zO_L{C6J{g_sHN>kSC)nZOTE#;9!c}4kosbCpo@k-KBmw@Rz6d^U0P4tmhTM}wrd!5 zMo`jLd8c8$u)VZm9^~$br=f0B6n)&_n%ao9?%<1}0>r6p?8euYq0e&Kt7R~+hU$3Z zqg#%L`)VAVP4W*)R2_<{ks+W@n+*GtBFMbaT)~x6-n2*LJ|awQ78pi@A*j}dej~>p zfe2r-Fq0H1I?2UZvk&-7+@UpK(9RGPVXHKn+m6^VjgzSjc8+!B@d}6BHk>sM)Jot{ zh2t0dq(&sk851<$-RoOB_ca>3nR4n&cF*1Nd442$5kFxv#il7fJu?iDFP+&k{eIguaMn^l0D zQ?j(%)b5WnF3Y&?I$I_m-G`leS#}~7FMapDuY_|e6q6yM5+aQlZ%G+57G}OS0HS;S=mvHAU&?9`u+y^s@)J>H6gLEbf=uL0|A_82C^_82Eelz@Mz- z_h|he5Qj&`(%shFQr^|nlK^%7y^rWGk|X%5IqDya1b-npX8##z{f*@O?r8dt(G3b+ z{opFK(H7XeVvqhnXaxQteBfo|732q_aNRFFA_NBg zUp1qW!HaVG{VN$L5RIzy)b{Y82Qo_iAsdi?m}W-sk3fld#<%|@5b}?c$}1=gMnS@V z2^9DNe5(A63;wL{ALjJ8zL1bV>-*;k6ab^p&~JSZFz6??I}1so`xB26{3}KNdsUAA zhv)LU{SqvUdglM~!!hy+eaHF_|4K7G(o3}vjtIG{7fI;n2_iDyz*}@l|4BQ8_7tq- zp*N(5t=%Qk8f4g!IE!z;z*$*YD?0OK1B9xk!BF?(z8#`!Ef&Sc(pv38k?8LeACd~j zMMj%#ojkos&SlHobGIha-mN?}eZM?3UAC!W8RPsJGY@$QyHlGv1~S`(89QP{CD)(& z3a7`et}IgkiGIXn5Kt4EiepW-pu_Gj zaFC_nH}`*LV-4Ch>BNVvnctORT|J(MZEZ<13E+8Z4}*er*Qqf=5}YjvRwl!e;=^|% zt_7>jS1AdtwtJmZO_Ef8ZuKLLX{zrCBfOe4;dP;xKGxd+w+A9+;kAtGTIc)KqFHZb z^;ersR{Lqcij+=ohgAv}Yo~b`mgz?t?j{qF&}(gSd8XW5E4DNIrl)mmtXJvI(&a^KTP zpKdjqH5YIHB~Uuf0!Nss0MVvsdS*~R$Ue*zLUbldmlf0wq6=H#$72^JDmK+2X}6-T zX)mV@4bxN(gPs+DHl{!&G3^DNH9p!e>cZ8Q5Ne6X0Q;%iUD+PpvCZuWdgGL*W9>@m zhSBV?h#J%hk;@Y3w)yqG`^G|X*`PKHE_DBcGF5jfT_;^*RRJzTD{?SL%+gBT4kDlM}s5VfP+RM;w z7bOx6%>b^Msqa|fWXqO9JXYzi><8M+QLc5UuO4J6EjV~ymIIur?82j$tYNFhD-Y^@i7U3#+grQl z?VV|H(xC;yu`z)=*!}hGrdNm^-0pLT$*~j=7P@w0S_`{`#u2`LTKGXp%4r-Hz0v^` zKpQvBf41^s5yD@3VPvs)QcpN#gZBKrD$=ZXf|)92luo5YsAxZxr+J2N)2 z>IZn~0V{|tIg>GWijz}Z$UfixOKNoZ<>cNOwYZtX1xJqZ<}x(AA{AgD?CGVx$0s;_ z!6(-lPvU0-H|%z#v7AwuI$>G%g=!0qon{(s?I4r`l=U1CtMNun&Bfv=JT9GrX_ob7 zmKJk$wNWLBP~`0t2R}0;F;&{P5!_=bVAt2OOZ#M${7Z7@MY4TM(kCrr7bnYTCnbvp zPn7wq*e>Fz;L*k$u_5nTFL7xyD;AOA#WFn2Op};O^=s-I)hX_lxVpkL&5AxKLt`^e z)9a`j9j&O^%`;2Ihbp^5z>C9e<+~zcduKZb13j1W@}5JyL>qXWStGpN(c5k?pv&#t zsONW!kdUp(M9HAC(*JZg^Jd z&45DcxW8fB-~VT1Zw>T1u8*NRD3$1d^5#7L<~e7Uq+JfQ11u z#{c;lF_iJ@=QN=6(9-I=8OFl$yF=^y*Q0J}GwSm)f*HSG%BY}LF2X2H|7}|M?gsl8 zrvbiqeCHaib)-4Qot@_# zCZk9whbI&EDgdrF;&b{W4{AM-@d7`P5mm?|Qep^VBnoU`?8YNn+P&3Jlg!)eD%Zz5 zNT5|2IaU%uD{jlll3X;B_*l2gORzj%6|lD=)Sr6q?p~f~xMfA+J=Nt$>>MY}>HM6T z(-me;w}!K}-%1yH`ei+A`%in`8h!d~%CKCw2|TCWZ#f#<)f=rO&ez=q&Qmukl+8 z(Y|i;e!TnPdQ((CW&Q{Rz9gcy%c8c&Kj<6~CDO~v4Gk$4={hi2!ZuoFHCnx9v?5S; zaMx*<&1p~Y%PuznS=2X-VvqC_S7x97x7@IgDJs)PjL|Xswtm!db7BQZb!uNAbM*pr zT9LWhWqJrkGRVC(%1gq0-*{b4@!|_2kA4l*XZdwF-IS(^)4GH1pu~i=Sf~H`cxB9y zy$N&LWFKWs<+JTA6ZXc*e)_MKJbk5N&#ZeKZ*a1<%qpG_r3?%Y26zmoxQL4HvXzqj z?P1@|Oo;bX#e7XntZEcd8RQ8;E;>KF#f{YlJaNyE{KF7}x|zDVd7%E@fItAu4+irR Lu(Hak$r1b?qMSi3 delta 47967 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 From 35a1631540fc88bce4dac4c797a8d8e8e2b46f3f Mon Sep 17 00:00:00 2001 From: Allie Sadler <102604716+aevesdocker@users.noreply.github.com> Date: Tue, 14 Jan 2025 09:23:05 +0000 Subject: [PATCH 4/9] ENGDOCS-2336 (#21736) ## Description Adds tags and improves page descriptions for some admin content ## Related issues or tickets ## Reviews - [ ] Technical review - [ ] Editorial review - [ ] Product review --- content/manuals/desktop/setup/allow-list.md | 5 +++-- .../desktop/setup/install/enterprise-deployment/faq.md | 4 ++-- .../enterprise-deployment/msi-install-and-configure.md | 3 ++- .../enterprise-deployment/pkg-install-and-configure.md | 3 ++- .../setup/install/enterprise-deployment/use-intune.md | 3 ++- .../setup/install/enterprise-deployment/use-jamf-pro.md | 3 ++- content/manuals/extensions/private-marketplace.md | 3 ++- .../manuals/security/for-admins/enforce-sign-in/_index.md | 3 ++- .../manuals/security/for-admins/enforce-sign-in/methods.md | 5 +++-- .../manuals/security/for-admins/hardened-desktop/_index.md | 1 + .../for-admins/hardened-desktop/image-access-management.md | 5 +++-- .../hardened-desktop/registry-access-management.md | 5 +++-- .../hardened-desktop/settings-management/_index.md | 1 + 13 files changed, 28 insertions(+), 16 deletions(-) diff --git a/content/manuals/desktop/setup/allow-list.md b/content/manuals/desktop/setup/allow-list.md index 78b7ea3e6a41..7c6df19e23cf 100644 --- a/content/manuals/desktop/setup/allow-list.md +++ b/content/manuals/desktop/setup/allow-list.md @@ -1,7 +1,8 @@ --- -description: Allowlist for Docker Desktop for Business customers -keywords: Docker Desktop, allowlist, allow list, firewall +description: A list of domain URLs required for Docker Desktop to function correctly within an organization. +keywords: Docker Desktop, allowlist, allow list, firewall, authentication URLs, analytics, title: Allowlist for Docker Desktop +tags: [admin] linkTitle: Allowlist weight: 100 aliases: diff --git a/content/manuals/desktop/setup/install/enterprise-deployment/faq.md b/content/manuals/desktop/setup/install/enterprise-deployment/faq.md index 2ca516dbcf11..0936a2a81fc4 100644 --- a/content/manuals/desktop/setup/install/enterprise-deployment/faq.md +++ b/content/manuals/desktop/setup/install/enterprise-deployment/faq.md @@ -1,8 +1,8 @@ --- title: FAQs description: Frequently asked questions for deploying Docker Desktop at scale -keywords: msi, deploy, docker desktop, faqs, pkg -tags: [FAQ] +keywords: msi, deploy, docker desktop, faqs, pkg, mdm, jamf, intune, windows, mac, enterprise, admin +tags: [FAQ, admin] aliases: - /desktop/install/msi/faq/ - /desktop/setup/install/msi/faq/ diff --git a/content/manuals/desktop/setup/install/enterprise-deployment/msi-install-and-configure.md b/content/manuals/desktop/setup/install/enterprise-deployment/msi-install-and-configure.md index e17641c0abad..9ddc34b2b6d9 100644 --- a/content/manuals/desktop/setup/install/enterprise-deployment/msi-install-and-configure.md +++ b/content/manuals/desktop/setup/install/enterprise-deployment/msi-install-and-configure.md @@ -1,7 +1,8 @@ --- title: Use the MSI installer description: Understand how to use the MSI installer. Also explore additional configuration options. -keywords: msi, windows, docker desktop, install, deploy, configure +keywords: msi, windows, docker desktop, install, deploy, configure, admin, mdm +tags: [admin] weight: 10 aliases: - /desktop/install/msi/install-and-configure/ diff --git a/content/manuals/desktop/setup/install/enterprise-deployment/pkg-install-and-configure.md b/content/manuals/desktop/setup/install/enterprise-deployment/pkg-install-and-configure.md index 34f9c9c31b9f..be154a60b2f0 100644 --- a/content/manuals/desktop/setup/install/enterprise-deployment/pkg-install-and-configure.md +++ b/content/manuals/desktop/setup/install/enterprise-deployment/pkg-install-and-configure.md @@ -1,7 +1,8 @@ --- title: Use the PKG installer description: Understand how to use the PKG installer. Also explore additional configuration options. -keywords: PKG, mac, docker desktop, install, deploy, configure +keywords: pkg, mac, docker desktop, install, deploy, configure, admin, mdm +tags: [admin] weight: 20 params: sidebar: diff --git a/content/manuals/desktop/setup/install/enterprise-deployment/use-intune.md b/content/manuals/desktop/setup/install/enterprise-deployment/use-intune.md index 7e7637c4e2b4..e2a7446b9965 100644 --- a/content/manuals/desktop/setup/install/enterprise-deployment/use-intune.md +++ b/content/manuals/desktop/setup/install/enterprise-deployment/use-intune.md @@ -1,7 +1,8 @@ --- title: Use Intune description: Use Intune, Microsoft's cloud-based device management tool, to deploy Docker Desktop -keywords: microsoft, windows, docker desktop, deploy, mdm, enterprise, administrator +keywords: microsoft, windows, docker desktop, deploy, mdm, enterprise, administrator, mac, pkg, dmg +tags: [admin] weight: 30 aliases: - /desktop/install/msi/use-intune/ diff --git a/content/manuals/desktop/setup/install/enterprise-deployment/use-jamf-pro.md b/content/manuals/desktop/setup/install/enterprise-deployment/use-jamf-pro.md index 2aa0e6ace141..e2b2b98fff76 100644 --- a/content/manuals/desktop/setup/install/enterprise-deployment/use-jamf-pro.md +++ b/content/manuals/desktop/setup/install/enterprise-deployment/use-jamf-pro.md @@ -1,7 +1,8 @@ --- title: Use Jamf Pro description: Use Jamf Pro to deploy Docker Desktop -keywords: jamf, mac, docker desktop, deploy, mdm, enterprise, administrator, +keywords: jamf, mac, docker desktop, deploy, mdm, enterprise, administrator, pkg +tags: [admin] weight: 40 --- diff --git a/content/manuals/extensions/private-marketplace.md b/content/manuals/extensions/private-marketplace.md index 24aa130599fc..661e0dbf82e8 100644 --- a/content/manuals/extensions/private-marketplace.md +++ b/content/manuals/extensions/private-marketplace.md @@ -1,7 +1,8 @@ --- description: How to configure and use Docker Extensions' private marketplace -keywords: Docker Extensions, Docker Desktop, Linux, Mac, Windows, Marketplace, private, security +keywords: Docker Extensions, Docker Desktop, Linux, Mac, Windows, Marketplace, private, security, admin title: Configure a private marketplace for extensions +tags: [admin] linkTitle: Configure a private marketplace weight: 30 aliases: diff --git a/content/manuals/security/for-admins/enforce-sign-in/_index.md b/content/manuals/security/for-admins/enforce-sign-in/_index.md index 530c1148553b..20b39724a0ee 100644 --- a/content/manuals/security/for-admins/enforce-sign-in/_index.md +++ b/content/manuals/security/for-admins/enforce-sign-in/_index.md @@ -1,9 +1,10 @@ --- description: Understand what happens when you force users to sign in to Docker Desktop toc_max: 2 -keywords: authentication, registry.json, configure, enforce sign-in, docker desktop, security, +keywords: authentication, registry.json, configure, enforce sign-in, docker desktop, security, .plist, registry key, mac, windows title: Enforce sign-in for Docker Desktop linkTitle: Enforce sign-in +tags: [admin] aliases: - /security/for-admins/configure-sign-in/ - /docker-hub/configure-sign-in/ diff --git a/content/manuals/security/for-admins/enforce-sign-in/methods.md b/content/manuals/security/for-admins/enforce-sign-in/methods.md index 218e2e480ac7..4c862c9621db 100644 --- a/content/manuals/security/for-admins/enforce-sign-in/methods.md +++ b/content/manuals/security/for-admins/enforce-sign-in/methods.md @@ -1,7 +1,8 @@ --- -description: Learn about the different ways you can force users to sign in to Docker Desktop -keywords: authentication, registry.json, configure, enforce sign-in, docker desktop, security +description: Learn about the different ways you can force your developers to sign in to Docker Desktop +keywords: authentication, registry.json, configure, enforce sign-in, docker desktop, security, .plist. registry key, mac, windows title: Ways to enforce sign-in for Docker Desktop +tags: [admin] linkTitle: Methods --- diff --git a/content/manuals/security/for-admins/hardened-desktop/_index.md b/content/manuals/security/for-admins/hardened-desktop/_index.md index 067476c2d1a3..529873f1e46c 100644 --- a/content/manuals/security/for-admins/hardened-desktop/_index.md +++ b/content/manuals/security/for-admins/hardened-desktop/_index.md @@ -5,6 +5,7 @@ description: Overview of what Hardened Docker Desktop is and its key features keywords: security, hardened desktop, enhanced container isolation, registry access management, settings management root access, admins, docker desktop, image access management +tags: [admin] aliases: - /desktop/hardened-desktop/ grid: diff --git a/content/manuals/security/for-admins/hardened-desktop/image-access-management.md b/content/manuals/security/for-admins/hardened-desktop/image-access-management.md index cb6115b7a8e2..ed85752ff505 100644 --- a/content/manuals/security/for-admins/hardened-desktop/image-access-management.md +++ b/content/manuals/security/for-admins/hardened-desktop/image-access-management.md @@ -1,7 +1,8 @@ --- -description: Image Access Management -keywords: image, access, management, trusted content, permissions, Docker Business feature +description: Manage Docker Hub image access with Image Access Management, restricting developers to trusted images for enhanced security +keywords: image, access, management, trusted content, permissions, Docker Business feature, security, admin title: Image Access Management +tags: [admin] aliases: - /docker-hub/image-access-management/ - /desktop/hardened-desktop/image-access-management/ diff --git a/content/manuals/security/for-admins/hardened-desktop/registry-access-management.md b/content/manuals/security/for-admins/hardened-desktop/registry-access-management.md index 7c7100907968..80aaad26d3b8 100644 --- a/content/manuals/security/for-admins/hardened-desktop/registry-access-management.md +++ b/content/manuals/security/for-admins/hardened-desktop/registry-access-management.md @@ -1,7 +1,8 @@ --- -description: Registry Access Management -keywords: registry, access, management, permissions, Docker Business feature +description: Control access to approved registries with Registry Access Management, ensuring secure Docker Desktop usage +keywords: registry, access, management, permissions, Docker Business feature, security, admin title: Registry Access Management +tags: [admin] aliases: - /desktop/hardened-desktop/registry-access-management/ - /admin/organization/registry-access/ diff --git a/content/manuals/security/for-admins/hardened-desktop/settings-management/_index.md b/content/manuals/security/for-admins/hardened-desktop/settings-management/_index.md index cb08fa970c91..27989e0c4062 100644 --- a/content/manuals/security/for-admins/hardened-desktop/settings-management/_index.md +++ b/content/manuals/security/for-admins/hardened-desktop/settings-management/_index.md @@ -2,6 +2,7 @@ description: Understand how Settings Management works, who it is for, and what the benefits are keywords: Settings Management, rootless, docker desktop, hardened desktop +tags: [admin] title: What is Settings Management? linkTitle: Settings Management aliases: From 74cc5b0829e92516a3b550ba3cf55de2658e73c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Gronowski?= Date: Fri, 10 Jan 2025 16:26:03 +0100 Subject: [PATCH 5/9] engine: 27.5.0 release notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Paweł Gronowski --- content/manuals/engine/release-notes/27.md | 33 ++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/content/manuals/engine/release-notes/27.md b/content/manuals/engine/release-notes/27.md index 7e2fe362696d..cb539519bf87 100644 --- a/content/manuals/engine/release-notes/27.md +++ b/content/manuals/engine/release-notes/27.md @@ -23,6 +23,39 @@ For more information about: - Deprecated and removed features, see [Deprecated Engine Features](../deprecated.md). - Changes to the Engine API, see [Engine API version history](/reference/api/engine/version-history.md). +## 27.5 + +Release notes for Docker Engine version 27.5 releases. + +### 27.5.0 + +{{< release-date date="2025-01-13" >}} + +For a full list of pull requests and changes in this release, refer to the relevant GitHub milestones: + +- [docker/cli, 27.5.0 milestone](https://github.com/docker/cli/issues?q=is%3Aclosed+milestone%3A27.5.0) +- [moby/moby, 27.5.0 milestone](https://github.com/moby/moby/issues?q=is%3Aclosed+milestone%3A27.5.0) + +#### Bugfixes and enhancements + +- containerd image store: Fix passing a build context via tarball to the `/build` endpoint. [moby/moby#49194](https://github.com/moby/moby/pull/49194) +- Builder garbage collection policies without a `keepStorage` value now inherit the `defaultKeepStorage` limit as intended. [moby/moby#49137](https://github.com/moby/moby/pull/49137) +- Preserve network labels during daemon startup. [moby/moby#49200](https://github.com/moby/moby/pull/49200) +- Fix a potential race condition error when deleting a container. [moby/moby#49239](https://github.com/moby/moby/pull/49239) + +#### Go SDK + +- `pkg/sysinfo`: deprecate `NumCPU`. This utility has the same behavior as `runtime.NumCPU`. [moby/moby#49247](https://github.com/moby/moby/pull/49247) +- `pkg/fileutils`: deprecate `GetTotalUsedFds`: this function is only used internally and will be removed in the next release. [moby/moby#49209](https://github.com/moby/moby/pull/49209) +- `pkg/ioutils`: deprecate `BytesPipe`, `NewBytesPipe`, `ErrClosed`, `WriteCounter`, `NewWriteCounter`, `NewReaderErrWrapper`, `NopFlusher`, `NopWriter`, `NopWriteCloser`. They were only used internally and will be removed in the next release. [moby/moby#49246](https://github.com/moby/moby/pull/49246), [moby/moby#49255](https://github.com/moby/moby/pull/49255) +- `pkg/reexec`: This package is deprecated and moved to a separate module. Use `github.com/moby/sys/reexec` instead. [moby/moby#49135](https://github.com/moby/moby/pull/49135) + +#### Packaging updates +- Update containerd to [v1.7.25](https://github.com/containerd/containerd/releases/tag/v1.7.25) [moby/moby#49253](https://github.com/moby/moby/pull/49253) +- Update `runc` to [v1.2.4](https://github.com/opencontainers/runc/releases/tag/v1.2.4) [moby/moby#49243](https://github.com/moby/moby/pull/49243) +- Update BuildKit to [v0.18.2](https://github.com/moby/buildkit/releases/tag/v0.18.2) [moby/moby#48949](https://github.com/moby/moby/pull/48949) +- Update Compose to [v2.32.2](https://github.com/docker/compose/releases/tag/v2.32.2) [docker/docker-ce-packaging#1140](https://github.com/docker/docker-ce-packaging/pull/1140) + ## 27.4 Release notes for Docker Engine version 27.4 releases. From b12bf99a0fa1ee05db64f6b5ee804fe0daaf9c2b Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Tue, 14 Jan 2025 10:19:16 +0100 Subject: [PATCH 6/9] engine: bump engine versions in hugo config Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com> --- hugo.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hugo.yaml b/hugo.yaml index 67661392ae7c..f433a02eebf3 100644 --- a/hugo.yaml +++ b/hugo.yaml @@ -107,8 +107,8 @@ params: docs_url: https://docs.docker.com latest_engine_api_version: "1.47" - docker_ce_version: "27.4.0" - docker_ce_version_prev: "27.3.1" + docker_ce_version: "27.5.0" + docker_ce_version_prev: "27.4.1" compose_version: "v2.32.3" compose_file_v3: "3.8" compose_file_v2: "2.4" From ba25f30bb59fcf7f49a8d358ea70cd36ffabeb83 Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Tue, 14 Jan 2025 10:47:03 +0100 Subject: [PATCH 7/9] vendor: github.com/moby/moby v27.5.0 Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com> --- _vendor/github.com/moby/moby/docs/api/v1.25.yaml | 1 + _vendor/github.com/moby/moby/docs/api/v1.26.yaml | 1 + _vendor/github.com/moby/moby/docs/api/v1.27.yaml | 1 + _vendor/github.com/moby/moby/docs/api/v1.28.yaml | 3 ++- _vendor/github.com/moby/moby/docs/api/v1.29.yaml | 3 ++- _vendor/github.com/moby/moby/docs/api/v1.30.yaml | 4 +++- _vendor/github.com/moby/moby/docs/api/v1.31.yaml | 4 +++- _vendor/github.com/moby/moby/docs/api/v1.32.yaml | 5 ++++- _vendor/github.com/moby/moby/docs/api/v1.33.yaml | 5 ++++- _vendor/github.com/moby/moby/docs/api/v1.34.yaml | 5 ++++- _vendor/github.com/moby/moby/docs/api/v1.35.yaml | 6 +++++- _vendor/github.com/moby/moby/docs/api/v1.36.yaml | 6 +++++- _vendor/github.com/moby/moby/docs/api/v1.37.yaml | 6 +++++- _vendor/github.com/moby/moby/docs/api/v1.38.yaml | 6 +++++- _vendor/github.com/moby/moby/docs/api/v1.39.yaml | 8 +++++--- _vendor/github.com/moby/moby/docs/api/v1.40.yaml | 10 ++++++---- _vendor/github.com/moby/moby/docs/api/v1.41.yaml | 10 ++++++---- _vendor/github.com/moby/moby/docs/api/v1.42.yaml | 10 ++++++---- _vendor/github.com/moby/moby/docs/api/v1.43.yaml | 10 ++++++---- _vendor/github.com/moby/moby/docs/api/v1.44.yaml | 10 ++++++---- _vendor/github.com/moby/moby/docs/api/v1.45.yaml | 10 ++++++---- _vendor/github.com/moby/moby/docs/api/v1.46.yaml | 10 ++++++---- _vendor/github.com/moby/moby/docs/api/v1.47.yaml | 10 ++++++---- .../github.com/moby/moby/docs/api/version-history.md | 5 +++++ _vendor/modules.txt | 2 +- go.mod | 4 ++-- go.sum | 2 ++ 27 files changed, 108 insertions(+), 49 deletions(-) diff --git a/_vendor/github.com/moby/moby/docs/api/v1.25.yaml b/_vendor/github.com/moby/moby/docs/api/v1.25.yaml index f3aba9f65c2f..8a57a98d8729 100644 --- a/_vendor/github.com/moby/moby/docs/api/v1.25.yaml +++ b/_vendor/github.com/moby/moby/docs/api/v1.25.yaml @@ -697,6 +697,7 @@ definitions: - "default" - "process" - "hyperv" + - "" Config: description: "Configuration for a container that is portable between hosts" diff --git a/_vendor/github.com/moby/moby/docs/api/v1.26.yaml b/_vendor/github.com/moby/moby/docs/api/v1.26.yaml index cd1470fb324a..8de146c0733b 100644 --- a/_vendor/github.com/moby/moby/docs/api/v1.26.yaml +++ b/_vendor/github.com/moby/moby/docs/api/v1.26.yaml @@ -697,6 +697,7 @@ definitions: - "default" - "process" - "hyperv" + - "" Config: description: "Configuration for a container that is portable between hosts" diff --git a/_vendor/github.com/moby/moby/docs/api/v1.27.yaml b/_vendor/github.com/moby/moby/docs/api/v1.27.yaml index 2b4b3e5be561..3e4c1167cf5e 100644 --- a/_vendor/github.com/moby/moby/docs/api/v1.27.yaml +++ b/_vendor/github.com/moby/moby/docs/api/v1.27.yaml @@ -724,6 +724,7 @@ definitions: - "default" - "process" - "hyperv" + - "" Config: description: "Configuration for a container that is portable between hosts" diff --git a/_vendor/github.com/moby/moby/docs/api/v1.28.yaml b/_vendor/github.com/moby/moby/docs/api/v1.28.yaml index f565ef5d1d0f..34ad0b839119 100644 --- a/_vendor/github.com/moby/moby/docs/api/v1.28.yaml +++ b/_vendor/github.com/moby/moby/docs/api/v1.28.yaml @@ -730,6 +730,7 @@ definitions: - "default" - "process" - "hyperv" + - "" Config: description: "Configuration for a container that is portable between hosts" @@ -5401,7 +5402,7 @@ paths: type: "string" example: "OK" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Docker-Experimental: diff --git a/_vendor/github.com/moby/moby/docs/api/v1.29.yaml b/_vendor/github.com/moby/moby/docs/api/v1.29.yaml index ff014b2086e7..0895a92ed223 100644 --- a/_vendor/github.com/moby/moby/docs/api/v1.29.yaml +++ b/_vendor/github.com/moby/moby/docs/api/v1.29.yaml @@ -736,6 +736,7 @@ definitions: - "default" - "process" - "hyperv" + - "" Config: description: "Configuration for a container that is portable between hosts" @@ -5434,7 +5435,7 @@ paths: type: "string" example: "OK" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Docker-Experimental: diff --git a/_vendor/github.com/moby/moby/docs/api/v1.30.yaml b/_vendor/github.com/moby/moby/docs/api/v1.30.yaml index 3461d022b034..8ab1764f047c 100644 --- a/_vendor/github.com/moby/moby/docs/api/v1.30.yaml +++ b/_vendor/github.com/moby/moby/docs/api/v1.30.yaml @@ -738,6 +738,7 @@ definitions: - "default" - "process" - "hyperv" + - "" ContainerConfig: description: | @@ -5681,7 +5682,7 @@ paths: type: "string" example: "OK" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Docker-Experimental: @@ -7582,6 +7583,7 @@ paths: example: ListenAddr: "0.0.0.0:2377" AdvertiseAddr: "192.168.1.1:2377" + DataPathAddr: "192.168.1.1" RemoteAddrs: - "node1:2377" JoinToken: "SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2" diff --git a/_vendor/github.com/moby/moby/docs/api/v1.31.yaml b/_vendor/github.com/moby/moby/docs/api/v1.31.yaml index 61c232bbe499..9ce5a361bff5 100644 --- a/_vendor/github.com/moby/moby/docs/api/v1.31.yaml +++ b/_vendor/github.com/moby/moby/docs/api/v1.31.yaml @@ -738,6 +738,7 @@ definitions: - "default" - "process" - "hyperv" + - "" ContainerConfig: description: | @@ -5771,7 +5772,7 @@ paths: type: "string" example: "OK" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Docker-Experimental: @@ -7679,6 +7680,7 @@ paths: example: ListenAddr: "0.0.0.0:2377" AdvertiseAddr: "192.168.1.1:2377" + DataPathAddr: "192.168.1.1" RemoteAddrs: - "node1:2377" JoinToken: "SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2" diff --git a/_vendor/github.com/moby/moby/docs/api/v1.32.yaml b/_vendor/github.com/moby/moby/docs/api/v1.32.yaml index 158d205d5789..5707b397fee2 100644 --- a/_vendor/github.com/moby/moby/docs/api/v1.32.yaml +++ b/_vendor/github.com/moby/moby/docs/api/v1.32.yaml @@ -800,6 +800,7 @@ definitions: - "default" - "process" - "hyperv" + - "" ContainerConfig: description: | @@ -3793,6 +3794,7 @@ definitions: - "default" - "hyperv" - "process" + - "" InitBinary: description: | Name and, optional, path of the `docker-init` binary. @@ -6809,7 +6811,7 @@ paths: type: "string" example: "OK" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Docker-Experimental: @@ -8664,6 +8666,7 @@ paths: example: ListenAddr: "0.0.0.0:2377" AdvertiseAddr: "192.168.1.1:2377" + DataPathAddr: "192.168.1.1" RemoteAddrs: - "node1:2377" JoinToken: "SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2" diff --git a/_vendor/github.com/moby/moby/docs/api/v1.33.yaml b/_vendor/github.com/moby/moby/docs/api/v1.33.yaml index af1375432b58..9853899d8803 100644 --- a/_vendor/github.com/moby/moby/docs/api/v1.33.yaml +++ b/_vendor/github.com/moby/moby/docs/api/v1.33.yaml @@ -804,6 +804,7 @@ definitions: - "default" - "process" - "hyperv" + - "" ContainerConfig: description: | @@ -3797,6 +3798,7 @@ definitions: - "default" - "hyperv" - "process" + - "" InitBinary: description: | Name and, optional, path of the `docker-init` binary. @@ -6813,7 +6815,7 @@ paths: type: "string" example: "OK" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Docker-Experimental: @@ -8672,6 +8674,7 @@ paths: example: ListenAddr: "0.0.0.0:2377" AdvertiseAddr: "192.168.1.1:2377" + DataPathAddr: "192.168.1.1" RemoteAddrs: - "node1:2377" JoinToken: "SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2" diff --git a/_vendor/github.com/moby/moby/docs/api/v1.34.yaml b/_vendor/github.com/moby/moby/docs/api/v1.34.yaml index d36f7d5bb578..b91aed4d2ccb 100644 --- a/_vendor/github.com/moby/moby/docs/api/v1.34.yaml +++ b/_vendor/github.com/moby/moby/docs/api/v1.34.yaml @@ -814,6 +814,7 @@ definitions: - "default" - "process" - "hyperv" + - "" ContainerConfig: description: | @@ -3825,6 +3826,7 @@ definitions: - "default" - "hyperv" - "process" + - "" InitBinary: description: | Name and, optional, path of the `docker-init` binary. @@ -6853,7 +6855,7 @@ paths: type: "string" example: "OK" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Docker-Experimental: @@ -8712,6 +8714,7 @@ paths: example: ListenAddr: "0.0.0.0:2377" AdvertiseAddr: "192.168.1.1:2377" + DataPathAddr: "192.168.1.1" RemoteAddrs: - "node1:2377" JoinToken: "SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2" diff --git a/_vendor/github.com/moby/moby/docs/api/v1.35.yaml b/_vendor/github.com/moby/moby/docs/api/v1.35.yaml index 5071dfd23967..ecba0678ab33 100644 --- a/_vendor/github.com/moby/moby/docs/api/v1.35.yaml +++ b/_vendor/github.com/moby/moby/docs/api/v1.35.yaml @@ -815,6 +815,7 @@ definitions: - "default" - "process" - "hyperv" + - "" ContainerConfig: description: | @@ -2723,6 +2724,7 @@ definitions: - "default" - "process" - "hyperv" + - "" Resources: description: "Resource requirements which apply to each individual container created as part of the service." type: "object" @@ -3828,6 +3830,7 @@ definitions: - "default" - "hyperv" - "process" + - "" InitBinary: description: | Name and, optional, path of the `docker-init` binary. @@ -6883,7 +6886,7 @@ paths: type: "string" example: "OK" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Docker-Experimental: @@ -8745,6 +8748,7 @@ paths: example: ListenAddr: "0.0.0.0:2377" AdvertiseAddr: "192.168.1.1:2377" + DataPathAddr: "192.168.1.1" RemoteAddrs: - "node1:2377" JoinToken: "SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2" diff --git a/_vendor/github.com/moby/moby/docs/api/v1.36.yaml b/_vendor/github.com/moby/moby/docs/api/v1.36.yaml index 96e905d3fe20..c0d4de57d88b 100644 --- a/_vendor/github.com/moby/moby/docs/api/v1.36.yaml +++ b/_vendor/github.com/moby/moby/docs/api/v1.36.yaml @@ -815,6 +815,7 @@ definitions: - "default" - "process" - "hyperv" + - "" ContainerConfig: description: | @@ -2736,6 +2737,7 @@ definitions: - "default" - "process" - "hyperv" + - "" Resources: description: "Resource requirements which apply to each individual container created as part of the service." type: "object" @@ -3841,6 +3843,7 @@ definitions: - "default" - "hyperv" - "process" + - "" InitBinary: description: | Name and, optional, path of the `docker-init` binary. @@ -6915,7 +6918,7 @@ paths: type: "string" example: "OK" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Docker-Experimental: @@ -8789,6 +8792,7 @@ paths: example: ListenAddr: "0.0.0.0:2377" AdvertiseAddr: "192.168.1.1:2377" + DataPathAddr: "192.168.1.1" RemoteAddrs: - "node1:2377" JoinToken: "SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2" diff --git a/_vendor/github.com/moby/moby/docs/api/v1.37.yaml b/_vendor/github.com/moby/moby/docs/api/v1.37.yaml index f10b29123609..6c00a3454898 100644 --- a/_vendor/github.com/moby/moby/docs/api/v1.37.yaml +++ b/_vendor/github.com/moby/moby/docs/api/v1.37.yaml @@ -819,6 +819,7 @@ definitions: - "default" - "process" - "hyperv" + - "" ContainerConfig: description: | @@ -2739,6 +2740,7 @@ definitions: - "default" - "process" - "hyperv" + - "" Resources: description: "Resource requirements which apply to each individual container created as part of the service." type: "object" @@ -3861,6 +3863,7 @@ definitions: - "default" - "hyperv" - "process" + - "" InitBinary: description: | Name and, optional, path of the `docker-init` binary. @@ -6958,7 +6961,7 @@ paths: type: "string" example: "OK" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Docker-Experimental: @@ -8832,6 +8835,7 @@ paths: example: ListenAddr: "0.0.0.0:2377" AdvertiseAddr: "192.168.1.1:2377" + DataPathAddr: "192.168.1.1" RemoteAddrs: - "node1:2377" JoinToken: "SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2" diff --git a/_vendor/github.com/moby/moby/docs/api/v1.38.yaml b/_vendor/github.com/moby/moby/docs/api/v1.38.yaml index f82650b01985..c5aca74b3a1d 100644 --- a/_vendor/github.com/moby/moby/docs/api/v1.38.yaml +++ b/_vendor/github.com/moby/moby/docs/api/v1.38.yaml @@ -820,6 +820,7 @@ definitions: - "default" - "process" - "hyperv" + - "" MaskedPaths: type: "array" description: "The list of paths to be masked inside the container (this overrides the default set of paths)" @@ -2773,6 +2774,7 @@ definitions: - "default" - "process" - "hyperv" + - "" Init: description: "Run an init inside the container that forwards signals and reaps processes. This field is omitted if empty, and the default (as configured on the daemon) is used." type: "boolean" @@ -3915,6 +3917,7 @@ definitions: - "default" - "hyperv" - "process" + - "" InitBinary: description: | Name and, optional, path of the `docker-init` binary. @@ -7029,7 +7032,7 @@ paths: type: "string" example: "OK" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Docker-Experimental: @@ -8903,6 +8906,7 @@ paths: example: ListenAddr: "0.0.0.0:2377" AdvertiseAddr: "192.168.1.1:2377" + DataPathAddr: "192.168.1.1" RemoteAddrs: - "node1:2377" JoinToken: "SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2" diff --git a/_vendor/github.com/moby/moby/docs/api/v1.39.yaml b/_vendor/github.com/moby/moby/docs/api/v1.39.yaml index 297cec305b9e..f5fff93f9510 100644 --- a/_vendor/github.com/moby/moby/docs/api/v1.39.yaml +++ b/_vendor/github.com/moby/moby/docs/api/v1.39.yaml @@ -1055,6 +1055,7 @@ definitions: - "default" - "process" - "hyperv" + - "" MaskedPaths: type: "array" description: | @@ -3780,6 +3781,7 @@ definitions: - "default" - "process" - "hyperv" + - "" Init: description: | Run an init inside the container that forwards signals and reaps @@ -5174,6 +5176,7 @@ definitions: - "default" - "hyperv" - "process" + - "" InitBinary: description: | Name and, optional, path of the `docker-init` binary. @@ -5223,8 +5226,6 @@ definitions: type: "string" example: - "WARNING: No memory limit support" - - "WARNING: bridge-nf-call-iptables is disabled" - - "WARNING: bridge-nf-call-ip6tables is disabled" # PluginsInfo is a temp struct holding Plugins name @@ -8253,7 +8254,7 @@ paths: type: "string" example: "OK" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Builder-Version: @@ -10224,6 +10225,7 @@ paths: example: ListenAddr: "0.0.0.0:2377" AdvertiseAddr: "192.168.1.1:2377" + DataPathAddr: "192.168.1.1" RemoteAddrs: - "node1:2377" JoinToken: "SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2" diff --git a/_vendor/github.com/moby/moby/docs/api/v1.40.yaml b/_vendor/github.com/moby/moby/docs/api/v1.40.yaml index fc2c7c8cf9f2..5e0171b987fd 100644 --- a/_vendor/github.com/moby/moby/docs/api/v1.40.yaml +++ b/_vendor/github.com/moby/moby/docs/api/v1.40.yaml @@ -1115,6 +1115,7 @@ definitions: - "default" - "process" - "hyperv" + - "" MaskedPaths: type: "array" description: | @@ -3883,6 +3884,7 @@ definitions: - "default" - "process" - "hyperv" + - "" Init: description: | Run an init inside the container that forwards signals and reaps @@ -5310,6 +5312,7 @@ definitions: - "default" - "hyperv" - "process" + - "" InitBinary: description: | Name and, optional, path of the `docker-init` binary. @@ -5360,8 +5363,6 @@ definitions: type: "string" example: - "WARNING: No memory limit support" - - "WARNING: bridge-nf-call-iptables is disabled" - - "WARNING: bridge-nf-call-ip6tables is disabled" # PluginsInfo is a temp struct holding Plugins name @@ -8576,7 +8577,7 @@ paths: type: "string" example: "OK" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Builder-Version: @@ -8615,7 +8616,7 @@ paths: type: "string" example: "(empty)" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Builder-Version: @@ -10538,6 +10539,7 @@ paths: example: ListenAddr: "0.0.0.0:2377" AdvertiseAddr: "192.168.1.1:2377" + DataPathAddr: "192.168.1.1" RemoteAddrs: - "node1:2377" JoinToken: "SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2" diff --git a/_vendor/github.com/moby/moby/docs/api/v1.41.yaml b/_vendor/github.com/moby/moby/docs/api/v1.41.yaml index 54a4c80d2469..97fbc83baba8 100644 --- a/_vendor/github.com/moby/moby/docs/api/v1.41.yaml +++ b/_vendor/github.com/moby/moby/docs/api/v1.41.yaml @@ -1146,6 +1146,7 @@ definitions: - "default" - "process" - "hyperv" + - "" MaskedPaths: type: "array" description: | @@ -4010,6 +4011,7 @@ definitions: - "default" - "process" - "hyperv" + - "" Init: description: | Run an init inside the container that forwards signals and reaps @@ -5545,6 +5547,7 @@ definitions: - "default" - "hyperv" - "process" + - "" InitBinary: description: | Name and, optional, path of the `docker-init` binary. @@ -5614,8 +5617,6 @@ definitions: type: "string" example: - "WARNING: No memory limit support" - - "WARNING: bridge-nf-call-iptables is disabled" - - "WARNING: bridge-nf-call-ip6tables is disabled" # PluginsInfo is a temp struct holding Plugins name @@ -8865,7 +8866,7 @@ paths: type: "string" example: "OK" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Builder-Version: @@ -8904,7 +8905,7 @@ paths: type: "string" example: "(empty)" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Builder-Version: @@ -10837,6 +10838,7 @@ paths: example: ListenAddr: "0.0.0.0:2377" AdvertiseAddr: "192.168.1.1:2377" + DataPathAddr: "192.168.1.1" RemoteAddrs: - "node1:2377" JoinToken: "SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2" diff --git a/_vendor/github.com/moby/moby/docs/api/v1.42.yaml b/_vendor/github.com/moby/moby/docs/api/v1.42.yaml index b3745325d2be..03521c03bd3c 100644 --- a/_vendor/github.com/moby/moby/docs/api/v1.42.yaml +++ b/_vendor/github.com/moby/moby/docs/api/v1.42.yaml @@ -1149,6 +1149,7 @@ definitions: - "default" - "process" - "hyperv" + - "" MaskedPaths: type: "array" description: | @@ -4029,6 +4030,7 @@ definitions: - "default" - "process" - "hyperv" + - "" Init: description: | Run an init inside the container that forwards signals and reaps @@ -5545,6 +5547,7 @@ definitions: - "default" - "hyperv" - "process" + - "" InitBinary: description: | Name and, optional, path of the `docker-init` binary. @@ -5614,8 +5617,6 @@ definitions: type: "string" example: - "WARNING: No memory limit support" - - "WARNING: bridge-nf-call-iptables is disabled" - - "WARNING: bridge-nf-call-ip6tables is disabled" # PluginsInfo is a temp struct holding Plugins name @@ -9130,7 +9131,7 @@ paths: type: "string" example: "OK" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Builder-Version: @@ -9186,7 +9187,7 @@ paths: type: "string" example: "(empty)" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Builder-Version: @@ -11215,6 +11216,7 @@ paths: example: ListenAddr: "0.0.0.0:2377" AdvertiseAddr: "192.168.1.1:2377" + DataPathAddr: "192.168.1.1" RemoteAddrs: - "node1:2377" JoinToken: "SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2" diff --git a/_vendor/github.com/moby/moby/docs/api/v1.43.yaml b/_vendor/github.com/moby/moby/docs/api/v1.43.yaml index 934e77e05486..4043a57996b7 100644 --- a/_vendor/github.com/moby/moby/docs/api/v1.43.yaml +++ b/_vendor/github.com/moby/moby/docs/api/v1.43.yaml @@ -1156,6 +1156,7 @@ definitions: - "default" - "process" - "hyperv" + - "" MaskedPaths: type: "array" description: | @@ -4060,6 +4061,7 @@ definitions: - "default" - "process" - "hyperv" + - "" Init: description: | Run an init inside the container that forwards signals and reaps @@ -5577,6 +5579,7 @@ definitions: - "default" - "hyperv" - "process" + - "" InitBinary: description: | Name and, optional, path of the `docker-init` binary. @@ -5647,8 +5650,6 @@ definitions: type: "string" example: - "WARNING: No memory limit support" - - "WARNING: bridge-nf-call-iptables is disabled" - - "WARNING: bridge-nf-call-ip6tables is disabled" # PluginsInfo is a temp struct holding Plugins name @@ -9148,7 +9149,7 @@ paths: type: "string" example: "OK" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Builder-Version: @@ -9204,7 +9205,7 @@ paths: type: "string" example: "(empty)" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Builder-Version: @@ -11233,6 +11234,7 @@ paths: example: ListenAddr: "0.0.0.0:2377" AdvertiseAddr: "192.168.1.1:2377" + DataPathAddr: "192.168.1.1" RemoteAddrs: - "node1:2377" JoinToken: "SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2" diff --git a/_vendor/github.com/moby/moby/docs/api/v1.44.yaml b/_vendor/github.com/moby/moby/docs/api/v1.44.yaml index 709203bf8545..b26c138b1220 100644 --- a/_vendor/github.com/moby/moby/docs/api/v1.44.yaml +++ b/_vendor/github.com/moby/moby/docs/api/v1.44.yaml @@ -1172,6 +1172,7 @@ definitions: - "default" - "process" - "hyperv" + - "" MaskedPaths: type: "array" description: | @@ -4128,6 +4129,7 @@ definitions: - "default" - "process" - "hyperv" + - "" Init: description: | Run an init inside the container that forwards signals and reaps @@ -5692,6 +5694,7 @@ definitions: - "default" - "hyperv" - "process" + - "" InitBinary: description: | Name and, optional, path of the `docker-init` binary. @@ -5762,8 +5765,6 @@ definitions: type: "string" example: - "WARNING: No memory limit support" - - "WARNING: bridge-nf-call-iptables is disabled" - - "WARNING: bridge-nf-call-ip6tables is disabled" CDISpecDirs: description: | List of directories where (Container Device Interface) CDI @@ -9317,7 +9318,7 @@ paths: type: "string" example: "OK" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Builder-Version: @@ -9373,7 +9374,7 @@ paths: type: "string" example: "(empty)" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Builder-Version: @@ -11403,6 +11404,7 @@ paths: example: ListenAddr: "0.0.0.0:2377" AdvertiseAddr: "192.168.1.1:2377" + DataPathAddr: "192.168.1.1" RemoteAddrs: - "node1:2377" JoinToken: "SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2" diff --git a/_vendor/github.com/moby/moby/docs/api/v1.45.yaml b/_vendor/github.com/moby/moby/docs/api/v1.45.yaml index 9aa5c241fd77..9d9522bf6adc 100644 --- a/_vendor/github.com/moby/moby/docs/api/v1.45.yaml +++ b/_vendor/github.com/moby/moby/docs/api/v1.45.yaml @@ -1180,6 +1180,7 @@ definitions: - "default" - "process" - "hyperv" + - "" MaskedPaths: type: "array" description: | @@ -4114,6 +4115,7 @@ definitions: - "default" - "process" - "hyperv" + - "" Init: description: | Run an init inside the container that forwards signals and reaps @@ -5678,6 +5680,7 @@ definitions: - "default" - "hyperv" - "process" + - "" InitBinary: description: | Name and, optional, path of the `docker-init` binary. @@ -5748,8 +5751,6 @@ definitions: type: "string" example: - "WARNING: No memory limit support" - - "WARNING: bridge-nf-call-iptables is disabled" - - "WARNING: bridge-nf-call-ip6tables is disabled" CDISpecDirs: description: | List of directories where (Container Device Interface) CDI @@ -9297,7 +9298,7 @@ paths: type: "string" example: "OK" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Builder-Version: @@ -9353,7 +9354,7 @@ paths: type: "string" example: "(empty)" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Builder-Version: @@ -11383,6 +11384,7 @@ paths: example: ListenAddr: "0.0.0.0:2377" AdvertiseAddr: "192.168.1.1:2377" + DataPathAddr: "192.168.1.1" RemoteAddrs: - "node1:2377" JoinToken: "SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2" diff --git a/_vendor/github.com/moby/moby/docs/api/v1.46.yaml b/_vendor/github.com/moby/moby/docs/api/v1.46.yaml index 5945f098f4e7..38fd49c2b477 100644 --- a/_vendor/github.com/moby/moby/docs/api/v1.46.yaml +++ b/_vendor/github.com/moby/moby/docs/api/v1.46.yaml @@ -1195,6 +1195,7 @@ definitions: - "default" - "process" - "hyperv" + - "" MaskedPaths: type: "array" description: | @@ -4167,6 +4168,7 @@ definitions: - "default" - "process" - "hyperv" + - "" Init: description: | Run an init inside the container that forwards signals and reaps @@ -5737,6 +5739,7 @@ definitions: - "default" - "hyperv" - "process" + - "" InitBinary: description: | Name and, optional, path of the `docker-init` binary. @@ -5807,8 +5810,6 @@ definitions: type: "string" example: - "WARNING: No memory limit support" - - "WARNING: bridge-nf-call-iptables is disabled" - - "WARNING: bridge-nf-call-ip6tables is disabled" CDISpecDirs: description: | List of directories where (Container Device Interface) CDI @@ -9431,7 +9432,7 @@ paths: type: "string" example: "OK" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Builder-Version: @@ -9487,7 +9488,7 @@ paths: type: "string" example: "(empty)" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Builder-Version: @@ -11502,6 +11503,7 @@ paths: example: ListenAddr: "0.0.0.0:2377" AdvertiseAddr: "192.168.1.1:2377" + DataPathAddr: "192.168.1.1" RemoteAddrs: - "node1:2377" JoinToken: "SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2" diff --git a/_vendor/github.com/moby/moby/docs/api/v1.47.yaml b/_vendor/github.com/moby/moby/docs/api/v1.47.yaml index a4b63a1833b0..bba025b6d7d0 100644 --- a/_vendor/github.com/moby/moby/docs/api/v1.47.yaml +++ b/_vendor/github.com/moby/moby/docs/api/v1.47.yaml @@ -1195,6 +1195,7 @@ definitions: - "default" - "process" - "hyperv" + - "" MaskedPaths: type: "array" description: | @@ -4185,6 +4186,7 @@ definitions: - "default" - "process" - "hyperv" + - "" Init: description: | Run an init inside the container that forwards signals and reaps @@ -5755,6 +5757,7 @@ definitions: - "default" - "hyperv" - "process" + - "" InitBinary: description: | Name and, optional, path of the `docker-init` binary. @@ -5825,8 +5828,6 @@ definitions: type: "string" example: - "WARNING: No memory limit support" - - "WARNING: bridge-nf-call-iptables is disabled" - - "WARNING: bridge-nf-call-ip6tables is disabled" CDISpecDirs: description: | List of directories where (Container Device Interface) CDI @@ -9568,7 +9569,7 @@ paths: type: "string" example: "OK" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Builder-Version: @@ -9624,7 +9625,7 @@ paths: type: "string" example: "(empty)" headers: - API-Version: + Api-Version: type: "string" description: "Max API Version the server supports" Builder-Version: @@ -11648,6 +11649,7 @@ paths: example: ListenAddr: "0.0.0.0:2377" AdvertiseAddr: "192.168.1.1:2377" + DataPathAddr: "192.168.1.1" RemoteAddrs: - "node1:2377" JoinToken: "SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2" diff --git a/_vendor/github.com/moby/moby/docs/api/version-history.md b/_vendor/github.com/moby/moby/docs/api/version-history.md index b9207d4d60b9..44e6e7576bd0 100644 --- a/_vendor/github.com/moby/moby/docs/api/version-history.md +++ b/_vendor/github.com/moby/moby/docs/api/version-history.md @@ -24,6 +24,11 @@ keywords: "API, Docker, rcli, REST, documentation" query parameter to `true`. WARNING: This is experimental and may change at any time without any backward compatibility. +* `GET /info` no longer includes warnings when `bridge-nf-call-iptables` or + `bridge-nf-call-ip6tables` are disabled when the daemon was started. The + `br_netfilter` module is now attempted to be loaded when needed, making those + warnings inaccurate. This change is not versioned, and affects all API versions + if the daemon has this patch. ## v1.46 API changes diff --git a/_vendor/modules.txt b/_vendor/modules.txt index 727d3822396a..6a852c96a633 100644 --- a/_vendor/modules.txt +++ b/_vendor/modules.txt @@ -1,4 +1,4 @@ -# github.com/moby/moby v27.4.0+incompatible +# github.com/moby/moby v27.5.0+incompatible # github.com/moby/buildkit v0.18.1 # github.com/docker/buildx v0.19.2 # github.com/docker/cli v27.4.0+incompatible diff --git a/go.mod b/go.mod index d7cc9af54056..8efb952c8a63 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/docker/compose/v2 v2.32.3 // indirect github.com/docker/scout-cli v1.15.0 // indirect github.com/moby/buildkit v0.18.1 // indirect - github.com/moby/moby v27.4.0+incompatible // indirect + github.com/moby/moby v27.5.0+incompatible // indirect ) replace ( @@ -17,5 +17,5 @@ replace ( github.com/docker/compose/v2 => github.com/docker/compose/v2 v2.32.3 github.com/docker/scout-cli => github.com/docker/scout-cli v1.15.0 github.com/moby/buildkit => github.com/moby/buildkit v0.18.0 - github.com/moby/moby => github.com/moby/moby v27.4.0+incompatible + github.com/moby/moby => github.com/moby/moby v27.5.0+incompatible ) diff --git a/go.sum b/go.sum index a8b3f415d3e9..5c22be4e7a02 100644 --- a/go.sum +++ b/go.sum @@ -362,6 +362,8 @@ github.com/moby/moby v27.3.1+incompatible h1:KQbXBjo7PavKpzIl7UkHT31y9lw/e71Uvrq github.com/moby/moby v27.3.1+incompatible/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc= github.com/moby/moby v27.4.0+incompatible h1:jGXXZCMAmFZS9pKsQqUt9yAPHOC450PM9lbQYPSQnuc= github.com/moby/moby v27.4.0+incompatible/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc= +github.com/moby/moby v27.5.0+incompatible h1:RuYLppjLxMzWmPUQAy/hkJ6pGcXsuVdcmIVFqVPegO8= +github.com/moby/moby v27.5.0+incompatible/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc= github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= From 7192b3227c37e93276d8aedf98bb66ebc41a434a Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Tue, 14 Jan 2025 10:48:15 +0100 Subject: [PATCH 8/9] vendor: github.com/docker/cli v27.5.0 Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com> --- _vendor/github.com/docker/cli/docs/reference/dockerd.md | 2 -- _vendor/modules.txt | 2 +- data/engine-cli/docker_image_build.yaml | 2 -- go.mod | 4 ++-- go.sum | 2 ++ 5 files changed, 5 insertions(+), 7 deletions(-) diff --git a/_vendor/github.com/docker/cli/docs/reference/dockerd.md b/_vendor/github.com/docker/cli/docs/reference/dockerd.md index ae6eb2fee3e2..523eb82f13df 100644 --- a/_vendor/github.com/docker/cli/docs/reference/dockerd.md +++ b/_vendor/github.com/docker/cli/docs/reference/dockerd.md @@ -92,7 +92,6 @@ Options: --no-new-privileges Set no-new-privileges by default for new containers --no-proxy string Comma-separated list of hosts or IP addresses for which the proxy is skipped --node-generic-resource list Advertise user-defined resource - --oom-score-adjust int Set the oom_score_adj for the daemon -p, --pidfile string Path to use for daemon PID file (default "/var/run/docker.pid") --raw-logs Full timestamps without ANSI coloring --registry-mirror list Preferred registry mirror @@ -1172,7 +1171,6 @@ The following is a full example of the allowed configuration options on Linux: "NVIDIA-GPU=UUID1", "NVIDIA-GPU=UUID2" ], - "oom-score-adjust": 0, "pidfile": "", "raw-logs": false, "registry-mirrors": [], diff --git a/_vendor/modules.txt b/_vendor/modules.txt index 6a852c96a633..8677c07dcfe5 100644 --- a/_vendor/modules.txt +++ b/_vendor/modules.txt @@ -1,6 +1,6 @@ # github.com/moby/moby v27.5.0+incompatible # github.com/moby/buildkit v0.18.1 # github.com/docker/buildx v0.19.2 -# github.com/docker/cli v27.4.0+incompatible +# github.com/docker/cli v27.5.0+incompatible # github.com/docker/compose/v2 v2.32.3 # github.com/docker/scout-cli v1.15.0 diff --git a/data/engine-cli/docker_image_build.yaml b/data/engine-cli/docker_image_build.yaml index 7f626cef86ec..2c7c1f28d455 100644 --- a/data/engine-cli/docker_image_build.yaml +++ b/data/engine-cli/docker_image_build.yaml @@ -407,8 +407,6 @@ examples: |- | `process` | Namespace isolation only. | | `hyperv` | Hyper-V hypervisor partition-based isolation. | - Specifying the `--isolation` flag without a value is the same as setting `--isolation="default"`. - ### Optional security options (--security-opt) {#security-opt} This flag is only supported on a daemon running on Windows, and only supports diff --git a/go.mod b/go.mod index 8efb952c8a63..c1341861a841 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.23.1 require ( github.com/docker/buildx v0.19.2 // indirect - github.com/docker/cli v27.4.0+incompatible // indirect + github.com/docker/cli v27.5.0+incompatible // indirect github.com/docker/compose/v2 v2.32.3 // indirect github.com/docker/scout-cli v1.15.0 // indirect github.com/moby/buildkit v0.18.1 // indirect @@ -13,7 +13,7 @@ require ( replace ( github.com/docker/buildx => github.com/docker/buildx v0.19.2 - github.com/docker/cli => github.com/docker/cli v27.4.0+incompatible + github.com/docker/cli => github.com/docker/cli v27.5.0+incompatible github.com/docker/compose/v2 => github.com/docker/compose/v2 v2.32.3 github.com/docker/scout-cli => github.com/docker/scout-cli v1.15.0 github.com/moby/buildkit => github.com/moby/buildkit v0.18.0 diff --git a/go.sum b/go.sum index 5c22be4e7a02..8eb8770b7206 100644 --- a/go.sum +++ b/go.sum @@ -138,6 +138,8 @@ github.com/docker/cli v27.3.2-0.20241107125754-eb986ae71b0c+incompatible h1:KqHa github.com/docker/cli v27.3.2-0.20241107125754-eb986ae71b0c+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v27.4.0+incompatible h1:/nJzWkcI1MDMN+U+px/YXnQWJqnu4J+QKGTfD6ptiTc= github.com/docker/cli v27.4.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v27.5.0+incompatible h1:aMphQkcGtpHixwwhAXJT1rrK/detk2JIvDaFkLctbGM= +github.com/docker/cli v27.5.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/compose-cli v1.0.35 h1:uZyEHLalfqBS2PiTpA1LAULyJmuQ+YtZg7nG4Xl3/Cc= github.com/docker/compose-cli v1.0.35/go.mod h1:mSXI4hFLpRU3EtI8NTo32bNwI0UXSr8jnq+/rYjGAUU= github.com/docker/compose/v2 v2.22.0 h1:3rRz4L7tPU75wRsV8JZh2/aTgerQvPa1cpzZN+tHqUY= From d7ffb99825c59210841800223a3bd9d736233d77 Mon Sep 17 00:00:00 2001 From: Igor Aleksandrov Date: Tue, 14 Jan 2025 14:09:18 +0400 Subject: [PATCH 9/9] Rails guide upgrade (part 1) (#21559) ## Description This PR upgrades the Rails framework guide and covers the application containerization step. In the following PRs, I will update the section about deploying with Docker Compose, and add a new "Deployment with Kamal" section. ## Reviews - [ ] Technical review - [x] Editorial review - [ ] Product review --- content/guides/ruby/containerize.md | 435 ++++++++++------------------ 1 file changed, 160 insertions(+), 275 deletions(-) diff --git a/content/guides/ruby/containerize.md b/content/guides/ruby/containerize.md index d968c28c873c..83f0c3933ecf 100644 --- a/content/guides/ruby/containerize.md +++ b/content/guides/ruby/containerize.md @@ -18,341 +18,226 @@ aliases: ## Overview -This section walks you through containerizing and running a Ruby on Rails application. +This section walks you through containerizing and running a [Ruby on Rails](https://rubyonrails.org/) application. -## Get the sample application +Starting from Rails 7.1 [Docker is supported out of the box](https://guides.rubyonrails.org/7_1_release_notes.html#generate-dockerfiles-for-new-rails-applications). This means that you will get a `Dockerfile`, `.dockerignore` and `bin/docker-entrypoint` files generated for you when you create a new Rails application. -The sample application uses the popular [Ruby on Rails](https://rubyonrails.org/) framework. - -Clone the sample application to use with this guide. Open a terminal, change directory to a directory that you want to work in, and run the following command to clone the repository: - -```console -$ git clone https://github.com/falconcr/docker-ruby-on-rails.git -``` +If you have an existing Rails application, you will need to create the Docker assets manually. Unfortunately `docker init` command does not yet support Rails. This means that if you are working with Rails, you'll need to copy Dockerfile and other related configurations manually from the examples below. ## Initialize Docker assets -Now that you have an application, you can create the necessary Docker assets to -containerize your application. You can use Docker Desktop's built-in Docker Init -feature to help streamline the process, or you can manually create the assets. +Rails 7.1 generates multistage Dockerfile out of the box, below is an example of such file generated from a Rails template. -`docker init`, the command for bootstrapping the Docker-related assets for a project, does not yet support the Ruby programming language. This means that if you are working with Ruby, you'll need to create Dockerfiles and other related configurations manually. +> Multistage Dockerfiles help create smaller, more efficient images by separating build and runtime dependencies, ensuring only necessary components are included in the final image. Read more in the [Multi-stage builds guide](/get-started/docker-concepts/building-images/multi-stage-builds/). -Inside the `docker-ruby-on-rails` directory, create the following files: +Although the Dockerfile is generated automatically, understanding its purpose and functionality is important. Reviewing the following example is highly recommended. -Create a file named `Dockerfile` with the following contents. -```dockerfile {collapse=true,title=Dockerfile} +```dockerfile {title=Dockerfile} # syntax=docker/dockerfile:1 +# check=error=true -# Use the official Ruby image with version 3.2.0 -FROM ruby:3.2.0 +# This Dockerfile is designed for production, not development. +# docker build -t app . +# docker run -d -p 80:80 -e RAILS_MASTER_KEY= --name app app -# Install dependencies -RUN apt-get update -qq && apt-get install -y \ - nodejs \ - postgresql-client \ - libssl-dev \ - libreadline-dev \ - zlib1g-dev \ - build-essential \ - curl +# For a containerized dev environment, see Dev Containers: https://guides.rubyonrails.org/getting_started_with_devcontainer.html -# Install rbenv -RUN git clone https://github.com/rbenv/rbenv.git ~/.rbenv && \ - echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc && \ - echo 'eval "$(rbenv init -)"' >> ~/.bashrc && \ - git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build && \ - echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc +# Make sure RUBY_VERSION matches the Ruby version in .ruby-version +ARG RUBY_VERSION=3.3.6 +FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base -# Install the specified Ruby version using rbenv -ENV PATH="/root/.rbenv/bin:/root/.rbenv/shims:$PATH" -RUN rbenv install 3.2.0 && rbenv global 3.2.0 +# Rails app lives here +WORKDIR /rails -# Set the working directory -WORKDIR /myapp +# Install base packages +# Replace libpq-dev with sqlite3 if using SQLite, or libmysqlclient-dev if using MySQL +RUN apt-get update -qq && \ + apt-get install --no-install-recommends -y curl libjemalloc2 libvips libpq-dev && \ + rm -rf /var/lib/apt/lists /var/cache/apt/archives -# Copy the Gemfile and Gemfile.lock -COPY Gemfile /myapp/Gemfile -COPY Gemfile.lock /myapp/Gemfile.lock +# Set production environment +ENV RAILS_ENV="production" \ + BUNDLE_DEPLOYMENT="1" \ + BUNDLE_PATH="/usr/local/bundle" \ + BUNDLE_WITHOUT="development" -# Install Gems dependencies -RUN gem install bundler && bundle install +# Throw-away build stage to reduce size of final image +FROM base AS build -# Copy the application code -COPY . /myapp +# Install packages needed to build gems +RUN apt-get update -qq && \ + apt-get install --no-install-recommends -y build-essential curl git pkg-config && \ + rm -rf /var/lib/apt/lists /var/cache/apt/archives -# Precompile assets (optional, if using Rails with assets) -RUN bundle exec rake assets:precompile +# Install JavaScript dependencies and Node.js for asset compilation +# +# Uncomment the following lines if you are using NodeJS need to compile assets +# +# ARG NODE_VERSION=18.12.0 +# ARG YARN_VERSION=1.22.19 +# ENV PATH=/usr/local/node/bin:$PATH +# RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \ +# /tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \ +# npm install -g yarn@$YARN_VERSION && \ +# npm install -g mjml && \ +# rm -rf /tmp/node-build-master + +# Install application gems +COPY Gemfile Gemfile.lock ./ +RUN bundle install && \ + rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \ + bundle exec bootsnap precompile --gemfile + +# Install node modules +# +# Uncomment the following lines if you are using NodeJS need to compile assets +# +# COPY package.json yarn.lock ./ +# RUN --mount=type=cache,id=yarn,target=/rails/.cache/yarn YARN_CACHE_FOLDER=/rails/.cache/yarn \ +# yarn install --frozen-lockfile -# Expose the port the app runs on -EXPOSE 3000 +# Copy application code +COPY . . -# Command to run the server -CMD ["rails", "server", "-b", "0.0.0.0"] -``` +# Precompile bootsnap code for faster boot times +RUN bundle exec bootsnap precompile app/ lib/ -Create a file named `compose.yaml` with the following contents. +# Precompiling assets for production without requiring secret RAILS_MASTER_KEY +RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile -```yaml {collapse=true,title=compose.yaml} -services: - web: - build: . - command: bundle exec rails s -b '0.0.0.0' - volumes: - - .:/myapp - ports: - - "3000:3000" +# Final stage for app image +FROM base + +# Copy built artifacts: gems, application +COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}" +COPY --from=build /rails /rails + +# Run and own only the runtime files as a non-root user for security +RUN groupadd --system --gid 1000 rails && \ + useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \ + chown -R rails:rails db log storage tmp +USER 1000:1000 + +# Entrypoint prepares the database. +ENTRYPOINT ["/rails/bin/docker-entrypoint"] + +# Start server via Thruster by default, this can be overwritten at runtime +EXPOSE 80 +CMD ["./bin/thrust", "./bin/rails", "server"] ``` -Create a file named `.dockerignore` with the following contents. +The Dockerfile above assumes you are using Thruster together with Puma as an application server. In case you are using any other server, you can replace the last three lines with the following: -```text {collapse=true,title=".dockerignore"} -git -.gitignore - -# Created by https://www.gitignore.io/api/git,ruby,rails,jetbrains+all -# Edit at https://www.gitignore.io/?templates=git,ruby,rails,jetbrains+all - -### Git ### -# Created by git for backups. To disable backups in Git: -# $ git config --global mergetool.keepBackup false -*.orig - -# Created by git when using merge tools for conflicts -*.BACKUP.* -*.BASE.* -*.LOCAL.* -*.REMOTE.* -*_BACKUP_*.txt -*_BASE_*.txt -*_LOCAL_*.txt -*_REMOTE_*.txt - -### JetBrains+all ### -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff -.idea/**/workspace.xml -.idea/**/tasks.xml -.idea/**/usage.statistics.xml -.idea/**/dictionaries -.idea/**/shelf - -# Generated files -.idea/**/contentModel.xml - -# Sensitive or high-churn files -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml -.idea/**/dbnavigator.xml - -# Gradle -.idea/**/gradle.xml -.idea/**/libraries - -# Gradle and Maven with auto-import -# When using Gradle or Maven with auto-import, you should exclude module files, -# since they will be recreated, and may cause churn. Uncomment if using -# auto-import. -# .idea/modules.xml -# .idea/*.iml -# .idea/modules -# *.iml -# *.ipr - -# CMake -cmake-build-*/ - -# Mongo Explorer plugin -.idea/**/mongoSettings.xml - -# File-based project format -*.iws - -# IntelliJ -out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Cursive Clojure plugin -.idea/replstate.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties - -# Editor-based Rest Client -.idea/httpRequests - -# Android studio 3.1+ serialized cache file -.idea/caches/build_file_checksums.ser - -### JetBrains+all Patch ### -# Ignores the whole .idea folder and all .iml files -# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360 - -.idea/ - -# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 - -*.iml -modules.xml -.idea/misc.xml -*.ipr - -# Sonarlint plugin -.idea/sonarlint - -### Rails ### -*.rbc -capybara-*.html -.rspec -/db/*.sqlite3 -/db/*.sqlite3-journal -/public/system -/coverage/ -/spec/tmp -rerun.txt -pickle-email-*.html +```dockerfile +# Start the application server +EXPOSE 3000 +CMD ["./bin/rails", "server"] +``` -# Ignore all logfiles and tempfiles. -/log/* -/tmp/* -!/log/.keep -!/tmp/.keep +This Dockerfile uses a script at `./bin/docker-entrypoint` as the container's entrypiont. This script prepares the database and runs the application server. Below is an example of such a script. -# TODO Comment out this rule if you are OK with secrets being uploaded to the repo -config/initializers/secret_token.rb -config/master.key +```bash {title=docker-entrypoint} +#!/bin/bash -e -# Only include if you have production secrets in this file, which is no longer a Rails default -# config/secrets.yml +# Enable jemalloc for reduced memory usage and latency. +if [ -z "${LD_PRELOAD+x}" ]; then + LD_PRELOAD=$(find /usr/lib -name libjemalloc.so.2 -print -quit) + export LD_PRELOAD +fi -# dotenv -# TODO Comment out this rule if environment variables can be committed -.env +# If running the rails server then create or migrate existing database +if [ "${@: -2:1}" == "./bin/rails" ] && [ "${@: -1:1}" == "server" ]; then + ./bin/rails db:prepare +fi -## Environment normalization: -/.bundle -/vendor/bundle +exec "${@}" +``` -# these should all be checked in to normalize the environment: -# Gemfile.lock, .ruby-version, .ruby-gemset +Besides the two files above you will also need a `.dockerignore` file. This file is used to exclude files and directories from the context of the build. Below is an example of a `.dockerignore` file. -# unless supporting rvm < 1.11.0 or doing something fancy, ignore this: -.rvmrc +```text {collapse=true,title=".dockerignore"} +# See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files. -# if using bower-rails ignore default bower_components path bower.json files -/vendor/assets/bower_components -*.bowerrc -bower.json +# Ignore git directory. +/.git/ +/.gitignore -# Ignore pow environment settings -.powenv +# Ignore bundler config. +/.bundle -# Ignore Byebug command history file. -.byebug_history +# Ignore all environment files. +/.env* -# Ignore node_modules -node_modules/ +# Ignore all default key files. +/config/master.key +/config/credentials/*.key -# Ignore precompiled javascript packs -/public/packs -/public/packs-test -/public/assets +# Ignore all logfiles and tempfiles. +/log/* +/tmp/* +!/log/.keep +!/tmp/.keep -# Ignore yarn files -/yarn-error.log -yarn-debug.log* -.yarn-integrity +# Ignore pidfiles, but keep the directory. +/tmp/pids/* +!/tmp/pids/.keep -# Ignore uploaded files in development +# Ignore storage (uploaded files in development and any SQLite databases). /storage/* !/storage/.keep +/tmp/storage/* +!/tmp/storage/.keep -### Ruby ### -*.gem -/.config -/InstalledFiles -/pkg/ -/spec/reports/ -/spec/examples.txt -/test/tmp/ -/test/version_tmp/ -/tmp/ - -# Used by dotenv library to load environment variables. -# .env - -# Ignore Byebug command history file. - -## Specific to RubyMotion: -.dat* -.repl_history -build/ -*.bridgesupport -build-iPhoneOS/ -build-iPhoneSimulator/ - -## Specific to RubyMotion (use of CocoaPods): -# -# We recommend against adding the Pods directory to your .gitignore. However -# you should judge for yourself, the pros and cons are mentioned at: -# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control -# vendor/Pods/ +# Ignore assets. +/node_modules/ +/app/assets/builds/* +!/app/assets/builds/.keep +/public/assets -## Documentation cache and generated files: -/.yardoc/ -/_yardoc/ -/doc/ -/rdoc/ +# Ignore CI service files. +/.github -/.bundle/ -/lib/bundler/man/ +# Ignore development files +/.devcontainer -# for a library or gem, you might want to ignore these files since the code is -# intended to run in multiple environments; otherwise, check them in: -# Gemfile.lock -# .ruby-version -# .ruby-gemset +# Ignore Docker-related files +/.dockerignore +/Dockerfile* +``` -# unless supporting rvm < 1.11.0 or doing something fancy, ignore this: +The last optional file that you may want is the `compose.yaml` file, which is used by Docker Compose to define the services that make up the application. Since SQLite is being used as the database, there is no need to define a separate service for the database. The only service required is the Rails application itself. -# End of https://www.gitignore.io/api/git,ruby,rails,jetbrains+all +```yaml {title=compose.yaml} +services: + web: + build: . + environment: + - RAILS_MASTER_KEY + ports: + - "3000:80" ``` -You should now have the following three files in your `docker-ruby-on-rails` -directory. +You should now have the following files in your application folder: -- .dockerignore -- compose.yaml -- Dockerfile +- `.dockerignore` +- `compose.yaml` +- `Dockerfile` +- `bin/docker-entrypoint` To learn more about the files, see the following: -- [Dockerfile](/reference/dockerfile.md) -- [.dockerignore](/reference/dockerfile.md#dockerignore-file) +- [Dockerfile](/reference/dockerfile) +- [.dockerignore](/reference/dockerfile#dockerignore-file) - [compose.yaml](/reference/compose-file/_index.md) +- [docker-entrypoint](/reference/dockerfile/#entrypoint) ## Run the application -Inside the `docker-ruby-on-rails` directory, run the following command in a -terminal. +To run the application, run the following command in a terminal inside the application's directory. ```console -$ docker compose up --build +$ RAILS_MASTER_KEY= docker compose up --build ``` Open a browser and view the application at [http://localhost:3000](http://localhost:3000). You should see a simple Ruby on Rails application.