Home > Software design >  How do I build a docker image from a Sveltekit app
How do I build a docker image from a Sveltekit app

Time:12-09

I am trying to build a docker image from a sample app I have created in Sveltekit.

I am using the @sveltejs/adapter-auto and have included both .js files for API calls and .svelte files in my routes folder.

Here is my Dockerfile (which builds fine, but might not be correct)

FROM node:14.15.0 as build

# install dependencies
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci

# Copy all local files into the image.
COPY . .

RUN npm run build

###
# Only copy over the Node pieces we need
# ~> Saves 35MB
###
FROM node:14.15.0

WORKDIR /app
COPY --from=build /app/.svelte-kit/build/. .


EXPOSE 3000
CMD ["node", "./app.js"]

When I try to run a container from the docker image, I get the error output

(node:1) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/app/app.js:1
import { respond } from '@sveltejs/kit/ssr';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (internal/modules/cjs/loader.js:979:16)
    at Module._compile (internal/modules/cjs/loader.js:1027:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
    at internal/main/run_main_module.js:17:47

My package.json does contain "type": "module"

{
  "name": "backendtest",
  "version": "0.0.1",
  "scripts": {
    "dev": "svelte-kit dev",
    "build": "svelte-kit build",
    "package": "svelte-kit package",
    "preview": "svelte-kit preview",
    "lint": "prettier --ignore-path .gitignore --check --plugin-search-dir=. .",
    "format": "prettier --ignore-path .gitignore --write --plugin-search-dir=. ."
  },
  "devDependencies": {
    "@sveltejs/adapter-auto": "next",
    "@sveltejs/kit": "next",
    "prettier": "^2.4.1",
    "prettier-plugin-svelte": "^2.4.0",
    "svelte": "^3.44.0"
  },
  "type": "module",
  "dependencies": {
    "dotenv": "^10.0.0",
    "mongodb": "^4.2.1"
  }
}

When I try to run npm run build in my local build environment I get the message.

Using @sveltejs/adapter-auto
  Could not detect a supported production environment. See https://kit.svelte.dev/docs#adapters to learn how to configure your app to run on the platform of your choosing

As I am new to svelte, not sure if this is correct.

If I try to use the node adapter, I get an error

config.kit.adapter should be an object with an "adapt" method. See https://kit.svelte.dev/docs#adapters
Error: config.kit.adapter should be an object with an "adapt" method. See https://kit.svelte.dev/docs#adapters
    at file:///Users/simon/development/svelte/my-app/node_modules/@sveltejs/kit/dist/cli.js:391:12
    at file:///Users/simon/development/svelte/my-app/node_modules/@sveltejs/kit/dist/cli.js:599:43
    at file:///Users/simon/development/svelte/my-app/node_modules/@sveltejs/kit/dist/cli.js:585:18
    at file:///Users/simon/development/svelte/my-app/node_modules/@sveltejs/kit/dist/cli.js:585:18
    at validate_config (file:///Users/simon/development/svelte/my-app/node_modules/@sveltejs/kit/dist/cli.js:739:9)
    at load_config (file:///Users/simon/development/svelte/my-app/node_modules/@sveltejs/kit/dist/cli.js:704:20)
    at async get_config (file:///Users/simon/development/svelte/my-app/node_modules/@sveltejs/kit/dist/cli.js:774:10)
    at async file:///Users/simon/development/svelte/my-app/node_modules/@sveltejs/kit/dist/cli.js:884:18

Here is my svelte.config.js contents

import adapter from '@sveltejs/adapter-node';

/** @type {import('@sveltejs/kit').Config} */
const config = {
    kit: {
        adapter: adapter(),

        // hydrate the <div id="svelte"> element in src/app.html
        target: '#svelte'
    }
};

export default config;

I have also tried the following svelte.config.js as per the github docs, but get the same "adapt" error

import adapter from '@sveltejs/adapter-node';

/** @type {import('@sveltejs/kit').Config} */
const config = {
  kit: {
    adapter: adapter({
      // default options are shown
      out: 'build',
      precompress: false,
      env: {
        host: 'HOST',
        port: 'PORT',
      },
    }),
  },
};

export default config;

CodePudding user response:

include your package.json in your final docker image

Edit: also I'm not sure you should use .svelte-kit/build since this is an intermediate result used by sveltekit internally. You should have a build folder after running build task but I'm not sure cause I never used auto adapter, I usually use node adapter.

Mine basically looks like this:

COPY --from=build /app/package.json /app/build /app/
CMD ["node", "index.js"]

CodePudding user response:

Try to copy the whole folder as following:

FROM node:14.15.0 as build

# install dependencies
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci

# Copy all local files into the image.
COPY . .

RUN npm run build

###
# Only copy over the Node pieces we need
# ~> Saves 35MB
###
FROM node:14.15.0

WORKDIR /app
COPY --from=build /app .
COPY . .


EXPOSE 3000
CMD ["node", "./app.js"]
  • Related