Introduction

Tableau Server in a Container is Tableau's first container-based server offering. Tableau Server in a Container is an all-in-one Tableau Server instance running inside of a Linux Docker container. In other words, a Tableau Server in a Container image is a docker image that runs an entire self-contained Tableau Server application. Tableau Server in a Container is our first of many steps to support Tableau Server running in container-based environments. The easiest way to understand the concept of Tableau Server in a Container is to think of it like a virtual machine (VM) with Tableau Server pre-installed. The image is based on a CentOS 7.x image and runs supervisord (instead of systemd) inside the container. When the container starts supervisord, it will immediately attempt to initialize and start Tableau Server. Much of the documentation here aims to describe how to provide configuration and leverage automation so you can run Tableau Server in Docker environments.

The Tableau Server in a Container Image Setup Tool helps you create and customize container images to include custom packages and artifacts. One of the primary functions of the tool is to build the container image and install custom data connectors.

To test out the Tableau Server in a Container Image quickly in a proof-of-concept scenarios, see Tableau Server in a Container - Quick Start.

Limitations

  • Tableau Server in a Container only supports license activation using Server ATR, which requires the container to have internet access. Therefore, offline activation in an air-gapped environment is not possible.
  • Tableau Server in a Container does not currently support the Resource Monitoring Tool (RMT) agent.
  • Kerberos is not supported in Tableau Server in a Container.

Tableau Server in a Container Image

The Tableau Server in a Container Image is a Docker image that contains all of Tableau Server. The image is built using the Tableau Server in a Container Setup Tool. The image comes with Tableau Server installed and not yet initialized. The default user in a Tableau Server in a Container image is a non-root unprivileged user.

Prerequisites

Run the configure-container-host script

When Tableau Server is installed outside a container on a machine certain resource limits and coredump properties are changed as part of the installation process. This is to help optimize the performance of Tableau Server. A Tableau Server in a Container image does not have the ability to make these changes on the host machine, so we recommend running the configure-container-host script that is provided in the Tableau Server in a Container Setup Tool on any machine that will be running Tableau Server in a Container images. This will help ensure the performance of the Tableau Server in a Container image is on-par with its bare metal counterpart.

To run the configure-container-host script:

  1. Locate the script (configure-container-host) in the top-level directory of the Tableau Server in a Container Setup Tool.
  2. Copy it to the environments you plan on running Tableau Server.

  3. Determine the unprivileged user account/uid that will run as the default user of the Tableau Server in a Container image. This user should exist on the host machine and should match the UID set in the Tableau Server container UNPRIVILEGED_TABLEAU_UID environment variable. If you did not set this when creating your Docker image, the default unprivileged user id inside the container is 999. If you are using Docker user-mapping, this uid should correspond with the user that exists on the host machine.

  4. Execute the script as root:

    sudo ./configure-container-host -u <uid>

Running the Image

To run a Tableau Server in a Container docker image, the simplest command to get a Tableau Server in a Container Image running is the following:

docker run \
-e LICENSE_KEY=<key>
-p 8080:8080
-d <Tableau Server in a Container image ID or tag>

This will run docker in the background and, after some time, will result in a fully installed instance of Tableau Server. Tableau Server can take 10 to 20 minutes to fully start up, depending on the hardware of the computer running the image. You can confirm that the container is running by typing the command docker ps. Once Tableau Server is operational, the initial Tableau Server administrator account will need to be created. This step can be automated. For more information, see Automate Initial Tableau Server Administrator.

Basic Run Arguments Summary

All the options used in the Docker run command are necessary, often times more options will be provided to leverage different functionality in the image. For now, let's take a closer look at just the arguments used in the simplest Docker run command for Tableau Server in a Container:

Argument Description
-e LICENSE_KEY=<key> Tableau Server must be licensed. This environment variable will store the key that will be used to license the server. This is a required component of the initialization process. You can provide multiple licenses separated with comma.
-p 8080:8080 This tells docker to expose port 8080 inside the container and bind it to port 8080 on the host machine. The first 8080 value is configurable, changing this will modify the port mapped on the host. Tableau Server by default expects to receive user traffic on port 8080 inside the container, you can choose whether to expose this port on a different host port or not at all.

 

Automate Initial Tableau Server Administrator

When Tableau Server starts up for the first time an initial administrator user must be created before remote network connections to Tableau Server are permitted. This can be done by running the tabcmd initialuser -s localhost:8080 -u <username> -p <password> command inside the container. You may also set admin credentials via environment variables. TABLEAU_USERNAME and TABLEAU_PASSWORD or TABLEAU_PASSWORD_FILE (preferred) are the environment variables that can be set to pass in initial admin credentials. For more information on password management, see Password Management.

For more information on the tabcmd initialuser command see initialuser.

Example

docker run \
-e LICENSE_KEY=<key> \
-e TABLEAU_USERNAME=<myadmin> \
-e TABLEAU_PASSWORD_FILE=/etc/tableau-admin-secret \
-v <full-path-to-pw-file>:/etc/tableau-admin-secret \
-p 8080:8080 -d <Tableau Server in a Container image ID or tag>

Licensing

Licensing in Containers

Licensing of Tableau Server in a Container uses the Server Authorization-To-Run (ATR) service to activate Tableau Server deployed in the cloud, containers, or virtual environments without running out of license activations. The ATR service achieves this by providing short-term leases of configurable duration (ATR duration) until the product key expiration date is met. ATR abstracts Tableau licensing from underlying hardware changes, which is a fundamental aspect of container deployments. Since Server ATR requires the container to be able to reach the ATR service hosted by Tableau, the containers require internet access. Tableau Server in a Container does not support offline or manual activation. See Activate Tableau Server Using the Authorization-To-Run (ATR) Service for more details.

Important: You must provide either the LICENSE_KEY or LICENSE_KEY_FILE environment variables (only set one).

When upgrading Tableau Server in a container, if you’ve used the maximum number of activations for your license, Tableau Server cannot start until the ATR duration has elapsed (4 hours/14400 seconds by default). For more information about setting or changing the ATR duration, see Activate Tableau Server Using the Authorization-To-Run (ATR) Service(Link opens in a new window).

