When writing the docker-compose.yml file, you’ll notice that you must write a Dockerfile for your appplication so that you can reference it in your compose file.Just as you’d do when containerizing your app for any other circumstances, this Dockerfile should package your application within a container image so that the application starts when you docker run a container using that image.
A typical Node.js Express app, for example, would have a Dockerfile similar to the one below.
FROM node:16-alpineWORKDIR /usr/src/app# Install your app's dependenciesCOPY package*.json ./RUN npm install# Copy the application code itselfCOPY . .# This is the port to which you'll bind ExpressEXPOSE 3001# Start the serverCMD ["node", "server.js"]
Once you’ve created a Dockerfile for your app, reference it in your docker-compose.yml, as shown below.
Once you do that, Ergomake Bot will add a comment containing a link to your application.By now, you should have a preview environment up and running for your application.That’s good, but most applications depend on multiple other pieces of software, like databases. To learn how to set them up, see Databases and other third-party applications.
Usually, you’ll only have to write a Dockerfile for applications you own and for which there isn’t a built image yet.Take it as a rule-of-thumb that you should not write Dockerfile for applications such as databases, or message queues. For those applications, you should usually default to picking an image from Docker Hub, which is Docker’s official image repository.We recommend that users only write Dockerfiles when they can’t find the software they need packed into a Docker Hub image.
If your integrations already build a Docker image as part of your
pull-request process, we recommend that you reuse that image so that preview
environments come up more quickly.
There will be cases in which a Dockerfile needs to have access to a particular service’s address during build-time. One such example is when you must bundle a front-end app including the value for the back-end address to which the web app will send requests, as shown in the example Dockerfile below.
FROM node:16-alpineARG REACT_APP_API_URLENV REACT_APP_API_URL $REACT_APP_API_URL# A bunch of other commands [...]RUN npm run buildEXPOSE 8080CMD ["npm", "run", "start-docker"]
In this example, we use the REACT_APP_API_URL build argument to set the environment variable REACT_APP_API_URL. This variable will be used during npm run build because it will go into the bundle so that the app knows what’s the backend to which it should send requests.To provide a build argument containing service’s public address, you’ll use the dev.ergomake.preview.replace-arg.YOUR_ENV_VAR label. Within that var, you can interpolate the address we’ll generate for a service, as shown in the example below.
version: '3.8'services: web: build: context: ./frontend ports: - "8080:8080" labels: # This label will cause Ergomake to set, during build time, # REACT_APP_API_URL to the address of the API service (https), # followed by "/prefix" dev.ergomake.env.replace-arg.REACT_APP_API_URL: 'https://{{ services.api.url }}/api' api: build: ./backend ports: - '3001:3001'
{"docsConfig":{"$schema":"https://mintlify.com/docs.json","theme":"mint","name":"Docs","colors":{"primary":"#1E5E46","light":"#89CCAA","dark":"#121212"},"favicon":"/favicon.png","logo":{"light":"https://mintcdn.com/ergomake/ScIiHhWeo4EpJxNG/logo/light.png?fit=max\u0026auto=format\u0026n=ScIiHhWeo4EpJxNG\u0026q=85\u0026s=1315263da58dac7099b7358c58ca8981","dark":"https://mintcdn.com/ergomake/ScIiHhWeo4EpJxNG/logo/dark.png?fit=max\u0026auto=format\u0026n=ScIiHhWeo4EpJxNG\u0026q=85\u0026s=bb777466c3396681aa2e313ce04ed4ee"},"appearance":{"default":"dark","strict":null},"background":{"image":"https://ergomake.dev/img/gradient.png","decoration":null,"color":{"light":null,"dark":"#121212"}},"navbar":{"links":[{"label":"Dashboard","href":"https://app.ergomake.dev"},{"label":"Support","href":"mailto:contact@ergomake.dev"}],"primary":{"type":"github","href":"https://github.com/ergomake/ergomake"}},"footer":{"socials":{"twitter":"https://twitter.com/GetErgomake","github":"https://github.com/ergomake/ergomake","linkedin":"https://www.linkedin.com/company/ergomake","discord":"https://discord.gg/daGzchUGDt"}},"integrations":{"plausible":{"domain":"docs.ergomake.dev"}},"navigation":{"global":{"anchors":[{"anchor":"Github","href":"https://github.com/ergomake/ergomake","icon":"github"},{"anchor":"Blog","href":"https://ergomake.dev/blog","icon":"memo"},{"anchor":"Community","href":"https://discord.gg/daGzchUGDt","icon":"discord"}]},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"ergomake","hasAudioNarration":false,"actualSubdomain":"ergomake","customDomains":["docs.ergomake.dev"],"gitSource":{"type":"github","owner":"ergomake","repo":"docs","deployBranch":"main","contentDirectory":"","isPrivate":false,"mountPath":"","label":""},"entitlements":{},"buildId":"6ae919eb490ed5cbb56272d5:success","clientVersion":"0.0.4111","searchFilterCounts":[{"language":"default","tag":"Documentation","count":14},{"language":"default","tag":"Configurations","count":7},{"language":"default","tag":"Environments in-depth","count":4},{"language":"default","tag":"Get Started","count":3}]},"assistantConfig":{},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-rbac-roles","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"dockerfiles","slug":"/dockerfiles","pageMetadata":{"id":"writing-dockerfiles","title":"Writing Dockerfiles","icon":"whale","description":null,"href":"/dockerfiles"},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,em:`em`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,..._provideComponents(),...props.components},{CodeBlock,Heading,Tip}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Tip)_missingMdxReference(`Tip`,true);return _jsxs(_Fragment,{children:[_jsxs(Heading,{level:`2`,id:`writing-dockerfiles-for-your-docker-compose-yml`,children:[`Writing Dockerfiles for your `,_jsx(_components.code,{children:`docker-compose.yml`})]}),`\n`,_jsxs(_components.p,{children:[`When writing the `,_jsx(_components.code,{children:`docker-compose.yml`}),` file, you’ll notice that you must write a `,_jsx(_components.code,{children:`Dockerfile`}),` for your appplication so that you can reference it in your compose file.`]}),`\n`,_jsxs(_components.p,{children:[`Just as you’d do when containerizing your app for any other circumstances, this `,_jsx(_components.code,{children:`Dockerfile`}),` should package your application within a `,_jsx(_components.a,{href:`https://docs.docker.com/get-started/#what-is-a-container-image`,children:`container image`}),` so that the application starts when you `,_jsx(_components.code,{children:`docker run`}),` a container using that image.`]}),`\n`,_jsx(Tip,{children:_jsxs(_components.p,{children:[`If you’re not familiar with Docker, we highly recommend reading `,_jsx(_components.a,{href:`https://docs.docker.com/get-started`,children:`Docker’s\nofficial “Get Started” page`}),`.`]})}),`\n`,_jsxs(_components.p,{children:[`A typical Node.js Express app, for example, would have a `,_jsx(_components.code,{children:`Dockerfile`}),` similar to the one below.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`16`,language:`docker`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`docker`,children:_jsxs(_components.code,{language:`docker`,numberOfLines:`16`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`FROM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` node:16-alpine`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`WORKDIR`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` /usr/src/app`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Install your app's dependencies`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`COPY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` package*.json ./`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`RUN`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` npm install`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Copy the application code itself`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`COPY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` . .`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# This is the port to which you'll bind Express`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`EXPOSE`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` 3001`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Start the server`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`CMD`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"node\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"server.js\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Once you’ve created a Dockerfile for your app, reference it in your `,_jsx(_components.code,{children:`docker-compose.yml`}),`, as shown below.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`6`,language:`yaml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`yaml`,children:_jsxs(_components.code,{language:`yaml`,numberOfLines:`6`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`version`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"3.8\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`services`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` api`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` build`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`../path_to_your_dockerfile_folder`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` ports`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"3001:3001\"`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`Once you do that, Ergomake Bot will add a comment containing a link to your application.`}),`\n`,_jsx(_components.p,{children:`By now, you should have a preview environment up and running for your application.`}),`\n`,_jsxs(_components.p,{children:[`That’s good, but most applications depend on multiple other pieces of software, like databases. To learn how to set them up, see `,_jsx(_components.em,{children:_jsx(_components.a,{href:`/configurations/third-party-software`,children:`Databases and other third-party applications`})}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`when-to-write-a-dockerfile`,children:`When to write a Dockerfile`}),`\n`,_jsxs(_components.p,{children:[`Usually, you’ll only have to write a `,_jsx(_components.code,{children:`Dockerfile`}),` for applications you `,_jsx(_components.em,{children:`own`}),` and for which there isn’t a built image yet.`]}),`\n`,_jsxs(_components.p,{children:[`Take it as a rule-of-thumb that you should `,_jsx(_components.em,{children:`not`}),` write `,_jsx(_components.code,{children:`Dockerfile`}),` for applications such as databases, or message queues. For those applications, you should usually default to picking an image from `,_jsx(_components.a,{href:`https://hub.docker.com/`,children:`Docker Hub`}),`, which is Docker’s official image repository.`]}),`\n`,_jsx(_components.p,{children:`We recommend that users only write Dockerfiles when they can’t find the software they need packed into a Docker Hub image.`}),`\n`,_jsx(Tip,{children:_jsx(_components.p,{children:`If your integrations already build a Docker image as part of your\npull-request process, we recommend that you reuse that image so that preview\nenvironments come up more quickly.`})}),`\n`,_jsx(Heading,{level:`2`,id:`setting-build-arguments`,children:`Setting build arguments`}),`\n`,_jsx(_components.p,{children:`There will be cases in which a Dockerfile needs to have access to a particular service’s address during build-time. One such example is when you must bundle a front-end app including the value for the back-end address to which the web app will send requests, as shown in the example Dockerfile below.`}),`\n`,_jsx(CodeBlock,{numberOfLines:`13`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`13`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`FROM node:16-alpine`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`ARG REACT_APP_API_URL`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`ENV REACT_APP_API_URL $REACT_APP_API_URL`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`# A bunch of other commands [...]`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`RUN npm run build`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`EXPOSE 8080`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`CMD [\"npm\", \"run\", \"start-docker\"]`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsxs(_components.p,{children:[`In this example, we use the `,_jsx(_components.code,{children:`REACT_APP_API_URL`}),` build argument to set the environment variable `,_jsx(_components.code,{children:`REACT_APP_API_URL`}),`. This variable will be used during `,_jsx(_components.code,{children:`npm run build`}),` because it will go into the bundle so that the app knows what’s the backend to which it should send requests.`]}),`\n`,_jsxs(_components.p,{children:[_jsxs(_components.strong,{children:[`To provide a build argument containing service’s public address, you’ll use the `,_jsx(_components.code,{children:`dev.ergomake.preview.replace-arg.YOUR_ENV_VAR`}),` label.`]}),` Within that var, you can interpolate the address we’ll generate for a service, as shown in the example below.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`17`,language:`yaml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`yaml`,children:_jsxs(_components.code,{language:`yaml`,numberOfLines:`17`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`version`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'3.8'`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`services`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` web`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` build`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` context`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`./frontend`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` ports`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"8080:8080\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` labels`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # This label will cause Ergomake to set, during build time,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # REACT_APP_API_URL to the address of the API service (https),`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # followed by \"/prefix\"`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` dev.ergomake.env.replace-arg.REACT_APP_API_URL`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'https://{{ services.api.url }}/api'`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` api`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` build`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`./backend`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` ports`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'3001:3001'`})]}),`\n`]})})})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"id":"writing-dockerfiles","title":"Writing Dockerfiles","icon":"whale","description":null,"href":"/dockerfiles"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Writing Dockerfiles for your docker-compose.yml","slug":"writing-dockerfiles-for-your-docker-compose-yml","depth":2,"children":[]},{"title":"When to write a Dockerfile","slug":"when-to-write-a-dockerfile","depth":2,"children":[]},{"title":"Setting build arguments","slug":"setting-build-arguments","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"ergomake","siteName":"Docs","title":"Writing Dockerfiles - Docs","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-01-06T22:57:29.864Z","originalFileLocation":"dockerfiles.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"dark\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"application-name\" content=\"Docs\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/ergomake/JNoiOhqoELSGbLoS/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/ergomake/JNoiOhqoELSGbLoS/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/ergomake/JNoiOhqoELSGbLoS/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/ergomake/JNoiOhqoELSGbLoS/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/ergomake/JNoiOhqoELSGbLoS/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/ergomake/JNoiOhqoELSGbLoS/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/ergomake/JNoiOhqoELSGbLoS/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/ergomake/JNoiOhqoELSGbLoS/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/ergomake/JNoiOhqoELSGbLoS/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Writing Dockerfiles - Docs\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Docs\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.ergomake.dev/dockerfiles\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://ergomake.mintlify.site/_mintlify/api/og/v2?division=Get+Started\u0026amp;title=Writing+Dockerfiles\u0026amp;theme=b562a147e19fbfc4c97bb794\u0026amp;signature=be5634be6aece08c206db266a08fda4971df009eea9c6224ec394ac2cec2b625\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Writing Dockerfiles - Docs\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://ergomake.mintlify.site/_mintlify/api/og/v2?division=Get+Started\u0026amp;title=Writing+Dockerfiles\u0026amp;theme=b562a147e19fbfc4c97bb794\u0026amp;signature=be5634be6aece08c206db266a08fda4971df009eea9c6224ec394ac2cec2b625\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/ergomake/JNoiOhqoELSGbLoS/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Docs\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#1E5E46\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.ergomake.dev/dockerfiles\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/dockerfiles.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.ergomake.dev/#organization\",\"name\":\"Docs\",\"url\":\"https://docs.ergomake.dev\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/ergomake/ScIiHhWeo4EpJxNG/logo/light.png?fit=max\u0026auto=format\u0026n=ScIiHhWeo4EpJxNG\u0026q=85\u0026s=1315263da58dac7099b7358c58ca8981\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.ergomake.dev#website\",\"name\":\"Docs\",\"url\":\"https://docs.ergomake.dev\",\"publisher\":{\"@id\":\"https://docs.ergomake.dev/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.ergomake.dev/dockerfiles#webpage\",\"url\":\"https://docs.ergomake.dev/dockerfiles\",\"name\":\"Writing Dockerfiles\",\"dateModified\":\"2026-01-06T22:57:29.864Z\",\"isPartOf\":{\"@id\":\"https://docs.ergomake.dev#website\"},\"breadcrumb\":{\"@id\":\"https://docs.ergomake.dev/dockerfiles#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.ergomake.dev/dockerfiles#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Get Started\",\"item\":\"https://docs.ergomake.dev/introduction\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Writing Dockerfiles\",\"item\":\"https://docs.ergomake.dev/dockerfiles\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.ergomake.dev/dockerfiles#article\",\"headline\":\"Writing Dockerfiles\",\"name\":\"Writing Dockerfiles\",\"url\":\"https://docs.ergomake.dev/dockerfiles\",\"mainEntityOfPage\":{\"@id\":\"https://docs.ergomake.dev/dockerfiles#webpage\"},\"dateModified\":\"2026-01-06T22:57:29.864Z\",\"publisher\":{\"@id\":\"https://docs.ergomake.dev/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.ergomake.dev#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Docs\",\"publisher\":{\"@type\":\"Organization\",\"name\":\"Docs\"},\"provider\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","agentPointerHref":"/dockerfiles.md","siteName":"Docs","nav":{"global":{"anchors":[{"anchor":"Github","href":"https://github.com/ergomake/ergomake","icon":"github"},{"anchor":"Blog","href":"https://ergomake.dev/blog","icon":"memo"},{"anchor":"Community","href":"https://discord.gg/daGzchUGDt","icon":"discord"}]},"anchors":[{"anchor":"Documentation","icon":"book-open","groups":[{"group":"Get Started","pages":[{"title":"Introduction","icon":"info","href":"/introduction"},{"title":"Your first preview using compose","description":"Learn how to integrate with GitHub pull requests to create your first automatic preview.","icon":"1","href":"/your-first-preview"},{"title":"Writing Dockerfiles","icon":"whale","href":"/dockerfiles"}]},{"group":"Configurations","pages":[{"title":"Environment variables and secrets","description":"How to manage environment variables for build and runtime.","icon":"key","href":"/configurations/environment-variables"},{"title":"Multiple repositories","icon":"rectangle-vertical-history","href":"/configurations/multiple-repos"},{"title":"Databases and other third-party software","icon":"database","href":"/configurations/third-party-software"},{"title":"Networking","icon":"network-wired","href":"/configurations/networking"},{"title":"Seeding","icon":"seedling","href":"/configurations/seeding"},{"title":"Managing resources","icon":"memory","href":"/configurations/managing-resources"},{"title":"Troubleshooting","icon":"bug","href":"/configurations/troubleshooting"}]},{"group":"Environments in-depth","pages":[{"title":"Preview lifecycle","icon":"clock","href":"/in-depth/lifecycle"},{"title":"Logs","icon":"line-columns","href":"/in-depth/logs"},{"title":"Persisting data","icon":"floppy-disk","href":"/in-depth/persisting-data"},{"title":"Authentication and permissions","icon":"users","href":"/in-depth/authentication-and-permissions"}]}]}]},"basePath":"","title":"Writing Dockerfiles - Docs","buildId":"dpl_DqYu5MPb49gWBBbUGgpHQUmCHY3P","deploymentId":"dpl_DqYu5MPb49gWBBbUGgpHQUmCHY3P","dynamics":[],"chunks":[]}