Skip to content

Instantly share code, notes, and snippets.

@aradalvand
Last active October 13, 2025 19:48
Show Gist options
  • Save aradalvand/04b2cad14b00e5ffe8ec96a3afbb34fb to your computer and use it in GitHub Desktop.
Save aradalvand/04b2cad14b00e5ffe8ec96a3afbb34fb to your computer and use it in GitHub Desktop.

Revisions

  1. aradalvand revised this gist Oct 7, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    *This Dockerfile is intended for SvelteKit applications that use [adapter-node](https://kit.svelte.dev/docs/adapter-node). So, the Dockerfile below assumes that you have installed and configured adapter-node.*
    *This Dockerfile is intended for SvelteKit applications that use [adapter-node](https://kit.svelte.dev/docs/adapter-node). So, the Dockerfile below assumes that you have already installed and configured the adapter.

    #### Dockerfile:
    ```dockerfile
  2. aradalvand revised this gist Jun 13, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    *This Dockerfile is intended for SvelteKit applications that use [adapter-node](https://kit.svelte.dev/docs/adapter-node). So, tghe Dockerfile below assumes that you have installed and configured adapter-node.*
    *This Dockerfile is intended for SvelteKit applications that use [adapter-node](https://kit.svelte.dev/docs/adapter-node). So, the Dockerfile below assumes that you have installed and configured adapter-node.*

    #### Dockerfile:
    ```dockerfile
  3. aradalvand revised this gist Jun 13, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    *This Dockerfile is intended for SvelteKit applications that use [adapter-node](https://kit.svelte.dev/docs/adapter-node).*
    *This Dockerfile is intended for SvelteKit applications that use [adapter-node](https://kit.svelte.dev/docs/adapter-node). So, tghe Dockerfile below assumes that you have installed and configured adapter-node.*

    #### Dockerfile:
    ```dockerfile
  4. aradalvand revised this gist Jun 13, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    *This Dockerfile is intended for SvelteKit applications that use [adapter-node](https://kit.svelte.dev/docs/adapters#supported-environments-node-js).*
    *This Dockerfile is intended for SvelteKit applications that use [adapter-node](https://kit.svelte.dev/docs/adapter-node).*

    #### Dockerfile:
    ```dockerfile
  5. aradalvand revised this gist May 23, 2023. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -65,7 +65,7 @@ And even though the size of the base image you use in the first stage ultimately

    Note that there's some tradeoffs that come with choosing Alpine that you should probably be aware of. Alpine uses [musl and BusyBox instead of the de-facto standard glibc and GNU Core Utilities](https://github.com/nodejs/docker-node#nodealpine) — if you don't know what these are, that's fine, this just means that some programs might not run or might run differently on Alpine than they do on bigger distributions like Ubuntu and Debian, but Node.js applications should be fine for the most part. For an overview of the differences between Docker images for various distros (e.g. Alpine, Debian, Ubuntu, etc.), check out [this article](https://crunchtools.com/comparison-linux-container-images/).

    If you don't want to use Alpine, you can remove the `-alpine` suffix from the image name, leaving only `node:18`, which defaults to the Debian-based image.
    If you don't want to use Alpine, you can remove the `-alpine` suffix from the image name, leaving only `node:18`, which defaults to the Debian-based image. If you decide to do this, remember to do the same for the next stage as well.

    ---

    @@ -124,7 +124,7 @@ Now that we have our `build` directory and its contents ready, we can begin the
    FROM node:18-alpine
    ```

    Here, we're using the same Alpine-based image we used in the first (build) stage. If want to use Debian-based images, you can also use `node:18-slim` (which is actually bigger than `node:18-alpine`, but smaller than `node:18`) to have a smaller image size. The `slim` variant doesn't contain things like `npm`, for instance, it only includes `node` itself. So, if you do need `npm` in your final image, still not the non-slim variants.
    Here, we're using the same Alpine-based image we used in the first (build) stage. If want to use Debian-based images, you can also use `node:18-slim` (which is actually bigger than `node:18-alpine`, but smaller than `node:18`) to have a smaller image size. The `slim` variant doesn't contain things like `npm`, for instance, it only includes `node` itself. So, if you do need `npm` in your final image, stick to the non-slim variants.

    ---

  6. aradalvand revised this gist May 23, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -61,7 +61,7 @@ We are setting `node:18-alpine` as the base image of our first stage, but you ca
    The `AS builder` part is simply assigning a custom name to this first stage, so that we can reference it later in the second stage more easily.

    The `alpine` variant is based on [Alpine Linux](https://alpinelinux.org/), which is a minimal Linux distro used mainly in containers because of its small size.
    And even though the size of the base image you use in the first stage, ultimately makes no difference to the final image size (since the second stage is all that remains in the end) it's a usually a good idea to use the same base image (or a derivative of it) in the build stage, so that you know that the build artifacts that are created in the first stage, will be compatible with the base image used in final stage.
    And even though the size of the base image you use in the first stage ultimately makes no difference to the final image size since the second stage is all that remains in the endit's normally a good idea to use the same base image in the build stage as the final stage (or a derivative of it), so that you can be sure that the build artifacts that are created in the first stage, will be compatible with the base image used in final stage.

    Note that there's some tradeoffs that come with choosing Alpine that you should probably be aware of. Alpine uses [musl and BusyBox instead of the de-facto standard glibc and GNU Core Utilities](https://github.com/nodejs/docker-node#nodealpine) — if you don't know what these are, that's fine, this just means that some programs might not run or might run differently on Alpine than they do on bigger distributions like Ubuntu and Debian, but Node.js applications should be fine for the most part. For an overview of the differences between Docker images for various distros (e.g. Alpine, Debian, Ubuntu, etc.), check out [this article](https://crunchtools.com/comparison-linux-container-images/).

  7. aradalvand revised this gist May 23, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -60,7 +60,7 @@ We are setting `node:18-alpine` as the base image of our first stage, but you ca

    The `AS builder` part is simply assigning a custom name to this first stage, so that we can reference it later in the second stage more easily.

    The `alpine` variant is based on [Alpine Linux](https://alpinelinux.org/), which is a minimal Linux distro used main in containers because of its small size.
    The `alpine` variant is based on [Alpine Linux](https://alpinelinux.org/), which is a minimal Linux distro used mainly in containers because of its small size.
    And even though the size of the base image you use in the first stage, ultimately makes no difference to the final image size (since the second stage is all that remains in the end) it's a usually a good idea to use the same base image (or a derivative of it) in the build stage, so that you know that the build artifacts that are created in the first stage, will be compatible with the base image used in final stage.

    Note that there's some tradeoffs that come with choosing Alpine that you should probably be aware of. Alpine uses [musl and BusyBox instead of the de-facto standard glibc and GNU Core Utilities](https://github.com/nodejs/docker-node#nodealpine) — if you don't know what these are, that's fine, this just means that some programs might not run or might run differently on Alpine than they do on bigger distributions like Ubuntu and Debian, but Node.js applications should be fine for the most part. For an overview of the differences between Docker images for various distros (e.g. Alpine, Debian, Ubuntu, etc.), check out [this article](https://crunchtools.com/comparison-linux-container-images/).
  8. aradalvand revised this gist May 23, 2023. 1 changed file with 5 additions and 4 deletions.
    9 changes: 5 additions & 4 deletions DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -60,11 +60,12 @@ We are setting `node:18-alpine` as the base image of our first stage, but you ca

    The `AS builder` part is simply assigning a custom name to this first stage, so that we can reference it later in the second stage more easily.

    The `alpine` variation is based on [Alpine Linux](https://alpinelinux.org/), which is a very minimal Linux distro, built precisely for being used in containers.
    And even though the size of the variation you use in the first stage, makes no difference to the final image size, since the second stage is what matters in that regard, it's good to use a minimal variant like this, so that your build times will be shorter, as Docker has to download every base image, and the smaller the base image, the less time and bandwidth will have to be spent for downloading it, obviously.
    Note that there's some tradeoffs that come with choosing Alpine that you might want to be aware of. Alpine uses [musl and BusyBox instead of the de-facto standard glibc and GNU Core Utilities](https://github.com/nodejs/docker-node#nodealpine) — if you don't know what these are, that's fine, this just means that some programs might not run or might run differently on Alpine than they do on bigger distributions like Ubuntu and Debian, but Node.js applications should be fine for the most part. For a overview of the differences between various distro images (e.g. Alpine, Debian, Ubuntu, etc.), check out [this article](https://crunchtools.com/comparison-linux-container-images/).
    The `alpine` variant is based on [Alpine Linux](https://alpinelinux.org/), which is a minimal Linux distro used main in containers because of its small size.
    And even though the size of the base image you use in the first stage, ultimately makes no difference to the final image size (since the second stage is all that remains in the end) it's a usually a good idea to use the same base image (or a derivative of it) in the build stage, so that you know that the build artifacts that are created in the first stage, will be compatible with the base image used in final stage.

    If you don't want to use Alpine, you can remove the `-alpine` suffix from the image name, which uses the default Debian-based image.
    Note that there's some tradeoffs that come with choosing Alpine that you should probably be aware of. Alpine uses [musl and BusyBox instead of the de-facto standard glibc and GNU Core Utilities](https://github.com/nodejs/docker-node#nodealpine) — if you don't know what these are, that's fine, this just means that some programs might not run or might run differently on Alpine than they do on bigger distributions like Ubuntu and Debian, but Node.js applications should be fine for the most part. For an overview of the differences between Docker images for various distros (e.g. Alpine, Debian, Ubuntu, etc.), check out [this article](https://crunchtools.com/comparison-linux-container-images/).

    If you don't want to use Alpine, you can remove the `-alpine` suffix from the image name, leaving only `node:18`, which defaults to the Debian-based image.

    ---

  9. aradalvand revised this gist May 23, 2023. 1 changed file with 10 additions and 11 deletions.
    21 changes: 10 additions & 11 deletions DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -2,15 +2,15 @@

    #### Dockerfile:
    ```dockerfile
    FROM node:16-alpine AS builder
    FROM node:18-alpine AS builder
    WORKDIR /app
    COPY package*.json .
    RUN npm ci
    COPY . .
    RUN npm run build
    RUN npm prune --production

    FROM mhart/alpine-node:slim-16
    FROM node:18-alpine
    WORKDIR /app
    COPY --from=builder /app/build build/
    COPY --from=builder /app/node_modules node_modules/
    @@ -54,14 +54,17 @@ This is highly recommended for applications that have a build step (such as Svel
    To learn more about multistage builds, see [official Docker documentation on multistage builds](https://docs.docker.com/develop/develop-images/multistage-build/).

    ```dockerfile
    FROM node:16-alpine AS builder
    FROM node:18-alpine AS builder
    ```
    We are setting `node:16-alpine` as the base image of our first stage, but you can of course change this, or use another version, if you see fit.
    We are setting `node:18-alpine` as the base image of our first stage, but you can of course change this, or use another version, if you see fit.

    The `AS builder` part is simply assigning a custom name to this first stage, so that we can reference it later in the second stage more easily.

    The `alpine` variation is based on [Alpine Linux](https://alpinelinux.org/), which is a very minimal Linux distro, built exactly to be used in containers.
    The `alpine` variation is based on [Alpine Linux](https://alpinelinux.org/), which is a very minimal Linux distro, built precisely for being used in containers.
    And even though the size of the variation you use in the first stage, makes no difference to the final image size, since the second stage is what matters in that regard, it's good to use a minimal variant like this, so that your build times will be shorter, as Docker has to download every base image, and the smaller the base image, the less time and bandwidth will have to be spent for downloading it, obviously.
    Note that there's some tradeoffs that come with choosing Alpine that you might want to be aware of. Alpine uses [musl and BusyBox instead of the de-facto standard glibc and GNU Core Utilities](https://github.com/nodejs/docker-node#nodealpine) — if you don't know what these are, that's fine, this just means that some programs might not run or might run differently on Alpine than they do on bigger distributions like Ubuntu and Debian, but Node.js applications should be fine for the most part. For a overview of the differences between various distro images (e.g. Alpine, Debian, Ubuntu, etc.), check out [this article](https://crunchtools.com/comparison-linux-container-images/).

    If you don't want to use Alpine, you can remove the `-alpine` suffix from the image name, which uses the default Debian-based image.

    ---

    @@ -117,14 +120,10 @@ We subsequently run the `npm prune --production` command to delete all the dev d
    Now that we have our `build` directory and its contents ready, we can begin the final stage, which is responsible for running our application.

    ```dockerfile
    FROM mhart/alpine-node:slim-16
    FROM node:18-alpine
    ```

    The base image I'm using here may have caught your attention, as it is not the [official `node` image](https://hub.docker.com/_/node).

    The official Node image doesn't have a variant that's both alpine-based AND [slim](https://hub.docker.com/_/node#:~:text=node%3A%3Cversion%3E%2Dslim-,This%20image%20does%20not%20contain%20the%20common,-packages%20contained%20in), this is why we're using this third-party image called [mhart/alpine-node](https://github.com/mhart/alpine-node), which has a variant called slim (what we're using here), which is precisely what we want, namely alpine-based + slim.

    With this, the resulting image will be smaller than it would've been had we used `node:16-alpine` or `node:16-slim` — also interestingly, `node:<version>-slim` is actually bigger than `node:<version>-alpine` so there would've been no point in using the former. But a combination of the two is smaller than either one of them, which is, once again, what this image provides.
    Here, we're using the same Alpine-based image we used in the first (build) stage. If want to use Debian-based images, you can also use `node:18-slim` (which is actually bigger than `node:18-alpine`, but smaller than `node:18`) to have a smaller image size. The `slim` variant doesn't contain things like `npm`, for instance, it only includes `node` itself. So, if you do need `npm` in your final image, still not the non-slim variants.

    ---

  10. aradalvand revised this gist Nov 9, 2022. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -27,7 +27,7 @@ Dockerfile
    .git
    .gitignore
    .gitattributes
    .README.md
    README.md
    .npmrc
    .prettierrc
    .eslintrc.cjs
  11. aradalvand revised this gist Jul 13, 2022. 1 changed file with 8 additions and 8 deletions.
    16 changes: 8 additions & 8 deletions DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -11,12 +11,12 @@ RUN npm run build
    RUN npm prune --production

    FROM mhart/alpine-node:slim-16
    ENV NODE_ENV=production
    WORKDIR /app
    COPY --from=builder /app/build build/
    COPY --from=builder /app/node_modules node_modules/
    COPY package.json .
    EXPOSE 3000
    ENV NODE_ENV=production
    CMD [ "node", "build" ]
    ```

    @@ -128,13 +128,6 @@ With this, the resulting image will be smaller than it would've been had we used

    ---

    ```dockerfile
    ENV NODE_ENV=production
    ```
    Here we set the `NODE-ENV` variable to `production`, to let Node.js and other code that we're about to run know that this is a production environment.

    ---

    ```dockerfile
    WORKDIR /app
    ```
    @@ -166,6 +159,13 @@ You can also change the port by assigning a different number to the `PORT` envir

    ---

    ```dockerfile
    ENV NODE_ENV=production
    ```
    Here we set the `NODE-ENV` variable to `production`, to let Node.js and other code that we're about to run know that this is a production environment.

    ---

    ```dockerfile
    CMD [ "node", "build" ]
    ```
  12. aradalvand revised this gist Jul 13, 2022. 1 changed file with 2 additions and 3 deletions.
    5 changes: 2 additions & 3 deletions DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,6 @@
    *This Dockerfile is intended for SvelteKit applications that use [adapter-node](https://kit.svelte.dev/docs/adapters#supported-environments-node-js).*

    # TL;DR:
    Dockerfile:
    #### Dockerfile:
    ```dockerfile
    FROM node:16-alpine AS builder
    WORKDIR /app
    @@ -21,7 +20,7 @@ EXPOSE 3000
    CMD [ "node", "build" ]
    ```

    .dockerignore:
    #### .dockerignore:
    ```dockerignore
    Dockerfile
    .dockerignore
  13. aradalvand revised this gist Jul 13, 2022. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -42,6 +42,8 @@ package
    **/.env
    ```

    ---

    # How it works:

    Let's break down this Dockerfile and explain its various parts:
  14. @xamir82 xamir82 revised this gist Apr 11, 2022. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -24,7 +24,6 @@ CMD [ "node", "build" ]
    .dockerignore:
    ```dockerignore
    Dockerfile
    Dockerfile
    .dockerignore
    .git
    .gitignore
  15. @xamir82 xamir82 revised this gist Apr 4, 2022. 1 changed file with 11 additions and 7 deletions.
    18 changes: 11 additions & 7 deletions DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -24,19 +24,23 @@ CMD [ "node", "build" ]
    .dockerignore:
    ```dockerignore
    Dockerfile
    Dockerfile
    .dockerignore
    .git
    .gitignore
    .gitattributes
    .README.md
    .npmrc
    .DS_Store
    .prettierrc
    .eslintrc.cjs
    .graphqlrc
    .editorconfig
    .svelte-kit
    .vscode
    node_modules
    /build
    /.svelte-kit
    /package
    .env
    .env.*
    !.env.example
    build
    package
    **/.env
    ```

    # How it works:
  16. @xamir82 xamir82 revised this gist Apr 4, 2022. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -107,6 +107,8 @@ We run the `npm run build` command so that SvelteKit generates the `build` dire

    We subsequently run the `npm prune --production` command to delete all the dev dependencies from the "node_modules" folder, since we no longer need any of them.

    ---

    ### Final Stage:
    Now that we have our `build` directory and its contents ready, we can begin the final stage, which is responsible for running our application.

  17. @xamir82 xamir82 revised this gist Apr 4, 2022. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -3,7 +3,7 @@
    # TL;DR:
    Dockerfile:
    ```dockerfile
    FROM node:16 AS builder
    FROM node:16-alpine AS builder
    WORKDIR /app
    COPY package*.json .
    RUN npm ci
    @@ -52,7 +52,7 @@ To learn more about multistage builds, see [official Docker documentation on mul
    ```dockerfile
    FROM node:16-alpine AS builder
    ```
    We are setting `node:lts-alpine` as the base image of our first stage, but you can of course change this, or use another version, if you see fit.
    We are setting `node:16-alpine` as the base image of our first stage, but you can of course change this, or use another version, if you see fit.

    The `AS builder` part is simply assigning a custom name to this first stage, so that we can reference it later in the second stage more easily.

  18. @xamir82 xamir82 revised this gist Apr 4, 2022. 1 changed file with 9 additions and 7 deletions.
    16 changes: 9 additions & 7 deletions DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -3,18 +3,19 @@
    # TL;DR:
    Dockerfile:
    ```dockerfile
    FROM node:16-alpine AS builder
    FROM node:16 AS builder
    WORKDIR /app
    COPY package*.json .
    RUN npm ci
    COPY . .
    RUN npm run build && npm prune --production
    RUN npm run build
    RUN npm prune --production

    FROM mhart/alpine-node:slim-16
    ENV NODE_ENV=production
    WORKDIR /app
    COPY --from=builder /app/build ./build
    COPY --from=builder /app/node_modules ./node_modules
    COPY --from=builder /app/build build/
    COPY --from=builder /app/node_modules node_modules/
    COPY package.json .
    EXPOSE 3000
    CMD [ "node", "build" ]
    @@ -99,7 +100,8 @@ This is a very common practice when writing Dockerfiles for Node applications an
    ---

    ```dockerfile
    RUN npm run build && npm prune --production
    RUN npm run build
    RUN npm prune --production
    ```
    We run the `npm run build` command so that SvelteKit generates the `build` directory, containing a standalone Node server that serves our application — assuming, of course, that you're using adapter-node.

    @@ -135,8 +137,8 @@ Same as the one in the first stage. Sets the working directory to `/app`.
    ---

    ```dockerfile
    COPY --from=builder /app/build ./build
    COPY --from=builder /app/node_modules ./node_modules
    COPY --from=builder /app/build build/
    COPY --from=builder /app/node_modules node_modules/
    COPY package.json .
    ```
    The adapter-node [documentation](https://github.com/sveltejs/kit/tree/master/packages/adapter-node#deploying) states the following:
  19. @xamir82 xamir82 revised this gist Apr 3, 2022. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -152,7 +152,7 @@ Only the artifacts that are strictly necessary for running the application shoul
    ```dockerfile
    EXPOSE 3000
    ```
    According to [the adapter-node documentation](https://github.com/sveltejs/kit/tree/master/packages/adapter-node#:~:text=By%20default%2C%20the%20server%20will%20accept%20connections%20on%200.0.0.0%20using%20port%203000.), the default port that that the application will run on is 3000, assuming this, we are exposing the port 3000 via this instruction.
    According to [the adapter-node documentation](https://github.com/sveltejs/kit/tree/master/packages/adapter-node#:~:text=By%20default%2C%20the%20server%20will%20accept%20connections%20on%200.0.0.0%20using%20port%203000.), the default port that the application will run on is 3000, assuming this, we are exposing the port 3000 via this instruction.

    You can also change the port by assigning a different number to the `PORT` environment variable, but there's no need to do that in this case.

  20. @xamir82 xamir82 revised this gist Apr 3, 2022. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -145,7 +145,7 @@ The adapter-node [documentation](https://github.com/sveltejs/kit/tree/master/pac
    And so here, we are copying the `node_modules` directory (stripped of all the dev dependencies, since we did `npm prune --production` in the previous stage), the `package.json` file, and of course the `build` directory, from the previous stage into the working directory.

    Note that some Dockerfiles (the one in this [article](https://blog.alexanderwolf.tech/how-to-dockerize-your-sveltekit-app/), for instance) make the mistake of copying everything from the first stage over to the second one, including the source files, this is completely redundant, unnecessarily increases the size of the image, and basically defeats the whole point of using multistage builds.
    The files that aren't required for running the application should be left out.
    Only the artifacts that are strictly necessary for running the application should be copied over to the final stage, everything else should be left out.

    ---

  21. @xamir82 xamir82 revised this gist Apr 2, 2022. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -136,7 +136,7 @@ Same as the one in the first stage. Sets the working directory to `/app`.

    ```dockerfile
    COPY --from=builder /app/build ./build
    COPY --from=builder /app/node_moduels ./node_moduels
    COPY --from=builder /app/node_modules ./node_modules
    COPY package.json .
    ```
    The adapter-node [documentation](https://github.com/sveltejs/kit/tree/master/packages/adapter-node#deploying) states the following:
  22. @xamir82 xamir82 revised this gist Apr 2, 2022. 1 changed file with 7 additions and 3 deletions.
    10 changes: 7 additions & 3 deletions DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -139,9 +139,13 @@ COPY --from=builder /app/build ./build
    COPY --from=builder /app/node_moduels ./node_moduels
    COPY package.json .
    ```
    Placeholder
    Note that some Dockerfiles (the one in this [article](https://blog.alexanderwolf.tech/how-to-dockerize-your-sveltekit-app/), for instance) make the mistake of copying everything from the first stage over to the, including the source files, this is completely redundant, unnecessarily increases the size of the image, and defeats the whole point of using multistage builds.
    So be careful to avoid this.
    The adapter-node [documentation](https://github.com/sveltejs/kit/tree/master/packages/adapter-node#deploying) states the following:
    > You will need the output directory (build by default), the project's package.json, and the production dependencies in node_modules to run the application.
    And so here, we are copying the `node_modules` directory (stripped of all the dev dependencies, since we did `npm prune --production` in the previous stage), the `package.json` file, and of course the `build` directory, from the previous stage into the working directory.

    Note that some Dockerfiles (the one in this [article](https://blog.alexanderwolf.tech/how-to-dockerize-your-sveltekit-app/), for instance) make the mistake of copying everything from the first stage over to the second one, including the source files, this is completely redundant, unnecessarily increases the size of the image, and basically defeats the whole point of using multistage builds.
    The files that aren't required for running the application should be left out.

    ---

  23. @xamir82 xamir82 revised this gist Apr 1, 2022. 1 changed file with 13 additions and 9 deletions.
    22 changes: 13 additions & 9 deletions DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -103,7 +103,7 @@ RUN npm run build && npm prune --production
    ```
    We run the `npm run build` command so that SvelteKit generates the `build` directory, containing a standalone Node server that serves our application — assuming, of course, that you're using adapter-node.

    We subsequently then run the `npm prune --production` command to delete all the dev dependencies from the "node_modules" folder, since we no longer need any of them.
    We subsequently run the `npm prune --production` command to delete all the dev dependencies from the "node_modules" folder, since we no longer need any of them.

    ### Final Stage:
    Now that we have our `build` directory and its contents ready, we can begin the final stage, which is responsible for running our application.
    @@ -112,21 +112,25 @@ Now that we have our `build` directory and its contents ready, we can begin the
    FROM mhart/alpine-node:slim-16
    ```

    The base image I'm using here may have caught your attention,
    The base image I'm using here may have caught your attention, as it is not the [official `node` image](https://hub.docker.com/_/node).

    The official Node image doesn't have a variant that's both alpine-based AND [slim](https://hub.docker.com/_/node#:~:text=node%3A%3Cversion%3E%2Dslim-,This%20image%20does%20not%20contain%20the%20common,-packages%20contained%20in), this is why we're using this third-party image called [mhart/alpine-node](https://github.com/mhart/alpine-node), which has a variant called slim (what we're using here), which is precisely what we want, namely alpine-based + slim.

    With this, the resulting image will be smaller than it would've been had we used `node:16-alpine` or `node:16-slim` — also interestingly, `node:<version>-slim` is actually bigger than `node:<version>-alpine` so there would've been no point in using the former. But a combination of the two is smaller than either one of them, which is, once again, what this image provides.

    ---

    ```dockerfile
    ENV NODE_ENV production
    ENV NODE_ENV=production
    ```
    Placeholder
    Here we set the `NODE-ENV` variable to `production`, to let Node.js and other code that we're about to run know that this is a production environment.

    ---

    ```dockerfile
    WORKDIR /app
    ```
    Placeholder
    Same as the one in the first stage. Sets the working directory to `/app`.

    ---

    @@ -144,18 +148,18 @@ So be careful to avoid this.
    ```dockerfile
    EXPOSE 3000
    ```
    The adapter-node documentation says the default port that that application will run on is 3000 — see [reference](https://github.com/sveltejs/kit/tree/master/packages/adapter-node#:~:text=By%20default%2C%20the%20server%20will%20accept%20connections%20on%200.0.0.0%20using%20port%203000.)assuming this, we are obviously exposing the port 3000 via this instruction.
    According to [the adapter-node documentation](https://github.com/sveltejs/kit/tree/master/packages/adapter-node#:~:text=By%20default%2C%20the%20server%20will%20accept%20connections%20on%200.0.0.0%20using%20port%203000.), the default port that that the application will run on is 3000, assuming this, we are exposing the port 3000 via this instruction.

    You can also change this using the `PORT` environment variable, but there's no need to do that in this case.
    You can also change the port by assigning a different number to the `PORT` environment variable, but there's no need to do that in this case.

    ---

    ```dockerfile
    CMD [ "node", "build" ]
    ```
    Placeholder
    We finally run the `node build` command — equivalent to `node build/index.js` — to start the server.

    ---

    Here's a great YouTube video on this subject:
    Also, here's a great YouTube video on this subject, building the same Dockerfile step-by-step:
    [Containerize SvelteKit NodeJs with Docker](https://www.youtube.com/watch?v=kVMG2nWjWk4)
  24. @xamir82 xamir82 revised this gist Apr 1, 2022. 1 changed file with 6 additions and 1 deletion.
    7 changes: 6 additions & 1 deletion DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -153,4 +153,9 @@ You can also change this using the `PORT` environment variable, but there's no n
    ```dockerfile
    CMD [ "node", "build" ]
    ```
    Placeholder
    Placeholder

    ---

    Here's a great YouTube video on this subject:
    [Containerize SvelteKit NodeJs with Docker](https://www.youtube.com/watch?v=kVMG2nWjWk4)
  25. @xamir82 xamir82 revised this gist Apr 1, 2022. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -101,9 +101,9 @@ This is a very common practice when writing Dockerfiles for Node applications an
    ```dockerfile
    RUN npm run build && npm prune --production
    ```
    We run the `npm run build` command, and subsequently SvelteKit will generate a `build` directory containing a standalone Node server that serves our application — assuming, of course, that you're using adapter-node.
    We run the `npm run build` command so that SvelteKit generates the `build` directory, containing a standalone Node server that serves our application — assuming, of course, that you're using adapter-node.

    We then run the `npm prune --production` command to delete all the dev dependencies, since we no longer need any them.
    We subsequently then run the `npm prune --production` command to delete all the dev dependencies from the "node_modules" folder, since we no longer need any of them.

    ### Final Stage:
    Now that we have our `build` directory and its contents ready, we can begin the final stage, which is responsible for running our application.
  26. @xamir82 xamir82 revised this gist Apr 1, 2022. 1 changed file with 5 additions and 13 deletions.
    18 changes: 5 additions & 13 deletions DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -99,10 +99,12 @@ This is a very common practice when writing Dockerfiles for Node applications an
    ---

    ```dockerfile
    RUN npm run build
    RUN npm run build && npm prune --production
    ```
    We run the `npm run build` command, and subsequently SvelteKit will generate a `build` directory containing a standalone Node server that serves our application — assuming, of course, that you're using adapter-node.

    We then run the `npm prune --production` command to delete all the dev dependencies, since we no longer need any them.

    ### Final Stage:
    Now that we have our `build` directory and its contents ready, we can begin the final stage, which is responsible for running our application.

    @@ -130,22 +132,12 @@ Placeholder

    ```dockerfile
    COPY --from=builder /app/build ./build
    ```
    Placeholder
    Note that some Dockerfiles make the mistake of copying everything from the first stage over to the, including the source files, this is completely redundant, unnecessarily increases the size of the image, and defeats the whole point of using multistage builds.
    So be careful to avoid this.

    ```dockerfile
    COPY --from=builder /app/node_moduels ./node_moduels
    ```
    Placeholder

    ---

    ```dockerfile
    COPY package.json .
    ```
    Placeholder
    Note that some Dockerfiles (the one in this [article](https://blog.alexanderwolf.tech/how-to-dockerize-your-sveltekit-app/), for instance) make the mistake of copying everything from the first stage over to the, including the source files, this is completely redundant, unnecessarily increases the size of the image, and defeats the whole point of using multistage builds.
    So be careful to avoid this.

    ---

  27. @xamir82 xamir82 revised this gist Apr 1, 2022. 1 changed file with 12 additions and 7 deletions.
    19 changes: 12 additions & 7 deletions DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -3,14 +3,14 @@
    # TL;DR:
    Dockerfile:
    ```dockerfile
    FROM node:lts-alpine AS builder
    FROM node:16-alpine AS builder
    WORKDIR /app
    COPY package*.json .
    RUN npm ci
    COPY . .
    RUN npm run build && npm prune --production

    FROM mhart/alpine-node:slim-lts
    FROM mhart/alpine-node:slim-16
    ENV NODE_ENV=production
    WORKDIR /app
    COPY --from=builder /app/build ./build
    @@ -49,9 +49,9 @@ This is highly recommended for applications that have a build step (such as Svel
    To learn more about multistage builds, see [official Docker documentation on multistage builds](https://docs.docker.com/develop/develop-images/multistage-build/).

    ```dockerfile
    FROM node:lts-alpine AS builder
    FROM node:16-alpine AS builder
    ```
    We are setting `node:lts-alpine` as the base image of our first stage, but you can of course change this, or use a specific version, if you see fit.
    We are setting `node:lts-alpine` as the base image of our first stage, but you can of course change this, or use another version, if you see fit.

    The `AS builder` part is simply assigning a custom name to this first stage, so that we can reference it later in the second stage more easily.

    @@ -107,7 +107,7 @@ We run the `npm run build` command, and subsequently SvelteKit will generate a `
    Now that we have our `build` directory and its contents ready, we can begin the final stage, which is responsible for running our application.

    ```dockerfile
    FROM mhart/alpine-node:slim-lts
    FROM mhart/alpine-node:slim-16
    ```

    The base image I'm using here may have caught your attention,
    @@ -129,12 +129,17 @@ Placeholder
    ---

    ```dockerfile
    COPY --from=builder /app/build .
    COPY --from=builder /app/build ./build
    ```
    Placeholder
    Note that some Dockerfiles make the mistake of copying everything from the first stage over to the, including the source files, this is completely redundant, unnecessarily increases the size of the image, and defeats the whole point of using multistage builds.
    So be careful to avoid this.

    ```dockerfile
    COPY --from=builder /app/node_moduels ./node_moduels
    ```
    Placeholder

    ---

    ```dockerfile
    @@ -154,6 +159,6 @@ You can also change this using the `PORT` environment variable, but there's no n
    ---

    ```dockerfile
    CMD [ "node", "." ]
    CMD [ "node", "build" ]
    ```
    Placeholder
  28. @xamir82 xamir82 revised this gist Apr 1, 2022. 1 changed file with 4 additions and 3 deletions.
    7 changes: 4 additions & 3 deletions DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -8,15 +8,16 @@ WORKDIR /app
    COPY package*.json .
    RUN npm ci
    COPY . .
    RUN npm run build
    RUN npm run build && npm prune --production

    FROM mhart/alpine-node:slim-lts
    ENV NODE_ENV=production
    WORKDIR /app
    COPY --from=builder /app/build .
    COPY --from=builder /app/build ./build
    COPY --from=builder /app/node_modules ./node_modules
    COPY package.json .
    EXPOSE 3000
    CMD [ "node", "." ]
    CMD [ "node", "build" ]
    ```

    .dockerignore:
  29. @xamir82 xamir82 revised this gist Apr 1, 2022. 1 changed file with 5 additions and 5 deletions.
    10 changes: 5 additions & 5 deletions DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -67,11 +67,11 @@ This instruction is pretty self-explanatory. We're simply setting the working di
    ---

    ```dockerfile
    COPY package*.json ./
    COPY package*.json .
    ```

    We copy the `package.json` + `package-lock.json` files into the working directory.
    The wildcard character `*` here is for convenience, it's to avoid explicitly naming both files, like `COPY package.json package-lock.json ./`.
    The wildcard character `*` here is for convenience, it's to avoid explicitly naming both files, like `COPY package.json package-lock.json .`.

    ---

    @@ -87,7 +87,7 @@ Note that we can't do `npm ci --production` — which doesn't install the dev de
    ---

    ```dockerfile
    COPY . ./
    COPY . .
    ```
    This instruction copies the rest of the source files into the working directory.

    @@ -128,7 +128,7 @@ Placeholder
    ---

    ```dockerfile
    COPY --from=builder /app/build ./
    COPY --from=builder /app/build .
    ```
    Placeholder
    Note that some Dockerfiles make the mistake of copying everything from the first stage over to the, including the source files, this is completely redundant, unnecessarily increases the size of the image, and defeats the whole point of using multistage builds.
    @@ -137,7 +137,7 @@ So be careful to avoid this.
    ---

    ```dockerfile
    COPY package.json ./
    COPY package.json .
    ```
    Placeholder

  30. @xamir82 xamir82 revised this gist Apr 1, 2022. 1 changed file with 5 additions and 5 deletions.
    10 changes: 5 additions & 5 deletions DockerfileForSvelteKit.md
    Original file line number Diff line number Diff line change
    @@ -5,16 +5,16 @@ Dockerfile:
    ```dockerfile
    FROM node:lts-alpine AS builder
    WORKDIR /app
    COPY package*.json ./
    COPY package*.json .
    RUN npm ci
    COPY . ./
    COPY . .
    RUN npm run build

    FROM mhart/alpine-node:slim-lts
    ENV NODE_ENV production
    ENV NODE_ENV=production
    WORKDIR /app
    COPY --from=builder /app/build ./
    COPY package.json ./
    COPY --from=builder /app/build .
    COPY package.json .
    EXPOSE 3000
    CMD [ "node", "." ]
    ```