License Environment Variable

Tableau Server in a Container supports setting license keys using an environment variable: the LICENSE_KEY can contain one or more keys(-e LICENSE_KEY="<key1> , <key2>") via a comma separated list.

Example

docker run \
-e LICENSE_KEY="<key1>, <key2>" \
-p 8080:8080 -d <Tableau Server in a Container image ID or tag>

License File

Tableau Server in a Container also supports setting license keys using a file. Mount a file to the default license key file location in the container (/docker/config/license_file) or as otherwise specified by the environment variable LICENSE_KEY_FILE.

Example

docker run \
-v <full-path-to-license-file>:/docker/config/license_file \
-p 8080:8080 -d <Tableau Server in a Container image ID or tag>

Requested license lease time

You can specify the ATR license lease time in a Tableau Server container by setting the environment variable REQUESTED_LEASE_TIME. You must provide the lease time in seconds, with the minimum duration being 3600 seconds (or 1 hour). It is recommended that you lower the lease time when experimenting and testing Tableau Server to reduce the likelihood of reaching the max activated lease limit. For production deployments, it is strongly recommend to not set the REQUESTED_LEASE_TIME parameter (thus using the default value), so Tableau can determine the ideal lease time.

Example

docker run \
...
-e REQUESTED_LEASE_TIME=<time-in-seconds> \
-p 8080:8080 -d <Tableau Server in a Container image ID or tag>

Running an Uninitialized Image

Tableau Server has two phases of installation, first the Tableau Service Manager (TSM) services are installed. In a typical On-Premise installation this step is a time for server admins to register their server, activate their licenses, and configure the server to behave the way they want it to. The second phase of installation is setting up and starting the Tableau Server processes which will handle end-user traffic and related business logic.

The default behavior of Tableau Server in a Container images is to automate all installation steps so the docker run command eventually results in a fully functional server. However, if you want to start a Tableau Server in a Container image and have it only running the TSM services (what a server administrator would expect if they just ran initialize-tsm), you can do this by passing the TSM_ONLY flag as an environment variable.

For example:

docker run \
-e TSM_ONLY=1 \
-p 8080:8080 -d <Tableau Server in a Container image ID or tag>

Interacting with the Image

When you have a Tableau Server in a Container image running, you can call TSM and tabcmd commands directly. Those tools are added directly to the environment path of the pid 1 user (which is root at this time). This means you can call TSM and tabcmd commands as folllows:

docker exec -it <container> tsm status -v
docker exec -it <container> tabcmd initialuser -s localhost -u <admin> -p <secret>

It is also possible to open a shell in the container to perform more general operations. This is generally not recommended except for debugging purposes:

docker exec -it <container> bash

TSM Web UI and Remote CLI

The TSM Web UI and remote CLI is not accessible by default. This is because it requires a username and password to authenticate and by default the user running tableau server processes in the container is not provided a password. This is done for security reasons (we do not recommend shipping images with a default password inside them as that would allow remote access). In some cases the TSM Web UI and making remote access calls using the TSM CLI can be useful. If you want to use these features you will need to follow the steps outlined below to create a remote access user account.

More detailed information about the TSM Web UI and CLI see Sign in to Tableau Services Manager Web UI.

Create a TSM Remote User

Specify the TSM_REMOTE_UID and TSM_REMOTE_USERNAME environment variables when you build the Tableau Server in a Container image using the Setup Tool. Creation of a TSM enabled account in the image requires privileged access in the image that isn't available at runtime, and therefor it can only be done when the Docker image is being built by the Tableau Server in a Container Setup Tool (build-image).

Example Tableau Server in a Container Setup Tool environment file:

TSM_REMOTE_UID=1010
TSM_REMOTE_USERNAME=myuser

Set the password for the TSM Remote User

The Tableau Server in a Container image requires a password for the account when the image is run. There are two ways you can set the password for this account.

Secrets File (Recommended)

Create a file named remote-user-secret, write the password into the file and mount it into the container at runtime. TSM_REMOTE_PASSWORD_FILE determines the expected location (default location is /docker/config/remote-user-secret) of the secrets file in the container.

Example remote-user-secret file:

mypassword

Example docker run command:

docker run \
-e LICENSE_KEY=<key>
-v {absolute-path}/remote-user-secret:/docker/config/remote-user-secret
-p 8080:8080 \
-p 8850:8850 \
-d <Tableau Server in a Container image ID or tag>
Environment Variable

You can also simply set the TSM_REMOTE_PASSWORD environment variable when starting the docker image.

Example docker run command:

docker run \
-e LICENSE_KEY=<key>
-e TSM_REMOTE_PASSWORD=<password>
-p 8080:8080 \
-p 8850:8850 \
-d <Tableau Server in a Container image ID or tag>

Security Notes

  • Port 8850 must be exposed to receive TSM request traffic.
  • If the password is not set properly in the image at runtime the container will exit immediately.
  • TSM relies on the image's Linux user account system. In this case the account is a restricted inside the image. This means the account will have a restricted shell and is limited to executing two commands: /bin/true and passwd.

How to Rotate the TSM Remote User's Password

If you want to rotate the account password of the TSM remote user, you can do this using either of these options:

Start a new Tableau Server in a Container

The account's password is set every time the container starts up. If you are persisting Tableau data outside the container then starting a fresh image with a new password will effectively rotate the password.

  1. Shut down and remove the running image
  2. Set a new password value in either TSM_REMOTE_PASSWORD or TSM_REMOTE_PASSWORD_FILE environment variables (see above) in your image configuration.
  3. Start the image up again.
Rotate the password manually inside a running container

If you don't want to shut down the image, you can still rotate the password manually.

  1. Open a shell in the running container
  2. Log in as the remote user account using the su command
  3. Run the passwd command to change the password.

    Warning: These manual rotations only persist as long as the container instance's write layer remains. If you delete the container, the manual changes will not be applied when a new container is started.

 

Initial Configuration Options

