2016-11-02 2 views
5

Wir wollen unsere Angular 2 App Bilder Dockerconfigure Angular 2 Webpack App in Docker Container umgebungsspezifischen

in verschiedenen Umgebungen (Staging/Test, Produktion, ...)

Bei der lokalen Entwicklung implementieren wir Verbindung mit der Backend-REST-API über http://localhost:8080, aber wenn wir in den verschiedenen Umgebungen bereitstellen möchten wir die gleichen Docker Bild verwenden und eine Verbindung zu einem anderen REST-API-Endpunkt .

Was wäre der bevorzugte Weg, um diese Konfiguration in die Docker Container zur Laufzeit injizieren?

Gibt es eine Möglichkeit, dies über Umgebungsvariablen zu tun?

Können wir tun dies über eine Textdatei enthält so etwas wie

{ 
    "BASE_URL": "https://api.test.example.com" 
} 
+0

verwenden Sie angular-CLI oder eine benutzerdefinierte Build? – Riscie

+0

haben wir das Projekt basierend auf https://github.com/AngularClass/angular2-webpack-starter/ erstellt –

+0

Sorry, ich bin nicht kompetent, wie das mit dem werbpack-Starter Repo funktioniert. eckig-cli, die wir verwenden, hat die Option, die Sie beschreiben (Umgebungen). – Riscie

Antwort

7

Nach einigen Diskussionen in diesem Post und auf Twitter sieht es so aus, als gäbe es keinen einfachen Weg, um über Webpack zu erreichen, was ich will. Die Dateien werden zur Laufzeit nur als statische Dateien bereitgestellt. Es ist nicht möglich, eine Datei zum Zeitpunkt der Erstellung auszuschließen und zur Laufzeit einzubeziehen.

Also entschied ich mich für die Lösung/Workaround, die ich im Sinn hatte: Ändern der statischen Dateien beim Starten des Docker-Container.

Ich eröffne mein Docker Bild von

npm run build:prod 
docker build -t angularapp . 

tun Ich bin mit dem offiziellen nginx Docker Bild als meine Basis-Image und die Dockerfile sieht aus wie

FROM nginx:1.11.1 

COPY dist /usr/share/nginx/html 
COPY run.sh /run.sh 

CMD ["bash", "/run.sh"] 

Die run.sh verwendet wird, um die Konfiguration zu ändern Datei über sed und starten nginx danach:

#!/bin/sh 

/bin/sed -i "s|http://localhost:8080|${BASE_URL}|" /usr/share/nginx/html/api.config.chunk.js 

nginx -g 'daemon off;' 

Dies ermöglicht es mir, die BASE_URL über Umwelt Variabel in meiner docker-compose.yml Datei (vereinfacht) zu konfigurieren:

version: '2' 

services: 
    api: 
    image: restapi 
    frontend: 
    image: angularapp 
    environment: 
     BASE_URL: https://api.test.example.com 

Mit dieser Lösung/Abhilfe, die ich das Docker Bild von meinem jenkins Job für eine bestimmte Version bereitstellen in allen meinen erstellt bereitstellen können Umgebungen (Entwicklung, Bereitstellung, Produktion) durch Konfigurieren des über die Umgebungsvariable verwendeten REST-API-Endpunkts beim Starten des Andockcontainers.

+0

Ich habe versucht, alle die Lösung, die Sie hier produziert haben, aber gescheitert, so können Sie Ihren Code mit mir bitte teilen. Ich sollte das auch tun. – Chandru

1

Die endgültige Lösung ist hier völlig Abhängigkeit von was Ihre CI/CD Werkzeugkette aussieht, aber diese Lösung kann in so ziemlich geformt werden etwas.

Erster Schritt: Fügen Sie etwas wie https://github.com/motdotla/dotenv zu Ihrem dependencies hinzu, dies wird Ihre Konfigurationswerte verarbeiten. Es gibt andere Optionen & je nach Ihren Bedürfnissen, rollen Sie Ihre eigenen ist einfach genug.

Laden Sie die Konfigurationsdatei so schnell wie möglich in Ihre App (global app.module.ts ist meine persönliche Wahl, da diese global verfügbar sein soll).

Einfach - Basierend auf process.env.NODE_ENV werden Sie verschiedene Konfigurationen pro Stack laden und um den DX einfach zu machen, gebe ich den Config-Werten immer einen Standard, damit meine Entwickler sich nicht um die Datei kümmern müssen.

