We are all excited about the great news that Tableau will release its Server version on Linux. Even if I’ve been testing the linux build for a while now, since this feature is currently in Beta I can start sharing tips and tricks that will make others’ (yours perhaps) lives easier. The first is an easy howto, namely how to run a Tableau Server Linux in Docker container. Running the production Server in docker definitely makes no sense, however, for quick and dirty checks or automated testing pipelines (CD/CI) it has it’s own place. So let’s see.
TL;DR
Dockerfile, instruction and code is here: https://github.com/tfoldi/tableau-server-docker
If you prefer to watch a geeky console video, here is the flow how you can build the image with few simple commands:
After the build you can simply execute make run to execute the built image.
Prerequisites
To start you need a systemd based Linux host (can be physical box or VM) with Docker installed. If you don’t have this I suggest to create an amazon ec2 instance with CentOS 7. Simply provision a new image with a CentOS7 marketplace image:
You need to install docker and set the required permissions to run it with a non-root user. To do that simply create a group called docker and set your desired user’s membership to include this group. If all good, you should be able to list running docker images with docker ps :
1 2 3 |
[centos@ip-172-30-2-105 ~]$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [centos@ip-172-30-2-105 ~]$ |
Now we are good to go and focus on Tableau specific tasks.
Building the Dockerfile
First of all, “Dockerizing” Linux is not that easy, even folks at Tableau had problems doing that:
The good old systemd. It’s a love hate relationship: we all know that the init.d/rc.d approach is not scalable but we all do hate systemd. Let’s address this first with our Dockerfile:
1 2 3 4 |
# Run `make run` to get things started # our image is centos default image with systemd FROM centos/systemd |
As you see we start from a special systemd centos image. If your parent docker image does not support systemd, you will have bad times.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# this is the version what we're building ENV TABLEAU_VERSION="10.5-beta5" \ LANG=en_US.UTF-8 # make systemd dbus visible VOLUME /sys/fs/cgroup /run /tmp /var/opt/tableau # Install core bits and their deps:w RUN rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm && \ yum install -y iproute curl sudo vim && \ adduser tsm && \ (echo tsm:tsm | chpasswd) && \ (echo 'tsm ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/tsm) && \ mkdir -p /run/systemd/system /opt/tableau/docker_build && \ yum install -y \ "https://beta.tableau.com/linux_files/tableau-server-automated-installer-${TABLEAU_VERSION}.noarch.rpm" \ "https://beta.tableau.com/linux_files/tableau-server-${TABLEAU_VERSION}.x86_64.rpm" \ "https://beta.tableau.com/linux_driver/tableau-postgresql-odbc-9.5.3-1.x86_64.rpm" && \ rm -rf /var/tmp/yum-* COPY config/* /opt/tableau/docker_build/ RUN mkdir -p /etc/systemd/system/ && \ cp /opt/tableau/docker_build/tableau_server_install.service /etc/systemd/system/ && \ systemctl enable tableau_server_install # Expose TSM and Gateway ports EXPOSE 80 8850 CMD /sbin/init |
Few important things here:
- Line 6: We should add the cgroup specific volumes here as external ones. Also, to speed things up /var/opt/tableau should go to a volume.
- Line 9: to reduce docker fs layers we install dependencies (plus vim), create the OS users and install the Tableau Server bits in the same RUN run.
- Line 22: my magic config file templates and init scripts go under /opt/tableau/docker_build/
- Line 24: this is the magic part: installing tableau_server_install.service systemd file and enable it. This systemd service will run only at the first execution and will invoke the initalization part.
- Line 31: the start command is systemd’s init
Now we have our docker image, let’s run it.
The first run: initalizing the container
Tableau Server must be initalized before you start using it. You have to accept the EULA, register, license and initalize the server. All these actions are performed during your first load from the above mentioned tableau server install systemd service. The code to initalize the server can be found here:
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
log start initalize tsm su tsm -c "sudo sh -x /opt/tableau/tableau_server/packages/scripts.*/initialize-tsm -f --accepteula" 2>&1 1> /var/log/tableau_docker.log log initalize done source /etc/profile.d/tableau_server.sh log login tsm su tsm -c "sudo /opt/tableau/tableau_server/packages/customer-bin.${TABLEAU_SERVER_DATA_DIR_VERSION}/tsm login --username tsm --password tsm" 2>&1 1>> /var/log/tableau_docker.log log login tsm done log licenses activate su tsm -c "sudo /opt/tableau/tableau_server/packages/customer-bin.${TABLEAU_SERVER_DATA_DIR_VERSION}/tsm licenses activate -t" 2>&1 1>> /var/log/tableau_docker.log log licenses activate done log register su tsm -c "sudo /opt/tableau/tableau_server/packages/customer-bin.${TABLEAU_SERVER_DATA_DIR_VERSION}/tsm register --file /opt/tableau/docker_build/registration_file.json" 2>&1 1>> /var/log/tableau_docker.log log register done log settings import su tsm -c "sudo /opt/tableau/tableau_server/packages/customer-bin.${TABLEAU_SERVER_DATA_DIR_VERSION}/tsm settings import -f /opt/tableau/docker_build/tableau_config.json" 2>&1 1>> /var/log/tableau_docker.log log settings import done log pending-changes apply su tsm -c "sudo /opt/tableau/tableau_server/packages/customer-bin.${TABLEAU_SERVER_DATA_DIR_VERSION}/tsm pending-changes apply --restart" 2>&1 1>> /var/log/tableau_docker.log log penging-changes apply done log initalize server su tsm -c "sudo /opt/tableau/tableau_server/packages/customer-bin.${TABLEAU_SERVER_DATA_DIR_VERSION}/tsm initialize --start-server --request-timeout 1800" 2>&1 1>> /var/log/tableau_docker.log log initalize server done log initialuser su tsm -c "sudo /opt/tableau/tableau_server/packages/bin.${TABLEAU_SERVER_DATA_DIR_VERSION}/tabcmd initialuser --server localhost:80 --username admin --password admin" 2>&1 1>> /var/log/tableau_docker.log log all done |
And now, for you, a boring but complete screencast from this phase:
After the initalization you can see that the container reached the multi user state:
1 2 3 4 5 6 7 8 |
[centos@ip-172-30-2-105 ~]$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 585552e58df3 tfoldi/tableau-server:beta "/bin/sh -c /sbin/ini" 11 minutes ago Up 11 minutes 8850/tcp, 0.0.0.0:32768->80/tcp silly_fermat [centos@ip-172-30-2-105 ~]$ docker logs 585552e58df3 --tail=4 [ OK ] Created slice User Slice of tsm. [ OK ] Removed slice User Slice of tsm. [ OK ] Started Tableau Silent Install in Docker. [ OK ] Reached target Multi-User System. |
And now nothing is left but log on to the server with admin / admin user / pass:
And wow, Linux, fully automated installation directly in docker.
*Pro tip*
After you initalized the image and your tableau server is up and running, it’s activated and licensed it’s time to save back to your docker repository. Thus, next time when you run the image you don’t have to wait 10 mins for the initalization. However, for that you have to keep track of your volumes and make sure that you set volume storage to a persistent location.
1 2 3 4 5 6 7 |
[centos@ip-172-30-2-105 ~]$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 585552e58df3 tfoldi/tableau-server:beta "/bin/sh -c /sbin/ini" 14 minutes ago Up 14 minutes 8850/tcp, 0.0.0.0:32768->80/tcp silly_fermat [centos@ip-172-30-2-105 ~]$ docker commit 585552e58df3 tfoldi/tableau-server:actvtd sha256:66350c3ca20ac3462db147bddb3ef950a53666aaeabe48ac4148fc176ae1c0dc [centos@ip-172-30-2-105 tableau-server-beta-docker]$ docker run -ti --privileged -v /sys/fs/cgroup:/sys/fs/cgroup -v /run -p 80 tfoldi/tableau-server:actvtd |
Where is the code?
Again, it’s here: https://github.com/tfoldi/tableau-server-docker
Questions? Comments?
Just drop a comment.
- Tableau Extensions Addons Introduction: Synchronized Scrollbars - December 2, 2019
- Tableau External Services API: Adding Haskell Expressions as Calculations - November 20, 2019
- Scaling out Tableau Extracts – Building a distributed, multi-node MPP Hyper Cluster - August 11, 2019