Introducing --optimise option

Closes #10737
This commit is contained in:
Pedro Igor 2022-07-15 08:26:50 -03:00
parent b959e5c32a
commit 89028613d8
32 changed files with 545 additions and 441 deletions

View file

@ -53,6 +53,19 @@ db-url-host=mykeycloakdb
The configuration source and the corresponding format you should use is use-case specific. That decision depends on the platform where the server is deployed and the runtime optimizations you are seeking. For instance, if you deploy the server into Kubernetes, you would probably rely
on environment variables to configure the server. However, you are not limited to a single configuration source or format.
== Starting the server
You start the server by entering the following command:
.Starting the server
<@kc.start parameters="--db postgres --db-url-host keycloak-postgres --db-username keycloak --db-password change_me --hostname mykeycloak.acme.com"/>
Under certain circumstances, you might prefer to allow a longer startup time in favor of updating the values of build options when starting the server, hence performing the two configuration stages
when starting the server.
By default, running the `start` command is going to automatically run the `build` command prior to starting the server. While this is a handy way to start the server with any available option,
including **build options** that otherwise are only available to the `build` command, it introduces an additional overhead in the server startup time. For most environments, this approach is not optimal.
== Configuration commands and stages
The server options are narrowed to a specific command or configuration stage. The goal is to perform a series of optimizations in a specific order to achieve optimal startup and runtime performance. This configuration occurs in two stages:
@ -84,18 +97,20 @@ The following are some optimizations performed by the `build` command:
Once you run the `build` command, you do not need to set the same **build options** when you start the server.
=== Second stage: Starting Keycloak
=== Second stage: Starting an optimized server instance
The second stage involves starting the server by using the `start` command and including **configuration options** with the appropriate values.
In order to achieve an optimal startup time when the server was previously built with any **build option**, you should run the `start` command together with the `--optimise` option and including any **configuration option** you want to set.
.Run the `start` command to start the server while setting various database options
<@kc.start parameters="--db-url-host=keycloak-postgres --db-username=keycloak --db-password=change_me --hostname mykeycloak.acme.com"/>
<@kc.start parameters="--optimise --db-url-host=keycloak-postgres --db-username=keycloak --db-password=change_me --hostname mykeycloak.acme.com"/>
The `--optimise` indicates that the server was previously configured with any build option so that it no longer need to run the `build` command prior to start the server.
Note that if you invoke commands containing special shell characters such as `;` using the CLI, you need to escape those characters. In that situation, you might choose to use the `keycloak.conf` file to set configuration options instead.
== Optimization by using a configuration file
Most optimizations to startup and memory footprint can be achieved by using the `build` command. Additionally, you can use the `conf/keycloak.conf` file to set configuration options. Using this file avoids some necessary parsing steps when providing configuration options using the CLI or environment variables.
Most optimizations to startup and memory footprint can be achieved by using the `build` command. Additionally, you can use the `conf/keycloak.conf` file to set configuration options. Using this file avoids some necessary parsing steps when providing configuration options using the CLI.
.Set any build option
<@kc.build parameters="--db=postgres"/>
@ -109,21 +124,10 @@ hostname=mykeycloak.acme.com
```
.Start the server
<@kc.start/>
<@kc.start parameters="--optimise"/>
By using the `keycloak.conf` file, the server can omit some steps at startup. As a result, the server starts faster.
== The auto-build option: automatic detection when the server needs a build
Under certain circumstances, you might prefer to allow a longer startup time in favor of updating the values of build options when starting the server. Using the `auto-build` option, you can perform the two configuration stages by using a single command. Note that using `auto-build` is very likely to double the startup time for Keycloak. For most environments, this approach is not optimal.
You start the server by entering the following command:
.Using the `auto-build` option
<@kc.start parameters="--auto-build --db postgres --db-url-host keycloak-postgres --db-username keycloak --db-password change_me --hostname mykeycloak.acme.com"/>
By including the `auto-build` option, the server calculates the build options that have changed and runs the `build` command, if necessary, before starting the server.
== Configuring the server by using configuration files
By default, the server always fetches configuration options from the `conf/keycloak.conf` file. For a new installation,

View file

@ -74,7 +74,7 @@ To start the image, run:
podman|docker run --name optimized_keycloak -p 8443:8443 \
-e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=change_me \
prebuilt_keycloak \
start
start --optimised
----
Keycloak starts in production mode, using only secured HTTPS communication, and is available on `https://localhost:8443`.
Notice that the startup log contains the following line:
@ -105,10 +105,10 @@ Invoking this command starts the Keycloak server in development mode.
This mode should be strictly avoided in production environments because it has insecure defaults.
For more information about running Keycloak in production, take a look at the <@links.server id="configuration-production"/> guide.
== Use auto-build to run a standard keycloak container
== Running a standard keycloak container
In keeping with concepts such as immutable infrastructure, containers need to be re-provisioned routinely.
In these environments, you need containers that start fast, therefore you need to create an optimized image as described in the preceding section.
However, if your environment has different requirements, you can run a standard Keycloak image using the `--auto-build` flag.
However, if your environment has different requirements, you can run a standard Keycloak image by just running the `start` command.
For example:
[source, bash]
@ -117,7 +117,6 @@ podman|docker run --name keycloak_auto_build -p 8080:8080 \
-e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=change_me \
quay.io/keycloak/keycloak:latest \
start \
--auto-build \
--db=postgres --features=token-exchange \
--db-url=<JDBC-URL> --db-username=<DB-USER> --db-password=<DB-PASSWORD> \
--https-key-store-file=<file> --https-key-store-password=<password>

View file