Für TESTING, STAGING, PRODUCTION - Als Beispiel möchten Sie BASE_URL_STAGING & BASE_URL_PRODUCTION in den Umgebungsvariablen für was auch immer CI-Provider Sie verwenden setzen.

Als Teil Ihrer CI Lauf & basierend auf git branch, schreiben Sie Ihre Konfigurationswerte in eine .env Datei und dann eine COPY in Ihrem Dockerfile hinzu || docker-compose.yml, um die soeben während des Docker-Builds erstellte Umgebungsdatei einzuholen.

Nach Ihren Validierungen, wenn Sie Ihr neues Docker-Image pushen, ist die .env-Komponente Teil Ihres Bereitstellungspakets und richtet sich an die jeweiligen umgebungsspezifischen Endpunkte.

+0

dies führt nicht zu dem, was ich will : Ich möchte ein Docker Bild einer bestimmten Version, die ich in mehreren Umgebungen mit unterschiedlichen Konfigurationen bereitstellen kann :( –

+1

Der Mechanismus für die Übergabe der Env-Variablen ist nicht wirklich wichtig. So etwas wie dotenv & es ist assoziierte Webpack-Plugin nur externe Umgebungsvariablen zu verbinden Ihre Anwendung Sie können genauso einfach so etwas wie 'BASE_URL_STAGING' in Ihren docker Startbefehl ' docker run-e übergeben 'oder in Ihrer docker-compose wie .. ' Umgebung. - BASE_URL = $ {} BASE_URL_FROM_ENVIRONMENT ' Es ist ein zweiteiliges Problem. Dotenv behandelt die externen Vars in Ihre Anwendung, diese Vars sind Toolchain-spezifische – d3viant0ne

+2

Ich verstehe, aber der wichtige Teil ist, dass ich nicht mehrere Docker Bilder für verschiedene Umgebungen (Staging, Produktion, ...) erstellen möchte. Ich möchte nur 'npm run build: prod' einmal ausführen und Paket, das erstellte Dateien in einem Docker-Bild –

0

Ich hätte einen etwas anderen, aber in gewisser Weise ähnlichen Ansatz zu Ihrem sed-Shellscript genommen.

Ich mag die Idee der „Klartext-Konfigurationsdatei“, die Sie erwähnt haben, wie über dieses:

die Konfigurationsdatei von einem bekannten Ort dienen, zum Beispiel ./config? Da Ihr JS bereits von der aktuellen Site geladen wurde, sollten Sie sich zumindest auf einen relativen Pfad verlassen können.

Schritt 1: Das Shellskript, das im Andockcontainer gestartet wird, schreibt die Konfigurationsparameter aus den Umgebungsvariablen in die Klartextdatei und speichert sie im selben Ordner wie der gepackte Winkelcode.

Schritt 2: In der Haupt-HTML-Datei, die die App dort lädt einige init-Code wie folgt aus:

$(function() { 
    $.get('./config') 
    .then(function(res) { 
     window.appConfig = res.data; 
     // your bootstrapping call 
     angular.bootstrap(....); 
    }); 
}); 

Schritt 3: Sie die globalen Variablen in Ihrer Winkel App verwenden, z.B. wenn Sie mit OpaqueToken:

import { OpaqueToken } from '@angular/core'; 

const CONFIG_TOKEN = new OpaqueToken('config'); 

export const THIRDPARTYLIBPROVIDERS = [ 
    { provide: CONFIG_TOKEN, useValue: window.appConfig } 
]; 

Ja, das ist immer noch ein bisschen hacky & in Ihrem dev-env der Knoten-Proxy, die Sie für die Bedienung der ng-App verwenden, auch eine solche Konfiguration Endpunkt auszusetzen hat. Auch dies benötigt eine zusätzliche Anfrage, aber dies könnte leicht vermieden werden, indem der Init-Code um ein Bit erweitert wird, um die Daten in localStorage zu cachen (vorausgesetzt, dass sich diese Daten im Laufe der Zeit nicht wirklich ändern).

Aber alles in allem denke ich, das ist ein bisschen wartungsfreundlicher als sed -ing einige Dateien, von denen Sie nicht wirklich wissen, wie sie ausgelegt sind.

Lassen Sie mich wissen, was Sie denken!