chore(deps): upgrade play to remove CVEs (#4864)

This commit is contained in:
RyanHolstien 2022-05-06 15:42:03 -05:00 committed by GitHub
parent 2a19a85f97
commit 84a026b126
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 171 additions and 81 deletions

View File

@ -75,7 +75,9 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: ./metadata-ingestion/scripts/install_deps.sh run: ./metadata-ingestion/scripts/install_deps.sh
- name: Gradle build - name: Gradle build
run: ./gradlew build -x check -x docs-website:build -x test -x yarnTest -x lint -x yarnLint -x testQuick -x :metadata-integration:java:spark-lineage:test run: |
./gradlew build -x check -x docs-website:build -x test -x yarnTest -x lint -x yarnLint -x testQuick -x :metadata-integration:java:spark-lineage:test
./gradlew :datahub-frontend:dist
- name: Smoke test - name: Smoke test
run: ./smoke-test/smoke.sh run: ./smoke-test/smoke.sh
env: env:

3
.gitignore vendored
View File

@ -65,3 +65,6 @@ metadata-ingestion/generated/**
docs/generated/ docs/generated/
tmp* tmp*
temp* temp*
# frontend assets
datahub-frontend/public/**

View File

@ -16,6 +16,7 @@ buildscript {
} }
classpath "io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.30.0" classpath "io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.30.0"
classpath "com.palantir.gradle.gitversion:gradle-git-version:0.12.3" classpath "com.palantir.gradle.gitversion:gradle-git-version:0.12.3"
classpath "org.gradle.playframework:gradle-playframework:0.12"
classpath "gradle.plugin.org.hidetake:gradle-swagger-generator-plugin:2.18.1" classpath "gradle.plugin.org.hidetake:gradle-swagger-generator-plugin:2.18.1"
} }
} }
@ -110,14 +111,14 @@ project.ext.externalDependency = [
'opentracingJdbc':'io.opentracing.contrib:opentracing-jdbc:0.2.15', 'opentracingJdbc':'io.opentracing.contrib:opentracing-jdbc:0.2.15',
'parquet': 'org.apache.parquet:parquet-avro:1.12.2', 'parquet': 'org.apache.parquet:parquet-avro:1.12.2',
'picocli': 'info.picocli:picocli:4.5.0', 'picocli': 'info.picocli:picocli:4.5.0',
'playCache': 'com.typesafe.play:play-cache_2.11:2.6.18', 'playCache': 'com.typesafe.play:play-cache_2.12:2.7.6',
'playWs': 'com.typesafe.play:play-ahc-ws-standalone_2.11:2.0.8', 'playWs': 'com.typesafe.play:play-ahc-ws-standalone_2.12:2.0.8',
'playDocs': 'com.typesafe.play:play-docs_2.11:2.6.18', 'playDocs': 'com.typesafe.play:play-docs_2.12:2.7.6',
'playGuice': 'com.typesafe.play:play-guice_2.11:2.6.18', 'playGuice': 'com.typesafe.play:play-guice_2.12:2.7.6',
'playJavaJdbc': 'com.typesafe.play:play-java-jdbc_2.11:2.6.18', 'playJavaJdbc': 'com.typesafe.play:play-java-jdbc_2.12:2.7.6',
'playTest': 'com.typesafe.play:play-test_2.11:2.6.18', 'playTest': 'com.typesafe.play:play-test_2.12:2.7.6',
'pac4j': 'org.pac4j:pac4j-oidc:3.6.0', 'pac4j': 'org.pac4j:pac4j-oidc:3.6.0',
'playPac4j': 'org.pac4j:play-pac4j_2.11:7.0.1', 'playPac4j': 'org.pac4j:play-pac4j_2.12:8.0.2',
'postgresql': 'org.postgresql:postgresql:42.3.3', 'postgresql': 'org.postgresql:postgresql:42.3.3',
'protobuf': 'com.google.protobuf:protobuf-java:3.19.3', 'protobuf': 'com.google.protobuf:protobuf-java:3.19.3',
'reflections': 'org.reflections:reflections:0.9.9', 'reflections': 'org.reflections:reflections:0.9.9',

View File

@ -12,7 +12,6 @@ import com.linkedin.metadata.restli.DefaultRestliClientFactory;
import com.linkedin.util.Configuration; import com.linkedin.util.Configuration;
import com.datahub.authentication.Authentication; import com.datahub.authentication.Authentication;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Collections; import java.util.Collections;
import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.digest.DigestUtils;
import org.pac4j.core.client.Client; import org.pac4j.core.client.Client;

View File

@ -1,6 +1,7 @@
package auth; package auth;
import com.typesafe.config.Config; import com.typesafe.config.Config;
import java.util.Optional;
import javax.inject.Inject; import javax.inject.Inject;
import play.mvc.Http; import play.mvc.Http;
import play.mvc.Result; import play.mvc.Result;
@ -22,7 +23,8 @@ public class Authenticator extends Security.Authenticator {
@Inject @Inject
public Authenticator(@Nonnull Config config) { public Authenticator(@Nonnull Config config) {
this.metadataServiceAuthEnabled = config.hasPath(METADATA_SERVICE_AUTH_ENABLED_CONFIG_PATH) && config.getBoolean(METADATA_SERVICE_AUTH_ENABLED_CONFIG_PATH); this.metadataServiceAuthEnabled = config.hasPath(METADATA_SERVICE_AUTH_ENABLED_CONFIG_PATH)
&& config.getBoolean(METADATA_SERVICE_AUTH_ENABLED_CONFIG_PATH);
} }
@Override @Override
@ -38,9 +40,28 @@ public class Authenticator extends Security.Authenticator {
} }
} }
@Override
public Optional<String> getUsername(@Nonnull Http.Request request) {
Http.Context ctx = Http.Context.current();
if (this.metadataServiceAuthEnabled) {
// If Metadata Service auth is enabled, we only want to verify presence of the
// "Authorization" header OR the presence of a frontend generated session cookie.
// At this time, the actor is still considered to be unauthenicated.
return Optional.ofNullable(AuthUtils.isEligibleForForwarding(ctx) ? "urn:li:corpuser:UNKNOWN" : null);
} else {
// If Metadata Service auth is not enabled, verify the presence of a valid session cookie.
return Optional.ofNullable(AuthUtils.hasValidSessionCookie(ctx) ? ctx.session().get(ACTOR) : null);
}
}
@Override @Override
@Nonnull @Nonnull
public Result onUnauthorized(@Nullable Http.Context ctx) { public Result onUnauthorized(@Nullable Http.Context ctx) {
return unauthorized(); return unauthorized();
} }
@Override
public Result onUnauthorized(Http.Request req) {
return unauthorized();
}
} }

View File

@ -10,6 +10,11 @@ import static play.mvc.Results.unauthorized;
public class OidcResponseErrorHandler { public class OidcResponseErrorHandler {
private OidcResponseErrorHandler() {
}
private static final Logger _logger = LoggerFactory.getLogger("OidcResponseErrorHandler"); private static final Logger _logger = LoggerFactory.getLogger("OidcResponseErrorHandler");
private static final String ERROR_FIELD_NAME = "error"; private static final String ERROR_FIELD_NAME = "error";
@ -22,20 +27,18 @@ public class OidcResponseErrorHandler {
getErrorDescription(context)); getErrorDescription(context));
if (getError(context).equals("access_denied")) { if (getError(context).equals("access_denied")) {
return unauthorized(String.format("Access denied. " + return unauthorized(String.format("Access denied. "
"The OIDC service responded with 'Access denied'. " + + "The OIDC service responded with 'Access denied'. "
"It seems that you don't have access to this application yet. Please apply for access. \n\n" + + "It seems that you don't have access to this application yet. Please apply for access. \n\n"
"If you already have been assigned this application, it may be so that your OIDC request is still in action. " + + "If you already have been assigned this application, it may be so that your OIDC request is still in action. "
"Error details: '%s':'%s'", + "Error details: '%s':'%s'",
context.getRequestParameter("error"), context.getRequestParameter("error"),
context.getRequestParameter("error_description"))); context.getRequestParameter("error_description")));
} }
return internalServerError( return internalServerError(
String.format("Internal server error. The OIDC service responded with an error: '%s'.\n" + String.format("Internal server error. The OIDC service responded with an error: '%s'.\n"
"Error description: '%s'", + "Error description: '%s'", getError(context), getErrorDescription(context)));
getError(context),
getErrorDescription(context)));
} }
public static boolean isError(final PlayWebContext context) { public static boolean isError(final PlayWebContext context) {

View File

@ -71,8 +71,12 @@ public class CustomOidcAuthenticator implements Authenticator<OidcCredentials> {
chosenMethod = preferredMethod; chosenMethod = preferredMethod;
} else { } else {
throw new TechnicalException( throw new TechnicalException(
"Preferred authentication method (" + preferredMethod + ") not supported " + "Preferred authentication method ("
"by provider according to provider metadata (" + metadataMethods + ")."); + preferredMethod
+ ") not supported "
+ "by provider according to provider metadata ("
+ metadataMethods
+ ").");
} }
} else { } else {
chosenMethod = firstSupportedMethod(metadataMethods); chosenMethod = firstSupportedMethod(metadataMethods);
@ -83,13 +87,13 @@ public class CustomOidcAuthenticator implements Authenticator<OidcCredentials> {
chosenMethod); chosenMethod);
} }
final ClientID _clientID = new ClientID(configuration.getClientId()); final ClientID clientID = new ClientID(configuration.getClientId());
if (ClientAuthenticationMethod.CLIENT_SECRET_POST.equals(chosenMethod)) { if (ClientAuthenticationMethod.CLIENT_SECRET_POST.equals(chosenMethod)) {
final Secret _secret = new Secret(configuration.getSecret()); final Secret secret = new Secret(configuration.getSecret());
clientAuthentication = new ClientSecretPost(_clientID, _secret); clientAuthentication = new ClientSecretPost(clientID, secret);
} else if (ClientAuthenticationMethod.CLIENT_SECRET_BASIC.equals(chosenMethod)) { } else if (ClientAuthenticationMethod.CLIENT_SECRET_BASIC.equals(chosenMethod)) {
final Secret _secret = new Secret(configuration.getSecret()); final Secret secret = new Secret(configuration.getSecret());
clientAuthentication = new ClientSecretBasic(_clientID, _secret); clientAuthentication = new ClientSecretBasic(clientID, secret);
} else if (ClientAuthenticationMethod.NONE.equals(chosenMethod)) { } else if (ClientAuthenticationMethod.NONE.equals(chosenMethod)) {
clientAuthentication = null; // No client authentication in none mode clientAuthentication = null; // No client authentication in none mode
} else { } else {
@ -128,8 +132,8 @@ public class CustomOidcAuthenticator implements Authenticator<OidcCredentials> {
if (firstSupported.isPresent()) { if (firstSupported.isPresent()) {
return firstSupported.get(); return firstSupported.get();
} else { } else {
throw new TechnicalException("None of the Token endpoint provider metadata authentication methods are supported: " + throw new TechnicalException("None of the Token endpoint provider metadata authentication methods are supported: "
metadataMethods); + metadataMethods);
} }
} }

View File

@ -56,7 +56,8 @@ public class AuthServiceClient {
try { try {
final String protocol = this.metadataServiceUseSsl ? "https" : "http"; final String protocol = this.metadataServiceUseSsl ? "https" : "http";
final HttpPost request = new HttpPost(String.format("%s://%s:%s/%s", protocol, this.metadataServiceHost, this.metadataServicePort, GENERATE_SESSION_TOKEN_ENDPOINT)); final HttpPost request = new HttpPost(String.format("%s://%s:%s/%s", protocol, this.metadataServiceHost,
this.metadataServicePort, GENERATE_SESSION_TOKEN_ENDPOINT));
// Build JSON request to generate a token on behalf of a user. // Build JSON request to generate a token on behalf of a user.
String json = String.format("{ \"%s\":\"%s\" }", USER_ID_FIELD, userId); String json = String.format("{ \"%s\":\"%s\" }", USER_ID_FIELD, userId);

View File

@ -14,7 +14,7 @@ import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import play.Play; import play.api.Play;
import play.http.HttpEntity; import play.http.HttpEntity;
import play.libs.ws.InMemoryBodyWritable; import play.libs.ws.InMemoryBodyWritable;
import play.libs.ws.StandaloneWSClient; import play.libs.ws.StandaloneWSClient;
@ -59,7 +59,7 @@ public class Application extends Controller {
*/ */
@Nonnull @Nonnull
private Result serveAsset(@Nullable String path) { private Result serveAsset(@Nullable String path) {
InputStream indexHtml = Play.application().classloader().getResourceAsStream("public/index.html"); InputStream indexHtml = Play.current().classloader().getResourceAsStream("public/index.html");
response().setHeader("Cache-Control", "no-cache"); response().setHeader("Cache-Control", "no-cache");
return ok(indexHtml).as("text/html"); return ok(indexHtml).as("text/html");
} }
@ -114,7 +114,8 @@ public class Application extends Controller {
.toMap() .toMap()
.entrySet() .entrySet()
.stream() .stream()
.filter(entry -> !AuthenticationConstants.LEGACY_X_DATAHUB_ACTOR_HEADER.equals(entry.getKey())) // Remove X-DataHub-Actor to prevent malicious delegation. // Remove X-DataHub-Actor to prevent malicious delegation.
.filter(entry -> !AuthenticationConstants.LEGACY_X_DATAHUB_ACTOR_HEADER.equals(entry.getKey()))
.filter(entry -> !Http.HeaderNames.CONTENT_LENGTH.equals(entry.getKey())) .filter(entry -> !Http.HeaderNames.CONTENT_LENGTH.equals(entry.getKey()))
.filter(entry -> !Http.HeaderNames.CONTENT_TYPE.equals(entry.getKey())) .filter(entry -> !Http.HeaderNames.CONTENT_TYPE.equals(entry.getKey()))
.filter(entry -> !Http.HeaderNames.AUTHORIZATION.equals(entry.getKey())) .filter(entry -> !Http.HeaderNames.AUTHORIZATION.equals(entry.getKey()))

View File

@ -19,14 +19,14 @@ public class CentralLogoutController extends LogoutController {
@Inject @Inject
public CentralLogoutController(Config config) { public CentralLogoutController(Config config) {
String _authBaseUrl = config.hasPath(AUTH_BASE_URL_CONFIG_PATH) String authBaseUrl = config.hasPath(AUTH_BASE_URL_CONFIG_PATH)
? config.getString(AUTH_BASE_URL_CONFIG_PATH) ? config.getString(AUTH_BASE_URL_CONFIG_PATH)
: DEFAULT_BASE_URL_PATH; : DEFAULT_BASE_URL_PATH;
_isOidcEnabled = config.hasPath("auth.oidc.enabled") && config.getBoolean("auth.oidc.enabled"); _isOidcEnabled = config.hasPath("auth.oidc.enabled") && config.getBoolean("auth.oidc.enabled");
setDefaultUrl(_authBaseUrl); setDefaultUrl(authBaseUrl);
setLogoutUrlPattern(_authBaseUrl + ".*"); setLogoutUrlPattern(authBaseUrl + ".*");
setLocalLogout(true); setLocalLogout(true);
setCentralLogout(true); setCentralLogout(true);

View File

@ -58,7 +58,8 @@ public class SsoCallbackController extends CallbackController {
private final OidcCallbackLogic _oidcCallbackLogic; private final OidcCallbackLogic _oidcCallbackLogic;
SsoCallbackLogic(final SsoManager ssoManager, final Authentication systemAuthentication, final EntityClient entityClient, final AuthServiceClient authClient) { SsoCallbackLogic(final SsoManager ssoManager, final Authentication systemAuthentication,
final EntityClient entityClient, final AuthServiceClient authClient) {
_oidcCallbackLogic = new OidcCallbackLogic(ssoManager, systemAuthentication, entityClient, authClient); _oidcCallbackLogic = new OidcCallbackLogic(ssoManager, systemAuthentication, entityClient, authClient);
} }

View File

@ -35,7 +35,7 @@ public class TrackingController extends Controller {
private final Logger _logger = LoggerFactory.getLogger(TrackingController.class.getName()); private final Logger _logger = LoggerFactory.getLogger(TrackingController.class.getName());
private static final List<String> KAFKA_SSL_PROTOCOLS = Collections.unmodifiableList( private static final List<String> KAFKA_SSL_PROTOCOLS = Collections.unmodifiableList(
Arrays.asList(SecurityProtocol.SSL.name(),SecurityProtocol.SASL_SSL.name(), Arrays.asList(SecurityProtocol.SSL.name(), SecurityProtocol.SASL_SSL.name(),
SecurityProtocol.SASL_PLAINTEXT.name())); SecurityProtocol.SASL_PLAINTEXT.name()));
private final Boolean _isEnabled; private final Boolean _isEnabled;
@ -81,7 +81,7 @@ public class TrackingController extends Controller {
_producer.send(record); _producer.send(record);
_producer.flush(); _producer.flush();
return ok(); return ok();
} catch(Exception e) { } catch (Exception e) {
_logger.error(String.format("Failed to emit product analytics event. actor: %s, event: %s", actor, event)); _logger.error(String.format("Failed to emit product analytics event. actor: %s, event: %s", actor, event));
return internalServerError(e.getMessage()); return internalServerError(e.getMessage());
} }

View File

@ -44,6 +44,7 @@ public class AuthenticationManager {
NameCallback nc = null; NameCallback nc = null;
PasswordCallback pc = null; PasswordCallback pc = null;
for (Callback callback : callbacks) { for (Callback callback : callbacks) {
Logger.error("The submitted callback is of type: " + callback.getClass() + " : " + callback);
if (callback instanceof NameCallback) { if (callback instanceof NameCallback) {
nc = (NameCallback) callback; nc = (NameCallback) callback;
nc.setName(this.username); nc.setName(this.username);

View File

@ -6,6 +6,10 @@ import com.typesafe.config.Config;
public class ConfigUtil { public class ConfigUtil {
private ConfigUtil() {
}
// New configurations, provided via application.conf file. // New configurations, provided via application.conf file.
public static final String METADATA_SERVICE_HOST_CONFIG_PATH = "metadataService.host"; public static final String METADATA_SERVICE_HOST_CONFIG_PATH = "metadataService.host";
public static final String METADATA_SERVICE_PORT_CONFIG_PATH = "metadataService.port"; public static final String METADATA_SERVICE_PORT_CONFIG_PATH = "metadataService.port";

View File

@ -47,3 +47,20 @@ graphqlCodegen {
tasks.withType(Checkstyle) { tasks.withType(Checkstyle) {
exclude "**/generated/**" exclude "**/generated/**"
} }
checkstyleMain.source = "app/"
/*
PLAY UPGRADE NOTE
Generates the distribution jars under the expected names. The playFramework plugin only accepts certain name values
for the resulting folders and files, so some changes were made to accommodate. Default distribution is main if these are excluded
*/
distributions {
create("datahub-frontend") {
distributionBaseName = project.ext.playBinaryBaseName
}
playBinary {
distributionBaseName = project.ext.playBinaryBaseName
}
}

View File

@ -26,6 +26,10 @@ play.modules.disabled += "play.api.mvc.CookiesModule"
play.modules.enabled += "play.api.mvc.LegacyCookiesModule" play.modules.enabled += "play.api.mvc.LegacyCookiesModule"
play.modules.enabled += "auth.AuthModule" play.modules.enabled += "auth.AuthModule"
# Legacy Configuration to avoid code changes, update to modern approaches eventually
play.allowHttpContext = true
play.allowGlobalApplication = true
# Database configuration # Database configuration
# ~~~~~ # ~~~~~
# You can declare as many datasources as you want. # You can declare as many datasources as you want.

View File

@ -1,4 +1,4 @@
apply plugin: 'play' apply plugin: "org.gradle.playframework"
// Change this to listen on a different port // Change this to listen on a different port
project.ext.httpPort = 9001 project.ext.httpPort = 9001
@ -23,42 +23,56 @@ dependencies {
play('org.springframework:spring-core:5.2.3.RELEASE') play('org.springframework:spring-core:5.2.3.RELEASE')
play('com.fasterxml.jackson.core:jackson-databind:2.9.10.4') play('com.fasterxml.jackson.core:jackson-databind:2.9.10.4')
play('com.nimbusds:nimbus-jose-jwt:7.9') play('com.nimbusds:nimbus-jose-jwt:7.9')
play('com.typesafe.akka:akka-actor_2.11:2.5.16') play('com.typesafe.akka:akka-actor_2.12:2.5.16')
play('net.minidev:json-smart:2.4.1') play('net.minidev:json-smart:2.4.1')
play('io.netty:netty-all:4.1.68.Final') play('io.netty:netty-all:4.1.68.Final')
} }
play project(":datahub-graphql-core") compile project(":datahub-graphql-core")
play project(":metadata-service:auth-api") compile project(":metadata-service:auth-api")
play externalDependency.jettyJaas implementation externalDependency.jettyJaas
play externalDependency.graphqlJava implementation externalDependency.graphqlJava
play externalDependency.antlr4Runtime implementation externalDependency.antlr4Runtime
play externalDependency.antlr4 implementation externalDependency.antlr4
play externalDependency.jerseyCore implementation externalDependency.jerseyCore
play externalDependency.jerseyGuava implementation externalDependency.jerseyGuava
play externalDependency.pac4j implementation externalDependency.pac4j
play externalDependency.playPac4j implementation externalDependency.playPac4j
play externalDependency.shiroCore implementation externalDependency.shiroCore
play externalDependency.playCache implementation externalDependency.playCache
play externalDependency.playWs implementation externalDependency.playWs
play externalDependency.kafkaClients implementation externalDependency.kafkaClients
playTest externalDependency.mockito testImplementation externalDependency.mockito
playTest externalDependency.playTest testImplementation externalDependency.playTest
playRun externalDependency.lombok compileOnly externalDependency.lombok
playRun externalDependency.guice runtime externalDependency.guice
playRun externalDependency.playDocs runtime externalDependency.playDocs
playRun externalDependency.playGuice runtime externalDependency.playGuice
playRun externalDependency.logbackClassic runtime externalDependency.logbackClassic
annotationProcessor externalDependency.lombok
}
dist.dependsOn(':datahub-web-react:copyAssets')
play {
platform {
playVersion = '2.7.6'
scalaVersion = '2.12'
javaVersion = JavaVersion.VERSION_1_8
}
injectedRoutesGenerator = true
} }
model { model {
components { components {
play { play {
platform play: '2.6.18', scala: '2.11', java: '1.8' platform play: '2.7.6', scala: '2.12', java: '1.8'
injectedRoutesGenerator = true injectedRoutesGenerator = true
binaries.all { binaries.all {
@ -73,11 +87,6 @@ model {
} }
} }
} }
distributions {
playBinary {
baseName = project.ext.playBinaryBaseName
}
}
} }
task unzipAssets(type: Copy, dependsOn: [configurations.assets, ':datahub-web-react:yarnBuild']) { task unzipAssets(type: Copy, dependsOn: [configurations.assets, ':datahub-web-react:yarnBuild']) {
@ -92,3 +101,14 @@ task moveAssets(type: Copy, dependsOn: unzipAssets) {
into "${buildDir}/assets" into "${buildDir}/assets"
from ("${buildDir}/assets/assets") from ("${buildDir}/assets/assets")
} }
clean {
delete 'public/platforms'
delete 'public/static'
delete 'public/asset-manifest.json'
delete 'public/manifest.json'
delete 'public/robots.txt'
delete 'public/logo.png'
delete 'public/index.html'
delete 'public/favicon.ico'
}

View File

@ -87,6 +87,14 @@ distZip {
from 'dist' from 'dist'
} }
task copyAssets {
dependsOn distZip
copy {
from 'dist'
into '../datahub-frontend/public/'
}
}
if (!gradle.startParameter.taskNames.any { it in ["idea"] }) { if (!gradle.startParameter.taskNames.any { it in ["idea"] }) {
artifacts { artifacts {
assets distZip assets distZip

View File

@ -52,4 +52,4 @@ ENV JAVA_OPTS=" \
-Dlogback.configurationFile=datahub-frontend/conf/logback.xml \ -Dlogback.configurationFile=datahub-frontend/conf/logback.xml \
-Dlogback.debug=false \ -Dlogback.debug=false \
-Dpidfile.path=/dev/null" -Dpidfile.path=/dev/null"
CMD ["datahub-frontend/bin/playBinary"] CMD ["datahub-frontend/bin/datahub-frontend"]

View File

@ -55,4 +55,4 @@ services:
args: args:
APP_ENV: dev APP_ENV: dev
volumes: volumes:
- ../datahub-frontend/build/stage/datahub-frontend:/datahub-frontend - ../datahub-frontend/build/stage/playBinary:/datahub-frontend