Add base image creation support.
diff --git a/pkg/cmd/local.go b/pkg/cmd/local.go
index 89b7740..af04dad 100644
--- a/pkg/cmd/local.go
+++ b/pkg/cmd/local.go
@@ -50,6 +50,7 @@
 	}
 
 	localCmd.AddCommand(cmdOnly(newCmdLocalRun(options)))
+	localCmd.AddCommand(cmdOnly(newCmdLocalCreate(options)))
 
 	return nil
 }
diff --git a/pkg/cmd/local_create.go b/pkg/cmd/local_create.go
new file mode 100644
index 0000000..53e6451
--- /dev/null
+++ b/pkg/cmd/local_create.go
@@ -0,0 +1,97 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package cmd
+
+import (
+	"fmt"
+
+	"github.com/pkg/errors"
+	"github.com/spf13/cobra"
+)
+
+func newCmdLocalCreate(rootCmdOptions *RootCmdOptions) (*cobra.Command, *localCreateCmdOptions) {
+	options := localCreateCmdOptions{
+		RootCmdOptions: rootCmdOptions,
+	}
+
+	cmd := cobra.Command{
+		Use:     "create [options]",
+		Short:   "Create integration images locally.",
+		Long:    `Create integration images locally for containerized integrations.`,
+		PreRunE: decode(&options),
+		RunE: func(_ *cobra.Command, args []string) error {
+			if err := options.validate(args); err != nil {
+				return err
+			}
+			if err := options.init(); err != nil {
+				return err
+			}
+			if err := options.run(args); err != nil {
+				fmt.Println(err.Error())
+			}
+			if err := options.deinit(); err != nil {
+				return err
+			}
+
+			return nil
+		},
+		Annotations: map[string]string{
+			offlineCommandLabel: "true",
+		},
+	}
+
+	cmd.Flags().Bool("base-image", false, "Create base image used as a starting point for any integration.")
+	cmd.Flags().String("docker-registry", "", "Docker registry to store intermediate images.")
+
+	return &cmd, &options
+}
+
+type localCreateCmdOptions struct {
+	*RootCmdOptions
+	BaseImage      bool   `mapstructure:"base-image"`
+	DockerRegistry string `mapstructure:"docker-registry"`
+}
+
+func (command *localCreateCmdOptions) validate(args []string) error {
+	// If containerize is set then docker registry must be set.
+	if command.BaseImage && command.DockerRegistry == "" {
+		return errors.New("base image cannot be created as no registry has been provided")
+	}
+
+	return nil
+}
+
+func (command *localCreateCmdOptions) init() error {
+	return createDockerBaseWorkingDirectory()
+}
+
+func (command *localCreateCmdOptions) run(args []string) error {
+	// Create the Dockerfile and build the base image.
+	if command.BaseImage {
+		err := createAndBuildBaseImage(command.DockerRegistry)
+		if err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+func (command *localCreateCmdOptions) deinit() error {
+	return deleteDockerBaseWorkingDirectory()
+}
diff --git a/pkg/cmd/local_run.go b/pkg/cmd/local_run.go
index a05968d..ca34eed 100644
--- a/pkg/cmd/local_run.go
+++ b/pkg/cmd/local_run.go
@@ -111,8 +111,28 @@
 		return nil
 	}
 
-	// Run the integration locally.
-	err = RunLocalIntegration(command.PropertyFiles, dependencies, args)
+	// Run integration inside a local container.
+	if command.Containerize {
+		// Get base image name.
+
+		// Assemble Dockerfile for containerized run.
+		// - copy properties
+		// - copy dependencies
+		// - copy sources
+		// = assemble run command: GetIntegrationRunCommand
+
+		// Build container image.
+
+		// Run container image.
+
+		return nil
+	}
+
+	// Get integration run command.
+	cmd := GetIntegrationRunCommand(command.PropertyFiles, dependencies, args)
+
+	// Run integration locally.
+	err = cmd.Run()
 	if err != nil {
 		return nil
 	}
diff --git a/pkg/cmd/util_commands.go b/pkg/cmd/util_commands.go
index 4819935..bc377ab 100644
--- a/pkg/cmd/util_commands.go
+++ b/pkg/cmd/util_commands.go
@@ -65,8 +65,8 @@
 	return strings.Join(classpathContents, ":")
 }
 
