Подтвердить что ты не робот

Node и докер - как обращаться с babel или typescript build?

У меня есть приложение node, которое я хочу разместить в контейнере Docker, который должен быть прямым, как показано в этой статье:

https://nodejs.org/en/docs/guides/nodejs-docker-webapp/

В моем проекте, однако, источники не могут запускаться напрямую, они должны быть скомпилированы из ES6 и/или Typescript. Я использую gulp для сборки с помощью babel, браузера и tsify - с различными настройками для браузера и сервера.

Каким будет лучший рабочий процесс для создания и автоматизации docker-изображений в этом случае? Есть ли в Интернете ресурсы, описывающие такой рабочий процесс? Должен ли Dockerimage делать здание после npm install или мне нужно создать оболочку script, чтобы сделать все это и просто иметь пакет Dockerfile все вместе?

Если Dockerfile должен выполнить сборку - образ должен содержать все dev-зависимости, которые не идеальны?

Примечание. Я смог настроить контейнер докеров и запустить его, но для этого потребовались все файлы, которые необходимо установить и создать заранее.

4b9b3361

Ответ 1

Одним из возможных решений является обертывание вашей процедуры сборки в специальном изображении докеров. Его часто называют Изображение Builder. Он должен содержать все ваши зависимости сборки: nodejs, npm, gulp, babel, tsc и т.д. Он инкапсулирует весь ваш процесс сборки, устраняя необходимость установки этих инструментов на хосте.

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

В качестве первого шага вы берете свой встроенный код и упаковываете его в образцовое изображение докеры, как и сейчас.

Ниже приведен пример изображения docker builder для TypeScript: https://hub.docker.com/r/sandrokeil/typescript/

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

Хорошая вещь о изображении строителя заключается в том, что ваша среда хоста остается незагрязненной, и вы можете попробовать более новые версии компилятора/разных инструментов/изменить порядок/выполнить задачи параллельно, модифицируя файл Docker вашего образа строителя. И в любое время вы можете откатить свой эксперимент с помощью процедуры сборки.

Ответ 2

Я лично предпочитаю просто удалять зависимости dev после запуска babel во время сборки:

FROM node:7

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install

# Copy app source
COPY src /usr/src/app/src

# Compile app sources
RUN npm run compile

# Remove dev dependencies
RUN npm prune --production

# Expose port and CMD
EXPOSE 8080
CMD [ "npm", "start" ]

Ответ 3

Следуй этим шагам:

Шаг 1: убедитесь, что внутри ваших зависимостей есть babel- зависимости, а не dev-зависимости на package.json. Также добавьте скрипт развертывания, который ссылается на babel, из папки node_modules. Вы будете вызывать этот скрипт из докера. Так выглядит мой файл package.json.

{
  "name": "tmeasy_api",
  "version": "1.0.0",
  "description": "Trade made easy Application",
  "main": "build/index.js",
  "scripts": {    
     "build": "babel -w src/ -d build/ -s inline",
    "deploy" : "node_modules/babel-cli/bin/babel.js src/ -d build/",
  },
  "devDependencies": {   
    "nodemon": "^1.9.2"
  },
  "dependencies": {    
    "babel-cli": "^6.10.1",
    "babel-polyfill": "^6.9.1",
    "babel-preset-es2015": "^6.9.0",
    "babel-preset-stage-0": "^6.5.0",
    "babel-preset-stage-3": "^6.22.0"
  }
}

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

Шаг 2: так как мы хотим сами выполнить преобразование babael, обязательно добавьте .dockerignore в папку сборки, которую вы используете во время разработки. Вот так выглядит мой файл .dockerignore.

    build
    node_modules    

Шаг 3. Создайте свой докер файл. ниже приведен пример моего файла Docker

FROM node:6

MAINTAINER stackoverflow

ENV NODE_ENV=production
ENV PORT=3000

# use changes to package.json to force Docker not to use the cache
# when we change our application nodejs dependencies:

ADD package.json /tmp/package.json
RUN cd /tmp && npm install
RUN mkdir -p /var/www && cp -a /tmp/node_modules /var/www