Configuring Tableau Server in a Container is essential for getting the Tableau Server behavior you want. Tableau Server in a Container is a clean installation of Tableau Server, so you need to provide the same information to the container as when configuring Tableau Server outside a container..

Runtime Environment Variables

The runtime environment variables below tell the Tableau Server in a Container image how to deploy Tableau Server. A subset of these will be described in greater detail.

All of these values are designed to be overridden to enable more flexibility for configuration.

Environment name Default Description
ACCEPTEULA 0 Automatically set to 1 when an image is built using the Tableau Server in a Container Setup tool.
LICENSE_KEY   Set to the license key that will be used to license the server. Accepts multiple licenses separated with commas.
LICENSE_KEY_FILE /docker/config/license_file File path to license file. The format of the license file should be one license key per line.
REGISTRATION_FILE /docker/config/tableau_reg.json File path to registration file inside the image. By default this contains the registration information that was provided when the Tableau Server in a Container image was built. This can be overwritten at run time. For more information, see Activate and Register Tableau Server.
REGISTRATION_DATA   An alternative way to overwrite registration information at runtime. This environment variable must be set to a serialized JSON string containing the same registration information that would be found in a Tableau Server registration file. For more information, see Activate and Register Tableau Server.
TABLEAU_USERNAME   This refers to the initial administrator account on Tableau Server. This is recommended but optional. If this user is not set the inital admin account for Tableau Server will need to be set using tabcmd. If this variable is set to a value then a password is also required. This is only used when Tableau Server is initialized for the first time. Setting this value will tell Tableau Server in a Container to automatically attempt to initialize the user. For more information, see Add an Administrator Account.
TABLEAU_PASSWORD   A plain text password for the tableau user. This refers to the initial administrator account on Tableau Server. This is required if TABLEAU_USERNAME is specified. For more information, see Add an Administrator Account.
TABLEAU_PASSWORD_FILE   A file path to a file containing only the password text for the tableau user. This refers to the initial administrator account on Tableau Server. This is required if TABLEAU_USERNAME is specified. For more information, see Add an Administrator Account.
CONFIG_FILE /docker/config/config.json

File path to default TSM config file. The file will be used to configure Tableau Server. For more information, see Configuration File Example.

Do not set CONFIG_DATA if CONFIG_FILE used

CONFIG_DATA   This can be used as a substitute for CONFIG_FILE. If you want to provide configuration to the server without mounting an external file, set this environment variable to the equivalent serialized contents of a TSM config file.

Example CONFIG_DATA="{\"configEntities\":{\"identityStore\":{\"_type\":\"identityStoreType\",\"type\":\"local\"}}}" For more information, see Configuration File Example

Do not set CONFIG_FILE if CONFIG_DATA is used

IGNORE_TOPOLOGY_CONFIG 0 0 or 1. If set to 1, the container will ignore any topology related configuration present in the config file designated by CONFIG_FILE.
BACKUP_FILE /docker/config/backup/backup-file.tsbak A file path to a Tableau Server backup file (.tsbak). If provided during initialization the server will attempt a restore.
INIT_CONTAINER 0 0 or 1. If set to 1 Tableau Server will only attempt to initialize TSM and initialize Tableau Server and the container will exit upon completion.
TSM_ONLY 0 0 or 1. Equivalent to installing the Tableau Server rpm and running initialize-tsm. Only the TSM (Tableau Service Manager) services will start. ONLY works if the container is initializing for the first time (this will not work if a Tableau Server in a Container is being started up with a previously initialized server directory).
BOOTSTRAP_INSTALL 0 0 or 1. Indicates whether or not the server is an initial node or an additional node. If set to 1, the container will wait indefinitely until a bootstrap file exists at the location specified by $BOOTSTRAP_FILE
ALWAYS_WRITE_BOOTSTRAP_FILE 0 0 or 1. If set to 1, the container will write a bootstrap file to the location given in BOOTSTRAP_FILE.
WAIT_FOR_BOOTSTRAP_FILE 1 0 or 1. If set to 1 (default), if the container detected it is a worker installation (BOOTSTRAP_INSTALL=1). The container will wait indefinitely until a file is detected located at the path set in BOOTSTRAP_FILE. If set to 0 when the startup process is run this wait will be skipped. This can be useful in some debug cases.
BOOTSTRAP_FILE /docker/config/bootstrap/bootstrap.json File path to bootstrap file. Only applies to worker containers. This file should only point to a bootstrap file. The typical usage would be to mount the directory of the target file (default would be /docker/config/bootstrap) to the host.
BOOTSTRAP_DATA This can be used as a substitute for BOOTSTRAP_FILE. If you want to provide a bootstrap file without mounting an external file, set this environment variable to the equivalent serialized contents of a TSM bootstrap file. Do not set BOOTSTRAP_DATA if using BOOTSTRAP_FILE.
PORT_RANGE_MIN 8800 For performance reasons, we recommend exposing only 200 ports (8800-9000) instead of the Tableau Server On-Premise default 8000-9000 port range because exposing 1000 ports in docker can negatively impact the start up time of the docker image. See Exposing Licensing and TSM ports below for more information.
PORT_RANGE_MAX 9000 We recommend exposing only 200 ports (8800-9000) instead of the Tableau Server On-Premise default 8000-9000 port range because exposing 1000 ports in docker can negatively impact the start up time of the docker image. See Exposing Licensing and TSM ports below for more information.
HTTP_PROXY   To forward http requests to your proxy server, set this environment variable to point your proxy host. For example, to set the proxy to example-host for port 8080, HTTP_PROXY=http://example-host:8080/
HTTPS_PROXY   To forward https requests to your proxy server, set this environment variable to point your proxy host. For example, to set the proxy to example-host for port 443, HTTPS_PROXY=http://example-host:443/ Be sure to use 'http' when you specify the URL for the HTTPS_PROXY environmental variable.
NO_PROXY   To bypass the proxy server, specify exceptions in the no_proxy variable. Use this variable if your proxy server does not route internal addresses. You must also add exceptions to this proxy configuration to guarantee that all communications within a local Tableau Server cluster (if you have one now or will have one later) do not route to the proxy server. Enter both the host name and the IP address for each computer, and add host name of the container. Additionally, include the canonical host name (localhost) and IP address (127.0.0.1) for the local computer. For example, to specify exceptions for a three-node cluster: NO_PROXY="localhost,127.0.0.1,hostname1,hostname2,hostname3,IP1,IP2,IP3"
COORDINATION_SERVICE_CLIENT_PORT Any port between PORT_RANGE_MIN and PORT_RANGE_MAX Client port for the coordination service.
COORDINATION_SERVICE_PEER_PORT Any port between PORT_RANGE_MIN and PORT_RANGE_MAX Peer port for the coordination service.
COORDINATION_SERVICE_LEADER_PORT Any port between PORT_RANGE_MIN and PORT_RANGE_MAX Leader port for the coordination service.
LICENSE_SERVICE_VENDOR_DAEMON_PORT Any port between PORT_RANGE_MIN and PORT_RANGE_MAX Vendor daemon port for the licensing service.
AGENT_FILE_TRANSFER_PORT Any port between PORT_RANGE_MIN and PORT_RANGE_MAX File transfer port for the agent service.
CONTROLLER_PORT Any port between PORT_RANGE_MIN and PORT_RANGE_MAX https port for the controller service.
REQUESTED_LEASE_TIME Default is currently set to 4 hours. Set the requested lease time for Server ATR activations. You need to provide the time value in seconds and the minimum duration is 14400 seconds (or 4 hours). Changing this value is generally not recommended for production deployments. However when developing or prototyping with Tableau Server in a Container you may want to set this to the minimum value so as to minimize the loss of activations.