@ -513,8 +513,9 @@ public class KeycloakDeployment extends OperatorManagedResource implements Statu
Container container = baseDeployment.getSpec().getTemplate().getSpec().getContainers().get(0);
var customImage = Optional.ofNullable(keycloakCR.getSpec().getImage());
container.setImage(customImage.orElse(config.keycloak().image()));
if (customImage.isEmpty()) {
container.getArgs().add("--auto-build");
if (customImage.isPresent()) {
container.getArgs().add("--optimised");
}
container.setImagePullPolicy(config.keycloak().imagePullPolicy());

View file

@ -388,8 +388,7 @@ public class KeycloakDeploymentTest extends BaseOperatorTest {
.list()
.getItems();
assertEquals(1, pods.get(0).getSpec().getContainers().get(0).getArgs().size());
assertEquals("start", pods.get(0).getSpec().getContainers().get(0).getArgs().get(0));
assertThat(pods.get(0).getSpec().getContainers().get(0).getArgs()).containsExactly("start", "--optimised");
} catch (Exception e) {
savePodLogs();
throw e;

View file

@ -24,6 +24,7 @@ set "SERVER_OPTS=-Djava.util.logging.manager=org.jboss.logmanager.LogManager -Dq
set DEBUG_MODE=false
set DEBUG_PORT_VAR=8787
set DEBUG_SUSPEND_VAR=n
set CONFIG_ARGS=
rem Read command-line args, the ~ removes the quotes from the parameter
:READ-ARGS
@ -128,10 +129,12 @@ set "JAVA_RUN_OPTS=%JAVA_OPTS% -Dkc.home.dir="%DIRNAME%.." -Djboss.server.config
SetLocal EnableDelayedExpansion
set "AUTO_BUILD_OPTION=auto-build"
set "ONLY_BUILD_OPTION= build"
set "NO_AUTO_BUILD_OPTION=optimised"
if not "!CONFIG_ARGS:%AUTO_BUILD_OPTION%=!"=="!CONFIG_ARGS!" (
"%JAVA%" -Dkc.config.rebuild-and-exit=true %JAVA_RUN_OPTS%
if "!CONFIG_ARGS:%NO_AUTO_BUILD_OPTION%=!"=="!CONFIG_ARGS!" if "!CONFIG_ARGS:%ONLY_BUILD_OPTION%=!"=="!CONFIG_ARGS!" (
"%JAVA%" -Dkc.config.build-and-exit=true %JAVA_RUN_OPTS%
set "JAVA_RUN_OPTS=-Dkc.config.built=true %JAVA_RUN_OPTS%"
)
"%JAVA%" %JAVA_RUN_OPTS%

View file

@ -48,7 +48,7 @@ do
*)
if [[ $1 = --* || ! $1 =~ ^-D.* ]]; then
if [[ "$1" = "start-dev" ]]; then
CONFIG_ARGS="$CONFIG_ARGS --profile=dev $1 --auto-build"
CONFIG_ARGS="$CONFIG_ARGS --profile=dev $1"
else
CONFIG_ARGS="$CONFIG_ARGS $1"
fi
@ -96,8 +96,9 @@ CLASSPATH_OPTS="'$DIRNAME'/../lib/quarkus-run.jar"
JAVA_RUN_OPTS="$JAVA_OPTS $SERVER_OPTS -cp $CLASSPATH_OPTS io.quarkus.bootstrap.runner.QuarkusEntryPoint ${CONFIG_ARGS#?}"
if [[ $CONFIG_ARGS = *"--auto-build"* ]]; then
eval "$JAVA" -Dkc.config.rebuild-and-exit=true $JAVA_RUN_OPTS
if [[ (! $CONFIG_ARGS = *"--optimised"*) ]] && [[ ! "$CONFIG_ARGS" == " build"* ]]; then
eval "$JAVA" -Dkc.config.build-and-exit=true $JAVA_RUN_OPTS
JAVA_RUN_OPTS="-Dkc.config.built=true $JAVA_RUN_OPTS"
EXIT_CODE=$?
if [ $EXIT_CODE != 0 ]; then
exit $EXIT_CODE

View file

@ -224,6 +224,10 @@ public final class Environment {
}
public static boolean isRebuildCheck() {
return Boolean.getBoolean("kc.config.rebuild-and-exit");
return Boolean.getBoolean("kc.config.build-and-exit");
}
public static boolean isRebuilt() {
return Boolean.getBoolean("kc.config.built");
}
}

View file

@ -23,6 +23,7 @@ import static org.keycloak.quarkus.runtime.Environment.getProfileOrDefault;
import static org.keycloak.quarkus.runtime.Environment.isImportExportMode;
import static org.keycloak.quarkus.runtime.Environment.isTestLaunchMode;
import static org.keycloak.quarkus.runtime.cli.Picocli.parseAndRun;
import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.*;
import static org.keycloak.quarkus.runtime.cli.command.Start.isDevProfileNotAllowed;
import java.io.PrintWriter;
@ -69,7 +70,7 @@ public class KeycloakMain implements QuarkusApplication {
cliArgs = new ArrayList<>(cliArgs);
// default to show help message
cliArgs.add("-h");
} else if (cliArgs.contains(Start.NAME) && cliArgs.size() == 1) {
} else if (isFastStart(cliArgs)) {
// fast path for starting the server without bootstrapping CLI
ExecutionExceptionHandler errorHandler = new ExecutionExceptionHandler();
PrintWriter errStream = new PrintWriter(System.err, true);
@ -88,6 +89,11 @@ public class KeycloakMain implements QuarkusApplication {
parseAndRun(cliArgs);
}
private static boolean isFastStart(List<String> cliArgs) {
// 'start --optimised' should start the server without parsing CLI
return cliArgs.size() == 2 && cliArgs.get(0).equals(Start.NAME) && cliArgs.stream().anyMatch(OPTIMISED_BUILD_OPTION_LONG::equals);
}
public static void start(ExecutionExceptionHandler errorHandler, PrintWriter errStream) {
ClassLoader originalCl = Thread.currentThread().getContextClassLoader();

View file

@ -17,6 +17,9 @@
package org.keycloak.quarkus.runtime.cli;
import static org.keycloak.quarkus.runtime.Environment.isRebuildCheck;
import static org.keycloak.quarkus.runtime.Environment.isRebuilt;
import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.*;
import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.AUTO_BUILD_OPTION_LONG;
import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.AUTO_BUILD_OPTION_SHORT;
import static org.keycloak.quarkus.runtime.configuration.ConfigArgsConfigSource.parseConfigArgs;
@ -40,6 +43,7 @@ import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@ -47,6 +51,7 @@ import java.util.stream.Collectors;
import org.eclipse.microprofile.config.spi.ConfigSource;
import org.keycloak.config.MultiOption;
import org.keycloak.config.OptionCategory;
import org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand;
import org.keycloak.quarkus.runtime.cli.command.Build;
import org.keycloak.quarkus.runtime.cli.command.ImportRealmMixin;
import org.keycloak.quarkus.runtime.cli.command.Main;
@ -98,7 +103,7 @@ public final class Picocli {
private static int runReAugmentationIfNeeded(List<String> cliArgs, CommandLine cmd) {
int exitCode = 0;
if (hasAutoBuildOption(cliArgs) && !isHelpCommand(cliArgs)) {
if (!isHelpCommand(cliArgs)) {
if (cliArgs.contains(StartDev.NAME)) {
String profile = Environment.getProfile();
@ -118,10 +123,6 @@ public final class Picocli {
return cliArgs.contains("--help") || cliArgs.contains("-h") || cliArgs.contains("--help-all");
}
public static boolean hasAutoBuildOption(List<String> cliArgs) {
return cliArgs.contains(AUTO_BUILD_OPTION_LONG) || cliArgs.contains(AUTO_BUILD_OPTION_SHORT);
}
public static boolean requiresReAugmentation(CommandLine cmd) {
if (hasConfigChanges()) {
if (!ConfigArgsConfigSource.getAllCliArgs().contains(StartDev.NAME) && "dev".equals(getConfig().getOptionalValue("kc.profile", String.class).orElse(null))) {
@ -169,24 +170,18 @@ public final class Picocli {
List<String> configArgsList = new ArrayList<>(cliArgs);
// remove this once auto-build option is removed
configArgsList.remove(AUTO_BUILD_OPTION_LONG);
configArgsList.remove(AUTO_BUILD_OPTION_SHORT);
configArgsList.remove(ImportRealmMixin.IMPORT_REALM);
configArgsList.replaceAll(new UnaryOperator<String>() {
@Override
public String apply(String arg) {
if (arg.equals(Start.NAME) || arg.equals(StartDev.NAME)) {
return Build.NAME;
}
return arg;
}
});
configArgsList.replaceAll(Picocli::replaceStartWithBuild);
exitCode = cmd.execute(configArgsList.toArray(new String[0]));
if(!isDevMode() && exitCode == cmd.getCommandSpec().exitCodeOnSuccess()) {
cmd.getOut().printf("Next time you run the server, just run:%n%n\t%s %s %s%n%n", Environment.getCommand(), Start.NAME, String.join(" ", getSanitizedRuntimeCliOptions()));
cmd.getOut().printf("Next time you run the server, just run:%n%n\t%s %s %s %s%n%n", Environment.getCommand(), Start.NAME, OPTIMISED_BUILD_OPTION_LONG, String.join(" ", getSanitizedRuntimeCliOptions()));
}
return exitCode;
@ -346,9 +341,9 @@ public final class Picocli {
.build());
}
addOption(spec, Start.NAME, hasAutoBuildOption(cliArgs), true);
addOption(spec, Start.NAME, isRebuilt(), true);
addOption(spec, StartDev.NAME, true, true);
addOption(spec, Build.NAME, true, hasAutoBuildOption(cliArgs));
addOption(spec, Build.NAME, true, isRebuildCheck());
CommandLine cmd = new CommandLine(spec);
@ -467,8 +462,19 @@ public final class Picocli {
}
}
}
if (!isRebuildCheck() && (arg.startsWith(AbstractStartCommand.AUTO_BUILD_OPTION_SHORT) || arg.startsWith(AUTO_BUILD_OPTION_LONG))) {
System.out.println(DEFAULT_WARN_MESSAGE_REPEATED_AUTO_BUILD_OPTION);
}
}
return args;
}
private static String replaceStartWithBuild(String arg) {
if (arg.equals(Start.NAME) || arg.equals(StartDev.NAME)) {
return Build.NAME;
}
return arg;
}
}

View file

@ -24,8 +24,11 @@ import picocli.CommandLine;
public abstract class AbstractStartCommand extends AbstractCommand implements Runnable {
// remove this once auto-build is removed
public static final String AUTO_BUILD_OPTION_LONG = "--auto-build";
public static final String AUTO_BUILD_OPTION_SHORT = "-b";
public static final String OPTIMISED_BUILD_OPTION_LONG = "--optimised";
public static final String DEFAULT_WARN_MESSAGE_REPEATED_AUTO_BUILD_OPTION = "WARNING: The '" + AUTO_BUILD_OPTION_LONG + "' option for 'start' command is DEPRECATED and no longer needed. When executing the '" + Start.NAME + "' command, a new server image is automatically built based on the configuration. If you want to disable this behavior and achieve an optimal startup time, use the '" + OPTIMISED_BUILD_OPTION_LONG + "' option instead.";
@Override
public void run() {

View file

@ -56,10 +56,7 @@ import picocli.CommandLine.Command;
+ " Enable metrics endpoints:%n%n"
+ " $ ${PARENT-COMMAND-FULL-NAME:-$PARENTCOMMAND} ${COMMAND-NAME} --metrics-enabled=true%n%n"
+ " Change the relative path:%n%n"
+ " $ ${PARENT-COMMAND-FULL-NAME:-$PARENTCOMMAND} ${COMMAND-NAME} --http-relative-path=/auth%n%n"
+ "You can also use the \"--auto-build\" option when starting the server to avoid running this command every time you change a configuration:%n%n"
+ " $ ${PARENT-COMMAND-FULL-NAME:-$PARENTCOMMAND} start --auto-build <OPTIONS>%n%n"
+ "By doing that you have an additional overhead when the server is starting.")
+ " $ ${PARENT-COMMAND-FULL-NAME:-$PARENTCOMMAND} ${COMMAND-NAME} --http-relative-path=/auth%n")
public final class Build extends AbstractCommand implements Runnable {
public static final String NAME = "build";

View file

@ -35,21 +35,27 @@ import java.util.Optional;
description = {
"%nUse this command to run the server in production."
},
footer = "%nYou may use the \"--auto-build\" option when starting the server to avoid running the \"build\" command everytime you need to change a static property:%n%n"
+ " $ ${PARENT-COMMAND-FULL-NAME:-$PARENTCOMMAND} ${COMMAND-NAME} --auto-build <OPTIONS>%n%n"
+ "By doing that you have an additional overhead when the server is starting. Run \"${PARENT-COMMAND-FULL-NAME:-$PARENTCOMMAND} build -h\" for more details.")
footer = "%nBy default, this command tries to update the server configuration by running a '" + Build.NAME + "' before starting the server. You can disable this behavior by using the '" + Start.OPTIMISED_BUILD_OPTION_LONG + "' option:%n%n"
+ " $ ${PARENT-COMMAND-FULL-NAME:-$PARENTCOMMAND} ${COMMAND-NAME} '" + Start.OPTIMISED_BUILD_OPTION_LONG + "'%n%n"
+ "By doing that, the server should start faster based on any previous configuration you have set when manually running the '" + Build.NAME + "' command.")
public final class Start extends AbstractStartCommand implements Runnable {
public static final String NAME = "start";
@CommandLine.Option(names = {AUTO_BUILD_OPTION_SHORT, AUTO_BUILD_OPTION_LONG},
description = "Automatically detects whether the server configuration changed and a new server image must be built" +
description = "(Deprecated) Automatically detects whether the server configuration changed and a new server image must be built" +
" prior to starting the server. This option provides an alternative to manually running the '" + Build.NAME + "'" +
" prior to starting the server. Use this configuration carefully in production as it might impact the startup time.",
paramLabel = NO_PARAM_LABEL,
order = 1)
Boolean autoConfig;
@CommandLine.Option(names = {OPTIMISED_BUILD_OPTION_LONG},
description = "Use this option to achieve an optional startup time if you have previously built a server image using the 'build' command.",
paramLabel = NO_PARAM_LABEL,
order = 1)
Boolean noAutoConfig;
@CommandLine.Mixin
ImportRealmMixin importRealmMixin;

View file

@ -21,7 +21,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.testcontainers.shaded.org.hamcrest.MatcherAssert.assertThat;
import static org.testcontainers.shaded.org.hamcrest.Matchers.containsString;
import static org.testcontainers.shaded.org.hamcrest.Matchers.*;
import java.util.List;
@ -92,6 +92,15 @@ public interface CLIResult extends LaunchResult {
assertThat(getOutput(), containsString(message));
}
default void assertNoMessage(String message) {
assertThat(getOutput(), not(containsString(message)));
}
default void assertMessageWasShownExactlyNumberOfTimes(String message, long numberOfShownTimes) {
long msgCount = getOutput().lines().filter(oneMessage -> oneMessage.contains(message)).count();
assertThat(msgCount, equalTo(numberOfShownTimes));
}
default void assertBuild() {
assertMessage("Server configuration updated and persisted");
}
@ -140,4 +149,5 @@ public interface CLIResult extends LaunchResult {
fail("No JSON found in output.");
}
}
}

View file

@ -27,6 +27,8 @@ import io.quarkus.test.junit.main.LaunchResult;
import org.keycloak.quarkus.runtime.cli.command.Start;
import org.keycloak.quarkus.runtime.cli.command.StartDev;
import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.OPTIMISED_BUILD_OPTION_LONG;
@CLITest
public class HelpCommandTest {
@ -52,7 +54,7 @@ public class HelpCommandTest {
}
@Test
@Launch({ Start.NAME, "--help" })
@Launch({ Start.NAME, "--help", OPTIMISED_BUILD_OPTION_LONG})
void testStartHelp(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
cliResult.assertHelp();

View file

@ -18,6 +18,7 @@
package org.keycloak.it.cli;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.OPTIMISED_BUILD_OPTION_LONG;
import org.junit.jupiter.api.Test;
import org.keycloak.it.junit5.extension.CLIResult;
@ -51,7 +52,7 @@ public class StartCommandTest {
}
@Test
@Launch({ "-v", "start", "--db=dev-mem" })
@Launch({ "-v", "start", "--db=dev-mem", OPTIMISED_BUILD_OPTION_LONG})
void failBuildPropertyNotAvailable(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
cliResult.assertError("Unknown option: '--db'");

View file

@ -31,6 +31,8 @@ import org.keycloak.it.utils.KeycloakDistribution;
import io.quarkus.test.junit.main.Launch;
import io.quarkus.test.junit.main.LaunchResult;
import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.OPTIMISED_BUILD_OPTION_LONG;
@DistributionTest(reInstall = DistributionTest.ReInstall.NEVER)
@RawDistOnly(reason = "Containers are immutable")
@TestMethodOrder(OrderAnnotation.class)
@ -45,7 +47,7 @@ public class BuildAndStartDistTest {
}
@Test
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false" })
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false", OPTIMISED_BUILD_OPTION_LONG})
@Order(2)
void testStartUsingCliArgs(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
@ -63,7 +65,7 @@ public class BuildAndStartDistTest {
}
@Test
@Launch({ "start" })
@Launch({ "start", OPTIMISED_BUILD_OPTION_LONG})
@Order(4)
void testStartUsingConfFile(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;

View file

@ -72,7 +72,7 @@ public class ClusterConfigDistTest {
@Test
@EnabledOnOs(value = { OS.LINUX, OS.MAC }, disabledReason = "different shell escaping behaviour on Windows.")
@Launch({ "start", "--auto-build", "--log-level=info,org.infinispan.remoting.transport.jgroups.JGroupsTransport:debug","--http-enabled=true", "--hostname-strict=false" })
@Launch({ "start", "--log-level=info,org.infinispan.remoting.transport.jgroups.JGroupsTransport:debug","--http-enabled=true", "--hostname-strict=false" })
void testStartDefaultsToClustering(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
cliResult.assertStarted();
@ -82,7 +82,7 @@ public class ClusterConfigDistTest {
@Test
@EnabledOnOs(value = { OS.WINDOWS }, disabledReason = "different shell behaviour on Windows.")
@Launch({ "start", "--auto-build", "--log-level=\"info,org.infinispan.remoting.transport.jgroups.JGroupsTransport:debug","--http-enabled=true\"", "--hostname-strict=false" })
@Launch({ "start", "--log-level=\"info,org.infinispan.remoting.transport.jgroups.JGroupsTransport:debug","--http-enabled=true\"", "--hostname-strict=false" })
void testWinStartDefaultsToClustering(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
cliResult.assertStarted();

View file

@ -19,6 +19,7 @@ import org.keycloak.quarkus.runtime.cli.command.StartDev;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.OPTIMISED_BUILD_OPTION_LONG;
@DistributionTest
@RawDistOnly(reason = "Containers are immutable")
@ -35,7 +36,7 @@ public class FeaturesDistTest {
}
@Test
@Launch({ Start.NAME, "--http-enabled=true", "--hostname-strict=false"})
@Launch({ Start.NAME, "--http-enabled=true", "--hostname-strict=false", OPTIMISED_BUILD_OPTION_LONG})
@Order(2)
public void testFeatureEnabledOnStart(LaunchResult result) {
assertPreviewFeaturesEnabled((CLIResult) result);

View file

@ -135,6 +135,7 @@ public class LoggingDistTest {
void testWinLogLevelSettingsAppliedWhenJsonEnabled(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
assertFalse(cliResult.getOutput().contains("\"loggerName\":\"io.quarkus\",\"level\":\"INFO\")"));
assertTrue(cliResult.getOutput().contains("\"loggerName\":\"org.keycloak.quarkus.runtime.storage.legacy.database.LegacyJpaConnectionProviderFactory\",\"level\":\"DEBUG\""));
assertTrue(cliResult.getOutput().contains("\"loggerName\":\"org.keycloak.services.resources.KeycloakApplication\",\"level\":\"DEBUG\""));
assertTrue(cliResult.getOutput().contains("\"loggerName\":\"org.infinispan.CONTAINER\",\"level\":\"INFO\""));
}

View file

@ -41,7 +41,7 @@ import io.quarkus.test.junit.main.LaunchResult;
public class QuarkusPropertiesAutoBuildDistTest {
@Test
@Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Order(1)
void reAugOnFirstRun(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
@ -50,7 +50,7 @@ public class QuarkusPropertiesAutoBuildDistTest {
@Test
@BeforeStartDistribution(QuarkusPropertiesAutoBuildDistTest.UpdateConsoleLogLevelToWarn.class)
@Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Order(2)
void testQuarkusRuntimePropDoesNotTriggerReAug(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
@ -60,7 +60,7 @@ public class QuarkusPropertiesAutoBuildDistTest {
@Test
@BeforeStartDistribution(UpdateConsoleLogLevelToInfo.class)
@Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Order(3)
void testNoReAugAfterChangingRuntimeProperty(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
@ -70,7 +70,7 @@ public class QuarkusPropertiesAutoBuildDistTest {
@Test
@BeforeStartDistribution(AddAdditionalDatasource.class)
@Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Order(4)
void testReAugForAdditionalDatasource(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
@ -79,7 +79,7 @@ public class QuarkusPropertiesAutoBuildDistTest {
@Test
@BeforeStartDistribution(ChangeAdditionalDatasourceUsername.class)
@Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Order(5)
void testNoReAugForAdditionalDatasourceRuntimeProperty(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
@ -88,7 +88,7 @@ public class QuarkusPropertiesAutoBuildDistTest {
@Test
@BeforeStartDistribution(ChangeAdditionalDatasourceDbKind.class)
@Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Order(6)
void testNoReAugWhenBuildTimePropertiesAreTheSame(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
@ -97,7 +97,7 @@ public class QuarkusPropertiesAutoBuildDistTest {
@Test
@BeforeStartDistribution(AddAdditionalDatasource2.class)
@Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Order(7)
void testReAugWhenAnotherDatasourceAdded(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
@ -106,7 +106,7 @@ public class QuarkusPropertiesAutoBuildDistTest {
@Test
@BeforeStartDistribution(EnableDatasourceMetrics.class)
@Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Order(8)
void testWrappedBuildPropertyTriggersBuildButGetsIgnoredWhenSetByQuarkus(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;

View file

@ -21,6 +21,7 @@ import static io.restassured.RestAssured.when;
import static org.hamcrest.Matchers.containsString;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.OPTIMISED_BUILD_OPTION_LONG;
import java.util.function.Consumer;
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
@ -119,7 +120,7 @@ public class QuarkusPropertiesDistTest {
@Test
@KeepServerAlive
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false" })
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false", OPTIMISED_BUILD_OPTION_LONG})
@Order(9)
void testUnknownQuarkusBuildTimePropertyApplied(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;

View file

@ -17,9 +17,8 @@
package org.keycloak.it.cli.dist;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import io.quarkus.test.junit.main.Launch;
import io.quarkus.test.junit.main.LaunchResult;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
@ -27,10 +26,13 @@ import org.junit.jupiter.api.TestMethodOrder;
import org.keycloak.it.junit5.extension.CLIResult;
import org.keycloak.it.junit5.extension.DistributionTest;
import org.keycloak.it.junit5.extension.RawDistOnly;
import io.quarkus.test.junit.main.Launch;
import io.quarkus.test.junit.main.LaunchResult;
import org.keycloak.it.utils.KeycloakDistribution;
import org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.DEFAULT_WARN_MESSAGE_REPEATED_AUTO_BUILD_OPTION;
import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.OPTIMISED_BUILD_OPTION_LONG;
@DistributionTest(reInstall = DistributionTest.ReInstall.NEVER)
@RawDistOnly(reason = "Containers are immutable")
@ -38,7 +40,7 @@ import org.keycloak.it.utils.KeycloakDistribution;
public class StartAutoBuildDistTest {
@Test
@Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Launch({ "start", AbstractStartCommand.AUTO_BUILD_OPTION_LONG, "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Order(1)
void testStartAutoBuild(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
@ -47,13 +49,14 @@ public class StartAutoBuildDistTest {
cliResult.assertMessage("Server configuration updated and persisted. Run the following command to review the configuration:");
cliResult.assertMessage(KeycloakDistribution.SCRIPT_CMD + " show-config");
cliResult.assertMessage("Next time you run the server, just run:");
cliResult.assertMessage(KeycloakDistribution.SCRIPT_CMD + " start --http-enabled=true --hostname-strict=false");
cliResult.assertMessage(KeycloakDistribution.SCRIPT_CMD + " start " + OPTIMISED_BUILD_OPTION_LONG + " --http-enabled=true --hostname-strict=false");
cliResult.assertMessage(DEFAULT_WARN_MESSAGE_REPEATED_AUTO_BUILD_OPTION);
assertFalse(cliResult.getOutput().contains("--cache"));
cliResult.assertStarted();
}
@Test
@Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Order(2)
void testShouldNotReAugIfConfigIsSame(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
@ -62,7 +65,7 @@ public class StartAutoBuildDistTest {
}
@Test
@Launch({ "start", "--auto-build", "--db=dev-mem", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Launch({ "start", "--db=dev-mem", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Order(3)
void testShouldReAugIfConfigChanged(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
@ -71,7 +74,7 @@ public class StartAutoBuildDistTest {
}
@Test
@Launch({ "start", "--auto-build", "--db=dev-mem", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Launch({ "start", "--db=dev-mem", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Order(4)
void testShouldNotReAugIfSameDatabase(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
@ -88,7 +91,7 @@ public class StartAutoBuildDistTest {
}
@Test
@Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Order(6)
void testReAugWhenNoOptionAfterBuild(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
@ -97,8 +100,25 @@ public class StartAutoBuildDistTest {
}
@Test
@Launch({ "start-dev" })
@Launch({ "start", "--db=postgres", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Order(7)
void testShouldReAugWithoutAutoBuildOptionAfterDatabaseChange(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
cliResult.assertNoMessage(DEFAULT_WARN_MESSAGE_REPEATED_AUTO_BUILD_OPTION);
cliResult.assertBuild();
}
@Test
@Launch({ "start", "--db=dev-file", "--http-enabled=true", "--hostname-strict=false", "--cache=local", OPTIMISED_BUILD_OPTION_LONG})
@Order(8)
void testShouldReAugAndNeedsAutoBuildOptionBecauseHasNoAutoBuildOption(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
cliResult.assertNoBuild();
}
@Test
@Launch({ "start-dev" })
@Order(8)
void testStartDevFirstTime(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
assertTrue(cliResult.getOutput().contains("Updating the configuration and installing your custom providers, if any. Please wait."));
@ -107,7 +127,7 @@ public class StartAutoBuildDistTest {
@Test
@Launch({ "start-dev" })
@Order(8)
@Order(9)
void testShouldNotReAugStartDevIfConfigIsSame(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
assertFalse(cliResult.getOutput().contains("Updating the configuration and installing your custom providers, if any. Please wait."));

View file

@ -22,6 +22,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.OPTIMISED_BUILD_OPTION_LONG;
import org.junit.jupiter.api.Test;
import org.keycloak.it.cli.StartCommandTest;
@ -36,7 +37,7 @@ import org.keycloak.it.utils.KeycloakDistribution;
public class StartCommandDistTest extends StartCommandTest {
@Test
@Launch({ "--profile=dev", "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false" })
@Launch({ "--profile=dev", "start", "--http-enabled=true", "--hostname-strict=false" })
void failIfAutoBuildUsingDevProfile(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
assertThat(cliResult.getErrorOutput(), containsString("You can not 'start' the server in development mode. Please re-build the server first, using 'kc.sh build' for the default production mode."));
@ -51,7 +52,7 @@ public class StartCommandDistTest extends StartCommandTest {
}
@Test
@Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
void testStartUsingAutoBuild(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
cliResult.assertMessage("Changes detected in configuration. Updating the server image.");
@ -59,7 +60,7 @@ public class StartCommandDistTest extends StartCommandTest {
cliResult.assertMessage("Server configuration updated and persisted. Run the following command to review the configuration:");
cliResult.assertMessage(KeycloakDistribution.SCRIPT_CMD + " show-config");
cliResult.assertMessage("Next time you run the server, just run:");
cliResult.assertMessage(KeycloakDistribution.SCRIPT_CMD + " start --http-enabled=true --hostname-strict=false");
cliResult.assertMessage(KeycloakDistribution.SCRIPT_CMD + " start " + OPTIMISED_BUILD_OPTION_LONG + " --http-enabled=true --hostname-strict=false");
assertFalse(cliResult.getOutput().contains("--cache"));
cliResult.assertStarted();
}

View file

@ -17,9 +17,43 @@
package org.keycloak.it.cli.dist;
import io.quarkus.test.junit.main.Launch;
import io.quarkus.test.junit.main.LaunchResult;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.keycloak.it.cli.StartDevCommandTest;
import org.keycloak.it.junit5.extension.CLIResult;
import org.keycloak.it.junit5.extension.DistributionTest;
import org.keycloak.it.junit5.extension.RawDistOnly;
@DistributionTest
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
@DistributionTest(reInstall = DistributionTest.ReInstall.NEVER)
@RawDistOnly(reason = "Containers are immutable")
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class StartDevCommandDistTest extends StartDevCommandTest {
@Test
@Launch({ "start-dev", "--debug" })
@Order(1)
void testStartDevShouldStartTwoJVMs(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
cliResult.assertMessage("Updating the configuration and installing your custom providers, if any. Please wait.");
cliResult.assertMessageWasShownExactlyNumberOfTimes("Listening for transport dt_socket at address:", 2);
cliResult.assertStartedDevMode();
}
@Test
@Launch({ "build", "--debug" })
@Order(2)
void testBuildMustNotRunTwoJVMs(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
cliResult.assertMessage("Updating the configuration and installing your custom providers, if any. Please wait.");
cliResult.assertMessageWasShownExactlyNumberOfTimes("Listening for transport dt_socket at address:", 1);
cliResult.assertBuild();
}
}

View file

@ -22,6 +22,7 @@ import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.keycloak.it.junit5.extension.CLIResult;
import org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand;
import io.quarkus.test.junit.main.Launch;
import io.quarkus.test.junit.main.LaunchResult;
@ -30,14 +31,14 @@ import io.quarkus.test.junit.main.LaunchResult;
public abstract class BasicDatabaseTest {
@Test
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false" })
@Launch({ "start", AbstractStartCommand.OPTIMISED_BUILD_OPTION_LONG, "--http-enabled=true", "--hostname-strict=false" })
void testSuccessful(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
cliResult.assertStarted();
}
@Test
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--db-username=wrong" })
@Launch({ "start", AbstractStartCommand.OPTIMISED_BUILD_OPTION_LONG,"--http-enabled=true", "--hostname-strict=false", "--db-username=wrong" })
void testWrongUsername(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
cliResult.assertMessage("ERROR: Failed to obtain JDBC connection");
@ -47,7 +48,7 @@ public abstract class BasicDatabaseTest {
protected abstract void assertWrongUsername(CLIResult cliResult);
@Test
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--db-password=wrong" })
@Launch({ "start", AbstractStartCommand.OPTIMISED_BUILD_OPTION_LONG,"--http-enabled=true", "--hostname-strict=false", "--db-password=wrong" })
void testWrongPassword(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
cliResult.assertMessage("ERROR: Failed to obtain JDBC connection");

View file

@ -32,7 +32,7 @@ import io.quarkus.test.junit.main.LaunchResult;
public class ChmStorageDistTest {
@Test
@Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--storage=chm" })
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--storage=chm" })
void testStartUsingChmsStorage(LaunchResult result, RawDistRootPath distPath) {
CLIResult cliResult = (CLIResult) result;
assertExpectedMessages(cliResult, distPath);

View file

@ -30,7 +30,7 @@ import io.quarkus.test.junit.main.LaunchResult;
public class JPAStoreDistTest {
@Test
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false" })
@Launch({ "start", "--optimised", "--http-enabled=true", "--hostname-strict=false" })
void testSuccessful(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
cliResult.assertMessage("Experimental feature enabled: map_storage");

View file

@ -102,11 +102,4 @@ Examples:
Change the relative path:
$ kc.sh build --http-relative-path=/auth
You can also use the "--auto-build" option when starting the server to avoid
running this command every time you change a configuration:
$ kc.sh start --auto-build <OPTIONS>
By doing that you have an additional overhead when the server is starting.
$ kc.sh build --http-relative-path=/auth

View file

@ -1,159 +1,160 @@
Start the server in development mode.
Usage:
kc.bat start-dev [OPTIONS]
Use this command if you want to run the server locally for development or
testing purposes.
Options:
-h, --help This help message.
--help-all This same help message but with additional options.
--import-realm Import realms during startup by reading any realm configuration file from the
'data/import' directory.
Database:
--db-password <password>
The password of the database user.
--db-pool-initial-size <size>
The initial size of the connection pool.
--db-pool-max-size <size>
The maximum size of the connection pool. Default: 100.
--db-pool-min-size <size>
The minimal size of the connection pool.
--db-schema <schema> The database schema to be used.
--db-url <jdbc-url> The full database JDBC URL. If not provided, a default URL is set based on the
selected database vendor. For instance, if using 'postgres', the default
JDBC URL would be 'jdbc:postgresql://localhost/keycloak'.
--db-url-database <dbname>
Sets the database name of the default JDBC URL of the chosen vendor. If the
`db-url` option is set, this option is ignored.
--db-url-host <hostname>
Sets the hostname of the default JDBC URL of the chosen vendor. If the
`db-url` option is set, this option is ignored.
--db-url-port <port> Sets the port of the default JDBC URL of the chosen vendor. If the `db-url`
option is set, this option is ignored.
--db-url-properties <properties>
Sets the properties of the default JDBC URL of the chosen vendor. If the
`db-url` option is set, this option is ignored.
--db-username <username>
The username of the database user.
Hostname:
--hostname <hostname>
Hostname for the Keycloak server.
--hostname-admin <hostname>
The hostname for accessing the administration console. Use this option if you
are exposing the administration console using a hostname other than the
value set to the 'hostname' option.
--hostname-path <path>
This should be set if proxy uses a different context-path for Keycloak.
--hostname-port <port>
The port used by the proxy when exposing the hostname. Set this option if the
proxy uses a port other than the default HTTP and HTTPS ports. Default: -1.
--hostname-strict <true|false>
Disables dynamically resolving the hostname from request headers. Should
always be set to true in production, unless proxy verifies the Host header.
Default: true.
--hostname-strict-backchannel <true|false>
By default backchannel URLs are dynamically resolved from request headers to
allow internal and external applications. If all applications use the public
URL this option should be enabled. Default: false.
HTTP/TLS:
--http-enabled <true|false>
Enables the HTTP listener. Default: false.
--http-host <host> The used HTTP Host. Default: 0.0.0.0.
--http-port <port> The used HTTP port. Default: 8080.
--https-certificate-file <file>
The file path to a server certificate or certificate chain in PEM format.
--https-certificate-key-file <file>
The file path to a private key in PEM format.
--https-cipher-suites <ciphers>
The cipher suites to use. If none is given, a reasonable default is selected.
--https-client-auth <auth>
Configures the server to require/request client authentication. Possible
Values: none, request, required. Default: none.
--https-key-store-file <file>
The key store which holds the certificate information instead of specifying
separate files.
--https-key-store-password <password>
The password of the key store file. Default: password.
--https-key-store-type <type>
The type of the key store file. If not given, the type is automatically
detected based on the file name.
--https-port <port> The used HTTPS port. Default: 8443.
--https-protocols <protocols>
The list of protocols to explicitly enable. Default: TLSv1.3.
--https-trust-store-file <file>
The trust store which holds the certificate information of the certificates to
trust.
--https-trust-store-password <password>
The password of the trust store file.
--https-trust-store-type <type>
The type of the trust store file. If not given, the type is automatically
detected based on the file name.
Proxy:
--proxy <mode> The proxy address forwarding mode if the server is behind a reverse proxy.
Possible values are: edge,reencrypt,passthrough Default: none.
Vault:
--vault-dir <dir> If set, secrets can be obtained by reading the content of files within the
given directory.
Logging:
--log <handler> Enable one or more log handlers in a comma-separated list. Available log
handlers are: console,file,gelf Default: console.
--log-console-color <true|false>
Enable or disable colors when logging to console. Default: false.
--log-console-format <format>
The format of unstructured console log entries. If the format has spaces in
it, escape the value using "<format>". Default: %d{yyyy-MM-dd HH:mm:ss,SSS} %
-5p [%c] (%t) %s%e%n.
--log-console-output <default|json>
Set the log output to JSON or default (plain) unstructured logging. Default:
default.
--log-file <path>/<file-name>.log
Set the log file path and filename. Default: data\log\keycloak.log.
--log-file-format <format>
Set a format specific to file log entries. Default: %d{yyyy-MM-dd HH:mm:ss,
SSS} %-5p [%c] (%t) %s%e%n.
--log-gelf-facility <name>
The facility (name of the process) that sends the message. Default: keycloak.
--log-gelf-host <hostname>
Hostname of the Logstash or Graylog Host. By default UDP is used, prefix the
host with 'tcp:' to switch to TCP. Example: 'tcp:localhost' Default:
localhost.
--log-gelf-include-location <true|false>
Include source code location. Default: true.
--log-gelf-include-message-parameters <true|false>
Include message parameters from the log event. Default: true.
--log-gelf-include-stack-trace <true|false>
If set to true, occuring stack traces are included in the 'StackTrace' field
in the gelf output. Default: true.
--log-gelf-max-message-size <size>
Maximum message size (in bytes). If the message size is exceeded, gelf will
submit the message in multiple chunks. Default: 8192.
--log-gelf-port <port>
The port the Logstash or Graylog Host is called on. Default: 12201.
--log-gelf-timestamp-format <pattern>
Set the format for the gelf timestamp field. Uses Java SimpleDateFormat
pattern. Default: yyyy-MM-dd HH:mm:ss,SSS.
--log-level <category:level>
The log level of the root category or a comma-separated list of individual
categories and their levels. For the root category, you don't need to
specify a category. Default: info.
Do NOT start the server using this command when deploying to production.
Use 'kc.bat start-dev --help-all' to list all available options, including
build options.
WARNING: The '--auto-build' option for 'start' command is DEPRECATED and no longer needed. When executing the 'start' command, a new server image is automatically built based on the configuration. If you want to disable this behavior and achieve an optimal startup time, use the '--optimised' option instead.
Start the server in development mode.
Usage:
kc.bat start-dev [OPTIONS]
Use this command if you want to run the server locally for development or
testing purposes.
Options:
-h, --help This help message.
--help-all This same help message but with additional options.
--import-realm Import realms during startup by reading any realm configuration file from the
'data/import' directory.
Database:
--db-password <password>
The password of the database user.
--db-pool-initial-size <size>
The initial size of the connection pool.
--db-pool-max-size <size>
The maximum size of the connection pool. Default: 100.
--db-pool-min-size <size>
The minimal size of the connection pool.
--db-schema <schema> The database schema to be used.
--db-url <jdbc-url> The full database JDBC URL. If not provided, a default URL is set based on the
selected database vendor. For instance, if using 'postgres', the default
JDBC URL would be 'jdbc:postgresql://localhost/keycloak'.
--db-url-database <dbname>
Sets the database name of the default JDBC URL of the chosen vendor. If the
`db-url` option is set, this option is ignored.
--db-url-host <hostname>
Sets the hostname of the default JDBC URL of the chosen vendor. If the
`db-url` option is set, this option is ignored.
--db-url-port <port> Sets the port of the default JDBC URL of the chosen vendor. If the `db-url`
option is set, this option is ignored.
--db-url-properties <properties>
Sets the properties of the default JDBC URL of the chosen vendor. If the
`db-url` option is set, this option is ignored.
--db-username <username>
The username of the database user.
Hostname:
--hostname <hostname>
Hostname for the Keycloak server.
--hostname-admin <hostname>
The hostname for accessing the administration console. Use this option if you
are exposing the administration console using a hostname other than the
value set to the 'hostname' option.
--hostname-path <path>
This should be set if proxy uses a different context-path for Keycloak.
--hostname-port <port>
The port used by the proxy when exposing the hostname. Set this option if the
proxy uses a port other than the default HTTP and HTTPS ports. Default: -1.
--hostname-strict <true|false>
Disables dynamically resolving the hostname from request headers. Should
always be set to true in production, unless proxy verifies the Host header.
Default: true.
--hostname-strict-backchannel <true|false>
By default backchannel URLs are dynamically resolved from request headers to
allow internal and external applications. If all applications use the public
URL this option should be enabled. Default: false.
HTTP/TLS:
--http-enabled <true|false>
Enables the HTTP listener. Default: false.
--http-host <host> The used HTTP Host. Default: 0.0.0.0.
--http-port <port> The used HTTP port. Default: 8080.
--https-certificate-file <file>
The file path to a server certificate or certificate chain in PEM format.
--https-certificate-key-file <file>
The file path to a private key in PEM format.
--https-cipher-suites <ciphers>
The cipher suites to use. If none is given, a reasonable default is selected.
--https-client-auth <auth>
Configures the server to require/request client authentication. Possible
Values: none, request, required. Default: none.
--https-key-store-file <file>
The key store which holds the certificate information instead of specifying
separate files.
--https-key-store-password <password>
The password of the key store file. Default: password.
--https-key-store-type <type>
The type of the key store file. If not given, the type is automatically
detected based on the file name.
--https-port <port> The used HTTPS port. Default: 8443.
--https-protocols <protocols>
The list of protocols to explicitly enable. Default: TLSv1.3.
--https-trust-store-file <file>
The trust store which holds the certificate information of the certificates to
trust.
--https-trust-store-password <password>
The password of the trust store file.
--https-trust-store-type <type>
The type of the trust store file. If not given, the type is automatically
detected based on the file name.
Proxy:
--proxy <mode> The proxy address forwarding mode if the server is behind a reverse proxy.
Possible values are: edge,reencrypt,passthrough Default: none.
Vault:
--vault-dir <dir> If set, secrets can be obtained by reading the content of files within the
given directory.
Logging:
--log <handler> Enable one or more log handlers in a comma-separated list. Available log
handlers are: console,file,gelf Default: console.
--log-console-color <true|false>
Enable or disable colors when logging to console. Default: false.
--log-console-format <format>
The format of unstructured console log entries. If the format has spaces in
it, escape the value using "<format>". Default: %d{yyyy-MM-dd HH:mm:ss,SSS} %
-5p [%c] (%t) %s%e%n.
--log-console-output <default|json>
Set the log output to JSON or default (plain) unstructured logging. Default:
default.
--log-file <path>/<file-name>.log
Set the log file path and filename. Default: data\log\keycloak.log.
--log-file-format <format>
Set a format specific to file log entries. Default: %d{yyyy-MM-dd HH:mm:ss,
SSS} %-5p [%c] (%t) %s%e%n.
--log-gelf-facility <name>
The facility (name of the process) that sends the message. Default: keycloak.
--log-gelf-host <hostname>
Hostname of the Logstash or Graylog Host. By default UDP is used, prefix the
host with 'tcp:' to switch to TCP. Example: 'tcp:localhost' Default:
localhost.
--log-gelf-include-location <true|false>
Include source code location. Default: true.
--log-gelf-include-message-parameters <true|false>
Include message parameters from the log event. Default: true.
--log-gelf-include-stack-trace <true|false>
If set to true, occuring stack traces are included in the 'StackTrace' field
in the gelf output. Default: true.
--log-gelf-max-message-size <size>
Maximum message size (in bytes). If the message size is exceeded, gelf will
submit the message in multiple chunks. Default: 8192.
--log-gelf-port <port>
The port the Logstash or Graylog Host is called on. Default: 12201.
--log-gelf-timestamp-format <pattern>
Set the format for the gelf timestamp field. Uses Java SimpleDateFormat
pattern. Default: yyyy-MM-dd HH:mm:ss,SSS.
--log-level <category:level>
The log level of the root category or a comma-separated list of individual
categories and their levels. For the root category, you don't need to
specify a category. Default: info.
Do NOT start the server using this command when deploying to production.
Use 'kc.bat start-dev --help-all' to list all available options, including
build options.

View file

@ -8,14 +8,16 @@ Use this command to run the server in production.
Options:
-b, --auto-build Automatically detects whether the server configuration changed and a new
server image must be built prior to starting the server. This option
provides an alternative to manually running the 'build' prior to starting
the server. Use this configuration carefully in production as it might
impact the startup time.
-b, --auto-build (Deprecated) Automatically detects whether the server configuration changed
and a new server image must be built prior to starting the server. This
option provides an alternative to manually running the 'build' prior to
starting the server. Use this configuration carefully in production as it
might impact the startup time.
-h, --help This help message.
--import-realm Import realms during startup by reading any realm configuration file from the
'data/import' directory.
--optimised Use this option to achieve an optional startup time if you have previously
built a server image using the 'build' command.
Database:
@ -156,10 +158,11 @@ Logging:
categories and their levels. For the root category, you don't need to
specify a category. Default: info.
You may use the "--auto-build" option when starting the server to avoid running
the "build" command everytime you need to change a static property:
By default, this command tries to update the server configuration by running a
'build' before starting the server. You can disable this behavior by using the
'--optimised' option:
$ kc.sh start --auto-build <OPTIONS>
$ kc.sh start '--optimised'
By doing that you have an additional overhead when the server is starting. Run
"kc.sh build -h" for more details.
By doing that, the server should start faster based on any previous
configuration you have set when manually running the 'build' command.

View file

@ -1,165 +1,168 @@
Start the server.
Usage:
kc.bat start [OPTIONS]
Use this command to run the server in production.
Options:
-b, --auto-build Automatically detects whether the server configuration changed and a new
server image must be built prior to starting the server. This option
provides an alternative to manually running the 'build' prior to starting
the server. Use this configuration carefully in production as it might
impact the startup time.
-h, --help This help message.
--import-realm Import realms during startup by reading any realm configuration file from the
'data/import' directory.
Database:
--db-password <password>
The password of the database user.
--db-pool-initial-size <size>
The initial size of the connection pool.
--db-pool-max-size <size>
The maximum size of the connection pool. Default: 100.
--db-pool-min-size <size>
The minimal size of the connection pool.
--db-schema <schema> The database schema to be used.
--db-url <jdbc-url> The full database JDBC URL. If not provided, a default URL is set based on the
selected database vendor. For instance, if using 'postgres', the default
JDBC URL would be 'jdbc:postgresql://localhost/keycloak'.
--db-url-database <dbname>
Sets the database name of the default JDBC URL of the chosen vendor. If the
`db-url` option is set, this option is ignored.
--db-url-host <hostname>
Sets the hostname of the default JDBC URL of the chosen vendor. If the
`db-url` option is set, this option is ignored.
--db-url-port <port> Sets the port of the default JDBC URL of the chosen vendor. If the `db-url`
option is set, this option is ignored.
--db-url-properties <properties>
Sets the properties of the default JDBC URL of the chosen vendor. If the
`db-url` option is set, this option is ignored.
--db-username <username>
The username of the database user.
Hostname:
--hostname <hostname>
Hostname for the Keycloak server.
--hostname-admin <hostname>
The hostname for accessing the administration console. Use this option if you
are exposing the administration console using a hostname other than the
value set to the 'hostname' option.
--hostname-path <path>
This should be set if proxy uses a different context-path for Keycloak.
--hostname-port <port>
The port used by the proxy when exposing the hostname. Set this option if the
proxy uses a port other than the default HTTP and HTTPS ports. Default: -1.
--hostname-strict <true|false>
Disables dynamically resolving the hostname from request headers. Should
always be set to true in production, unless proxy verifies the Host header.
Default: true.
--hostname-strict-backchannel <true|false>
By default backchannel URLs are dynamically resolved from request headers to
allow internal and external applications. If all applications use the public
URL this option should be enabled. Default: false.
HTTP/TLS:
--http-enabled <true|false>
Enables the HTTP listener. Default: false.
--http-host <host> The used HTTP Host. Default: 0.0.0.0.
--http-port <port> The used HTTP port. Default: 8080.
--https-certificate-file <file>
The file path to a server certificate or certificate chain in PEM format.
--https-certificate-key-file <file>
The file path to a private key in PEM format.
--https-cipher-suites <ciphers>
The cipher suites to use. If none is given, a reasonable default is selected.
--https-client-auth <auth>
Configures the server to require/request client authentication. Possible
Values: none, request, required. Default: none.
--https-key-store-file <file>
The key store which holds the certificate information instead of specifying
separate files.
--https-key-store-password <password>
The password of the key store file. Default: password.
--https-key-store-type <type>
The type of the key store file. If not given, the type is automatically
detected based on the file name.
--https-port <port> The used HTTPS port. Default: 8443.
--https-protocols <protocols>
The list of protocols to explicitly enable. Default: TLSv1.3.
--https-trust-store-file <file>
The trust store which holds the certificate information of the certificates to
trust.
--https-trust-store-password <password>
The password of the trust store file.
--https-trust-store-type <type>
The type of the trust store file. If not given, the type is automatically
detected based on the file name.
Proxy:
--proxy <mode> The proxy address forwarding mode if the server is behind a reverse proxy.
Possible values are: edge,reencrypt,passthrough Default: none.
Vault:
--vault-dir <dir> If set, secrets can be obtained by reading the content of files within the
given directory.
Logging:
--log <handler> Enable one or more log handlers in a comma-separated list. Available log
handlers are: console,file,gelf Default: console.
--log-console-color <true|false>
Enable or disable colors when logging to console. Default: false.
--log-console-format <format>
The format of unstructured console log entries. If the format has spaces in
it, escape the value using "<format>". Default: %d{yyyy-MM-dd HH:mm:ss,SSS} %
-5p [%c] (%t) %s%e%n.
--log-console-output <default|json>
Set the log output to JSON or default (plain) unstructured logging. Default:
default.
--log-file <path>/<file-name>.log
Set the log file path and filename. Default: data\log\keycloak.log.
--log-file-format <format>
Set a format specific to file log entries. Default: %d{yyyy-MM-dd HH:mm:ss,
SSS} %-5p [%c] (%t) %s%e%n.
--log-gelf-facility <name>
The facility (name of the process) that sends the message. Default: keycloak.
--log-gelf-host <hostname>
Hostname of the Logstash or Graylog Host. By default UDP is used, prefix the
host with 'tcp:' to switch to TCP. Example: 'tcp:localhost' Default:
localhost.
--log-gelf-include-location <true|false>
Include source code location. Default: true.
--log-gelf-include-message-parameters <true|false>
Include message parameters from the log event. Default: true.
--log-gelf-include-stack-trace <true|false>
If set to true, occuring stack traces are included in the 'StackTrace' field
in the gelf output. Default: true.
--log-gelf-max-message-size <size>
Maximum message size (in bytes). If the message size is exceeded, gelf will
submit the message in multiple chunks. Default: 8192.
--log-gelf-port <port>
The port the Logstash or Graylog Host is called on. Default: 12201.
--log-gelf-timestamp-format <pattern>
Set the format for the gelf timestamp field. Uses Java SimpleDateFormat
pattern. Default: yyyy-MM-dd HH:mm:ss,SSS.
--log-level <category:level>
The log level of the root category or a comma-separated list of individual
categories and their levels. For the root category, you don't need to
specify a category. Default: info.
You may use the "--auto-build" option when starting the server to avoid running
the "build" command everytime you need to change a static property:
$ kc.bat start --auto-build <OPTIONS>
By doing that you have an additional overhead when the server is starting. Run
"kc.bat build -h" for more details.
Start the server.
Usage:
kc.bat start [OPTIONS]
Use this command to run the server in production.
Options:
-b, --auto-build (Deprecated) Automatically detects whether the server configuration changed
and a new server image must be built prior to starting the server. This
option provides an alternative to manually running the 'build' prior to
starting the server. Use this configuration carefully in production as it
might impact the startup time.
-h, --help This help message.
--import-realm Import realms during startup by reading any realm configuration file from the
'data/import' directory.
--optimised Use this option to achieve an optional startup time if you have previously
built a server image using the 'build' command.
Database:
--db-password <password>
The password of the database user.
--db-pool-initial-size <size>
The initial size of the connection pool.
--db-pool-max-size <size>
The maximum size of the connection pool. Default: 100.
--db-pool-min-size <size>
The minimal size of the connection pool.
--db-schema <schema> The database schema to be used.
--db-url <jdbc-url> The full database JDBC URL. If not provided, a default URL is set based on the
selected database vendor. For instance, if using 'postgres', the default
JDBC URL would be 'jdbc:postgresql://localhost/keycloak'.
--db-url-database <dbname>
Sets the database name of the default JDBC URL of the chosen vendor. If the
`db-url` option is set, this option is ignored.
--db-url-host <hostname>
Sets the hostname of the default JDBC URL of the chosen vendor. If the
`db-url` option is set, this option is ignored.
--db-url-port <port> Sets the port of the default JDBC URL of the chosen vendor. If the `db-url`
option is set, this option is ignored.
--db-url-properties <properties>
Sets the properties of the default JDBC URL of the chosen vendor. If the
`db-url` option is set, this option is ignored.
--db-username <username>
The username of the database user.
Hostname:
--hostname <hostname>
Hostname for the Keycloak server.
--hostname-admin <hostname>
The hostname for accessing the administration console. Use this option if you
are exposing the administration console using a hostname other than the
value set to the 'hostname' option.
--hostname-path <path>
This should be set if proxy uses a different context-path for Keycloak.
--hostname-port <port>
The port used by the proxy when exposing the hostname. Set this option if the
proxy uses a port other than the default HTTP and HTTPS ports. Default: -1.
--hostname-strict <true|false>
Disables dynamically resolving the hostname from request headers. Should
always be set to true in production, unless proxy verifies the Host header.
Default: true.
--hostname-strict-backchannel <true|false>
By default backchannel URLs are dynamically resolved from request headers to
allow internal and external applications. If all applications use the public
URL this option should be enabled. Default: false.
HTTP/TLS:
--http-enabled <true|false>
Enables the HTTP listener. Default: false.
--http-host <host> The used HTTP Host. Default: 0.0.0.0.
--http-port <port> The used HTTP port. Default: 8080.
--https-certificate-file <file>
The file path to a server certificate or certificate chain in PEM format.
--https-certificate-key-file <file>
The file path to a private key in PEM format.
--https-cipher-suites <ciphers>
The cipher suites to use. If none is given, a reasonable default is selected.
--https-client-auth <auth>
Configures the server to require/request client authentication. Possible
Values: none, request, required. Default: none.
--https-key-store-file <file>
The key store which holds the certificate information instead of specifying
separate files.
--https-key-store-password <password>
The password of the key store file. Default: password.
--https-key-store-type <type>
The type of the key store file. If not given, the type is automatically
detected based on the file name.
--https-port <port> The used HTTPS port. Default: 8443.
--https-protocols <protocols>
The list of protocols to explicitly enable. Default: TLSv1.3.
--https-trust-store-file <file>
The trust store which holds the certificate information of the certificates to
trust.
--https-trust-store-password <password>
The password of the trust store file.
--https-trust-store-type <type>
The type of the trust store file. If not given, the type is automatically
detected based on the file name.
Proxy:
--proxy <mode> The proxy address forwarding mode if the server is behind a reverse proxy.
Possible values are: edge,reencrypt,passthrough Default: none.
Vault:
--vault-dir <dir> If set, secrets can be obtained by reading the content of files within the
given directory.
Logging:
--log <handler> Enable one or more log handlers in a comma-separated list. Available log
handlers are: console,file,gelf Default: console.
--log-console-color <true|false>
Enable or disable colors when logging to console. Default: false.
--log-console-format <format>
The format of unstructured console log entries. If the format has spaces in
it, escape the value using "<format>". Default: %d{yyyy-MM-dd HH:mm:ss,SSS} %
-5p [%c] (%t) %s%e%n.
--log-console-output <default|json>
Set the log output to JSON or default (plain) unstructured logging. Default:
default.
--log-file <path>/<file-name>.log
Set the log file path and filename. Default: data\log\keycloak.log.
--log-file-format <format>
Set a format specific to file log entries. Default: %d{yyyy-MM-dd HH:mm:ss,
SSS} %-5p [%c] (%t) %s%e%n.
--log-gelf-facility <name>
The facility (name of the process) that sends the message. Default: keycloak.
--log-gelf-host <hostname>
Hostname of the Logstash or Graylog Host. By default UDP is used, prefix the
host with 'tcp:' to switch to TCP. Example: 'tcp:localhost' Default:
localhost.
--log-gelf-include-location <true|false>
Include source code location. Default: true.
--log-gelf-include-message-parameters <true|false>
Include message parameters from the log event. Default: true.
--log-gelf-include-stack-trace <true|false>
If set to true, occuring stack traces are included in the 'StackTrace' field
in the gelf output. Default: true.
--log-gelf-max-message-size <size>
Maximum message size (in bytes). If the message size is exceeded, gelf will
submit the message in multiple chunks. Default: 8192.
--log-gelf-port <port>
The port the Logstash or Graylog Host is called on. Default: 12201.
--log-gelf-timestamp-format <pattern>
Set the format for the gelf timestamp field. Uses Java SimpleDateFormat
pattern. Default: yyyy-MM-dd HH:mm:ss,SSS.
--log-level <category:level>
The log level of the root category or a comma-separated list of individual
categories and their levels. For the root category, you don't need to
specify a category. Default: info.
By default, this command tries to update the server configuration by running a
'build' before starting the server. You can disable this behavior by using the
'--optimised' option:
$ kc.bat start '--optimised'
By doing that, the server should start faster based on any previous
configuration you have set when manually running the 'build' command.

View file

@ -177,6 +177,7 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta
commands.add(getCommand());
commands.add("-v");
commands.add("start");
commands.add("--optimised");
commands.add("--http-enabled=true");
if (Boolean.parseBoolean(System.getProperty("auth.server.debug", "false"))) {
@ -195,9 +196,9 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta
commands.add("-Djboss.node.name=" + configuration.getRoute());
}
// only run auto-build during restarts or when running cluster tests
// only run build during restarts or when running cluster tests
if (restart.get() || "ha".equals(System.getProperty("auth.server.quarkus.cluster.config"))) {
commands.add("--auto-build");
commands.removeIf("--optimised"::equals);
commands.add("--http-relative-path=/auth");
String cacheMode = System.getProperty("auth.server.quarkus.cluster.config", "local");