Dockerfile для Fresh

Fresh — это современный фреймворк для разработки веб-приложений на JavaScript и TypeScript с использованием Deno. Для развёртывания приложений в контейнерах Docker важно создать эффективный Dockerfile, который обеспечит быстрый билд, минимальный размер образа и корректное выполнение приложения. Рассмотрим пошаговую организацию Dockerfile для Fresh.


Базовый образ

Для Fresh предпочтительно использовать официальные образы Deno, так как они уже содержат интерпретатор и оптимизированы для выполнения TypeScript и Jav * aScript:

FROM denoland/deno:alpine-1.42.0

Использование Alpine минимизирует размер итогового образа. Версия Deno фиксируется для предсказуемости билдов и совместимости с зависимостями проекта.


Настройка рабочей директории

Определение рабочей директории обеспечивает изоляцию файлов проекта внутри контейнера:

WORKDIR /app

Все команды последующего копирования и установки будут выполняться относительно /app.


Копирование файлов и зависимостей

Для ускорения сборки контейнера рекомендуется сначала копировать только файлы, отвечающие за зависимости, и установить их, а затем копировать весь проект. В Fresh зависимости управляются через import_map.json и deno.json:

COPY deno.json import_map.json ./
RUN deno cache main.ts

Команда deno cache загружает все внешние зависимости и кэширует их, что позволяет при последующих изменениях кода не пересобирать слои с зависимостями.

После кэширования зависимостей копируются остальные файлы проекта:

COPY . .

Сборка и оптимизация

Fresh поддерживает компиляцию в Deno Deploy или генерацию статических ресурсов. Для контейнеризации может потребоваться подготовка билда:

RUN deno task build

Если проект использует TypeScript, этот этап гарантирует компиляцию всех файлов и проверку типов.


Настройка прав и пользователя

Для безопасности контейнера рекомендуется запускать приложение не от root:

USER deno

Официальный образ Deno содержит пользователя deno, у которого есть доступ к рабочей директории /app.


Экспонирование порта

Fresh по умолчанию слушает порт 8000, его необходимо открыть в контейнере:

EXPOSE 8000

Команда запуска

Для запуска приложения используется стандартная команда Deno:

CMD ["run", "--allow-net", "--allow-read", "main.ts"]
  • --allow-net позволяет приложению принимать сетевые подключения.
  • --allow-read даёт доступ к файловой системе контейнера.
  • main.ts — точка входа приложения Fresh.

Для Production можно использовать флаг --unstable при необходимости включения экспериментальных возможностей Deno или флаг --no-check для ускорения старта.


Минимизация образа

Для уменьшения размера образа часто применяют двухэтапную сборку:

# Stage 1: билд
FROM denoland/deno:alpine-1.42.0 AS build
WORKDIR /app
COPY deno.json import_map.json ./
COPY . .
RUN deno task build

# Stage 2: минимальный runtime
FROM denoland/deno:alpine-1.42.0
WORKDIR /app
COPY --from=build /app ./
USER deno
EXPOSE 8000
CMD ["run", "--allow-net", "--allow-read", "main.ts"]

Такой подход позволяет исключить лишние зависимости и исходные файлы, оставив только готовый билд приложения, что значительно уменьшает итоговый размер контейнера и ускоряет его запуск.


Кэширование слоёв и ускорение сборки

  • Разделение копирования зависимостей и исходного кода позволяет Docker использовать кэш слоёв при изменении только кода.
  • Использование deno cache на начальном этапе обеспечивает скачивание всех внешних модулей до копирования остального проекта.
  • Минимизация числа RUN-команд объединением нескольких действий снижает количество слоёв и ускоряет сборку.

Работа с конфигурацией

Fresh позволяет управлять настройками через deno.json, что упрощает интеграцию с Docker. Например, можно определить таски:

{
  "tasks": {
    "start": "deno run --allow-net --allow-read main.ts",
    "build": "deno bundle main.ts dist/main.js"
  }
}

В Dockerfile это позволяет заменить длинные команды на вызов deno task start или deno task build.


Поддержка Hot Reload (для dev-среды)

Для разработки внутри Docker удобно использовать Live Reload с помощью Fresh CLI:

CMD ["task", "start:dev"]

Где start:dev в deno.json может быть настроен как:

{
  "tasks": {
    "start:dev": "fresh dev"
  }
}

Это обеспечивает автоматическую перезагрузку при изменении файлов проекта.


Такой подход к написанию Dockerfile для Fresh позволяет сочетать эффективность билда, безопасность контейнера, минимальный размер образа и простоту конфигурации для Production и Development сред.