# copy current working directory into docker; but it first checks for  
# .dockerignore so build will not be included.

COPY      . /var/www/
WORKDIR   /var/www/

# remove any previous builds and create a new build folder and then
# call our node script deploy

RUN rm -f build
RUN mkdir build
RUN chmod 777 /var/www/build
RUN npm run deploy

VOLUME    /var/www/uploads
EXPOSE $PORT


ENTRYPOINT ["node","build/index.js"]

Ответ 4

Я только что выпустил большое приложение для семян для Typescript и Node.js, используя Docker.

Вы можете найти его на GitHub.

Проект объясняет все команды, используемые Dockerfile, и объединяет tsc с gulp для некоторых дополнительных преимуществ.

Если вы не хотите проверять репо, здесь подробности:

Dockerfile

FROM node:8

ENV USER=app

ENV SUBDIR=appDir

RUN useradd --user-group --create-home --shell /bin/false $USER &&\
    npm install --global tsc-watch npm ntypescript typescript gulp-cli

ENV HOME=/home/$USER

COPY package.json gulpfile.js $HOME/$SUBDIR/

RUN chown -R $USER:$USER $HOME/*

USER $USER

WORKDIR $HOME/$SUBDIR

RUN npm install

CMD ["node", "dist/index.js"]

докер-compose.yml

version: '3.1'

services:
  app:
    build: .
    command: npm run build
    environment:
      NODE_ENV: development
    ports:
      - '3000:3000'
    volumes:
      - .:/home/app/appDir
      - /home/app/appDir/node_modules

package.json

{
  "name": "docker-node-typescript",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "build": "gulp copy; gulp watch & tsc-watch -p . --onSuccess \"node dist/index.js\"",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "Stephen Gardner ([email protected])",
  "license": "ISC",
  "dependencies": {
    "express": "^4.10.2",
    "gulp": "^3.9.1",
    "socket.io": "^1.2.0"
  },
  "devDependencies": {
    "@types/express": "^4.11.0",
    "@types/node": "^8.5.8"
  }
}

tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "outDir": "./dist/",
    "sourceMap": true,
    "declaration": false,
    "module": "commonjs",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "ES6"
  },
  "include": [
    "**/*.ts"
  ],
  "exclude": [
    "node_modules",
    "**/*.spec.ts"
  ]
}

Чтобы получить больше ответа на ваш вопрос - ts скомпилируется из вызова docker-compose.yml файла npm run build, который затем вызывает tsc. tsc затем копирует наши файлы в папку dist, и простая команда node dist/index.js запускает этот файл. Вместо использования nodemon мы используем tsc-watch и gulp.watch для просмотра изменений в приложении и fire node dist/index.js снова после каждой повторной компиляции.

Надеюсь, что поможет:) Если у вас есть какие-либо вопросы, дайте мне знать!

Ответ 5

На данный момент я использую рабочий процесс, где:

  • npm install и tsd install локально
  • gulp создать локально
  • В Dockerfile скопируйте все файлы программы, но не typings/ node_modules для изображения докеров
  • В файле Docker, npm install --production

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

Dockerfile:

FROM node:5.1

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Bundle app
COPY package.json index.js /usr/src/app/
COPY views/ /usr/src/app/views/
COPY build/ /usr/src/app/build/
COPY public/ /usr/src/app/public/

# Install app dependencies
RUN npm install --production --silent

EXPOSE 3000
CMD [ "node", "index.js" ]

Я предполагаю, что полная автоматизация в "процессе обработки изображений" может быть установлена ​​путем создания в Dockerimage script, а затем удаления ненужных файлов перед установкой снова.

Ответ 6

Современная рекомендация для такого рода вещей (по состоянию на Docker 17.05) - использовать многоэтапную сборку. Таким образом, вы можете использовать все ваши зависимости dev/build в одном Dockerfile, но при этом конечный результат будет оптимизирован и свободен от ненужного кода.