Readonly Environment Variables

These are environment properties that describe some of the basic properties of the Tableau Server in a Container image. Overriding these values is not recommended.

Environment name Default Description
PRE_INIT_COMMAND_SCRIPT ${DOCKER_CONFIG}/customer-files/pre_init_command Path to a user custom bash/executable file to be run in Tableau Server prior to Tableau Server initialization. Note: Make sure the file has execute permission for all users, otherwise run chmod +rx <path-to-pre-init-command-file>
POST_INIT_COMMAND_SCRIPT ${DOCKER_CONFIG}/customer-files/post_init_command Path to a user custom bash/executable file to be run in Tableau Server after the server is fully functional and running. Note: Make sure the file has execute permission for all users, otherwise run chmod +rx <path-to-post-init-command-file>
DATA_DIR /var/opt/tableau/tableau_server The data directory where Tableau Server bits should be written.
INSTALL_DIR /opt/tableau/tableau_server The installation directory where Tableau Server installation bits are written.
SERVICE_NAME Tableau Server Name of the application running in the container.
SERVICE_VERSION N/A Version of Tableau Server installed in the container.
DOCKER_CONFIG /docker Directory that stores Tableau specific docker configuration.
ENV_FILE ${DOCKER_CONFIG}/customer-files/environment File that contains all user environment overrides.

Build-Time Environment Variables

     
BASE_IMAGE_URL Use the build tool command: build-image -b The default image specified in the build-image tool and Dockerfile is the only officially supported base image. This parameter can be used to either pull a copy of this specific base image from a custom docker image repository or define a custom base image. If you choose to use a custom-defined base image, it is your responsibility to ensure it is based on CentOS or RHEL 7 and contains the necessary resources to run Tableau Server properly. For more information on custom base images, see Tableau Server in a Container - Using an Image.
PRIVILEGED_TABLEAU_GID 997 The GID of the privileged Tableau group.
UNPRIVILEGED_TABLEAU_GID 998 The GID of the unprivileged Tableau group.
UNPRIVILEGED_TABLEAU_UID 999 The UID of the user that runs Tableau processes (single user deployment).
UNPRIVILEGED_USERNAME tableau The string name of the unprivileged user.
UNPRIVILEGED_GROUP_NAME tableau The string name of the unprivileged group.
PRIVILEGED_GROUP_NAME tsmadmin The string name of the privileged group.
LANG en_US.UTF-8 Locale setting

 

Tableau Server Configuration Overrides

These environment variables can be overwritten by Docker to point at any file in the container. So if you want to specify a different mount point you are welcome to do so.

Tableau Server needs a configuration file to start and run:

CONFIG_FILE=/docker/config/config.json

CONFIG_FILE refers to a TSM configuration file. The format and usage is identical to the configuration file described in Configuration File Example.

Pre-initialization and Post-initialization Commands

Tableau Server runs an automated installation script designed to take Server from a pre-initialized state to fully running. However, sometimes you may want to add in your own automation code in the initialization process. We offer two hooks to do this, the pre-initialization script and post-initialization script.

Pre-initialization script

This script will run immediately after the base TSM processes are initialized and before any other TSM setup steps are executed. This is useful for executing TSM configuration commands before Tableau Server runs. For configuration changes made at this point, you do not need to apply the changes because the normal Tableau Server automation does this after your script completes.

Post-initialization script

This script will run after all other Tableau Server initialization and start-up automation completes. Tableau Server will be fully functional and running when this script executes. Configuration changes made at this point must be applied.

Instructions

To add a custom script to one of these hooks in your image, follow these steps:

  1. Write your custom script
  2. Copy the custom script into the customer-files directory of the Tableau Server in Containers Build Image Tool.
  3. Rename the script to be either pre_init_command or post_init_command depending on when you would like the script to run (you can use both hooks independently from each other).
  4. Ensure the permissions of the script are either executable by other (chmod +rx <command-file>) or the ownership permissions match the unprivileged user in the container.

User Configuration

Tableau Server uses an unprivileged user to run server processes. This user created inside the container when Tableau Server in a Container is initializing. By default the user is named tableau with a UID of 999. If you are deploying a Tableau Server in a Container that uses mounts to externally store data on the host machine you may prefer to change the UID to map a to a UID on the host machine. Using docker user namespaces is another way to achieve the same result.

Tableau Server in a Container Utilities and Tools

All Tableau Server in a Container utility and tool functions are placed under this directory:

/docker/

File Permission Management

