diff --git a/examples/with-docker/.dockerignore b/examples/with-docker/.dockerignore new file mode 100644 index 0000000000000000000000000000000000000000..fabc1be3226b280ae87f3912c56ff8923fb07a80 --- /dev/null +++ b/examples/with-docker/.dockerignore @@ -0,0 +1,3 @@ +.next/ +node_modules/ +Dockerfile diff --git a/examples/with-docker/Dockerfile b/examples/with-docker/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..1ca3dd5bac8a77cb9f933b00cd087eb73e98a9ed --- /dev/null +++ b/examples/with-docker/Dockerfile @@ -0,0 +1,10 @@ +FROM mhart/alpine-node + +WORKDIR /app +COPY . . + +RUN yarn install +RUN yarn build + +EXPOSE 3000 +CMD ["yarn", "start"] diff --git a/examples/with-docker/Dockerfile.multistage b/examples/with-docker/Dockerfile.multistage new file mode 100644 index 0000000000000000000000000000000000000000..ebf28bf6f848e1d8a46a717424a1667575160007 --- /dev/null +++ b/examples/with-docker/Dockerfile.multistage @@ -0,0 +1,14 @@ +# Do the npm install or yarn install in the full image +FROM mhart/alpine-node AS builder +WORKDIR /app +COPY package.json . +RUN yarn install +COPY . . +RUN yarn build + +# And then copy over node_modules, etc from that stage to the smaller base image +FROM mhart/alpine-node:base +WORKDIR /app +COPY --from=builder /app . +EXPOSE 3000 +CMD ["node_modules/.bin/next", "start"] diff --git a/examples/with-docker/README.md b/examples/with-docker/README.md new file mode 100644 index 0000000000000000000000000000000000000000..d5017b40e9e7dc78238e0c16ecc51177bd03dd84 --- /dev/null +++ b/examples/with-docker/README.md @@ -0,0 +1,58 @@ +[![Deploy to now](https://deploy.now.sh/static/button.svg)](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/with-docker&env=API_URL&docker=true) + +# With Docker + +## How to use + +### Using `create-next-app` + +Execute [`create-next-app`](https://github.com/segmentio/create-next-app) with [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) or [npx](https://github.com/zkat/npx#readme) to bootstrap the example: + +```bash +npx create-next-app --example with-docker with-docker-app +# or +yarn create next-app --example with-docker with-docker-app +``` + +### Download manually + +Download the example [or clone the repo](https://github.com/zeit/next.js): + +```bash +curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/with-docker +cd with-docker +``` + +Build it with docker: + +```bash +# build +docker build -t next-app . +# or, use multi-stage builds to build a smaller docker image +docker build -t next-app -f ./Dockerfile.multistage . +``` + +Run it: + +```bash +docker run --rm -it \ + -p 3000:3000 \ + -e "API_URL=https://example.com" \ + next-app +``` + +Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download)) + +```bash +now --docker -e API_URL="https://example.com" +``` + +>*Note: Multi-stage only works in OSS plan. [\[#962\]](https://github.com/zeit/now-cli/issues/962#issuecomment-383860104)* + +## The idea behind the example + +This example show how to set custom environment variables for your __docker application__ at runtime. + +The `dockerfile` is the simplest way to run Next.js app in docker, and the size of output image is `173MB`. However, for an even smaller build, you can do multi-stage builds with `dockerfile.multistage`. The size of output image is `85MB`. + +You can check the [Example Dockerfile for your own Node.js project](https://github.com/mhart/alpine-node/tree/43ca9e4bc97af3b1f124d27a2cee002d5f7d1b32#example-dockerfile-for-your-own-nodejs-project) section in [mhart/alpine-node](https://github.com/mhart/alpine-node) for more details. \ No newline at end of file diff --git a/examples/with-docker/next.config.js b/examples/with-docker/next.config.js new file mode 100644 index 0000000000000000000000000000000000000000..5c61948691209b2a22695eb2e9c28238ce3e0841 --- /dev/null +++ b/examples/with-docker/next.config.js @@ -0,0 +1,9 @@ +// next.config.js +module.exports = { + serverRuntimeConfig: { // Will only be available on the server side + mySecret: 'secret' + }, + publicRuntimeConfig: { // Will be available on both server and client + API_URL: process.env.API_URL + } +} diff --git a/examples/with-docker/package.json b/examples/with-docker/package.json new file mode 100644 index 0000000000000000000000000000000000000000..68aaac427df4b97be667c6ecb39e2718ceb6561f --- /dev/null +++ b/examples/with-docker/package.json @@ -0,0 +1,12 @@ +{ + "scripts": { + "dev": "next", + "build": "next build", + "start": "next start" + }, + "dependencies": { + "next": "latest", + "react": "16.2.0", + "react-dom": "16.2.0" + } +} diff --git a/examples/with-docker/pages/index.js b/examples/with-docker/pages/index.js new file mode 100644 index 0000000000000000000000000000000000000000..6d3657a454d55809b52dae853c871c8cc6730913 --- /dev/null +++ b/examples/with-docker/pages/index.js @@ -0,0 +1,18 @@ +import React from 'react' +import getConfig from 'next/config' +const { publicRuntimeConfig } = getConfig() + +const { API_URL } = publicRuntimeConfig + +export default class extends React.Component { + static async getInitialProps () { + // fetch(`${API_URL}/some-path`) + return {} + } + + render () { + return