-// RunLocalIntegration --
-func RunLocalIntegration(properties []string, dependencies []string, routes []string) error {
+// GetIntegrationRunCommand --
+func GetIntegrationRunCommand(properties []string, dependencies []string, routes []string) *exec.Cmd {
 	// Create classpath value.
 	classpathValue := assembleClasspatchArgValue(properties, dependencies, routes)
 
@@ -83,13 +83,13 @@
 	cmd.Stderr = os.Stderr
 	cmd.Stdout = os.Stdout
 
-	fmt.Printf("executing: %s", strings.Join(cmd.Args, " "))
-
 	// Add directory where the properties file resides.
 	cmd.Env = append(cmd.Env, "CAMEL_K_CONF_D="+getPropertiesDir())
 
 	// Add files to the command line under the CAMEL_K_ROUTES flag.
 	cmd.Env = append(cmd.Env, "CAMEL_K_ROUTES="+strings.Join(formatRoutes(routes), ","))
 
-	return cmd.Run()
+	fmt.Printf("executing: %s", strings.Join(cmd.Args, " "))
+
+	return cmd
 }
diff --git a/pkg/cmd/util_containerization.go b/pkg/cmd/util_containerization.go
new file mode 100644
index 0000000..cc8780c
--- /dev/null
+++ b/pkg/cmd/util_containerization.go
@@ -0,0 +1,74 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package cmd
+
+import (
+	"fmt"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"strings"
+
+	"github.com/apache/camel-k/pkg/util/docker"
+	"github.com/pkg/errors"
+)
+
+func createDockerBaseWorkingDirectory() error {
+	// Create local docker base directory.
+	temporaryDirectory, err := ioutil.TempDir(os.TempDir(), "docker-base-")
+	if err != nil {
+		return err
+	}
+
+	// Set the Docker base directory to the default value.
+	docker.BaseWorkingDirectory = temporaryDirectory
+
+	return nil
+}
+
+func deleteDockerBaseWorkingDirectory() error {
+	// Remove directory used for computing the dependencies.
+	defer os.RemoveAll(docker.BaseWorkingDirectory)
+
+	return nil
+}
+
+func createAndBuildBaseImage(dockerRegistry string) error {
+	// Set docker registry.
+	docker.RegistryName = dockerRegistry
+
+	// Create the base image Docker file.
+	err := docker.CreateBaseImageDockerFile()
+	if err != nil {
+		return err
+	}
+
+	// Get the Docker command arguments for building the base image and create the command.
+	args := docker.BuildBaseImageArgs()
+	cmd := exec.CommandContext(ctx, "docker", args...)
+
+	// Output executed command.
+	fmt.Printf("Executing: " + strings.Join(cmd.Args, " "))
+
+	// Run the command.
+	if err := cmd.Run(); err != nil {
+		errors.Errorf("base image containerization did not run successfully: %v", err)
+	}
+
+	return nil
+}
diff --git a/pkg/util/docker/docker.go b/pkg/util/docker/docker.go
new file mode 100644
index 0000000..ec38e47
--- /dev/null
+++ b/pkg/util/docker/docker.go
@@ -0,0 +1,54 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package docker
+
+import (
+	"path"
+	"strings"
+
+	"github.com/apache/camel-k/pkg/util"
+)
+
+// CreateBaseImageDockerFile --
+func CreateBaseImageDockerFile() error {
+	dockerFile := []string{}
+
+	// Base image is a java-only image since the integration command is just a java command.
+	dockerFile = append(dockerFile, FROM("adoptopenjdk/openjdk11:alpine"))
+
+	// Ensure Maven is already installed.
+	dockerFile = append(dockerFile, RUNMavenInstall())
+
+	// Write <base-work-dir>/Dockerfile
+	baseDockerFilePath := path.Join(BaseWorkingDirectory, "Dockerfile")
+	err := util.WriteToFile(baseDockerFilePath, strings.Join(dockerFile, "\n"))
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// BuildBaseImageArgs --
+func BuildBaseImageArgs() []string {
+	// Construct the docker command:
+	//
+	// docker build -f <BaseWorkingDirectory>/Dockerfile -t <dockerRegistry>/<BaseImageName>
+	//
+	return BuildImageArgs(BaseWorkingDirectory, BaseImageName, BaseWorkingDirectory)
+}
diff --git a/pkg/util/docker/docker_base.go b/pkg/util/docker/docker_base.go
new file mode 100644
index 0000000..de7c3f7
--- /dev/null
+++ b/pkg/util/docker/docker_base.go
@@ -0,0 +1,228 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package docker
+
+import (
+	"path"
+	"strings"
+)
+
+// RegistryName -- the docker registry name.
+var RegistryName = ""
+
+// BaseImageName -- base image name.
+var BaseImageName string = "integration-base-image"
+
+// BaseWorkingDirectory -- directory used by Docker to construct the base image.
+var BaseWorkingDirectory string = ""
+
+// Internal variables.
+var (
+	dockerEndpointSeparator = "/"
+	containerFileSeparator  = "/"
+	latestTag               = "latest"
+)
+
+// BuildImageArgs - standard docker build arguments.
+func BuildImageArgs(dockerFileDir string, imageName string, sourceDir string) []string {
+	// Construct the docker command:
+	//
+	// docker build -f <docker-file> -t <image-name> <source-directory>
+	//
+	args := make([]string, 0)
+	args = append(args, "build")
+
+	// Add path to Dockerfile:
+	dockerFile := path.Join(dockerFileDir, "Dockerfile")
+	args = append(args, DockerfilePathArg(dockerFile)...)
+
+	// Image name:
+	args = append(args, ImageArg(imageName, "")...)
+
+	// Root of source directory.
+	if sourceDir != "" {
+		args = append(args, sourceDir)
+	}
+
+	return args
+}
+
+// RunImageArgs -- standard docker run arguments.
+func RunImageArgs(imageName string, imageTag string) []string {
+	// Construct the docker command:
+	//
+	// docker run --network="host" <image-name>:<tag>
+	//
+	// TODO: support other types of network connections.
+	args := make([]string, 0)
+	args = append(args, "run")
+
+	// TODO: support other networks.
+	args = append(args, "--network=host")
+
+	// Path to Docker image:
+	args = append(args, ImageArg(imageName, imageTag)...)
+
+	return args
+}
+
+//
+// Arguments to docker command line.
+//
+
+// DockerfilePathArg --
+func DockerfilePathArg(dockerfilePath string) []string {
+	args := make([]string, 0)
+	args = append(args, "-f")
+	args = append(args, dockerfilePath)
+	return args
+}
+
+// ImageArg --
+func ImageArg(dockerImageName string, tag string) []string {
+	args := make([]string, 0)
+	args = append(args, "-t")
+	args = append(args, GetFullDockerImage(dockerImageName, tag))
+	return args
+}
+
+// LatestImageArg --
+func LatestImageArg(dockerImageName string) []string {
+	args := make([]string, 0)
+	args = append(args, "-t")
+	args = append(args, GetFullDockerImage(dockerImageName, latestTag))
+	return args
+}
+
+//
+// Docker-spcific helper functions.
+//
+
+// GetImage - <image-name>:<tag>
+func GetImage(dockerImageName string, tag string) string {
+	image := make([]string, 0)
+	image = append(image, dockerImageName)
+	image = append(image, tag)
+	return strings.Join(image, ":")
+}
+
+// GetLatestImage - <image-name>:latest
+func GetLatestImage(dockerImageName string) string {
+	return GetImage(dockerImageName, latestTag)
+}
+
+// GetFullDockerImage - <docker-registry>/<image-name>:<tag>
+func GetFullDockerImage(dockerImageName string, tag string) string {
+	fullImagePath := make([]string, 0)
+	fullImagePath = append(fullImagePath, RegistryName)
+	if tag == "" {
+		fullImagePath = append(fullImagePath, dockerImageName)
+	} else {
+		fullImagePath = append(fullImagePath, GetImage(dockerImageName, tag))
+	}
+
+	return strings.Join(fullImagePath, dockerEndpointSeparator)
+}
+
+//
+// Container file management.
+//
+
+// JoinPath -- for container paths.
+func JoinPath(lhsPath string, rhsPath string) string {
+	p := []string{lhsPath, rhsPath}
+	return strings.Join(p, containerFileSeparator)
+}
+
+//
+// Docker syntax functions.
+//
+
+// Generic commands.
+
+// COPY --
+func COPY(from string, to string) string {
+	c := []string{"COPY", from, to}
+	return strings.Join(c, " ")
+}
+
+// RUN --
+func RUN(command string) string {
+	c := []string{"RUN", command}
+	return strings.Join(c, " ")
+}
+
+// FROM --
+func FROM(imageName string) string {
+	c := []string{"FROM", imageName}
+	return strings.Join(c, " ")
+}
+
+// WORKDIR --
+func WORKDIR(workDir string) string {
+	c := []string{"WORKDIR", workDir}
+	return strings.Join(c, " ")
+}
+
+// ENV --
+func ENV(envVar string, value string) string {
+	p := []string{envVar, value}
+	c := []string{"ENV", strings.Join(p, "=")}
+	return strings.Join(c, " ")
+}
+
+// AS --
+func AS(image string, alias string) string {
+	c := []string{image, "as", alias}
+	return strings.Join(c, " ")
+}
+
+// CMD --
+func CMD(command string) string {
+	c := []string{"CMD", command}
+	return strings.Join(c, " ")
+}
+
+// // COPYFromBuilder --
+// func COPYFromBuilder(from string, to string) string {
+// 	flag := []string{"--from", internalBuilderImageName}
+// 	newFrom := []string{strings.Join(flag, "="), from}
+// 	return COPY(strings.Join(newFrom, " "), to)
+// }
+
+// RUNMavenInstall --
+func RUNMavenInstall() string {
+	return RUN("apk add --update maven && apk update && apk upgrade")
+}
+
+// RUNMakeDir --
+func RUNMakeDir(dirName string) string {
+	c := []string{"mkdir", "-p", dirName}
+	return RUN(strings.Join(c, " "))
+}
+
+// ENVAppend --
+func ENVAppend(envVar string, value string) string {
+	tail := []string{value, "$" + envVar}
+	return ENV(envVar, strings.Join(tail, ":"))
+}
+
+// CMDShellWrap --
+func CMDShellWrap(command string) string {
+	return CMD("/bin/sh -c \"" + command + "\"")
+}
diff --git a/pkg/util/util.go b/pkg/util/util.go
index 30ff77b..5e47e2d 100644
--- a/pkg/util/util.go
+++ b/pkg/util/util.go
@@ -23,6 +23,7 @@
 	"encoding/xml"
 	"fmt"
 	"io"
+	"io/ioutil"
 	"os"
 	"path"
 	"regexp"
@@ -74,6 +75,7 @@
 	return false
 }
 
+// StringSliceContainsAnyOf --
 func StringSliceContainsAnyOf(slice []string, items ...string) bool {
 	for i := 0; i < len(slice); i++ {
 		for j := 0; j < len(items); j++ {
@@ -325,3 +327,14 @@
 
 	return yamldata, nil
 }
+
+// WriteToFile --
+func WriteToFile(filePath string, fileContents string) error {
+	err := ioutil.WriteFile(filePath, []byte(fileContents), 0777)
+	if err != nil {
+		return errors.Errorf("error writing file: %v", filePath)
+	}
+
+	// All went well, return true.
+	return nil
+}