When passing any configuration files to the container you will want to ensure the user running the Tableau Server process inside the container has permission to access the files. To avoid granting all users access to files being mounted to the container you can change the UID and/or the GID of the user running Tableau Server inside the container to match the user/group owner on the host. The container user will have a UID determined by the UNPRIVILEGED_TABLEAU_UID environment variable (default: 999) and GID determined by UNPRIVILEGED_TABLEAU_GID (default: 998). These values can be changed by overriding the environment variable or you can use a Docker user namepace mapping to associate the UID/GID in the container to a different UID/GID on the host.

Password Management

Certain features and options require user credentials to be provided as a configuration setting into the container. Tableau Initial Admin credentials is an example of optional credentials that enable additional features. In these cases we always provide two methods of setting the password. First, you can provide a file containing the password and supply a file path to an environment variable. Alternatively, you can set an environment variable to store the password directly.

The recommended and more secure option is to provide the password as a file path to the container. Providing a secret in a file is a well supported pattern in Docker, Docker Swarm, Kubernetes, and other container orchestration systems. Storing passwords directly in environment variables is a common pattern so we do support it, but it typically means the password is less secure.

Examples

Let's take a look at the TABLEAU_USERNAME credential. You can provide the password for the user as either TABLEAU_PASSWORD or TABLEAU_PASSWORD_FILE. When running a Tableau Server in a Container image you can provide either environment variable to supply the password.

The password file environment variable expects a file path inside the container to a valid secrets file. The secrets file should be a single line containing the secret.

Example of using a secrets file
docker run \
...
-e TABLEAU_USERNAME=admin \
-e TABLEAU_PASSWORD_FILE=/etc/admin-secret \
-v <full-path-to-pw-file>:/etc/admin-secret \
-d <Tableau Server in a Container image ID or tag>
Example contents of a secrets file
mypassword23879172

Alternatively one can directly store the password in plain text in the password environment variable. This approach is considered less secure but it is more convenient and a common pattern with containers.

Example
docker run \
...
-e TABLEAU_USERNAME=admin \
-e TABLEAU_PASSWORD=password \
-d <Tableau Server in a Container image ID or tag>

Configuring Tableau Server after it is running

Once Tableau Server has been initialized and is running, the best way to interact with the server is to use the TSM CLI tool. This is the classic Tableau Server tool for performing administrative tasks. In the future we will support Tableau Server reacting to changes in the static configuration provided in the CONFIG_FILE environment variable in between runs. But for now, after Tableau Server is initialized, you must interact with the server using the classic tools.

For more information on the TSM command-line see tsm Command Line Reference.

Status

There are two basic status checks for Tableau Server provided in the image. These can be used to check the aliveness and readiness of the server.

Liveness Check

The liveness check indicates whether or not TSM services are running. This means it will indicate whether the orchestrated services of Tableau Server are operating and are functioning. This check is callable here:

/docker/alive-check

Another option is to expose port 8850 which the Tableau Controller service runs to provide administrative functions through a web browser. One could periodically check the health of the service by checking the health of the service through tcp health checks.

Readiness Check

The readiness check indicates whether Tableau Server is running and business services are ready to receive traffic. This can be determined using the following script:

/docker/server-ready-check

Another option is to use tcp health checks against port 8080 (or whatever port Tableau Server is bound to receive traffic). Sometimes this kind of tcp health check is more reliable than the server-ready-check, as the server-ready-check is based on service status reported to TSM which can sometimes be delayed as the service state is updated.

Persisting Data

Often times with containers we want the capability to shut a container down and then turn it back on without losing any important information. Tableau Server in a Container images support this in that you can mount certain directories outside of the container so you can completely destroy or remove container instances and still preserve your data. This data can be used to start another container instance and resume where the previous container left off.

The following sections cover the different kinds of managed state.

Tableau Server Data

Server Data is all stored in the data directory. The data directory is where all user-related data and service runtime metadata is stored. Externalizing this data means your user's data can be persisted even after the Tableau Server in a Container is completely removed.

This data is transferable and can is usable with cloud-managed block storage system, like AWS EBS volumes.

When Tableau Server in a Container is used in conjunction with External Filestore, the data directory must be on EBS. Do not use a network file system (for example, NFS) for the data directory. The External Filestore directory can be on an NFS volume.

Static Hostnames

Tableau Server does not handle dynamic hostname changes well so it is important to specify the container's internal hostname so it is consistent between container runs. The hostname inside a container is arbitrary and can be set to any value. Using the --hostname option allows one to specify the internal hostname of the container. Make sure subsequent containers using the same persistent data are run using the same hostname value.

This is not to be confused with multi-node server installations. In these, additional nodes should each be assigned a different hostname. What matters is when any single container is restarted the replacing container that will use the same persistent data for that instance must have a matching hostname.

Complete Example

Here is an example where the data directory is mounted outside the container.

docker run \
-v <empty-data-dir>:/var/opt/tableau \
-e LICENSE_KEY=<key> \
--hostname=<static (internal) name of host machine> \
-p 8080:8080 -d <Tableau Server in a Container image ID or tag>

Backup and Restore

Tableau Server in a Container supports Tableau Server creating backups and restoring from a backup file (.tsbak). The first step is to get a Tableau Server in a Container image running, have the backup file (.tsbak) mounted in the image and set the environment variable BACKUP_FILE with the file path to the backup file. Additionally you must provide the backup json configuration file in the CONFIG_FILE environment variable. The Tableau Server container automates the restore process even for multi-node deployments. If at any point this automation fails to fully restore the system, you can always fallback on the classic Tableau Server tools and processes such as TSM commands to interact with Tableau Server in the same way you would with a non-container deployment.

For more information on how to perform a backup and restore of a standard Tableau Server instance see Perform a Full Backup and Restore of Tableau Server.

