2016-05-24 31 views
11

Ho un'applicazione nodo che voglio ospitare in un contenitore Docker, che dovrebbe essere semplice, come si vede in questo articolo:Nodo e finestra mobile - come gestire babel o dattiloscritto?

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

Nel mio progetto, tuttavia, le fonti non può essere eseguito direttamente, devono essere compilati da ES6 e/o Typescript. Io uso gulp per costruire con babel, browserify e tsify - con diverse impostazioni per browser e server.

Quale sarebbe il miglior flusso di lavoro per la creazione di e l'automazione delle immagini del docker in questo caso? Ci sono risorse sul web che descrivono un tale flusso di lavoro? Il Dockerimage dovrebbe fare l'edificio dopo npm install o dovrei creare uno script di shell per fare tutto questo e semplicemente avere il Dockerfile comprimere tutto insieme?

Se il Dockerfile dovrebbe eseguire la build, l'immagine dovrà contenere tutte le dipendenze di dev, che non sono l'ideale?

Nota: sono stato in grado di configurare un contenitore finestra mobile ed eseguirlo, ma in questo caso tutti i file devono essere installati e creati in anticipo.

risposta

7

Una possibile soluzione è avvolgere la procedura di compilazione in un'immagine di finestra mobile speciale. Viene spesso indicato come Immagine builder. Dovrebbe contenere tutte le dipendenze di build: nodejs, npm, gulp, babel, tsc e così via. Incapsula tutto il processo di compilazione, eliminando la necessità di installare questi strumenti sull'host.

Prima di eseguire l'immagine del builder, montare la directory del codice sorgente come volume. Lo stesso o un volume separato può essere usato come directory di output. La prima immagine prende il tuo codice ed esegue tutti i comandi di compilazione.

Come primo passo, si prende il codice generato e lo si inserisce nell'immagine di finestra mobile di produzione come si fa ora.

Ecco un esempio un'immagine costruttore finestra mobile di per dattiloscritto: https://hub.docker.com/r/sandrokeil/typescript/

è ok per avere lo stesso costruttore finestra mobile per diversi progetti in quanto è in genere progettati per essere di uso generale wrapper per alcuni strumenti comuni. Ma è corretto costruire il proprio che descrive una procedura più complicata.

L'aspetto positivo dell'immagine del builder è che l'ambiente host non è inquinato e si è liberi di provare versioni più recenti del compilatore/strumenti diversi/modificare l'ordine/eseguire attività in parallelo semplicemente modificando il Dockerfile dell'immagine del builder. E in qualsiasi momento puoi eseguire il rollback del tuo esperimento con la procedura di compilazione.

+0

Suppongo che tu suggerisca un'immagine docker separata per il processo di compilazione, che può essere avviata per eseguire la build. Quindi l'immagine di produzione effettiva contiene questo output di build? –

+0

Sei libero di includere qualsiasi contenuto nell'immagine di produzione. Utilizza un Dockerfile separato, quindi puoi includere sia l'output di build che alcuni file originali (file di configurazione e così via) – gerichhome

2

Per il momento, sto utilizzando un flusso di lavoro in cui:

  1. npm install e tsd install localmente
  2. gulp accumulo localmente
  3. In Dockerfile, copiare tutti i file di programma, ma non tipizzazioni/node_modules per finestra mobile immagine
  4. In Dockerfile, npm install --production

In questo modo ottengo solo i file desiderati nell'immagine, ma sarebbe meglio se il Dockerfile potesse fare la build stessa.

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" ] 

immagino una completa automazione del "processo di imaging" potrebbe essere stabilita con la costruzione nello script Dockerimage e quindi eliminando i file indesiderati prima di installare di nuovo.

0

Nel mio progetto, tuttavia, le origini non possono essere eseguite direttamente, devono essere compilate da ES6 e/o Typescript. Io uso gulp per costruire con babel, browserify e tsify - con diverse impostazioni per browser e server. Quale sarebbe il miglior flusso di lavoro per la creazione e l'automazione delle immagini di finestra mobile in questo caso?

Quando ho saputo che a destra, si desidera distribuire le tue applicazioni Web all'interno di un contenitore Docker e fornire gusti diversi per i diversi target di-ambienti (voi hanno citato browser e server diverso). (1)

Se la Dockerfile dovrebbe fare la formazione - l'immagine dovrebbe contenere tutti i dev-dipendenze, che non sono l'ideale?

Dipende. Se vuoi fornire un'immagine pronta per l'uso, deve contenere tutto ciò che la tua app web deve eseguire. Un vantaggio è che in seguito devi solo avviare il contenitore, passare alcuni parametri e sei pronto per partire.

Durante la fase di sviluppo, quell'immagine non è realmente necessaria, a causa del proprio ambiente di sviluppo predefinito predefinito. Costa tempo e risorse, se si genera tale immagine dopo ogni modifica.

