SvelteKit(hello world)를 Docker Container로 띄우기

Create app

mkdir sveltekit-hello-world
npx sv create .

으로 hello-world를 생성한다. 

옵션에는 pnpm으로 설치하게 선택하였다.

 

.dockerignore 생성
→ 다 때려 넣어준다

Dockerfile
.git
.gitignore
.gitattributes
README.md
.npmrc
.prettierrc
.eslintrc.cjs
.graphqlrc
.editorconfig
.svelte-kit
.vscode
node_modules
npm-debug.log
build
package
.env* 
!.env.*.set

마지막 줄은 있다가 사용할 것이라 예외 처리

 

dependency 설치

pnpm add @sveltejs/adapter-node --save-dev

 

svelete.config.js file을 아래와 같이 수정

- import adapter from '@sveltejs/adapter-auto';  // delete
+ import adapter from '@sveltejs/adapter-node';  // add


→ Svelte는 여러 환경과 플랫폼을 지원하기 위해 adapter의 종류가 많다.
adapter-auto는 docker container 배포에 이상적이지 않은 면이 있고 특히 adapter-node는 node server를 시작할 수 있는 entry point를 제공해주기 때문에, 배포시에 adapter-auto보다 adapter-node를 더 많이 쓴다.

 

Dockerfile

create Dockerfile  생성 → multi-stage로 작성

 

# Stage 1: Build the SvelteKit app
FROM node:22-alpine AS builder

RUN corepack enable
WORKDIR /app

# Install dependencies using pnpm
COPY package.json pnpm-lock.yaml ./
RUN pnpm install

# Copy all files and build
COPY . .
RUN pnpm build
RUN pnpm prune --production

# Stage 2: Run the production server
FROM node:22-alpine AS runner

WORKDIR /app

# Copy production output from builder (using the default output location)
COPY --from=builder /app/build build/
COPY --from=builder /app/node_modules node_modules/

EXPOSE 3000
ENV NODE_ENV=production

# Run the server using the entry file in the output directory
CMD [ "node", "build" ]

pnpm으로 설치하기 위해 corepack enable을 한다.
pnpm prune --production은 위에서처럼 --save-dev로 설치했던 dependencies를 제거하여 최종 이미지의 크기를 줄여준다.

 

빌드하고 실행

docker build -t hello-svelte .
docker run -d -p 3000:3000 hello-svelte

 

너무 간단한 것 같으니, 추가로 환경변수까지 추가해서 배포해보자.

 

환경 변수 추가

develop, stage, production에서 각각 사용하는 환경변수를 추가해서 빌드해보자.
SvelteKit 폴더에서 우선 다음 두 dependencies를 설치한다.

pnpm add -D dotenv cross-env

 

다음 파일들을 생성한다.
.env.develop.set

PUBLIC_API_URL=https://dev-api.example.com
DATABASE_URL=postgres://user:password@dev-db.example.com:5432/myapp
LOG_LEVEL=debug

 

.env.stage.set

PUBLIC_API_URL=https://stage-api.example.com
DATABASE_URL=postgres://user:password@stage-db.example.com:5432/myapp
LOG_LEVEL=info

 

.env.production.set

PUBLIC_API_URL=https://api.example.com
DATABASE_URL=postgres://user:password@db.example.com:5432/myapp
LOG_LEVEL=warn

 

svelte.config.js를 다음과 같이 변경한다.

import adapter from '@sveltejs/adapter-node';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
import * as dotenv from 'dotenv';

// 환경변수 불러오기
const envType = process.env.APP_ENV || 'develop';
console.log(`Loading environment: ${envType}`);
dotenv.config({ path: `.env.${envType}.set` });

/** @type {import('@sveltejs/kit').Config} */
const config = {
    preprocess: vitePreprocess(),
    kit: {
        adapter: adapter({
            out: 'build'
        }),
        env: {
            publicPrefix: 'PUBLIC_'
        }
    }
};

export default config;

 

package.json에 다음 script를 6줄을 추가해준다.

"scripts": {

  "build:develop": "cross-env APP_ENV=develop vite build",
  "build:stage": "cross-env APP_ENV=stage vite build",
  "build:prod": "cross-env APP_ENV=production vite build",

  "preview:develop": "cross-env APP_ENV=develop vite preview",
  "preview:stage": "cross-env APP_ENV=stage vite preview",
  "preview:prod": "cross-env APP_ENV=production vite preview",

}

 

Dockerfile을 다음처럼 ${APP_ENV}라는 인자를 받아 빌드할 수 있도록 수정한다.

# Stage 1: Build the SvelteKit app
FROM node:22-alpine AS builder

RUN corepack enable
WORKDIR /app

# Add build argument for environment
ARG APP_ENV=develop
ENV APP_ENV=${APP_ENV}

# Install dependencies using pnpm
COPY package.json pnpm-lock.yaml ./
RUN pnpm install

# First run svelte-kit sync to ensure adapters are configured
RUN pnpm svelte-kit sync

# Copy all files and build
COPY . .
RUN pnpm build:${APP_ENV}
RUN pnpm prune --production

# Stage 2: Run the production server
FROM node:22-alpine AS runner

WORKDIR /app

# Add runtime argument for environment
ARG APP_ENV=develop
ENV APP_ENV=${APP_ENV}
ENV NODE_ENV=production

# Copy environment files
COPY .env.*.set ./

# Copy production output from builder (using the default output location)
COPY --from=builder /app/build build/
COPY --from=builder /app/node_modules node_modules/

EXPOSE 3000

# Run the server using the entry file in the output directory
CMD [ "node", "build" ]

 

 

다음 docker build와 docker run 명령어로 각 기별로 container를 실행할 수 있다.

docker build --build-arg APP_ENV=develop -t svelte-app:develop .
docker build --build-arg APP_ENV=stage -t svelte-app:stage .
docker build --build-arg APP_ENV=production -t svelte-app:production .

docker run -p 3000:3000 -e APP_ENV=develop svelte-app:develop
docker run -p 3000:3000 -e APP_ENV=stage svelte-app:stage
docker run -p 3000:3000 -e APP_ENV=production svelte-app:production

 

  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유