Backup in Tableau Server Container

  1. Open shell inside the Tableau Server in a Container version A. Create repository backup, and topology and configuration backup files.

    docker exec -it my-server bash
    
    # Just providing filename automatically produces the backup file at /var/opt/tableau/tableau_server/data/tabsvc/files/backups/
    tsm maintenance backup -f <repository-backup>.tsbak -d
    
    # Any filepath where current user(UNPRIVILEGED USER) can write.
    tsm settings export -f /var/opt/tableau/tableau_server/data/tabsvc/files/backups/<topology-conf-backup>.json
  2. Copy the files created in previous step into the host machine. Change the file permission to have read-all permission set for both files.

    docker cp my-server:/var/opt/tableau/tableau_server/data/tabsvc/files/backups/<repository-backup>.tsbak ./<repository-backup>.tsbak
    docker cp my-server:/var/opt/tableau/tableau_server/data/tabsvc/files/backups/<topology-conf-backup>.json ./<topology-conf-backup>.json
    chmod a+r ./<repository-backup>.tsbak ./<topology-conf-backup>.json
  3. Store backup artifacts in a secure location. Follow the restore steps below when needed.

Restore inside Tableau Server Container

Backups from any supported Tableau Server version (container and non-container) can be restored inside the Tableau Server container.

Prerequisites
  • Tableau Server backup file.
  • Configuration json file containing both configuration and topology information.
  • Note: You will likely need to change the backup files to have read-all permission set. Backup files are typically locked to the user that created the file, and this one will likely be different than the Tableau user running in the container.
docker run \
-v <full-path-to-backup-file>:/docker/config/backup/backup-file.tsbak \
-v <full-path-to-config-only-file>:/docker/config/config.json:ro \
-e LICENSE_KEY=<key> \
-p 8080:8080 -d <Tableau Server in a Container image ID or tag>

Notes:

  • If you are restoring a multi-node system you must also start the other nodes in order for the restore automation to work. See the Multi-node Tableau Server in a Container section of this document for more information. Only the initial node requires the backup file, backup configuration file, and license.
  • The backup files only need to be provided in the first run of the container. Once the server is initialized you do not need to keep mounting in the backup files.

 

Migrating from Tableau Server to Tableau Server in a Container

In order to migrate from a standard Tableau Server installation to Tableau Server in a Container you must use the backup and restore technique. Backups from any supported Tableau Server version (container and non-container) can be restored inside the Tableau Server container. See the Restore inside Tableau Server Container section above for more information.

Upgrading Tableau Server Versions

There are two ways to upgrade Tableau Server. The Upgrade-Image method listed in this section is the recommended solution. However, as a fallback it is also possible to upgrade Tableau Server using Backup/Restore.

Upgrading through Upgrade-Image method

The Upgrade Image is a Docker image that can be built using the build-upgrade-image script from the Tableau Server in a Container setup tool. The purpose of the image is solely to upgrade the currently running Tableau Server in a Container.

Follow the below steps to do the upgrade.

  1. Create an upgrade-image using the build-upgrade-image script. The new version's tableau server rpm is needed to build this container.
  2. Shutdown the container currently running the Tableau Server.
  3. Start the upgrade-image, mounting the same data directory from the container shutdown in the previous step.
  4. The upgrade process takes a while, but the tableau server will be upgraded, check docker logs for upgrade process update. The container will shut down after the upgrade process.
  5. Start a new Tableau Server in a Container of newer version. Mount the same directory from the previous steps.

Example:

Let's say we have a Tableau Server in a Container running Tableau Server. Here are some assumptions made in this example:

  • I have valuable data, and I don't want to lose any data during the upgrade process. The data directory needs to be persisted outside the container.
  • The container is named my-server. The docker image is named as tableau-server:versionA.
  • The server version my-server is currently using is version A.
  • The server version I want to upgrade to is version B.
  1. Get tableau server rpm for version B. Create an upgrade-image.

    # For all the options available in the script
    ./build-upgrade-image -h
     
    # Frequently used command to create a upgrade-image
    ./build-upgrade-image --installer=<path to the tableau server version B> -i tableau-server:versionA -o tableau-server-upgrade:versionAB
  2. Stop the my-server container.

    docker stop my-server -t 120
  3. Start the newly created image tableau-server-upgrade:versionAB. Mount the same data directory from the previously stopped container. The container starts the upgrade process to version B.

    docker run --name my-upgrade-server \
    -v <data-dir mount from previous step>:/var/opt/tableau \
    ...
    tableau-server-upgrade:versionAB
  4. The container will stop once the upgrade is complete. Check the docker logs for upgrade process logs and make sure the upgrade process is a success. You can also check the exit code of the docker container, to make sure the upgrade process is completed successfully.

    # The log file /var/opt/tableau/tableau_server/logs/upgrade-console.log is created after 3-4 mins into the start of upgrade container. When the upgrade completes successfully, "upgrade is complete" log will be # seen.
    docker logs my-upgrade-server
    ...
    ...
    Verifying licensing state.
    Tableau Server has been upgraded to version near.20.0801.1050.
    >> The upgraded Tableau binary directory will be added to PATH for new shells. To get the
    >> updated path, either start a new session, or for bash users run:
    >> source /etc/profile.d/tableau_server.sh
    Starting service...
    Starting service...
    Job id is '12', timeout is 30 minutes.
    Service was started successfully.
    Status: RUNNING
    Tableau Server is Running
    upgrade is complete
  5. Stop the my-upgrade-server container. Start the new version B of Tableau Server in a Container image and mount the data directory from the stopped my-upgrade-server container

    # Stop the server.
    docker stop my-upgrade-server -t 120
    
    
    # Run the new version Hu
    docker run --name my-upgraded-server \
    -v <data-dir mount from previous step>:/var/opt/tableau \
    ...
    ...
    tableau-server:versionB

Upgrading though Backup-Restore method

Follow the steps in the Backup and Restore Section of this document. The only adjustment needed to change a backup-restore operation into an upgrade operation, is to restore the backup on a new version of Tableau Server.

Multi-node Tableau Server in a Container

Multi-node Tableau Server in a Container refers to a single deployment of Tableau Server distributed across multiple nodes. Multi-node in this context is the same as Tableau Server multi-node where certain processes can be run on other nodes to increase capacity, compute power, etc. This is distinct from starting up multiple individual Tableau Server in a Container where each container is an independent server with its own distinct data.