Я не очень знаком с машинопись, но здесь пример реализации с использованием пряжи и Babel. Используя этот Dockerfile, мы можем создать образ разработки (с помощью docker build --target development.) Для локального запуска nodemon, тестов и т. Д.; но с прямой docker build. мы получаем оптимизированный производственный образ, который запускает приложение с pm2.

# common base image for development and production
FROM node:10.11.0-alpine AS base
WORKDIR /app


# dev image contains everything needed for testing, development and building
FROM base AS development
COPY package.json yarn.lock ./

# first set aside prod dependencies so we can copy in to the prod image
RUN yarn install --pure-lockfile --production
RUN cp -R node_modules /tmp/node_modules

# install all dependencies and add source code
RUN yarn install --pure-lockfile
COPY . .


# builder runs unit tests and linter, then builds production code 
FROM development as builder
RUN yarn lint
RUN yarn test:unit --colors
RUN yarn babel ./src --out-dir ./dist --copy-files


# release includes bare minimum required to run the app, copied from builder
FROM base AS release
COPY --from=builder /tmp/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package.json ./
CMD ["yarn", "pm2-runtime", "dist/index.js"]

Ответ 7

В моем проекте, однако, источники не могут запускаться напрямую, они должны быть скомпилированы из ES6 и/или Typescript. Я использую gulp для сборки с помощью babel, браузера и tsify - с различными настройками для браузера и сервера. Каким будет лучший рабочий процесс для создания и автоматизации изображений докеров в этом случае?

Когда я понимаю вас правильно, вы хотите развернуть свое веб-приложение внутри контейнера Docker и предоставить различные варианты для разных целевых сред (вы упомянули разные браузеры и сервер). (1)

Если Dockerfile должен выполнить сборку - образ должен содержать все dev-зависимости, которые не идеальны?

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

На этапе разработки это изображение не обязательно необходимо из-за вашей обычно предопределенной dev-среды. Это требует времени и ресурсов, если вы создаете такое изображение после каждого изменения.

Предлагаемый подход: Я бы предложил двухстороннюю настройку:

  • Во время разработки: используйте постоянную среду для разработки своего приложения. Все программное обеспечение может работать локально или внутри докера/виртуальной машины. Я предлагаю использовать контейнер Docker с вашей настройкой dev, особенно если вы работаете в команде, и каждый должен иметь один и тот же dev-basement.
  • Развертывание веб-приложения. Как я понял, вы правы (1), вы хотите развернуть приложение для разных сред и, следовательно, нужно создавать/предоставлять различные конфигурации. Чтобы реализовать что-то подобное, вы можете начать с оболочки script, которая упаковывает ваше приложение в другой контейнер докеров. Вы запускаете script перед развертыванием. Если у вас запущен Jekyll, он вызывает ваш shell-script после каждой фиксации после того, как все тесты прошли нормально.

Контейнер докеров для этапа разработки и развертывания: Я хотел бы сослаться на проект моего и коллеги: https://github.com/k00ni/Docker-Nodejs-environment

Этот докер обеспечивает всю среду разработки и развертывания, поддерживая:

  • Node.js
  • NPM
  • Gulp
  • Вавилон (автоматическая трансляция из ECMA6 в JavaScript при смене файла)
  • Webpack

и других помощников JavaScript внутри контейнера докеров. Вы просто связываете папку своего проекта с помощью тома внутри контейнера докеров. Он инициализирует вашу среду (например, развертывает все зависимости от package.json), и вам хорошо идти.

Вы можете использовать его для целей разработки, чтобы вы и ваша команда использовали одну и ту же среду (Node.js версия, версия NPM,...) Еще одно преимущество заключается в том, что изменения файла приводят к повторной компиляции файлов ECMA6/ReactJS/... в файлы JavaScript (не нужно делать это вручную после каждого изменения). Для этого мы используем Вавилон.

Для целей развертывания просто расширьте это изображение докеры и измените необходимые части. Вместо того, чтобы связывать ваше приложение внутри контейнера, вы можете вытащить его через Git (или что-то в этом роде). Вы будете использовать один и тот же подвал для всей своей работы.