{"id":13452236,"url":"https://github.com/garethr/multi-stage-build-example","last_synced_at":"2025-04-14T16:10:37.463Z","repository":{"id":50199791,"uuid":"155577923","full_name":"garethr/multi-stage-build-example","owner":"garethr","description":"Example repository to accompany my talk at Velocity 2018","archived":false,"fork":false,"pushed_at":"2022-12-08T01:16:43.000Z","size":54,"stargazers_count":118,"open_issues_count":9,"forks_count":24,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-26T06:51:44.806Z","etag":null,"topics":["cloudbuild","docker","dockerfile","github-actions","knative-build","multi-stage"],"latest_commit_sha":null,"homepage":null,"language":"Makefile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/garethr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-10-31T15:11:43.000Z","updated_at":"2025-03-17T17:50:43.000Z","dependencies_parsed_at":"2023-01-24T02:30:39.159Z","dependency_job_id":null,"html_url":"https://github.com/garethr/multi-stage-build-example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/garethr%2Fmulti-stage-build-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/garethr%2Fmulti-stage-build-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/garethr%2Fmulti-stage-build-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/garethr%2Fmulti-stage-build-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/garethr","download_url":"https://codeload.github.com/garethr/multi-stage-build-example/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246273533,"owners_count":20750904,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cloudbuild","docker","dockerfile","github-actions","knative-build","multi-stage"],"created_at":"2024-07-31T07:01:17.896Z","updated_at":"2025-03-30T03:31:28.024Z","avatar_url":"https://github.com/garethr.png","language":"Makefile","funding_links":[],"categories":["Makefile"],"sub_categories":[],"readme":"# Multi-stage build example for Velocity 2018\n\nThis repository contains a working example for the talk at Velocity 2018 in London on _Advanced Docker image build patterns_. The focus is on the Dockerfile, with other tooling or code included to make that example actually work. The application is written in Python, but hopefully the ideas should be pretty generally applicable. The Makefile is included as much as documentation as for actual usage. I've included an annotated version of the `Dockerfile` below.\n\n```dockerfile\n# We name the `base` stage so we can refence it in multiple later\n# stages but only need to update it in one place if we change it\nFROM python:3-alpine AS base\n\nWORKDIR /app\nRUN pip install pipenv==2018.10.13\n\nCOPY Pipfile /app/\nCOPY Pipfile.lock /app/\n\nRUN pipenv install --system --deploy\n\n\n# The `app` stage is used as the base for images that don't\n# need the development dependencies\nFROM base AS app\nCOPY src /app\n\n\n# The `test-base` stage is used as the base for images that require\n# the development dependencies. The duplication of the COPY instruction\n# avoids breaking the cache for that later when the Pipfile changes \nFROM base AS test-base\nRUN pipenv install --system --deploy --dev\nCOPY src /app\n\n\n# The `Test` stage runs the application unit tests, the build will fail\n# if the tests fail. Note this stage name is capitalised, this is purely\n# a convetion for stages which result in useful images. Think of it like\n# hint that this is a public interface\nFROM test-base AS Test\nRUN pytest --black\n\n\n# The `Check` stage runs a check of the package dependencies against a list\n# of known security vulnerabilities. The build will fail if vulnerabilities\n# are found\nFROM test-base AS Check\nRUN safety check\n\n\n# The `Security` stage checks the application for security vulnerabilities using the \n# Aqua MicroScanner. This requires providing a build-arg with your MicroScanner token\nFROM app AS Security\nARG MICROSCANNER\nRUN wget -O /microscanner https://get.aquasec.com/microscanner \u0026\u0026 chmod +x /microscanner\nRUN /microscanner $MICROSCANNER --full-output\n\n\n# The `Docs` stage builds documentation from the application source code\n# and serves that on a simple web server\nFROM test-base AS Docs\nRUN pycco -i *.py\nWORKDIR /app/docs\nEXPOSE 8000\nCMD [\"python\", \"-m\", \"http.server\"]\n\n\n# `Shell` will build an image that, when run, drops you into a \n# python shell with the application context loaded\nFROM app AS Shell\nCMD [\"flask\", \"shell\"]\n\n\n# `release` acts as the basis for images which will actually run the application \nFROM app AS release\nEXPOSE 5000\n\n\n# `Dev` runs the application using the development web server, and enables\n# developer tools like the debugger and interactive expcetions\nFROM release AS Dev\nENV FLASK_ENV=development\nCMD [\"python\", \"app.py\"]\n\n\n# The `Prod` stage is the default stage if the Dockerfile is run without \n# a target stage set. The resulting image will run the application using a\n# production webserver and configuration\nFROM release As Prod\nCMD [\"gunicorn\", \"-b\", \":5000\", \"app:app\"]\n```\n\n## Google Cloud Build\n\nThe above Dockerfile is also used for running the tests in Google Cloud Build. See the accompanying `cloudbuild.yaml` file for details. The plan is to mechanically generate this file from the `Dockerfile`. \n\n\n## GitHub Actions\n\nThe Dockerfile is also used for running on GitHub with GitHub Actions. If you're thinking this duplicates the Google Cloud Build example you'd be right. This repository is intended as an example and playground. As with the `cloudbuild.yaml` file above it should be possible to mechanically generate this too.\n\n```hcl\nworkflow \"Quality\" {\n   on = \"push\"\n   resolves = [\"check\", \"test\", \"lint\", \"security\", \"validate\"]\n }\n\n action \"check\" {\n   uses = \"actions/docker/cli@master\"\n   args = \"build --target check .\"\n }\n\n action \"test\" {\n   uses = \"actions/docker/cli@master\"\n   args = \"build --target test .\"\n }\n\n action \"security\" {\n   uses = \"actions/docker/cli@master\"\n   secrets = [\"MICROSCANNER\"]\n   args = \"build --target security --build-arg MICROSCANNER=${MICROSCANNER} .\"\n }\n\n action \"lint\" {\n   uses = \"actions/docker/cli@master\"\n   args = \"run -i hadolint/hadolint hadolint --ignore SC2035 - \u003c Dockerfile\"\n }\n\n action \"build\" {\n   uses = \"actions/docker/cli@master\"\n   args = \"build -t sample .\"\n }\n\n action \"validate\" {\n   uses = \"docker://gcr.io/gcp-runtimes/container-structure-test\"\n   needs = \"build\"\n   args = \"test --image sample --config structure-tests.yaml\"\n }\n```\n\n\n## Knative Build\n\n[Knative Build](https://github.com/knative/build) is a CRD for Kubernetes which supports building in a cluster. I've also included a sample `buildtemplate.yaml` which demonstrates using Knative Build to run the above checks as well. This template uses a local Docker socket for demonstration purposes but could be converted to a different builder if needed.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgarethr%2Fmulti-stage-build-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgarethr%2Fmulti-stage-build-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgarethr%2Fmulti-stage-build-example/lists"}