Multi-node Tableau Server in a Container works much like a non-container Tableau Server multi-nodeinstallation, and uses the same underlying mechanism. To get an overview of setting up a non-container Tableau Server multi-node installation, see Distributed and High Availability Tableau Server Installations.

Here is an example:

Multi-Node Basic Usage

Initial node

Option 1: Use this if the server configuration (CONFIG_FILE) specifies a multi-node topology:

docker run \
-v <network-shared-directory>:/docker/config/bootstrap \
-v <full-path-to-config-file>:/docker/config/config.json:ro \
-e LICENSE_KEY=<key> \
-p 8080:8080 -p 8800-9000:8800-9000 -p 27000-27010:27000-27010 \
--hostname=<static (internal) name of host machine> \
-d <Tableau Server in a Container image ID or tag>

Option 2: Use this if you want a multi-node deployment even if server configuration does not specify multi-node topology:

docker run \
-v <network-shared-directory>:/docker/config/bootstrap \
-e LICENSE_KEY=<key> -e ALWAYS_WRITE_BOOTSTRAP_FILE=1 \
-p 8080:8080 -p 8800-9000:8800-9000 -p 27000-27010:27000-27010 \

--hostname=<static (internal) name of host machine> \
-d <Tableau Server in a Container image ID or tag>
Additional node
docker run \
-v <network-shared-directory>:/docker/config/bootstrap \
-e BOOTSTRAP_INSTALL=1 \
-p 8080:8080 -p 8800-9000:8800-9000 \
--hostname=<static (internal) name of host machine> \
-d <Tableau Server in a Container image ID or tag>

Exposing Licensing and TSM ports

In order for worker nodes to communicate with the primary instance we need to open up additional ports. You will need to allow traffic from other nodes on your primary Tableau Server in a Container instance in the following port ranges:

Service Ports: 8800-9000
Postgres Port: 8060
Licensing Ports: 27000-27010

Be careful how many ports you open: We recommend exposing only 200 ports, 8800-9000, instead of the Tableau Server default port range of 8000-9000, because exposing 1000 ports in Docker can negatively impact the performance and start up time of the Docker image. You can use a smaller or larger port range depending on how complex your Tableau Server topology is. Generally we do not recommend exposing fewer than 100 ports, otherwise you run the risk of services in a cluster being unable to talk to certain services. If you specify your own port range make sure you expose port 8850 (this is implicitly included in the 8800-9000). The port range is specified by setting the PORT_RANGE_MIN and PORT_RANGE_MAX environment variables.

Additional nodes will also need to expose the Service Port range (8800-9000), but not the Licensing Port range. It is important to note that these port ranges are only to allow Tableau Server inter-process communication. These ports should not be exposed to users or any other machines other than computers that are running Tableau Server in a Container for the same multi-node cluster.

These port rules are consistent with Tableau Server firewall documentation. For more information, see Configure Local Firewall.

Resolving Hostnames

The multiple nodes of Tableau Server in a Container need to be run with consistent hostnames because Tableau Server does not handle dynamic hostname changes. When running Tableau Server multi-node, those nodes will want to communicate with each other. Tableau Server nodes will attempt to reach each other using the hostnames that multi nodes' Tableau Server in a Container are configured to use. For example, if you run your initial node with a hostname of "initial", additional nodes will attempt to send traffic to a host called "initial". There are multiple ways you can configure images to resolve hostnames to other images. /etc/hosts file in each container to map the arbitrary container hostname (i.e. "initial") to the IP address that is actually running the other container.

Bootstrapping additional nodes

The initial Tableau Server container that runs as part of a cluster generates a bootstrap file that subsequent additional nodes need to use to join the cluster. After additional nodes are registered to the cluster's topology you can start assigning Tableau Server processes to run on them. This process can be fully automated. If you have provided a Tableau Server configuration file (commonly supplied by mounting a configuration file to the file path specified by CONFIG_FILE, default path: /docker/config/config.json) that specifies a Multi-node topology, the initial node will automatically wait until all additional nodes have registered. Once registered the Multi-node topology will be applied across the cluster.

Once the initial node in Tableau Server in a Container is fully running Tableau Server you can have it generate a bootstrap file for additional nodes:

docker exec -it <container-name> tsm topology nodes get-bootstrap-file -f $BOOTSTRAP_FILE

This command is automatically called for you if you set the value of ALWAYS_WRITE_BOOTSTRAP_FILE to 1.

Security Considerations

The bootstrap file contains server secrets that allow it to establish a TSM session with the initial node. This means if a malicious user obtained the file they could send TSM commands to the server for a period of time. The file itself also contains data that would enable the decryption of server configuration secrets. This file should be treated as sensitive and should be accessible only by services and systems directly pertaining to establishing a multi-node deployment.

Bootstrap Expiration

Bootstrap files carry a limited-time session that lasts for 2 hours. In that window the additional nodes will not need to supply credentials to the initial node in order to join as an additional node. It is possible to use a bootstrap file once the session has expired, however it would mean needing to supply credentials to the initial node.

Transferring the Bootstrap File

The bootstrap file needs to be made available to and consumed by worker nodes' Tableau Server in a Container. The bootstrap file will need to be shared with all other nodes' Tableau Server in a Container that you want to as worker nodes for this deployment. This can be done in many different ways.

Transfer the file over a secure network

Part of your automation on the initial node can involve sending the file directly to additional nodes. This should be done using some secure file transfer client/tool. This is probably more useful in scenarios where multiple bootstrap files may be generated throughout the life of the initial node (possibly to add more additional nodes at a later time).

Use a network file mount

A network file mount shared by all the containers in a given deployment is another option.

Other

The end goal is to securely transfer a file produced by one container and transfer it to a specific set of other containers. So any method that achieves this and is secure is sufficient.

Starting additional nodes

To start up a Tableau Server in a Container additional node, simply start the container with the BOOTSTRAP_INSTALL environment variable set to 1.

