├── .gitignore ├── .travis.yml ├── Dockerfile ├── LICENSE.md ├── Makefile ├── README.md ├── bibliography.bib ├── examples ├── README.md ├── full-demo │ ├── Dockerfile │ ├── README.md │ ├── analysis.py │ ├── input │ │ └── data.txt │ ├── myscript.sh │ ├── plots.R │ └── requirements.txt ├── geospatial-python-qgis-model-workflow │ ├── Dockerfile │ ├── Dockerfile.original.1 │ ├── Dockerfile.original.2 │ └── README.md ├── microsimulation-model-virus-C++ │ ├── Dockerfile │ ├── Dockerfile.original │ └── README.md ├── pass-parameter-env │ ├── README.md │ └── run.sh ├── spatial-statistics-R │ ├── Dockerfile │ ├── Dockerfile.before │ └── README.md ├── spatial-subsampling-marine-inverts-R │ ├── Dockerfile │ ├── Dockerfile.original │ └── README.md ├── teaching-vm_openrefine │ ├── Dockerfile │ ├── Dockerfile.original │ ├── README.md │ └── openrefine.sh ├── text-analysis-wordclouds_R-Binder │ ├── Dockerfile │ ├── Dockerfile.original │ ├── README.md │ └── install.R └── vcn_regularity-python │ ├── Dockerfile │ ├── Dockerfile.original │ ├── README.md │ └── environment.yml ├── figures ├── PLOS-submission.eps ├── analogy.drawio ├── analogy.png ├── analogy.svg ├── analogy.tif ├── summary.drawio ├── summary.png ├── summary.svg └── summary.tif ├── plos.csl ├── summary.Rmd ├── ten-simple-rules-dockerfiles.Rmd ├── ten-simple-rules-dockerfiles.Rproj └── ten-simple-rules-dockerfiles.tex /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | *.log 6 | 7 | ten-simple-rules-dockerfiles\.pdf 8 | 9 | *.tex 10 | 11 | README.html 12 | 13 | examples/full-demo/figures/ 14 | 15 | examples/full-demo/outputData/ 16 | 17 | examples/microsimulation-model-virus-C\+\+/covid-sim 18 | 19 | examples/geospatial-python-qgis-model-workflow/docker-qgis-model/ 20 | 21 | diff.pdf 22 | 23 | diff.synctex.gz 24 | 25 | ten-simple-rules-dockerfiles.synctex.gz 26 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | os: linux 2 | 3 | services: 4 | - docker 5 | 6 | language: generic 7 | 8 | branches: 9 | only: 10 | - master 11 | 12 | #install: 13 | # - docker build --tag ten-simple-rules-dockerfiles . 14 | 15 | # - access to GITHUB_PAT for rate limit 16 | # - --user is needed to write into mounted directory 17 | script: 18 | - docker run --interactive --name tsrd --volume $(pwd):/tsrd nuest/ten-simple-rules-dockerfiles Rscript -e 'setwd("/tsrd"); rmarkdown::render("ten-simple-rules-dockerfiles.Rmd", output_file = "/tmp/tsrd.pdf")' 19 | - mkdir -p site 20 | - docker cp tsrd:/tmp/tsrd.pdf site/ten-simple-rules-dockerfiles.pdf 21 | - ls -l 22 | - ls -l site 23 | 24 | # only works for one branch, because of reset 25 | after_success: 26 | - cd site 27 | - ls -l 28 | - git init 29 | - git config user.name "${GH_USER_NAME}" 30 | - git config user.email "${GH_USER_EMAIL}" 31 | - git remote add upstream "https://${GH_TOKEN}@${GH_REF}" 32 | - git fetch upstream 33 | - git reset upstream/gh-pages 34 | - git add -A . 35 | - rev=$(git rev-parse --short HEAD) 36 | - git commit -m "Rebuild at ${rev}" 37 | - git push -q upstream HEAD:gh-pages 38 | 39 | env: 40 | global: 41 | # GITHUB_PAT to solve GH API rate limit 42 | - secure: "at0zw2gJ+KR1Y9I7IGeiy0uyBHizVCcYfZ2iKjvxVUSNyMf7IB0X+ffODnJkVC/5aX0AMO8xIYZA35Q19DzF9WF73RkdcWU77cvmeyiwX2k/bgSFKvmILwBt/alrcksfh0HRr0NniTtU+Ip5ywhlCwR52nE5h58x0DJkfvSAI7HqZqjEJqwZZAvnYeW6+XH1isUDtMgqkgwUDmCgX3NPu3dlCD8RcfNbRnSWGebwW/BVPKG2/w/VwxnPwquPXQNcj7lar6UZSHMVap+RtqUcEVLnUcsgWzrtXjdD3GRsWAqT0HW2YyYv9pV5vwNUiKQlFs8FxKF9XjwMF+lJ6PVRWPPXMG8QMgfx1tn2G2di05m3kXFN4Kmmn5b8l4Qb1lxDy7gZxp4HVtvnb7a1Cb41hy87G57piIJPNC8CBtR50jHsECU8dg5lDvBkMAecKcg2orQJdPwQBI63poeOlRLjTPJvDGLGnoKOjzzPMjVCHRCdLs2c1y/KFQvueTJ8T/E8dOzmLkQEMXg+tjUbvgYLyvRgyiu9sxQVVcokZF7eb53WppCuGcsyqNShQ0lF6L41ei/Qfb1N0a3JkBrWuHmxt1a7bmPmFTaR1h1DnV5v+dfaeOZKOp1ojWzT3yVKLKGh7ZKbip6OFBJxDfVD18Nptg6eCprzxyKKJe2gpSm2OE0=" 43 | - GH_USER_NAME: "nuest" 44 | - GH_REF: "github.com/nuest/ten-simple-rules-dockerfiles" 45 | # GH token and email 46 | - secure: "Np0h+wPn8j3pcP9A66dfPwjQ9IMhe0yc1vyfhL29qKd0S2NQWVzhujXrPbrA6PjbJrR8+u/pdYn3viFE8rWyMhSF8gLoOwrb9nNlpoQgZjp+B1d1Bb/JC6+uWmofNh+c2wlyCN71AeBhcGVzOTV9wkSuzi+HbxKgtxoIg65+VwDrvgIuCDnrsXOKOOcikWG6bY6c5umEXI+5EnLIyHQzcuFi7CLJlroiqVYzK1KNIytuQMr67IUAP0Z50WzGcdWzV/r/RaMoZpgZstPHieVoVicWR3czjDb2BJaJK536gtHLZ1WRiamcvB2gfTyFlerG91wERqIWzPvCFMn0acVaAG7fFavBd9FQg64/1kg2H4RSjKdMgkN+JR5zRtJXMz0LEFPPhSsKfB9a/x0/hFMPLws4mFIRENHlmKkbYQTWuQTiVNqP+oa9DFyrf0aZY+yYkEx2quDi5nb/qiXxudvbcLjjAjI28Xqyf93oIW74nEEQJrKGP0v3LlOzfVRBPmWZvMRwCBgmvqEh7Ia7DPvxxbP7ttY9mp+wGCLiEA/d55vazEdrv1n8FPoMGjGrFuh0Wmglh2NKLmkV2eaEh9RtGJ8ToZNHPffONjtCq0UVzL043EApJlslQ4FxSjFygjjCGGqqtyqA4S4d0nRSPAvpIY5qRhHQT34GFmY5Nz3XSS4=" 47 | - secure: "MMn8elsq9Dmuj2iZn5kp52oPwDngtc2GbP9d+26HQhMpVdjIb5SXyAVVNc4mmUIeja+Bd4opRQriEYPpqKKAfzkhzquAioZI1A43dA9xPqva7nx3juEzeB/dekbM1H83/043BlkBejoTewO/JYI/NS0wlR+oLVyefohsA8kuInTgFaqFXaIap8hbcOb0YlFpsg5xdWcbpNAACvaxUkQOQ3lOx8CSdE7i+oK/HkqOAQRNcs7Ua3YmKE8ZjQ5iE/3mdlLY2rHydRcM/+AavvjCOB5kEl2dtaheMExQXmrCkwh9mQYV9Tbx8gPlCYqmhRfRvg1QLSXMfUOhrFKhnTLeRZD/AdtdeXXPGWzpFOJr8WkfEl6c9L0LnpJZXwWx1KRdD/iTS86e/Mg031nDFMY61p9vO/HSmDyOy4hp0lnyb41V0xRVxjoAYDSff/XXlrfbkZsoV7YtsF5y1wiH4fN1V54weZ70W5yyovJdXdPpS7LMJUadB28PkGzzwCYUshUW9qgrka0xp99M/As+4WycMNrEJ1Q7mOYC3ipg+Q5AMrt8uahRLY4piXc06GrNkh03ZXEaDk7KRAkl7N1jz8IQmT+XY1aB2wbtXH0MAWOQIacX6GcD+eoZ7XJ8vHEiQx0ec/dwjLTwQxadmOZB4j59NINSLpfTqwub3AnE1MPtT+I=" 48 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM docker.io/rocker/verse:3.6.2 2 | 3 | RUN r -e 'tinytex::tlmgr_install(pkgs = c("changepage", \ 4 | "ucs", \ 5 | "marvosym", \ 6 | "lineno", \ 7 | "microtype", \ 8 | "xcolor", \ 9 | "colortbl", \ 10 | "lastpage", \ 11 | "fancyhdr", \ 12 | "forarray", \ 13 | "xstring", \ 14 | "listings", \ 15 | "ec", \ 16 | "latexdiff", \ 17 | # needed for latexdiff: 18 | "ulem"))' 19 | 20 | LABEL maintainer='D. Nüst ' \ 21 | org.opencontainers.image.authors='Nüst (daniel.nuest@uni-muenster.de), Sochat, Marwick, Eglen, Head, Hirst, and Evans' \ 22 | org.opencontainers.image.url='https://github.com/nuest/ten-simple-rules' \ 23 | org.opencontainers.image.documentation='https://nuest.github.io/ten-simple-rules-dockerfiles/ten-simple-rules-dockerfiles.pdf' \ 24 | org.opencontainers.image.version='1.0.0' 25 | 26 | # Usage instructions: 27 | # $ docker build -t ten-simple-rules-dockerfiles . 28 | # $ docker run --interactive --rm --name tensimpledockerfiles --user $UID --volume $(pwd):/tsrd ten-simple-rules-dockerfiles Rscript -e 'setwd("/tsrd"); rmarkdown::render("ten-simple-rules-dockerfiles.Rmd")' 29 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Attribution 4.0 International 2 | 3 | ======================================================================= 4 | 5 | Creative Commons Corporation ("Creative Commons") is not a law firm and 6 | does not provide legal services or legal advice. Distribution of 7 | Creative Commons public licenses does not create a lawyer-client or 8 | other relationship. Creative Commons makes its licenses and related 9 | information available on an "as-is" basis. Creative Commons gives no 10 | warranties regarding its licenses, any material licensed under their 11 | terms and conditions, or any related information. Creative Commons 12 | disclaims all liability for damages resulting from their use to the 13 | fullest extent possible. 14 | 15 | Using Creative Commons Public Licenses 16 | 17 | Creative Commons public licenses provide a standard set of terms and 18 | conditions that creators and other rights holders may use to share 19 | original works of authorship and other material subject to copyright 20 | and certain other rights specified in the public license below. The 21 | following considerations are for informational purposes only, are not 22 | exhaustive, and do not form part of our licenses. 23 | 24 | Considerations for licensors: Our public licenses are 25 | intended for use by those authorized to give the public 26 | permission to use material in ways otherwise restricted by 27 | copyright and certain other rights. Our licenses are 28 | irrevocable. Licensors should read and understand the terms 29 | and conditions of the license they choose before applying it. 30 | Licensors should also secure all rights necessary before 31 | applying our licenses so that the public can reuse the 32 | material as expected. Licensors should clearly mark any 33 | material not subject to the license. This includes other CC- 34 | licensed material, or material used under an exception or 35 | limitation to copyright. More considerations for licensors: 36 | wiki.creativecommons.org/Considerations_for_licensors 37 | 38 | Considerations for the public: By using one of our public 39 | licenses, a licensor grants the public permission to use the 40 | licensed material under specified terms and conditions. If 41 | the licensor's permission is not necessary for any reason--for 42 | example, because of any applicable exception or limitation to 43 | copyright--then that use is not regulated by the license. Our 44 | licenses grant only permissions under copyright and certain 45 | other rights that a licensor has authority to grant. Use of 46 | the licensed material may still be restricted for other 47 | reasons, including because others have copyright or other 48 | rights in the material. A licensor may make special requests, 49 | such as asking that all changes be marked or described. 50 | Although not required by our licenses, you are encouraged to 51 | respect those requests where reasonable. More considerations 52 | for the public: 53 | wiki.creativecommons.org/Considerations_for_licensees 54 | 55 | ======================================================================= 56 | 57 | Creative Commons Attribution 4.0 International Public License 58 | 59 | By exercising the Licensed Rights (defined below), You accept and agree 60 | to be bound by the terms and conditions of this Creative Commons 61 | Attribution 4.0 International Public License ("Public License"). To the 62 | extent this Public License may be interpreted as a contract, You are 63 | granted the Licensed Rights in consideration of Your acceptance of 64 | these terms and conditions, and the Licensor grants You such rights in 65 | consideration of benefits the Licensor receives from making the 66 | Licensed Material available under these terms and conditions. 67 | 68 | 69 | Section 1 -- Definitions. 70 | 71 | a. Adapted Material means material subject to Copyright and Similar 72 | Rights that is derived from or based upon the Licensed Material 73 | and in which the Licensed Material is translated, altered, 74 | arranged, transformed, or otherwise modified in a manner requiring 75 | permission under the Copyright and Similar Rights held by the 76 | Licensor. For purposes of this Public License, where the Licensed 77 | Material is a musical work, performance, or sound recording, 78 | Adapted Material is always produced where the Licensed Material is 79 | synched in timed relation with a moving image. 80 | 81 | b. Adapter's License means the license You apply to Your Copyright 82 | and Similar Rights in Your contributions to Adapted Material in 83 | accordance with the terms and conditions of this Public License. 84 | 85 | c. Copyright and Similar Rights means copyright and/or similar rights 86 | closely related to copyright including, without limitation, 87 | performance, broadcast, sound recording, and Sui Generis Database 88 | Rights, without regard to how the rights are labeled or 89 | categorized. For purposes of this Public License, the rights 90 | specified in Section 2(b)(1)-(2) are not Copyright and Similar 91 | Rights. 92 | 93 | d. Effective Technological Measures means those measures that, in the 94 | absence of proper authority, may not be circumvented under laws 95 | fulfilling obligations under Article 11 of the WIPO Copyright 96 | Treaty adopted on December 20, 1996, and/or similar international 97 | agreements. 98 | 99 | e. Exceptions and Limitations means fair use, fair dealing, and/or 100 | any other exception or limitation to Copyright and Similar Rights 101 | that applies to Your use of the Licensed Material. 102 | 103 | f. Licensed Material means the artistic or literary work, database, 104 | or other material to which the Licensor applied this Public 105 | License. 106 | 107 | g. Licensed Rights means the rights granted to You subject to the 108 | terms and conditions of this Public License, which are limited to 109 | all Copyright and Similar Rights that apply to Your use of the 110 | Licensed Material and that the Licensor has authority to license. 111 | 112 | h. Licensor means the individual(s) or entity(ies) granting rights 113 | under this Public License. 114 | 115 | i. Share means to provide material to the public by any means or 116 | process that requires permission under the Licensed Rights, such 117 | as reproduction, public display, public performance, distribution, 118 | dissemination, communication, or importation, and to make material 119 | available to the public including in ways that members of the 120 | public may access the material from a place and at a time 121 | individually chosen by them. 122 | 123 | j. Sui Generis Database Rights means rights other than copyright 124 | resulting from Directive 96/9/EC of the European Parliament and of 125 | the Council of 11 March 1996 on the legal protection of databases, 126 | as amended and/or succeeded, as well as other essentially 127 | equivalent rights anywhere in the world. 128 | 129 | k. You means the individual or entity exercising the Licensed Rights 130 | under this Public License. Your has a corresponding meaning. 131 | 132 | 133 | Section 2 -- Scope. 134 | 135 | a. License grant. 136 | 137 | 1. Subject to the terms and conditions of this Public License, 138 | the Licensor hereby grants You a worldwide, royalty-free, 139 | non-sublicensable, non-exclusive, irrevocable license to 140 | exercise the Licensed Rights in the Licensed Material to: 141 | 142 | a. reproduce and Share the Licensed Material, in whole or 143 | in part; and 144 | 145 | b. produce, reproduce, and Share Adapted Material. 146 | 147 | 2. Exceptions and Limitations. For the avoidance of doubt, where 148 | Exceptions and Limitations apply to Your use, this Public 149 | License does not apply, and You do not need to comply with 150 | its terms and conditions. 151 | 152 | 3. Term. The term of this Public License is specified in Section 153 | 6(a). 154 | 155 | 4. Media and formats; technical modifications allowed. The 156 | Licensor authorizes You to exercise the Licensed Rights in 157 | all media and formats whether now known or hereafter created, 158 | and to make technical modifications necessary to do so. The 159 | Licensor waives and/or agrees not to assert any right or 160 | authority to forbid You from making technical modifications 161 | necessary to exercise the Licensed Rights, including 162 | technical modifications necessary to circumvent Effective 163 | Technological Measures. For purposes of this Public License, 164 | simply making modifications authorized by this Section 2(a) 165 | (4) never produces Adapted Material. 166 | 167 | 5. Downstream recipients. 168 | 169 | a. Offer from the Licensor -- Licensed Material. Every 170 | recipient of the Licensed Material automatically 171 | receives an offer from the Licensor to exercise the 172 | Licensed Rights under the terms and conditions of this 173 | Public License. 174 | 175 | b. No downstream restrictions. You may not offer or impose 176 | any additional or different terms or conditions on, or 177 | apply any Effective Technological Measures to, the 178 | Licensed Material if doing so restricts exercise of the 179 | Licensed Rights by any recipient of the Licensed 180 | Material. 181 | 182 | 6. No endorsement. Nothing in this Public License constitutes or 183 | may be construed as permission to assert or imply that You 184 | are, or that Your use of the Licensed Material is, connected 185 | with, or sponsored, endorsed, or granted official status by, 186 | the Licensor or others designated to receive attribution as 187 | provided in Section 3(a)(1)(A)(i). 188 | 189 | b. Other rights. 190 | 191 | 1. Moral rights, such as the right of integrity, are not 192 | licensed under this Public License, nor are publicity, 193 | privacy, and/or other similar personality rights; however, to 194 | the extent possible, the Licensor waives and/or agrees not to 195 | assert any such rights held by the Licensor to the limited 196 | extent necessary to allow You to exercise the Licensed 197 | Rights, but not otherwise. 198 | 199 | 2. Patent and trademark rights are not licensed under this 200 | Public License. 201 | 202 | 3. To the extent possible, the Licensor waives any right to 203 | collect royalties from You for the exercise of the Licensed 204 | Rights, whether directly or through a collecting society 205 | under any voluntary or waivable statutory or compulsory 206 | licensing scheme. In all other cases the Licensor expressly 207 | reserves any right to collect such royalties. 208 | 209 | 210 | Section 3 -- License Conditions. 211 | 212 | Your exercise of the Licensed Rights is expressly made subject to the 213 | following conditions. 214 | 215 | a. Attribution. 216 | 217 | 1. If You Share the Licensed Material (including in modified 218 | form), You must: 219 | 220 | a. retain the following if it is supplied by the Licensor 221 | with the Licensed Material: 222 | 223 | i. identification of the creator(s) of the Licensed 224 | Material and any others designated to receive 225 | attribution, in any reasonable manner requested by 226 | the Licensor (including by pseudonym if 227 | designated); 228 | 229 | ii. a copyright notice; 230 | 231 | iii. a notice that refers to this Public License; 232 | 233 | iv. a notice that refers to the disclaimer of 234 | warranties; 235 | 236 | v. a URI or hyperlink to the Licensed Material to the 237 | extent reasonably practicable; 238 | 239 | b. indicate if You modified the Licensed Material and 240 | retain an indication of any previous modifications; and 241 | 242 | c. indicate the Licensed Material is licensed under this 243 | Public License, and include the text of, or the URI or 244 | hyperlink to, this Public License. 245 | 246 | 2. You may satisfy the conditions in Section 3(a)(1) in any 247 | reasonable manner based on the medium, means, and context in 248 | which You Share the Licensed Material. For example, it may be 249 | reasonable to satisfy the conditions by providing a URI or 250 | hyperlink to a resource that includes the required 251 | information. 252 | 253 | 3. If requested by the Licensor, You must remove any of the 254 | information required by Section 3(a)(1)(A) to the extent 255 | reasonably practicable. 256 | 257 | 4. If You Share Adapted Material You produce, the Adapter's 258 | License You apply must not prevent recipients of the Adapted 259 | Material from complying with this Public License. 260 | 261 | 262 | Section 4 -- Sui Generis Database Rights. 263 | 264 | Where the Licensed Rights include Sui Generis Database Rights that 265 | apply to Your use of the Licensed Material: 266 | 267 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right 268 | to extract, reuse, reproduce, and Share all or a substantial 269 | portion of the contents of the database; 270 | 271 | b. if You include all or a substantial portion of the database 272 | contents in a database in which You have Sui Generis Database 273 | Rights, then the database in which You have Sui Generis Database 274 | Rights (but not its individual contents) is Adapted Material; and 275 | 276 | c. You must comply with the conditions in Section 3(a) if You Share 277 | all or a substantial portion of the contents of the database. 278 | 279 | For the avoidance of doubt, this Section 4 supplements and does not 280 | replace Your obligations under this Public License where the Licensed 281 | Rights include other Copyright and Similar Rights. 282 | 283 | 284 | Section 5 -- Disclaimer of Warranties and Limitation of Liability. 285 | 286 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE 287 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS 288 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF 289 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, 290 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, 291 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 292 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, 293 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT 294 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT 295 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. 296 | 297 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE 298 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, 299 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, 300 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, 301 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR 302 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN 303 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR 304 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR 305 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. 306 | 307 | c. The disclaimer of warranties and limitation of liability provided 308 | above shall be interpreted in a manner that, to the extent 309 | possible, most closely approximates an absolute disclaimer and 310 | waiver of all liability. 311 | 312 | 313 | Section 6 -- Term and Termination. 314 | 315 | a. This Public License applies for the term of the Copyright and 316 | Similar Rights licensed here. However, if You fail to comply with 317 | this Public License, then Your rights under this Public License 318 | terminate automatically. 319 | 320 | b. Where Your right to use the Licensed Material has terminated under 321 | Section 6(a), it reinstates: 322 | 323 | 1. automatically as of the date the violation is cured, provided 324 | it is cured within 30 days of Your discovery of the 325 | violation; or 326 | 327 | 2. upon express reinstatement by the Licensor. 328 | 329 | For the avoidance of doubt, this Section 6(b) does not affect any 330 | right the Licensor may have to seek remedies for Your violations 331 | of this Public License. 332 | 333 | c. For the avoidance of doubt, the Licensor may also offer the 334 | Licensed Material under separate terms or conditions or stop 335 | distributing the Licensed Material at any time; however, doing so 336 | will not terminate this Public License. 337 | 338 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public 339 | License. 340 | 341 | 342 | Section 7 -- Other Terms and Conditions. 343 | 344 | a. The Licensor shall not be bound by any additional or different 345 | terms or conditions communicated by You unless expressly agreed. 346 | 347 | b. Any arrangements, understandings, or agreements regarding the 348 | Licensed Material not stated herein are separate from and 349 | independent of the terms and conditions of this Public License. 350 | 351 | 352 | Section 8 -- Interpretation. 353 | 354 | a. For the avoidance of doubt, this Public License does not, and 355 | shall not be interpreted to, reduce, limit, restrict, or impose 356 | conditions on any use of the Licensed Material that could lawfully 357 | be made without permission under this Public License. 358 | 359 | b. To the extent possible, if any provision of this Public License is 360 | deemed unenforceable, it shall be automatically reformed to the 361 | minimum extent necessary to make it enforceable. If the provision 362 | cannot be reformed, it shall be severed from this Public License 363 | without affecting the enforceability of the remaining terms and 364 | conditions. 365 | 366 | c. No term or condition of this Public License will be waived and no 367 | failure to comply consented to unless expressly agreed to by the 368 | Licensor. 369 | 370 | d. Nothing in this Public License constitutes or may be interpreted 371 | as a limitation upon, or waiver of, any privileges and immunities 372 | that apply to the Licensor or You, including from the legal 373 | processes of any jurisdiction or authority. 374 | 375 | 376 | ======================================================================= 377 | 378 | Creative Commons is not a party to its public 379 | licenses. Notwithstanding, Creative Commons may elect to apply one of 380 | its public licenses to material it publishes and in those instances 381 | will be considered the “Licensor.” The text of the Creative Commons 382 | public licenses is dedicated to the public domain under the CC0 Public 383 | Domain Dedication. Except for the limited purpose of indicating that 384 | material is shared under a Creative Commons public license or as 385 | otherwise permitted by the Creative Commons policies published at 386 | creativecommons.org/policies, Creative Commons does not authorize the 387 | use of the trademark "Creative Commons" or any other trademark or logo 388 | of Creative Commons without its prior written consent including, 389 | without limitation, in connection with any unauthorized modifications 390 | to any of its public licenses or any other arrangements, 391 | understandings, or agreements concerning use of licensed material. For 392 | the avoidance of doubt, this paragraph does not form part of the 393 | public licenses. 394 | 395 | Creative Commons may be contacted at creativecommons.org. 396 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | default: edit 2 | 3 | ten-simple-rules-dockerfiles.pdf: ten-simple-rules-dockerfiles.Rmd 4 | Rscript -e 'rmarkdown::render("$<")' 5 | 6 | edit: 7 | docker build --tag ten-simple-rules-dockerfiles . 8 | docker run --rm -it -p 8787:8787 -e PASSWORD=simple -v $(shell pwd):/home/rstudio/ten-simple-rules-dockerfiles ten-simple-rules-dockerfiles 9 | 10 | 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ten Simple Rules for Writing Dockerfiles for Reproducible Data Science 2 | 3 | Ten Simple Rules for Writing Dockerfiles for Reproducible Research - Summary 4 | 5 | [![Article DOI](https://img.shields.io/badge/Article-10.1371%2Fjournal.pcbi.1008316-yellow)](https://doi.org/10.1371/journal.pcbi.1008316) 6 | 7 | [![Preprint DOI](https://img.shields.io/badge/Preprint-10.31219%2Fosf.io%2Ffsd7t-blue)](https://doi.org/10.31219/osf.io/fsd7t) 8 | 9 | The manuscript is published as a preprint: **[https://osf.io/fsd7t](https://osf.io/fsd7t)** 10 | 11 | We welcome your feedback, e.g., by opening issues on this repository or with [OSF annotations](https://help.osf.io/hc/en-us/articles/360019738554-Annotate-a-Preprint). 12 | We especially welcome your help by creating strong illustrating examples, see [issue #4](https://github.com/nuest/ten-simple-rules-dockerfiles/issues/4). 13 | 14 | [Ten Simple Rules Collection on PLOS](https://collections.plos.org/ten-simple-rules) 15 | 16 | [Current draft as PDF](https://nuest.github.io/ten-simple-rules-dockerfiles/ten-simple-rules-dockerfiles.pdf) 17 | 18 | ## Author contributions 19 | 20 | 21 | DN conceived the idea and contributed to conceptualisation, methodology, and writing - original draft, review & editing, and validation. 22 | VS contributed to conceptualisation, methodology, and writing - original draft, and review & editing. 23 | BM contributed to writing – review & editing. 24 | SJE contributed to conceptualisation, writing – review & editing, and validation. 25 | THe contributed to conceptualisation. 26 | THi contributed to writing – review & editing. 27 | BDE contributed to conceptualisation, writing – review & editing, visualisation, and validation. 28 | This articles was written collaboratively on GitHub, where [contributions in form of text or discussions comments](https://github.com/nuest/ten-simple-rules-dockerfiles/graphs/contributors) are documented: [https://github.com/nuest/ten-simple-rules-dockerfiles/](https://github.com/nuest/ten-simple-rules-dockerfiles/). 29 | 30 | ## Run container for editing the document 31 | 32 | First, build the container. It will install the dependencies that you 33 | need for compiling the LaTex. 34 | 35 | ```bash 36 | docker build -t ten-simple-rules-dockerfiles . 37 | ``` 38 | 39 | Then run it! You'll need to set a password to login with user "rstudio." 40 | 41 | ```bash 42 | PASSWORD=simple 43 | docker run --rm -it -p 8787:8787 -e PASSWORD=$PASSWORD -v $(pwd):/home/rstudio/ten-simple-rules-dockerfiles ten-simple-rules-dockerfiles 44 | ``` 45 | 46 | Open http://localhost:8787 to get to RStudio, log in, and navigate to the directory `~/ten-simple-rules-dockerfiles` to open the `Rmd` file and start editing. 47 | Use the "Knit" button to render the PDF. 48 | The first rendering takes a bit longer, because required LaTeX packages must be installed. 49 | 50 | See more options [in the Rocker docs](https://github.com/rocker-org/rocker-versioned/blob/master/rstudio/README.md#additional-configuration-options). 51 | 52 | ## Run container for building the PDF 53 | 54 | See the end of the `Dockerfile` for instructions. 55 | 56 | ## Useful snippets 57 | 58 | - Get all author's GitHub handles: 59 | ```bash 60 | cat *.Rmd | grep ' # https://github.com/' | sed 's| # https://github.com/|@|' 61 | ``` 62 | - Get all author's emails: 63 | ```bash 64 | cat *.Rmd | grep 'email:' | sed 's| email: ||' 65 | ``` 66 | - [Work in progress!] Get a `.docx` file out of the Rmd so one can compare versions and generate marked-up copies of changes: 67 | ```r 68 | # https://github.com/davidgohel/officedown 69 | library("officedown") 70 | rmarkdown::render("ten-simple-rules-dockerfiles.Rmd", output_format = officedown::rdocx_document(), output_file = "tsrd.docx") 71 | 72 | # https://noamross.github.io/redoc/articles/mixed-workflows-with-redoc.html 73 | library("redoc") 74 | rmarkdown::render("ten-simple-rules-dockerfiles.Rmd", output_format = redoc::redoc(), output_file = "tsrd.docx") 75 | ``` 76 | - Compare with `latexdiff` 77 | ```bash 78 | # get a specific version of the text file 79 | wget -O submission.v2.tex https://raw.githubusercontent.com/nuest/ten-simple-rules-dockerfiles/submission.v2/ten-simple-rules-dockerfiles.tex 80 | # compare it with current version 81 | latexdiff --graphics-markup=2 submission.v2.tex ten-simple-rules-dockerfiles.tex > diff.tex 82 | # render diff.tex with RStudio 83 | ``` 84 | 85 | ## License 86 | 87 | This manuscript is published under a [Creative Commons Attribution 4.0 International](https://creativecommons.org/licenses/by/4.0/) (CC BY 4.0) license, see file [LICENSE.md](LICENSE.md). 88 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Dockerfile Examples 2 | 3 | [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.3878583.svg)](https://doi.org/10.5281/zenodo.3878583) 4 | 5 | ## About 6 | 7 | This directory contains `Dockerfile`s to demonstrate the application of the rules in [_Ten Simple Rules for Writing Dockerfiles for Reproducible Data Science_](https://github.com/nuest/ten-simple-rules-dockerfiles/). 8 | Each subdirectory contains an example consisting of a `README.md` with documentation, a `Dockerfile.before` showing the original as created by the author (optional), and a `Dockerfile` demonstrating the improvements made based on the articles rules. 9 | 10 | **Note:** The `Dockerfile`s in this repository serve as examples, but should be used carefully as templates for new projects because, while it should be possible to build an image from them, they might not be up to date. 11 | For example, base images might be outdated, because the historic original `Dockerfile` that was used as a basis for revision has not been changed in a while. 12 | 13 | ## License 14 | 15 | Unless noted otherwise in the `README.md` file next to a `Dockerfile` or within any file, the contents of this repository are licensed under a [Creative Commons Attribution 4.0 International](https://creativecommons.org/licenses/by/4.0/) (CC BY 4.0) license, see file [../LICENSE.md](LICENSE.md). 16 | 17 | ## Contributions welcome! 18 | 19 | Do you have a `Dockerfile` used for data science and think it follows good practice? 20 | Do you want your `Dockerfile` to be reviewed by someone else? 21 | Did you update a `Dockerfile` based on the article's rules and can share your experiences? 22 | 23 | _In any of these cases, please leave a comment on the [Examples issue](https://github.com/nuest/ten-simple-rules-dockerfiles/issues/4) - we welcome your input._ 24 | 25 | **Considerations for adding an example:** 26 | 27 | - The `README.md` must include the source and license of the published Dockerfile, and the (original) authors; it should also include comments or notes, a few keywords or a descriptive abstract that searching the repository gives reasonable results; it may include a (colourised) diff output, if the changes between Dockerfiles were small 28 | - The directory name should contain scientific domain (e.g. `neuroscience`, `sedimentology`) and the main workflow language(s) or tool(s) (e.g. `Python`, `R-tidyverse`, `pandas`) 29 | - The `Dockerfile` should be buildable, but it is acceptable if it does run with the same set of features as the original, i.e., problems or issues of the resulting image may be fixed but also left as they are 30 | -------------------------------------------------------------------------------- /examples/full-demo/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM docker.io/rocker/verse:3.6.2 2 | 3 | ### INSTALL BASE SOFTWARE ##################################################### 4 | # Install Java, needed for package rJava 5 | RUN apt-get update && \ 6 | apt-get install -y default-jdk && \ 7 | rm -rf /var/lib/apt/lists/* 8 | 9 | ### INSTALL WORKFLOW TOOLS #################################################### 10 | # Install system dependencies for R packages 11 | RUN apt-get update && \ 12 | apt-get install -y \ 13 | # needed for RNetCDF, found via https://sysreqs.r-hub.io/pkg/RNetCDF 14 | libnetcdf-dev libudunits2-dev \ 15 | # needed for git2r: 16 | libgit2-dev 17 | 18 | # Install R packages, based on https://github.com/rocker-org/geospatial/blob/master/Dockerfile 19 | RUN install2.r --error \ 20 | RColorBrewer \ 21 | RNetCDF \ 22 | git2r \ 23 | rJava 24 | 25 | WORKDIR /tmp 26 | 27 | # Install Python tools and their system dependencies 28 | RUN apt-get update && \ 29 | apt-get install -y python-pip && \ 30 | rm -rf /var/lib/apt/lists/* 31 | COPY requirements.txt requirements.txt 32 | RUN pip install -r requirements.txt 33 | 34 | # Download superduper image converter 35 | RUN wget https://downloads.apache.org/pdfbox/2.0.19/pdfbox-app-2.0.19.jar 36 | 37 | ### ADD MY OWN SCRIPTS ######################################################## 38 | # Add workflow scripts 39 | WORKDIR /work 40 | COPY myscript.sh myscript.sh 41 | COPY analysis.py analysis.py 42 | COPY plots.R plots.R 43 | 44 | # Configure workflow 45 | ENV DATA_SIZE 42 46 | 47 | # Uncomment the following lines to execute preprocessing tasks during build 48 | #RUN python analysis.py 49 | #RUN Rscript plots.R 50 | 51 | ### WORKFLOW CONTAINER FEATURE ################################################ 52 | # CMD from base image used for development, uncomment the following lines to 53 | # have a "run workflow only" image 54 | # CMD["./myscript.sh"] 55 | 56 | ### Usage instructions ######################################################## 57 | # Build the images with 58 | # > docker build --tag datascidockerfiles:1.0.0 . 59 | # Run the image interactively with RStudio, open it on http://localhost/ 60 | # > docker run -it -p 80:8787 -e PASSWORD=ten --volume $(pwd)/input:/input datascidockerfiles:1.0.0 61 | # Run the workflow: 62 | # > docker run -it --name gwf datascidockerfiles:1.0.0 /work/myscript.sh 63 | # Extract the data: 64 | # > docker cp gwf:/output/ ./outputData 65 | # Extract the figures: 66 | # > docker cp gwf:/work/figures/ ./figures 67 | -------------------------------------------------------------------------------- /examples/full-demo/README.md: -------------------------------------------------------------------------------- 1 | # Listing 1 from the paper 2 | 3 | Dockerfile full example. 4 | 5 | - See instructions in [Dockerfile](Dockerfile) for building and running locally. 6 | - Run pre-built images (see Dockerfile for naming the container and extracting result files): 7 | ```bash 8 | docker run -it docker.io/nuest/datascidockerfiles:1.0.0 /work/myscript.sh 9 | 10 | docker run -it quay.io/nuest/datascidockerfiles:master /work/myscript.sh 11 | ``` -------------------------------------------------------------------------------- /examples/full-demo/analysis.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import csv23 3 | import random 4 | import os 5 | 6 | # Code based on https://gist.github.com/AlanHohn/293c98f9dadfc67443b8078d843d4401 7 | size = int(os.environ['DATA_SIZE']) 8 | print("Data size: %d\n" % size) 9 | 10 | fieldnames = ['id', 'name', 'age', 'city'] 11 | writer = csv23.DictWriter(open("data.csv", "w"), fieldnames = fieldnames) 12 | names = ['Daniel', 'Vanessa', 'Ben', 'Stephen', 'Tim', 'Tony', 'Ben'] 13 | cities=['Muenster', 'Stanford', 'Seattle', 'Cambridge', 'Zurich', 'Bristol'] 14 | 15 | writer.writerow(dict(zip(fieldnames, fieldnames))) 16 | for i in range(0, size): 17 | writer.writerow(dict([ 18 | ('id', i), 19 | ('name', random.choice(names)), 20 | ('age', str(random.randint(18,81))), 21 | ('city', random.choice(cities))])) 22 | -------------------------------------------------------------------------------- /examples/full-demo/input/data.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 11 3 | 2 4 | 22 5 | 3 6 | 33 -------------------------------------------------------------------------------- /examples/full-demo/myscript.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | mkdir /output 4 | 5 | python analysis.py 6 | Rscript plots.R 7 | 8 | cp data.csv /output/generated_data.csv 9 | 10 | cd /output 11 | java -jar /tmp/pdfbox-app-2.0.19.jar PDFToImage -imageType png /work/figures/mainplot.pdf 12 | 13 | echo "Done!" 14 | -------------------------------------------------------------------------------- /examples/full-demo/plots.R: -------------------------------------------------------------------------------- 1 | # read data 2 | data <- read.csv("data.csv") 3 | 4 | # save in other format, based on https://cran.r-project.org/web/packages/RNetCDF/RNetCDF.pdf 5 | library("RNetCDF") 6 | nc <- create.nc("/output/data.nc") 7 | 8 | dim.def.nc(nc, "station", dimlength = as.numeric(Sys.getenv("DATA_SIZE"))) 9 | dim.def.nc(nc, "max_string_length", 32) 10 | var.def.nc(nc, "name", "NC_CHAR", c("max_string_length", "station")) 11 | 12 | print(data$name) 13 | var.put.nc(nc, "name", as.character(data$name)) 14 | close.nc(nc) 15 | list.files("/output/") 16 | 17 | # plot it 18 | dir.create("figures") 19 | pdf("figures/mainplot.pdf") 20 | plot(data) 21 | dev.off() 22 | cat("Done\n") 23 | -------------------------------------------------------------------------------- /examples/full-demo/requirements.txt: -------------------------------------------------------------------------------- 1 | csv23==0.3.2 2 | -------------------------------------------------------------------------------- /examples/geospatial-python-qgis-model-workflow/Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Daniel Nüst 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | FROM docker.io/ubuntu:16.04 9 | 10 | # Install QGIS and GIS libs from https://launchpad.net/ubuntu/+source/qgis 11 | ENV QGIS_VERSION 2.8.6+dfsg-1build1 12 | 13 | RUN apt-get update \ 14 | && apt-get install -qqy --no-install-recommends \ 15 | gdal-bin \ 16 | python-gdal \ 17 | python-scipy \ 18 | python-numpy \ 19 | python-shapely \ 20 | qgis=$QGIS_VERSION \ 21 | qgis-providers=$QGIS_VERSION \ 22 | python-qgis-common=$QGIS_VERSION \ 23 | python-qgis=$QGIS_VERSION \ 24 | xvfb \ 25 | tree \ 26 | && apt-get clean \ 27 | && rm -rf /var/lib/apt/lists/* 28 | 29 | # Install SAGA in specific version to avoid compatibility issues: http://hub.qgis.org/issues/13279 30 | # A manualy try using software-properties-common and devscripts (rmadison) from different source packages/repos shows many different versions, but explicitly installing 2.2.0+dfsg-1build2 or 2.1.4+dfsg-1ubuntu1 does NOT work 31 | # Instructions based on https://sourceforge.net/p/saga-gis/wiki/Compiling%20a%20Linux%20Unicode%20version/ 32 | ENV SAGA_VERSION 2.2 33 | ENV SAGA_VERSION_MINOR $SAGA_VERSION.0 34 | WORKDIR /saga 35 | RUN apt-get update \ 36 | && apt-get install -qqy --no-install-recommends \ 37 | g++ \ 38 | make \ 39 | automake \ 40 | libtool \ 41 | libwxgtk3.0-dev \ 42 | libtiff5-dev \ 43 | libgdal-dev \ 44 | libproj-dev \ 45 | libjasper-dev \ 46 | libexpat1-dev \ 47 | wx-common \ 48 | libogdi3.2-dev \ 49 | unixodbc-dev \ 50 | wget \ 51 | && apt-get clean 52 | RUN wget http://downloads.sourceforge.net/project/saga-gis/SAGA%20-%20$SAGA_VERSION/SAGA%20$SAGA_VERSION_MINOR/saga_$SAGA_VERSION_MINOR.tar.gz \ 53 | && tar -xvzf saga*.tar.gz 54 | WORKDIR /saga/saga-$SAGA_VERSION_MINOR 55 | RUN ./configure \ 56 | && make \ 57 | && make install 58 | 59 | # Install OTB, see https://www.orfeo-toolbox.org/CookBook/Installation.html 60 | ENV OTB_VERSION OTB-5.6.1-Linux64 61 | WORKDIR /otb 62 | RUN wget https://www.orfeo-toolbox.org/packages/archives/OTB/$OTB_VERSION.run -q \ 63 | && chmod +x $OTB_VERSION.run \ 64 | && ./$OTB_VERSION.run \ 65 | && rm $OTB_VERSION.run 66 | # Set non-typical OTB installation dirs for usage in model.py, no profile needed then (see https://github.com/qgis/QGIS/pull/2840/files) 67 | ENV OTB_FOLDER /otb/$OTB_VERSION/bin 68 | ENV OTB_LIB_FOLDER /otb/$OTB_VERSION/lib/otb/applications 69 | 70 | # Set environment variables for workflow execution 71 | ENV PYTHONPATH=/usr/share/qgis/python:/usr/share/qgis/python/plugins 72 | ENV QGIS_LOGFILE=/qgis/qgis.log 73 | ENV QGIS_PROCESSING_LOGFILE=/root/.qgis2/processing/processing.log 74 | ENV QGIS_WORKSPACE=/workspace 75 | ENV QGIS_MODELFILE=/workspace/models/*.model 76 | ENV QGIS_MODELSCRIPT=/workspace/model.py 77 | ENV QGIS_SCRIPTFILE=/workspace/scripts/*.py 78 | ENV QGIS_RESULT=/results 79 | ENV QGIS_USER_MODELDIR=/root/.qgis2/processing/models 80 | ENV QGIS_USER_SCRIPTDIR=/root/.qgis2/processing/scripts 81 | ENV XVFB_LOGFILE=/qgis/xvfb.log 82 | 83 | # Add main script 84 | WORKDIR /qgis 85 | COPY model.sh model.sh 86 | RUN chmod 0755 model.sh 87 | 88 | # Expose default volumes for Kitematic UI 89 | VOLUME $QGIS_WORKSPACE 90 | VOLUME $QGIS_RESULT 91 | 92 | # Copy data into the container, can be overwritten with a mount 93 | COPY . /workspace 94 | 95 | LABEL maintainer="Daniel Nüst " \ 96 | org.opencontainers.image.authors="Nüst (daniel.nuest@uni-muenster.de), Knoth" \ 97 | org.opencontainers.image.url="https://github.com/nuest/docker-qgis-model" \ 98 | org.opencontainers.image.documentation="Reproducibility and Practical Adoption of GEOBIA with Open-Source Software in Docker Containers " \ 99 | org.opencontainers.image.description="Reproducible workflow image" \ 100 | org.opencontainers.image.licenses="Apache-2.0" \ 101 | author.orcid="0000-0002-0024-5046" 102 | 103 | ENTRYPOINT ["/bin/bash", "/qgis/model.sh"] 104 | 105 | # Execute the following commands _in the directory of this file_ to build and execute a self-contained image: 106 | # BUILD COMMAND: docker build -t qgis-model-example . 107 | # RUN COMMAND: docker run --rm -it qgis-model-example 108 | -------------------------------------------------------------------------------- /examples/geospatial-python-qgis-model-workflow/Dockerfile.original.1: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Daniel Nüst 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | FROM ubuntu:16.04 9 | MAINTAINER Daniel Nüst 10 | 11 | # Install QGIS and GIS libs from https://launchpad.net/ubuntu/+source/qgis 12 | ENV QGIS_VERSION 2.8.6+dfsg-1build1 13 | 14 | RUN apt-get update \ 15 | && apt-get install -qqy --no-install-recommends \ 16 | gdal-bin \ 17 | python-gdal \ 18 | python-scipy \ 19 | python-numpy \ 20 | python-shapely \ 21 | qgis=$QGIS_VERSION \ 22 | qgis-providers=$QGIS_VERSION \ 23 | python-qgis-common=$QGIS_VERSION \ 24 | python-qgis=$QGIS_VERSION \ 25 | xvfb \ 26 | tree \ 27 | && apt-get clean \ 28 | && rm -rf /var/lib/apt/lists/* 29 | 30 | # Install SAGA in specific version to avoid compatibility issues: http://hub.qgis.org/issues/13279 31 | # A manualy try using software-properties-common and devscripts (rmadison) from different source packages/repos shows many different versions, but explicitly installing 2.2.0+dfsg-1build2 or 2.1.4+dfsg-1ubuntu1 does NOT work 32 | # Instructions based on https://sourceforge.net/p/saga-gis/wiki/Compiling%20a%20Linux%20Unicode%20version/ 33 | ENV SAGA_VERSION 2.2 34 | ENV SAGA_VERSION_MINOR $SAGA_VERSION.0 35 | WORKDIR /saga 36 | RUN apt-get update \ 37 | && apt-get install -qqy --no-install-recommends \ 38 | g++ \ 39 | make \ 40 | automake \ 41 | libtool \ 42 | libwxgtk3.0-dev \ 43 | libtiff5-dev \ 44 | libgdal-dev \ 45 | libproj-dev \ 46 | libjasper-dev \ 47 | libexpat1-dev \ 48 | wx-common \ 49 | libogdi3.2-dev \ 50 | unixodbc-dev \ 51 | wget \ 52 | && apt-get clean 53 | RUN wget http://downloads.sourceforge.net/project/saga-gis/SAGA%20-%20$SAGA_VERSION/SAGA%20$SAGA_VERSION_MINOR/saga_$SAGA_VERSION_MINOR.tar.gz \ 54 | && tar -xvzf saga*.tar.gz 55 | WORKDIR /saga/saga-$SAGA_VERSION_MINOR 56 | RUN ./configure \ 57 | && make \ 58 | && make install 59 | 60 | # Install OTB, see https://www.orfeo-toolbox.org/CookBook/Installation.html 61 | ENV OTB_VERSION OTB-5.6.1-Linux64 62 | WORKDIR /otb 63 | RUN wget https://www.orfeo-toolbox.org/packages/archives/OTB/$OTB_VERSION.run -q \ 64 | && chmod +x $OTB_VERSION.run \ 65 | && ./$OTB_VERSION.run \ 66 | && rm $OTB_VERSION.run 67 | # Set non-typical OTB installation dirs for usage in model.py, no profile needed then (see https://github.com/qgis/QGIS/pull/2840/files) 68 | ENV OTB_FOLDER /otb/$OTB_VERSION/bin 69 | ENV OTB_LIB_FOLDER /otb/$OTB_VERSION/lib/otb/applications 70 | 71 | # Set environment variables for workflow execution 72 | ENV PYTHONPATH=/usr/share/qgis/python:/usr/share/qgis/python/plugins 73 | ENV QGIS_LOGFILE=/qgis/qgis.log 74 | ENV QGIS_PROCESSING_LOGFILE=/root/.qgis2/processing/processing.log 75 | ENV QGIS_WORKSPACE=/workspace 76 | ENV QGIS_MODELFILE=/workspace/models/*.model 77 | ENV QGIS_MODELSCRIPT=/workspace/model.py 78 | ENV QGIS_SCRIPTFILE=/workspace/scripts/*.py 79 | ENV QGIS_RESULT=/results 80 | ENV QGIS_USER_MODELDIR=/root/.qgis2/processing/models 81 | ENV QGIS_USER_SCRIPTDIR=/root/.qgis2/processing/scripts 82 | ENV XVFB_LOGFILE=/qgis/xvfb.log 83 | 84 | # Add main script 85 | WORKDIR /qgis 86 | COPY model.sh model.sh 87 | RUN chmod 0755 model.sh 88 | 89 | # Expose default volumes for Kitematic UI 90 | VOLUME $QGIS_WORKSPACE 91 | VOLUME $QGIS_RESULT 92 | 93 | ENTRYPOINT ["/bin/bash", "/qgis/model.sh"] 94 | 95 | # docker build --tag xenial --file Dockerfile.xenial . 96 | -------------------------------------------------------------------------------- /examples/geospatial-python-qgis-model-workflow/Dockerfile.original.2: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Daniel Nüst 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | FROM nuest/qgis-model:xenial 9 | MAINTAINER Daniel Nüst 10 | 11 | # This Dockerfile is only an extension of the main Dockerfile to 12 | # show how data can be copied into the container, instead of 13 | # mounting it at execution time. 14 | COPY . /workspace 15 | 16 | # CMD/ENTRYPOINT can stay the same 17 | 18 | # Execute the following commands _in the directory of this file_ to build and execute a self-contained image: 19 | # BUILD COMMAND: docker build -t qgis-model-example . 20 | # RUN COMMAND: docker run --rm -it qgis-model-example 21 | -------------------------------------------------------------------------------- /examples/geospatial-python-qgis-model-workflow/README.md: -------------------------------------------------------------------------------- 1 | # Dockerfile revision example 2 | 3 | This example is based on two Dockerfiles from https://github.com/nuest/docker-qgis-model. 4 | The files are published under the Apache License 2.0, are presented/used in a [peer reviewed publication](https://doi.org/10.3390/rs9030290), and are archived [on Zenodo](https://doi.org/10.5281/zenodo.168370) together with the actual image files. 5 | 6 | The Docker image captures a complex and intricate combination of specific versions of a number of open source tools for Geospatial Object Based Image Analysis (GEOBIA). 7 | 8 | ## Review and changes 9 | 10 | - Re-integrate two images into one: the multiple options are by now an artifact of the creation process, but can be simplified for the actual use. 11 | - Base image: https://github.com/nuest/docker-qgis-model/blob/master/ubuntu/Dockerfile.xenial 12 | - Derived image: https://github.com/nuest/docker-qgis-model/blob/master/workspace/example/Dockerfile 13 | - Remove `MAINTAINER` and add `LABEL` with additional metadata, at the end of the Dockerfile 14 | - Explicitly mention the image registry (i.e., starting image name with `docker.io/`) 15 | 16 | Note the image must be built in the directory `docker-qgis-model/workspace/example/`: 17 | 18 | ```bash 19 | git clone https://github.com/nuest/docker-qgis-model.git 20 | docker build --tag qgis-model-ten-rules --file Dockerfile docker-qgis-model/workspace/example/ 21 | ``` 22 | 23 | The build _does not work_ because of broken packages: 24 | 25 | ``` 26 | E: Unable to correct problems, you have held broken packages. 27 | The command '/bin/sh -c apt-get update && apt-get install -qqy --no-install-recommends gdal-bin python-gdal python-scipy python-numpy python-shapely qgis=$QGIS_VERSION qgis-providers=$QGIS_VERSION python-qgis-common=$QGIS_VERSION python-qgis=$QGIS_VERSION xvfb tree && apt-get clean && rm -rf /var/lib/apt/lists/*' returned a non-zero code: 100 28 | ``` 29 | -------------------------------------------------------------------------------- /examples/microsimulation-model-virus-C++/Dockerfile: -------------------------------------------------------------------------------- 1 | # Dockerfile vor covid-sim analysis https://github.com/mrc-ide/covid-sim 2 | FROM docker.io/debian:buster AS build 3 | 4 | # Install system dependencies, keep in sync with covid-sim/ci/install_dependencies.sh 5 | RUN apt-get update && \ 6 | apt-get install -y cmake make g++ python3 7 | 8 | WORKDIR /src 9 | 10 | COPY . . 11 | 12 | WORKDIR /src/build 13 | 14 | RUN cmake .. \ 15 | && make 16 | 17 | # This allows for building a release without having to potentially re-run the tests. 18 | FROM docker.io/debian:buster-slim AS release 19 | 20 | # Install runtime dependencies. 21 | RUN apt-get update \ 22 | && apt-get install -y --no-install-recommends libgomp1 \ 23 | python3 \ 24 | && apt-get clean -y \ 25 | && apt-get autoremove -y \ 26 | && rm -rf /var/lib/apt/lists/* 27 | 28 | # Copy software from previous build stage 29 | COPY --from=build /src/build/src/CovidSim /usr/bin/. 30 | COPY data /data/input 31 | 32 | # Run the model by default 33 | ENTRYPOINT ["/usr/bin/CovidSim"] 34 | 35 | # Use a multi-stage build phase to run the tests of the previously installed software 36 | FROM build AS test 37 | 38 | WORKDIR /src/build 39 | 40 | ARG SKIP_TESTS="" 41 | RUN if [ -z ${SKIP_TESTS} ] ; then \ 42 | pwd \ 43 | && ls -l \ 44 | && make test ARGS="-V" ; \ 45 | else echo 'Skipping tests!' ; fi 46 | 47 | # This ensures that the default behavior is to run the tests and then create a release 48 | FROM release 49 | 50 | LABEL maintainer="Matthew Gretton-Dann" \ 51 | org.opencontainers.image.authors="https://github.com/mrc-ide/covid-sim/graphs/contributors" \ 52 | org.opencontainers.image.url="https://github.com/mrc-ide/covid-sim" 53 | 54 | ### Build (including execution of tests, ~ 15 minutes of build time) 55 | # docker build --tag covid-sim:$(git rev-parse --short HEAD) . 56 | ### Build (skipping tests) 57 | # docker build --tag covid-sim:$(git rev-parse --short HEAD) --build-arg SKIP_TESTS=1 . 58 | ### Run sample script 59 | # docker run --rm -it --entrypoint /bin/bash covid-sim:92fa33a ./data/input/run_sample.py United_Kingdom 60 | -------------------------------------------------------------------------------- /examples/microsimulation-model-virus-C++/Dockerfile.original: -------------------------------------------------------------------------------- 1 | FROM debian:stable AS build 2 | 3 | WORKDIR /src 4 | 5 | COPY . . 6 | 7 | RUN mkdir -p build \ 8 | && ./ci/install_dependencies.sh 9 | 10 | WORKDIR /src/build 11 | 12 | RUN cmake .. \ 13 | && make 14 | 15 | # This allows for building a release without having to potentially re-run the tests. 16 | FROM debian:stable-slim AS release 17 | 18 | # Install runtime dependencies. 19 | RUN apt-get update \ 20 | && apt-get install -y --no-install-recommends libgomp1 \ 21 | && apt-get clean -y \ 22 | && apt-get autoremove -y \ 23 | && rm -rf /var/lib/apt/lists/* 24 | 25 | COPY --from=build /src/build/src/CovidSim /usr/bin/. 26 | COPY data /data/input 27 | 28 | ENTRYPOINT ["/usr/bin/CovidSim"] 29 | 30 | FROM build AS test 31 | 32 | WORKDIR /src/build 33 | 34 | RUN pwd \ 35 | && ls -l \ 36 | && make test ARGS="-V" 37 | 38 | # This ensures that the default behavior is to run the tests and then create a release 39 | FROM release 40 | -------------------------------------------------------------------------------- /examples/microsimulation-model-virus-C++/README.md: -------------------------------------------------------------------------------- 1 | # Dockerfile revision example 2 | 3 | The original Dockerfile from https://github.com/mrc-ide/covid-sim/blob/master/Dockerfile is authored by members of the MRC Centre for Global Infectious Disease Analysis and published under GNU General Public License v3.0. 4 | See the project README.md for [details on licensing](https://github.com/mrc-ide/covid-sim#copyright-and-licensing). 5 | 6 | This Dockerfile does some nice tricks with a multi-stage build. 7 | Note the Dockerfile needs to be built with the wording directory in the original source repository, and that the sample script does not run successfully. 8 | 9 | ```bash 10 | git clone https://github.com/mrc-ide/covid-sim 11 | docker build --tag covid-sim-ten-simple --file Dockerfile covid-sim/ 12 | ``` 13 | 14 | ## Review and changes 15 | 16 | - The original Dockerfile uses a multi-stage build, which I kept, though the size reduction between `debian` and `debian..-slim` is probably not crazy. 17 | - Use named version of Debian release, `debian:buster` 18 | - Explicitly mention the image registry (i.e., starting image name with `docker.io/`) 19 | - Added more documentation, e.g., link to GitHub repo 20 | - The external file `install_dependencies.sh` is used to flexibly install required system dependencies across many platforms, which is a reasonable requirement given the use case; however, for a more transparent data science workflow, I'll follow the rules and integrated the two lines of code matching the used Linux distro. 21 | - Moved the system dependency installation before the copy step (only works because of previous change) 22 | - The multi-stage build nicely takes advantage of running tests as part of the build and then falling back to the configuration of the `release` stage > kept in the example though it adds complexity and build time 23 | - Added a buil argument to skip tests, so the image becomes easier to rebuild and could be used for the actual development of the workflow, not just for documentation/demonstration 24 | - Added labels 25 | - Added usage instructions 26 | -------------------------------------------------------------------------------- /examples/pass-parameter-env/README.md: -------------------------------------------------------------------------------- 1 | # Docker run example 2 | 3 | Passing a parameter to a running container via an environment variable. 4 | 5 | Open a terminal and type 6 | 7 | ```bash 8 | ./run.sh 9 | ``` 10 | 11 | Note that for this simple task, we don't follow all rules and use an image tagged `latest`. 12 | 13 | Your output should be similar to the following example execution: 14 | 15 | ```bash 16 | daniel@nuest ~/git/ten-simple-rules-dockerfiles/examples/pass-parameter-env [master]$ ./run.sh 17 | > l = length(readLines(Sys.getenv('CONFIG_PARAM'))); print(paste('Number of lines: ', l)) 18 | [1] "Number of lines: 833" 19 | > 20 | ``` 21 | -------------------------------------------------------------------------------- /examples/pass-parameter-env/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | docker run \ 3 | --env CONFIG_PARAM="/data/ten-simple-rules-dockerfiles.Rmd" \ 4 | --volume $(pwd)/../..:/data \ 5 | docker.io/nuest/ten-simple-rules-dockerfiles:latest \ 6 | R --quiet -e "l = length(readLines(Sys.getenv('CONFIG_PARAM'))); print(paste('Number of lines: ', l))" 7 | -------------------------------------------------------------------------------- /examples/spatial-statistics-R/Dockerfile: -------------------------------------------------------------------------------- 1 | ## Dockerfile for the following paper: 2 | ## 3 | ## Bivariate spatial point patterns in the retina: a reproducible 4 | ## review. Journal de la Société Française de Statistique 157:33–48. 5 | ## 6 | ## Home page for project: 7 | 8 | FROM rocker/verse:3.6.3 9 | LABEL maintainer = "Stephen Eglen " 10 | RUN Rscript -e 'install.packages(c("splancs", "spatstat", "knitr", "xtable"))' 11 | RUN Rscript -e 'install.packages(c("sjedmin", "sjedrp", "sjevor","sjedist"), type="source", contriburl="http://damtp.cam.ac.uk/user/eglen/r/")' 12 | 13 | 14 | ## RUN Rscript -e 'devtools::install_github("sje30/eglen2015")' 15 | USER rstudio 16 | ENV PROJ /home/rstudio/ 17 | WORKDIR $PROJ 18 | RUN git clone https://github.com/sje30/eglen2015 19 | WORKDIR $PROJ/eglen2015 20 | RUN make install 21 | 22 | 23 | ## --- Building --- 24 | ## docker build -t sje30/eglen2015 . 25 | 26 | ## --- Linting --- 27 | ## To lint this file (also as "make dockerfile-lint"): 28 | ## docker run --rm -i hadolint/hadolint < Dockerfile 29 | 30 | ## --- Running --- 31 | ## This dockerfile is on dockerhub, so the following should "just work": 32 | ## docker run --rm -p 8787:8787 -e PASSWORD=simple sje30/eglen2015 33 | ## 34 | ## If you are on linux, you can then visit http://localhost:8787 35 | ## 36 | ## On windows and mac, you first need to find the IP address which is given by: 37 | ## docker-machine ip 38 | ## and should be something like 192.168.99.100 39 | ## from there you can open http://192.168.99.100:8787 40 | ## 41 | ## To login, the username is "rstudio" and the password is "simple" 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /examples/spatial-statistics-R/Dockerfile.before: -------------------------------------------------------------------------------- 1 | FROM rocker/verse 2 | MAINTAINER Stephen Eglen 3 | ## RUN apt-get update -y && apt-get install -y texlive-base 4 | ## texlive-bibtex-extra lmodern 5 | RUN Rscript -e 'install.packages(c("splancs", "spatstat", "knitr", "xtable"))' 6 | RUN Rscript -e 'install.packages(c("sjedmin", "sjedrp", "sjevor","sjedist"), type="source", contriburl="http://damtp.cam.ac.uk/user/eglen/r/")' 7 | 8 | 9 | ## RUN Rscript -e 'devtools::install_github("sje30/eglen2015")' 10 | USER rstudio 11 | ENV PROJ /home/rstudio/ 12 | WORKDIR $PROJ 13 | RUN git clone https://github.com/sje30/eglen2015 14 | WORKDIR $PROJ/eglen2015 15 | ## USER root 16 | RUN make install 17 | 18 | 19 | ## To rebuild: 20 | ## docker build -t sje30/eglen2015 https://raw.githubusercontent.com/sje30/eglen2015/master/Dockerfile 21 | ## or to rebuild locally 22 | ## docker build -t sje30/eglen2015 . 23 | 24 | ## may need to run as if we get permission errors in the Dockerfile... 25 | ## docker run -d -p 8787:8787 -e ROOT=TRUE sje30/eglen2015 26 | 27 | 28 | ## texlive-bibtex-extra is required for the breakcites.sty package 29 | ## which in turn is needed by the JSFDS package. 30 | 31 | ## 2018-08-05 32 | ## Since writing the Dockerfile in 2016, rocker/verse has switched to 33 | ## using the new "tinytex" package for installing latex packages on 34 | ## the fly. On the plus-side, it means that I don't need to tweak 35 | ## with the latex to get extra packages. Another bonus is that when 36 | ## running e.g. knit2pdf() if there are latex style files missing, 37 | ## they are automatically downloaded by R . The downside is that the 38 | ## downloading of the style files takes a few minutes... 39 | 40 | ## I'm also not quite sure why I need to have the "USER root" line... 41 | ## and so I need to check why this is? By default it seems that rstudio 42 | ## should have write access to the /opt/tinytex area, but see error below when running as rstudio user 43 | 44 | 45 | 46 | 47 | ## lmgr search --file --global '/helvet.sty' 48 | ## Trying to automatically install missing LaTeX packages... 49 | ## tlmgr install psnfss 50 | ## tlmgr: package repository http://mirror.utexas.edu/ctan/systems/texlive/tlnet (not verified: gpg unavailable) 51 | ## [1/1, ??:??/??:??] install: psnfss [12k] 52 | ## copy /opt/TinyTeX/tlpkg/texlive.tlpdb.tmp to /opt/TinyTeX/tlpkg/texlive.tlpdb failed: Operation not permitted at /opt/TinyTeX/tlpkg/TeXLive/TLPDB.pm line 628. 53 | ## tlmgr update --self 54 | -------------------------------------------------------------------------------- /examples/spatial-statistics-R/README.md: -------------------------------------------------------------------------------- 1 | # Spatial statistics 2 | 3 | This Dockerfile came from a repository that I used to create what I 4 | called "a reproducible review", i.e. it is a review manuscript but 5 | where most of the figures are actively generated rather than simply 6 | being copied from previous papers. (The first figure is a drawing of the 7 | retina, and so is simply included, but all other figures are generated 8 | by running code in the project.) 9 | 10 | ## Review and changes 11 | 12 | - The version of the "verse" from rocker is specified. 13 | - The deprecated MAINTAINER field was replaced by a label. 14 | - Most comments in the original referred to older versions of the 15 | Dockerfile. These comments have been removed. 16 | - New comments have been added to better reflect our guidelines, 17 | describing how to use the container, and how to lint the file. 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /examples/spatial-subsampling-marine-inverts-R/Dockerfile: -------------------------------------------------------------------------------- 1 | # Written by Roger A. Close to accompany analysis R code for Close et al. (in review) The spatial structure of Phanerozoic marine animal diversity. 2 | # Paper: https://doi.org/10.1126/science.aay8309 3 | FROM docker.io/rocker/rstudio:3.6.0 4 | 5 | # Install system dependencies for R packages, including spatial packages and Java 6 | RUN apt-get update && apt-get install -y \ 7 | r-cran-ncdf4 \ 8 | netcdf-* \ 9 | libnetcdf-dev \ 10 | libproj-dev \ 11 | default-jre \ 12 | default-jdk \ 13 | libxml2-* \ 14 | libmagick++-dev \ 15 | libgdal-dev libproj-dev libgeos-dev \ 16 | lbzip2 \ 17 | nano \ 18 | && rm -rf /var/lib/apt/lists/* 19 | 20 | # Make sure R finds the Java installation 21 | RUN R CMD javareconf 22 | 23 | LABEL maintainer="Roger Close " \ 24 | org.opencontainers.image.authors="R. A. Close, R. B. J. Benson, E. E. Saupe, M. E. Clapham, J. Butler" \ 25 | org.opencontainers.image.url="https://science.sciencemag.org/content/suppl/2020/04/22/368.6489.420.DC1" \ 26 | org.opencontainers.image.documentation="The spatial structure of Phanerozoic marine animal diversity " \ 27 | org.opencontainers.image.description="Reproducible workflow image, details in README.md" \ 28 | author.orcid="https://orcid.org/0000-0003-3302-9902" 29 | 30 | ### Build 31 | # docker build --tag phanerozoic-diversity . 32 | 33 | ### Run interactively with RStudio 34 | # docker run --rm -it -p 8787:8787 -v $(pwd)/spatial-subsampling-marine-inverts:/home/rstudio/spatial-subsampling-marine-inverts -e USERID=$UID -e PASSWORD=phanerozoic phanerozoic-diversity 35 | # Go to localhost:8787, login, open and execute run-master-script.R 36 | 37 | ### Run process only container 38 | # docker run -it -v $(pwd)/spatial-subsampling-marine-inverts:/home/rstudio/ phanerozoic-diversity Rscript --vanilla /home/rstudio/run-master-script.R 39 | # Extract results from container using container ID and docker copy 40 | 41 | # See README.md for details. 42 | -------------------------------------------------------------------------------- /examples/spatial-subsampling-marine-inverts-R/Dockerfile.original: -------------------------------------------------------------------------------- 1 | # Written by Roger A. Close to accompany analysis R code for Close et al. (in review) The spatial structure of Phanerozoic marine animal diversity. 2 | 3 | FROM rocker/rstudio:3.6.0 4 | 5 | RUN apt-get update && apt-get install -y \ 6 | r-cran-ncdf4 \ 7 | netcdf-* \ 8 | libnetcdf-dev \ 9 | libproj-dev \ 10 | default-jre \ 11 | default-jdk \ 12 | libxml2-* \ 13 | libmagick++-dev \ 14 | libgdal-dev libproj-dev libgeos-dev \ 15 | lbzip2 \ 16 | nano \ 17 | && rm -rf /var/lib/apt/lists/* 18 | 19 | RUN R CMD javareconf 20 | -------------------------------------------------------------------------------- /examples/spatial-subsampling-marine-inverts-R/README.md: -------------------------------------------------------------------------------- 1 | # Dockerfile revision example 2 | 3 | This Dockerfile was published as part of a large (> 2 GB) supplemental material packages at https://science.sciencemag.org/content/suppl/2020/04/22/368.6489.420.DC1 for the report [The spatial structure of Phanerozoic marine animal diversity](https://science.sciencemag.org/content/368/6489/420.full) published in Science. 4 | 5 | The Dockerfile and the documentation are already in a very good state, including estimates for execution time given example hardware and how to reduce execution time. 6 | Only small changes were made: 7 | 8 | - Add commmands from README to the file to the end of the Dockerfile 9 | - Using more unique name for image 10 | - Use long version of build parameters 11 | - Adjust instructions to match the folder structure found in the ZIP archive from the supplemental material 12 | - Add a few more docs 13 | - Add `LABEL`s 14 | - Add examples for running just the process 15 | 16 | Build and execute container: 17 | 18 | ```bash 19 | # 1. Download and unzip https://science.sciencemag.org/highwire/filestream/743688/field_highwire_adjunct_files/1/aay8309_DataS1.zip 20 | # 2. Build the Dockerfile, see docs at the end of Dockerfile 21 | # 3. Go to directory ../aay8309_DataS1/Code-for-Close-et-al-The-spatial-structure-of-Phanerozoic-marine-animal-diversity/ 22 | ``` -------------------------------------------------------------------------------- /examples/teaching-vm_openrefine/Dockerfile: -------------------------------------------------------------------------------- 1 | # Integrated example for the Ten Simple Rules for Dockerfiles project, 2 | # see https://osf.io/fsd7t/ 3 | # This Dockerfile is a rewrite based on 4 | # - https://github.com/innovationOUtside/tm351vm/blob/master/build/minimal/Dockerfile 5 | # - https://github.com/innovationOUtside/tm351vm/blob/master/build/openrefine/Dockerfile 6 | FROM docker.io/ubuntu:16.04 7 | 8 | RUN apt-get update && \ 9 | apt-get upgrade -y && \ 10 | apt-get install -y \ 11 | # required for installation of OpenRefine 12 | wget \ 13 | ant \ 14 | unzip \ 15 | openjdk-8-jre-headless && \ 16 | apt-get purge && \ 17 | apt-get clean -y && \ 18 | rm -rf /var/lib/apt/lists/* 19 | 20 | # Download and unpack OpenRefine ((https://openrefine.org/) to /opt/openrefine-x.y, then delete the downloaded archive 21 | ENV OPENREFINE_VERSION="3.2" 22 | # other versions: 2.8, 3.0-beta 23 | ENV OPENREFINEGZ="openrefine-linux-${OPENREFINE_VERSION}.tar.gz" \ 24 | OPENREFINESRC="https://github.com/OpenRefine/OpenRefine/releases/download/${OPENREFINE_VERSION}/openrefine-linux-${OPENREFINE_VERSION}.tar.gz" 25 | RUN wget -q --no-check-certificate -P /tmp $OPENREFINESRC && \ 26 | tar -xzf /tmp/$OPENREFINEGZ -C /opt && \ 27 | rm /tmp/$OPENREFINEGZ 28 | 29 | # Create working directly and expose it as a volume 30 | WORKDIR /openrefine_projects 31 | VOLUME /openrefine_projects 32 | 33 | LABEL maintainer="tony.hirst@gmail.com" \ 34 | org.opencontainers.image.authors="Tony Hirst" \ 35 | org.opencontainers.image.url="https://github.com/innovationOUtside/tm351vm" 36 | 37 | # Default command runs OpenRefine on the exposed port 38 | ENV OPENREFINE_PORT 3334 39 | EXPOSE ${OPENREFINE_PORT} 40 | CMD ["sh", "-c", "/opt/openrefine-${OPENREFINE_VERSION}/refine -p ${OPENREFINE_PORT} -i 0.0.0.0 -d /openrefine_projects"] 41 | 42 | # Usage instructions: 43 | # docker build --tag tensimpleexamples:openrefine . 44 | # docker run --rm -it -p 3334:3334 tensimpleexamples:openrefine 45 | # > open your browser at localhost with the port shown in the command line 46 | -------------------------------------------------------------------------------- /examples/teaching-vm_openrefine/Dockerfile.original: -------------------------------------------------------------------------------- 1 | #docker build --rm -t psychemedia/ou-tm351-openrefine-test . 2 | #docker build --rm --build-arg BASE=etc -t psychemedia/ou-tm351-openrefine-test . 3 | 4 | ARG BASE=psychemedia/ou-tm351-minimal-test 5 | # Base machine 6 | FROM ${BASE} 7 | 8 | MAINTAINER tony.hirst@gmail.com 9 | 10 | ENV DOCKERBUILD 1 11 | 12 | 13 | #Build OpenRefine 14 | ADD openrefine.sh /tmp/openrefine/openrefine.sh 15 | ADD root /tmp/openrefine/root 16 | 17 | RUN /tmp/openrefine/openrefine.sh 18 | RUN rm -rf /tmp/openrefine 19 | 20 | EXPOSE 3334 21 | 22 | RUN mkdir -p /openrefine_projects 23 | RUN chown oustudent:100 /openrefine_projects 24 | 25 | VOLUME /openrefine_projects 26 | 27 | CMD su - oustudent -c "/opt/openrefine-3.0-beta/refine -p 3334 -i 0.0.0.0 -d /openrefine_projects" -------------------------------------------------------------------------------- /examples/teaching-vm_openrefine/README.md: -------------------------------------------------------------------------------- 1 | # Teaching VM 2 | 3 | This Dockerfile is used for distributing and deploying a teaching environment as part of the course [TM351 at The Open University](http://www.open.ac.uk/courses/modules/tm351) on data management and data analytics. 4 | It was authored by Tony Hirst [@psychemedia](https://github.com/psychemedia)). 5 | License information is currently missing (see [related issue](https://github.com/innovationOUtside/tm351vm/issues/30)). 6 | 7 | ## Review and changes 8 | 9 | - The Dockerfile was based on a self-managed "minimal" base image, see [base Dockerfile](Base image: https://github.com/innovationOUtside/tm351vm/blob/master/build/minimal/Dockerfile), which was actually not that long, so I reintegrated them 10 | - Explicitly mention the image registry (i.e., starting image name with `docker.io/`) 11 | - Replace the deprecated `MAINTAINER` instruction 12 | - Remove `apt-get autoremove` commands at beginning of base image 13 | - use `COPY` instead of `ADD` for adding files to the image because of clearer semantics 14 | - Put cleanup of OpenRefine installation in the same layer as the installation itself 15 | - Use `WORKDIR` instead of `RUN mkdir -p` because of clearer semantics 16 | - Use an `ENV` for the exposed port, move exposed port closer to the command running the tool behind the port 17 | - Remove `--rm` from `docker build` commands, as it is the default 18 | - Use long argument form `--tag` in usage instructions 19 | - Integrate the [OpenRefine installation script `openrefine.sh`](https://github.com/innovationOUtside/tm351vm/blob/master/build/openrefine/openrefine.sh) (see local copy of file) because once the "not a Docker build" option was removed, the echo statements were left out, an chown with an non-existing user `$OPENREFINE_USER` was left out, the `openrefine.done` hack was skipped, and the mkdir statements of already existing directories were skipped... not that much code was left; _IMO:_ this script suffered from the dual use outside and inside a container, or more likely dual use for Vagrant and Docker 20 | - Add `OPENREFINE_VERSION` as `ENV` so that version is only defined in one spot, there even was a mismatch between the downloaded version and the one in `CMD` (inconsistency between `openrefine.sh` and `Dockerfile.original`) 21 | - Move all system dependencies into one layer, used more extensive cleaning up commands for apt-get 22 | - Skip installation of `apt-show-versions`, since undocumented and usage unclear; `dpkg -l` still available in the container 23 | - Use default USER, though potentially the `oustudent` users with id `100` is really needed for the image to be deployed in the target infrastructure, see also [`settings.sh`](https://github.com/innovationOUtside/tm351vm/blob/master/build/base/settings.sh) in the repo 24 | - Use `WORKDIR` instead of `mkdir -p` for working directory 25 | - Don't download to `/root` (may cause problems if ported to Singularity) 26 | -------------------------------------------------------------------------------- /examples/teaching-vm_openrefine/openrefine.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | THISDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 3 | 4 | #DEBUG TOOLS 5 | #systemctl list-units | grep refine 6 | #journalctl -u refine.service 7 | 8 | # OpenRefine installer script 9 | 10 | apt-get update && 11 | apt-get install -y wget ant unzip openjdk-8-jre-headless && 12 | apt-get clean -y 13 | 14 | #OPENREFINEGZ="openrefine-linux-2.8.tar.gz" 15 | #OPENREFINESRC="https://github.com/OpenRefine/OpenRefine/releases/download/2.8/openrefine-linux-2.8.tar.gz" 16 | #OPENREFINEGZ="openrefine-linux-3.0-beta.tar.gz" 17 | #OPENREFINESRC="https://github.com/OpenRefine/OpenRefine/releases/download/3.0-beta/openrefine-linux-3.0-beta.tar.gz" 18 | OPENREFINEGZ="openrefine-linux-3.2.tar.gz" 19 | OPENREFINESRC="https://github.com/OpenRefine/OpenRefine/releases/download/3.2/openrefine-linux-3.2.tar.gz" 20 | 21 | OPENREFINE_DIR=/vagrant/openrefine_projects 22 | mkdir -p $OPENREFINE_DIR 23 | chown $OPENREFINE_USER:$OPENREFINE_GID $OPENREFINE_DIR 24 | 25 | echo "" 26 | echo "" 27 | echo "**************************************************************" 28 | echo "************* Setting up OpenRefine *************" 29 | echo "**************************************************************" 30 | echo "" 31 | echo "" 32 | 33 | #Prep for download 34 | mkdir -p /opt 35 | mkdir -p /root 36 | 37 | if [ ! -f /opt/openrefine.done ]; then 38 | echo "Downloading OpenRefine..." 39 | if [ ! -f $THISDIR/root/$OPENREFINEGZ ]; then 40 | /usr/bin/wget -q --no-check-certificate -P /root $OPENREFINESRC 41 | else 42 | cp $THISDIR/root/$OPENREFINEGZ /root/$OPENREFINEGZ 43 | fi 44 | echo "...downloaded OpenRefine" 45 | 46 | echo "Unpacking OpenRefine..." 47 | tar -xzf /root/$OPENREFINEGZ -C /opt && rm /root/$OPENREFINEGZ 48 | #Unpacks to: /opt/openrefine-2.7 49 | touch /opt/openrefine.done 50 | echo "...unpacked OpenRefine" 51 | else 52 | echo "...already downloaded and unpacked OpenRefine" 53 | fi 54 | 55 | 56 | #If not the Docker build, set up the services 57 | #Note - the correct path needs to be set in the .service definition files 58 | if [[ -z "${DOCKERBUILD}" ]]; then 59 | 60 | if [[ -z "${AUTHBUILD}" ]]; then 61 | cp $THISDIR/services/refine.service /lib/systemd/system/refine.service 62 | else 63 | cp $THISDIR/services/refine_auth.service /lib/systemd/system/refine.service 64 | fi 65 | 66 | # Enable autostart 67 | systemctl enable refine.service 68 | 69 | # Refresh service config 70 | systemctl daemon-reload 71 | 72 | #(Re)start service 73 | systemctl restart refine.service 74 | fi 75 | 76 | 77 | echo "" 78 | echo "" 79 | echo "**************************************************************" 80 | echo "************* DONE: setting up OpenRefine *************" 81 | echo "**************************************************************" 82 | echo "" 83 | echo "" -------------------------------------------------------------------------------- /examples/text-analysis-wordclouds_R-Binder/Dockerfile: -------------------------------------------------------------------------------- 1 | # This Dockerfile is based on the rocker/binder example Dockerfile from https://github.com/rocker-org/binder/ 2 | # We use 3.6.0 because it is a recent version of R that has a fixed MRAN date in the Rocker image. 3 | # The used MRAN URL is: https://mran.microsoft.com/snapshot/2019-07-05 4 | FROM docker.io/rocker/binder:3.6.0 5 | 6 | ## Declares build arguments 7 | ARG NB_USER 8 | ARG NB_UID 9 | 10 | # Install system dependency for pdftools 11 | USER root 12 | RUN apt-get update \ 13 | && apt-get install -y --no-install-recommends \ 14 | libpoppler-cpp-dev \ 15 | && apt-get clean \ 16 | && rm -rf /var/lib/apt/lists/ 17 | 18 | ## Run install.R script, which installs required R packages and LaTeX packages via tinytex 19 | COPY install.R ${HOME} 20 | RUN R --quiet -f install.R 21 | 22 | ## Copies all repo files into the Docker Container into the home directory configured in the base image 23 | COPY . ${HOME} 24 | RUN chown -R ${NB_USER} ${HOME} 25 | 26 | ## Become normal user again 27 | USER ${NB_USER} 28 | 29 | ## Export system libraries and R package versions 30 | RUN dpkg --list > dpkg-list.txt && \ 31 | R -e 'capture.output(knitr::kable(as.data.frame(installed.packages())[c("Package", "Version", "License", "Built")], format = "markdown", row.names = FALSE), file = "r-packages.md")' 32 | 33 | # --- Metadata --- 34 | LABEL maintainer="daniel.nuest@uni-muenster.de" \ 35 | Name="Reproducible research at GIScience - computing environment" \ 36 | org.opencontainers.image.created="2020-04" \ 37 | org.opencontainers.image.authors="Daniel Nüst" \ 38 | org.opencontainers.image.url="https://github.com/nuest/reproducible-research-at-giscience/blob/master/Dockerfile" \ 39 | org.opencontainers.image.documentation="https://github.com/nuest/reproducible-research-at-giscience/" \ 40 | org.opencontainers.image.licenses="Apache-2.0" \ 41 | org.label-schema.description="Reproducible workflow image (license: Apache 2.0)" 42 | 43 | # --- Development instructions --- 44 | # From time to time, run a linter on the Dockerfile: 45 | # $ docker run -it --rm --privileged -v $PWD:/root/ projectatomic/dockerfile-lint dockerfile_lint 46 | 47 | 48 | # --- Usage instructions --- 49 | ## Build the image 50 | # $ docker build --tag rr-giscience . 51 | # 52 | ## Run the image for interactive UI 53 | # $ docker run -it -p 8888:8888 rr-giscience 54 | # Next, open a browser at http://localhost:8888 or click on the login link shown in the console. 55 | # It will show the Jupyter start page and you can now open RStudio via the menu "New". 56 | # 57 | ## Run the image to render the PDF for the assessment figures or the text analysis 58 | # $ docker run -i -v $(pwd):/giscience --user $UID rr-giscience Rscript -e 'setwd("/giscience"); rmarkdown::render("giscience-reproducibility-assessment.Rmd")' 59 | # $ docker run -i -v $(pwd):/giscience --user $UID rr-giscience Rscript -e 'setwd("/giscience"); rmarkdown::render("giscience-historic-text-analysis.Rmd")' 60 | -------------------------------------------------------------------------------- /examples/text-analysis-wordclouds_R-Binder/Dockerfile.original: -------------------------------------------------------------------------------- 1 | FROM rocker/binder:3.4.3 2 | 3 | # Install system dependency for pdftools 4 | USER root 5 | RUN apt-get update \ 6 | && apt-get install -y --no-install-recommends \ 7 | libpoppler-cpp-dev \ 8 | && apt-get clean \ 9 | && rm -rf /var/lib/apt/lists/ 10 | 11 | # Copy repo into ${HOME}, make user own $HOME 12 | USER root 13 | COPY . ${HOME} 14 | RUN chown -R ${NB_USER} ${HOME} 15 | 16 | # Configure current MRAN mirror, based on https://github.com/rocker-org/rocker-versioned/blob/master/r-ver/Dockerfile 17 | # (append /etc/environment and Rprofile, latest statement matters) 18 | ENV MRAN=https://mran.microsoft.com/snapshot/2018-05-23 19 | RUN echo MRAN=$MRAN >> /etc/environment \ 20 | && export MRAN=$MRAN \ 21 | && echo "options(repos = c(CRAN='$MRAN'), download.file.method = 'libcurl')" >> /usr/local/lib/R/etc/Rprofile.site 22 | 23 | # return back to regular user 24 | USER ${NB_USER} 25 | 26 | # run any install.R script we find 27 | RUN if [ -f install.R ]; then R --quiet -f install.R; fi 28 | -------------------------------------------------------------------------------- /examples/text-analysis-wordclouds_R-Binder/README.md: -------------------------------------------------------------------------------- 1 | # Dockerfile revision example 2 | 3 | The original Dockerfile from https://github.com/nuest/reproducible-research-and-giscience/blob/master/Dockerfile and is authored by me, Daniel Nüst ([@nuest](https://github.com/nuest/)), and published under the Apache License 2.0. 4 | The workflow is part of a [peer reviewed publication](https://doi.org/10.7717/peerj.5072) and uses a Binder base image to run RStudio in a browser. 5 | Binder's `install.R` file is used to install required dependencies and the base image includes already a number of required R packages, including the Tidyverse packages, and a LaTeX installation using `tinytex`, which is needed to create the manuscript output as LaTeX. 6 | 7 | ## Review and changes 8 | 9 | - The original Dockerfile did not have usage instructions, which were only in the projects [README.md](https://github.com/nuest/reproducible-research-and-giscience/blob/master/README.md) 10 | - Explicitly mention the image registry (i.e., starting image name with `docker.io/`) 11 | - Some reasoning behind instructions was not explained well 12 | - The base image version changed because 13 | - I removed the explicit setting of the MRAN date, instead relying on the MRAN date already specified in the base image, which was obtained with `docker run --rm -it rocker/binder:3.6.0 Rscript -e 'options("repos")` 14 | - The `install.R` file is present, I know that, so the `if [ -f install.R ];` check that was copied over from a more generic Binder-created Dockerfile could be removed to simplify the instruction 15 | -------------------------------------------------------------------------------- /examples/text-analysis-wordclouds_R-Binder/install.R: -------------------------------------------------------------------------------- 1 | cat("Dummy install.R file so the revised Dockerfile can be built") 2 | -------------------------------------------------------------------------------- /examples/vcn_regularity-python/Dockerfile: -------------------------------------------------------------------------------- 1 | # Originally written by Dan Goodman (@thesamovar) to make interactive models to accompany: 2 | # "Modelling firing regularity in the ventral cochlear nucleus: mechanisms, and effects of stimulus level and synaptopathy" (Goodman et al. 2017). 3 | # Paper: https://doi.org/10.1016/j.heares.2017.09.010 4 | FROM docker.io/jupyter/scipy-notebook:82b978b3ceeb 5 | 6 | # Copy notebooks and data into the image and set permissions 7 | # N.B. Mount arguments can not be used with Binder so all necessary files must 8 | # be included in the image build process 9 | USER root 10 | COPY ./ /home/jovyan/ 11 | RUN chown -R jovyan /home/jovyan 12 | # Switch back to unprivileged user and set working directory 13 | USER jovyan 14 | WORKDIR $HOME 15 | 16 | RUN conda config --add channels brian-team 17 | RUN conda remove --yes -n root ipaddress jupyterhub 18 | RUN conda env update -v -n root -f environment.yml 19 | 20 | # Install and configure nbextensions 21 | RUN jupyter nbextension enable --py widgetsnbextension 22 | RUN conda install --quiet --yes jupyter_contrib_nbextensions==0.3.3 23 | RUN jupyter nbextension enable hide_input_all/main 24 | 25 | # Trust notebooks 26 | RUN find "$HOME/" -name '*.ipynb' -exec jupyter trust {} \; 27 | 28 | # Set matplotlib backend 29 | RUN mkdir -p "/home/${NB_USER}/.config/matplotlib" 30 | RUN echo "backend : Agg" > "/home/${NB_USER}/.config/matplotlib/matplotlibrc" 31 | 32 | # Fix matplotlib font cache 33 | RUN rm -rf /home/main/.matplolib 34 | RUN rm -rf /home/main/.cache/matplolib 35 | RUN rm -rf /home/main/.cache/fontconfig 36 | RUN python -c "import matplotlib.pyplot as plt" 37 | 38 | # --- Metadata --- 39 | LABEL maintainer="d.goodman@imperial.ac.uk" \ 40 | Name="Modelling of firing regularity of VCN cells" \ 41 | org.opencontainers.image.created="2020-06" \ 42 | org.opencontainers.image.authors="Dan Goodman" \ 43 | org.opencontainers.image.url="https://github.com/neural-reckoning/vcn_regularity/blob/master/Dockerfile" \ 44 | org.opencontainers.image.documentation="https://github.com/neural-reckoning/vcn_regularity/" \ 45 | org.label-schema.description="Reproducible Binder image (license: MIT)" 46 | 47 | # Print out all packages in environment 48 | RUN conda list --explicit 49 | 50 | # --- Usage instructions --- 51 | # The Dockerfile is designed to run on the Binder service which can be 52 | # launched by navigating to the following address in a browser: 53 | # https://mybinder.org/v2/gh/neural-reckoning/vcn_regularity/master?filepath=index.ipynb 54 | 55 | ## Build the image locally 56 | # As an alternative to using Binder, the image can be built locally: 57 | # $ docker build --tag vcn-regularity . 58 | 59 | ## Run the image for interactive UI 60 | # $ docker run -it -p 8888:8888 vcn-regularity 61 | # Next, open a browser at http://localhost:8888 or click on the login link shown in the console. 62 | # It will show the Jupyter notebook start page and you can now open index.ipynb from the list. 63 | -------------------------------------------------------------------------------- /examples/vcn_regularity-python/Dockerfile.original: -------------------------------------------------------------------------------- 1 | FROM jupyter/scipy-notebook:82b978b3ceeb 2 | 3 | USER root 4 | #ADD * /home/jovyan/ 5 | ADD ./ /home/jovyan/ 6 | RUN chown -R jovyan /home/jovyan 7 | USER jovyan 8 | WORKDIR $HOME 9 | 10 | RUN conda config --add channels brian-team 11 | RUN conda remove --yes -n root ipaddress jupyterhub 12 | RUN conda env update -v -n root -f environment.yml 13 | 14 | # Install and configure nbextensions 15 | RUN jupyter nbextension enable --py widgetsnbextension 16 | RUN conda install --quiet --yes jupyter_contrib_nbextensions==0.3.3 17 | #RUN jupyter nbextension enable init_cell/main 18 | RUN jupyter nbextension enable hide_input_all/main 19 | 20 | # Trust notebooks 21 | RUN find $HOME/ -name '*.ipynb' -exec jupyter trust {} \; 22 | 23 | # Set matplotlib backend 24 | RUN mkdir -p /home/${NB_USER}/.config/matplotlib 25 | RUN echo "backend : Agg" > /home/${NB_USER}/.config/matplotlib/matplotlibrc 26 | 27 | # Fix matplotlib font cache 28 | RUN rm -rf /home/main/.matplolib 29 | RUN rm -rf /home/main/.cache/matplolib 30 | RUN rm -rf /home/main/.cache/fontconfig 31 | RUN python -c "import matplotlib.pyplot as plt" -------------------------------------------------------------------------------- /examples/vcn_regularity-python/README.md: -------------------------------------------------------------------------------- 1 | # Dockerfile revision example 2 | 3 | The original Dockerfile from https://github.com/neural-reckoning/vcn_regularity/blob/master/Dockerfile and is authored by Dan Goodman ([@thesamovar](https://github.com/thesamovar)), and published under the MIT License. 4 | The workflow is part of a [peer reviewed publication](https://doi.org/10.1016/j.heares.2017.09.010) and uses an image from the [Jupyter docker stacks](https://jupyter-docker-stacks.readthedocs.io/en/latest/) to run notebook-based interactive models in a browser with the [Binder](https://mybinder.org/) service. 5 | In the original repository, the `environment.yml` file is used to install additional required dependencies, however a dummy file is used here. Consequently, the image does not build (and neither does the original now due to its dependence on deprecated packages). 6 | 7 | ## Review and changes 8 | 9 | - The original Dockerfile did not have usage instructions, which were only in the projects [README.md](https://github.com/neural-reckoning/vcn_regularity/blob/master/README.md) 10 | - Explicitly mention the image registry (i.e., starting image name with `docker.io/`) 11 | - Use double quotes around file paths including variables to prevent globbing and word splitting (conforming to hadolint). 12 | -------------------------------------------------------------------------------- /examples/vcn_regularity-python/environment.yml: -------------------------------------------------------------------------------- 1 | name: root 2 | channels: 3 | - conda-forge 4 | - defaults 5 | - brian-team 6 | dependencies: 7 | - python=2.7 -------------------------------------------------------------------------------- /figures/PLOS-submission.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuest/ten-simple-rules-dockerfiles/be8c87e5604b31144802a9385cdcd6cb5a9a1fa2/figures/PLOS-submission.eps -------------------------------------------------------------------------------- /figures/analogy.drawio: -------------------------------------------------------------------------------- 1 | 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 -------------------------------------------------------------------------------- /figures/analogy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuest/ten-simple-rules-dockerfiles/be8c87e5604b31144802a9385cdcd6cb5a9a1fa2/figures/analogy.png -------------------------------------------------------------------------------- /figures/analogy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 |
Docker
Docker
Container
docker build -t myimg .
docker build -t myimg .
docker run myimg
docker run myimg
C/C++
C/C++
Process
g++ myprog.c -o myprog
g++ myprog.c -o myprog
./myprog
./myprog
Executable
Binary
Executable...
Dockerfile
Dockerfile
Source code
Source code
Image
Image
Layer 1
Layer 1
Layer 2
Layer 2
Layer 3
Layer 3
© Benjamin D. Evans, 2020. This work is released under the CC-BY 4.0 license https://creativecommons.org/licenses/by/4.0/
© Benjamin D. Evans, 2020. This work is released under the CC-BY 4.0 license https:...
Viewer does not support full SVG 1.1
-------------------------------------------------------------------------------- /figures/analogy.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuest/ten-simple-rules-dockerfiles/be8c87e5604b31144802a9385cdcd6cb5a9a1fa2/figures/analogy.tif -------------------------------------------------------------------------------- /figures/summary.drawio: -------------------------------------------------------------------------------- 1 | 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 -------------------------------------------------------------------------------- /figures/summary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuest/ten-simple-rules-dockerfiles/be8c87e5604b31144802a9385cdcd6cb5a9a1fa2/figures/summary.png -------------------------------------------------------------------------------- /figures/summary.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 |
1
1
2
2
3
3
4
4
5
5