approccio consigliata: Vorrei suggerire una configurazione a due vie:

  1. Durante lo sviluppo: utilizzare un ambiente fisso per sviluppare la vostra applicazione. Tutto il software può essere eseguito localmente o all'interno di una finestra mobile/VM. Suggerisco di usare un contenitore Docker con il tuo dev-setup, specialmente se lavori in una squadra e tutti hanno bisogno di avere lo stesso dev-seminterrato.
  2. Distribuire app Web: Come ho capito bene (1), si desidera distribuire l'app per diversi ambienti e quindi è necessario creare/fornire diverse configurazioni. Per realizzare qualcosa del genere, potresti iniziare con uno script di shell che impacchetta la tua app in un contenitore docker differente. Si esegue lo script prima della distribuzione. Se hai in esecuzione Jekyll, chiama lo script della shell dopo ogni commit, dopo che tutti i test sono andati a buon fine.

Docker contenitore sia per lo sviluppo e distribuire fase: Vorrei fare riferimento a un mio progetto e un collega: https://github.com/k00ni/Docker-Nodejs-environment

Questa finestra mobile fornisce un insieme sviluppo- e distribuire-ambiente attraverso il mantenimento:

  • Nodo.js
  • NPM
  • Gulp
  • Babel (auto transpiling da ECMA6 a JavaScript su una modifica di file)
  • Webpack

e altri soccorritori JavaScript all'interno del contenitore finestra mobile. Basta collegare la cartella del progetto tramite un volume all'interno della finestra mobile. Inizializza il tuo ambiente (ad es. Distribuisce tutte le dipendenze da package.json) e sei a posto.

Lo si può utilizzare per lo sviluppo scopi in modo che voi e il vostro team stanno utilizzando lo stesso ambiente (versione Node.js, versione NPM, ...) Un altro vantaggio è, che i cambiamenti dei file portare ad una ri-compilazione di file ECMA6/ReactJS/... in file JavaScript (non è necessario eseguire questa operazione manualmente dopo ogni modifica). Usiamo Babel per quello.

Per gli scopi di distribuzione, estendere questa immagine di Docker e modificare le parti richieste. Invece di collegare la tua app all'interno del contenitore, puoi estrarla tramite Git (o qualcosa del genere). Userai lo stesso seminterrato per tutto il tuo lavoro.

5

seguire questa procedura:

Fase 1: assicurarsi di avere le dipendenze babel all'interno di dipendenze non dipendenze dev su package.json. Aggiungi anche uno script di distribuzione che fa riferimento a babel dalla cartella node_modules. sarete chiamando questo script dall'interno finestra mobile Questo è ciò che il mio file package.json assomiglia

{ 
    "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 è per i vostri scopi di sviluppo sul computer locale e distribuire è di essere chiamato da dentro di voi dockerfile.

Passaggio 2: poiché vogliamo eseguire la trasformazione di babael, assicurati di aggiungere .dockerignore con la cartella di build che stai utilizzando durante lo sviluppo. Ecco come appare il mio file .dockerignore.

build 
    node_modules  

Fase 3. costruire il dockerfile. qui di seguito è un esempio del mio file finestra mobile

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's 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

Io personalmente preferisco di rimuovere solo le dipendenze dev dopo l'esecuzione di babele durante la costruzione:

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" ] 
2

Ho appena rilasciato una grande applicazione seme per tipografico e Node.js utilizzando docker.

Lo trovi su GitHub.

Il progetto spiega tutti i comandi che il Dockerfile utilizza e combina tsc con gulp per alcuni vantaggi aggiuntivi.

Se non si desidera controllare il repo, ecco i dettagli:

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"] 

finestra mobile-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.j figlio

{ 
    "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" 
    ] 
} 

Per ottenere più verso la risposta della sua domanda - i ts viene compilato dalla chiamata del file docker-compose.yml di npm run build che poi chiama tsc. tsc quindi copia i nostri file nella cartella dist e un semplice comando node dist/index.js esegue questo file. Invece di utilizzare nodemon, utilizziamo tsc-watch e gulp.watch per controllare le modifiche nell'app e attivare nuovamente node dist/index.js dopo ogni ri-compilazione.

Spero che questo aiuti :) Se avete domande, fatemi sapere!

+0

Ciao, grazie per aver condiviso! Mi aiuta molto. Una nota: per i progetti con un lungo processo di sviluppo consiglio di utilizzare la versione LTS. Per Nodo è Carbon. Il nodo lo consiglia anche sul proprio nodojs con la guida docker: https://nodejs.org/en/docs/guides/nodejs-docker-webapp/ – Stan

+0

Grazie, Stan: lo verificherò stasera e aggiornerò il mio repository :) –

Problemi correlati