This will tell the Tableau Server in a Container instance to sleep until a bootstrap file exists at the path specified by the BOOTSTRAP_FILE environment variable (which is also configurable). Refer to the environment variable table to view the default file path. To clarify, if you run a Tableau Server in a Container image in "additional node mode" the container will not start supervisord or any other process other than a bash script running as pid 1 that checks every 5 seconds to see if the bootstrap file exists. Once the file is present the Tableau Server in a Container will proceed to initialize as an additional node.

Configuring additional nodes

Configuring additional nodes to run a specific topology works the same as it does in a normal Tableau Server deployment. It also comes with the same requirements, which means adding new processes on a node may require a cluster-wide restart. For more information, see Configure Nodes.

Tableau Server Feature Considerations

Some Tableau Server features works differently in containers. This section covers specific features that have special or different considerations in a container environment.

Active Directory

Set AD Domain Controller

If you plan on using Active Directory as an Identity Store for Tableau Server web pages and sites, there is an additional consideration to account for. Tableau Servers running in Linux environments dynamically determine which AD Domain Controller to communicate with by examining their IP subnet. Containers can be assigned arbitrary IP addresses, and in this case Tableau Server will not necessarily be able to use its IP address to find an appropriate domain controller. For this reason it may be necessary to configure a specific domain controller / hostname for Tableau Server to communicate with. To do this follow these steps:

  1. Determine which domain controller you want Tableau Server to use and get the hostname.
  2. Set the configuration key wgserver.domain.ldap.hostname to the hostname using the standard Tableau Server Admin configuration options:

    • Set the value in the json configuration file CONFIG_FILE .
    • Use the TSM configuration command

      tsm configuration set -k wgserver.domain.ldap.hostname -v <hostname>

Import AD certificate to Tableau Server Keystore

By default Tableau Server in a container communicates with AD via StartTLS whenever simple bind is used. So when the container is run in this configuration, it is necessary to import the AD server certificate to the Tableau Server Keystore, otherwise server initialization will fail. To do this follow these steps:

  1. Create a pre-init-command script (check Pre-initialization script section). Add the following line to add the AD certificate to tableau server keystore.

    ${INSTALL_DIR}/packages/repository.${SERVICE_VERSION}/jre/bin -importcert -noprompt -alias startTlsCert -file <mounted-certificate-path> -storetype JKS -storepass changeit -keystore ${DATA_DIR}/config/tableauservicesmanagerca.jks
  2. Mount the AD server certificate at the filepath provided for -file parameter in the pre-init-command script.

Alternatively, the default setting to communicating with AD via StartTLS can be disabled. Set wgserver.domain.ldap.starttls.enabled to false to disable the StartTLS. But it is not recommended.

Deployment Configuration Examples

Docker

Tableau Server in a Container Basic Usage
docker run \
-e LICENSE_KEY=<key>
-p 8080:8080
-d <Tableau Server in a Container image ID or tag>
Tableau Server in a Container Basic Usage with Automated Initial Admin User
docker run \
-e LICENSE_KEY=<key> \
-e TABLEAU_USERNAME=<myadmin> \
-e TABLEAU_PASSWORD_FILE=/etc/tableau-admin-secret \
-v <full-path-to-pw-file>:/etc/tableau-admin-secret \
-p 8080:8080 -d <Tableau Server in a Container image ID or tag>
TSM only mode
docker run \
-e TSM_ONLY=1 \
-p 8080:8080 -d <Tableau Server in a Container image ID or tag>
Multi-Node Basic Usage
Initial Node

Option 1: Use this if the server configuration (CONFIG_FILE) specifies a multi-node topology:

docker run \
-v <network-shared-directory>:/docker/config/bootstrap \
-v <full-path-to-config-file>:/docker/config/config.json:ro \
-e LICENSE_KEY=<key> \
-p 8080:8080 -p 8800-9000:8800-9000 -p 27000-27010:27000-27010 \
--hostname=<static (internal) name of host machine> \
-d <Tableau Server in a Container image ID or tag>

Option 2: Use this if you want a multi-node deployment even if server configuration does not specify multi-node topology:

docker run \
-v <network-shared-directory>:/docker/config/bootstrap \
-e LICENSE_KEY=<key> -e ALWAYS_WRITE_BOOTSTRAP_FILE=1 \
-p 8080:8080 -p 8800-9000:8800-9000 -p 27000-27010:27000-27010 \
--hostname=<static (internal) name of host machine> \
-d <Tableau Server in a Container image ID or tag>
Additional node
docker run \
-v <network-shared-directory>:/docker/config/bootstrap \
-e BOOTSTRAP_INSTALL=1 \
-p 8080:8080 -p 8800-9000:8800-9000 \
--hostname=<static (internal) name of host machine> \
-d <Tableau Server in a Container image ID or tag>
Externalize Data Usage
docker run \
-v <empty-data-dir>:/var/opt/tableau \
-e LICENSE_KEY=<key> \
--hostname=<static (internal) name of host machine> \
-p 8080:8080 -d <Tableau Server in a Container image ID or tag>
Init-Container Basic Usage

Init Container

docker run \
-v <empty-data-dir>:/var/opt/tableau \
-e LICENSE_KEY=<key> \
-e INIT_CONTAINER=1 \
--hostname=<static (internal) name of host machine> \
-p 8080:8080 -d <Tableau Server in a Container image ID or tag>

Run Container

docker run \
-v <empty-data-dir>:/var/opt/tableau \
--hostname=<static (internal) name of host machine> \
-p 8080:8080 -d <Tableau Server in a Container image ID or tag>
Basic Restore from Backup Single-Node
docker run \
-v <full-path-to-backup-file>:/docker/config/backup/backup-file.tsbak \
-v <full-path-to-config-only-file>:/docker/config/config.json:ro \
-e LICENSE_KEY=<key> \
-p 8080:8080 -d <Tableau Server in a Container image ID or tag>

Docker-Compose

version: '3.2'
services:
    tableau-server:
         hostname: localhost
         volumes:
              - <your-tsm-command-file>:/docker/config/tsm-commands:ro
              - <your-config-file >:/docker/config/config.json:ro
         ports:
              - "8080:8080"
         image: ${IMAGE_NAME}
         environment:
              - LICENSE_KEY=<license-key>

 

 

Thanks for your feedback!