Use available tools

Use available tools

Build upon existing images

Build upon existing images

Format for clarity

Format for clarity

Document within the Dockerfile

Document within the Dockerfile

Specify software versions

Specify software versions
6
6

Use version control

Use version control
7
7

Mount datasets at run time

Mount datasets at run time
8
8

Make the image one-click runnable

Make the image one-click runnable
9
9

Order the instructions

Order the instructions
10
10

Regularly use and rebuild containers

Regularly use and rebuild containers
Ten Simple Rules for Writing Dockerfiles for Reproducible Data Science
Ten Simple Rules for Writing Docker...
© Benjamin D. Evans, 2020. This work is released under the CC-BY 4.0 license https://creativecommons.org/licenses/by/4.0/
© Benjamin D. Evans, 2020. This work is released under the CC-BY 4.0 license https://creativecommons.org/licenses/by/4.0/
Viewer does not support full SVG 1.1
-------------------------------------------------------------------------------- /figures/summary.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuest/ten-simple-rules-dockerfiles/be8c87e5604b31144802a9385cdcd6cb5a9a1fa2/figures/summary.tif -------------------------------------------------------------------------------- /plos.csl: -------------------------------------------------------------------------------- 1 | 2 | 317 | -------------------------------------------------------------------------------- /summary.Rmd: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | 1. Use available tools 4 | a. Use ready-made images (e.g. from Docker Hub) 5 | b. Dockerfile generators (e.g. repo2docker) 6 | c. Linters 7 | d. Tools for templating 8 | 2. Build upon existing images 9 | a. Use version-specific tags 10 | b. Publish your own images with version tags 11 | 3. Format for clarity 12 | a. Use indentation, line breaks and unabbreviated arguments 13 | b. Clarity is better than brevity 14 | c. Group related commands 15 | 4. Document within the Dockerfile 16 | a. Add comments explaining the instructions 17 | b. Use labels for metadata 18 | c. Include usage instructions 19 | 5. Specify software versions 20 | a. Pin system library versions 21 | b. Explictly list package versions to install 22 | c. Comment why each is needed 23 | 6. Use version control 24 | a. Use Continuous Integration and automated testing 25 | b. Include scripts (and requirements.txt) in the same repository 26 | 7. Mount datasets at run time 27 | a. Use bind mounts for accessibility 28 | b. Keep large or sensitive datasets out with `.dockerignore` 29 | c. Document expected mounts for external resources 30 | 8. Make the image one-click runnable 31 | a. Set default behaviour with `CMD` and `ENTRYPOINT` 32 | b. Document how to use it interactively 33 | 9. Order the instructions 34 | a. Least --> most changable for caching and fast builds 35 | b. Regularly use `--no-cache` to catch problems 36 | 10. Regularly use and rebuild containers 37 | a. Use the container throughout each project for confidence in your workflow 38 | b. Rebuild every 1-2 weeks to catch problems 39 | c. Provide a `Makefile` or script for convenience 40 | d. Ask a colleague to try it 41 | e. Publicly archive the image used for the publication 42 | -------------------------------------------------------------------------------- /ten-simple-rules-dockerfiles.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: XeLaTeX 14 | 15 | BuildType: Makefile 16 | --------------------------------------------------------------------------------