diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..a678cbd
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,10 @@
+# top-most EditorConfig file
+root = true
+
+[*]
+end_of_line = lf
+charset = utf-8
+indent_style = space
+indent_size = 2
+insert_final_newline = true
+
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..485dee6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+.idea
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..5cf3b92
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,65 @@
+FROM ubuntu:18.04
+
+# Install prerequisites
+RUN apt-get update && apt-get install -y \
+ ca-certificates \
+ wget \
+ zip \
+ unzip \
+ pciutils \
+ locales \
+ libssl1.0.0 \
+ # helper packages
+ curl \
+ sudo \
+ net-tools \
+ nano \
+ && rm -rf /var/lib/apt/lists/*
+
+# Set the locale
+# see: https://stackoverflow.com/questions/28405902/how-to-set-the-locale-inside-a-debian-ubuntu-docker-container
+RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
+ENV LANG en_US.UTF-8
+ENV LANGUAGE en_US:en
+ENV LC_ALL en_US.UTF-8
+
+# Add a user
+ARG USER=developer
+ARG PASSWORD=developer
+RUN useradd --create-home --shell /bin/bash ${USER} \
+ && echo "${USER}:${PASSWORD}" | chpasswd
+ENV HOME /home/${USER}
+
+# Allow sudo without password
+# See: https://stackoverflow.com/questions/8784761/adding-users-to-sudoers-through-shell-script/8784846
+RUN echo "${USER} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
+
+USER ${USER}
+WORKDIR ${HOME}
+
+# Remove sudo notice on login
+# See: https://askubuntu.com/questions/22607/remove-note-about-sudo-that-appears-when-opening-the-terminal
+RUN touch .sudo_as_admin_successful
+
+# Install tizen studio
+# See: https://developer.tizen.org/development/tizen-studio/download/installing-tizen-studio#cli_installer
+ARG TIZEN_STUDIO_VERSION=3.7
+ARG TIZEN_STUDIO_FILE=web-cli_Tizen_Studio_${TIZEN_STUDIO_VERSION}_ubuntu-64.bin
+RUN wget http://download.tizen.org/sdk/Installer/tizen-studio_${TIZEN_STUDIO_VERSION}/${TIZEN_STUDIO_FILE} \
+ && chmod +x ${TIZEN_STUDIO_FILE} \
+ && echo y | ./${TIZEN_STUDIO_FILE} --accept-license \
+ && rm ${TIZEN_STUDIO_FILE}
+
+# Copy author certificate and profiles.xml
+COPY --chown=${USER} tizen-profile/author.p12 author.p12
+COPY --chown=${USER} tizen-profile/profiles.xml ${HOME}/tizen-studio-data/profile/profiles.xml
+
+# Copy and extract webOS CLI
+COPY vendor/webos_cli_tv.zip .
+RUN unzip -q webos_cli_tv.zip -d webOS_TV_SDK \
+ && chmod -R +x webOS_TV_SDK/CLI/bin \
+ && rm webos_cli_tv.zip
+
+# Add tizen/webos cli to PATH
+ENV PATH $PATH:$HOME/tizen-studio/tools/:$HOME/tizen-studio/tools/ide/bin/:$HOME/tizen-studio/package-manager/:$HOME/webOS_TV_SDK/CLI/bin
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..65854bd
--- /dev/null
+++ b/README.md
@@ -0,0 +1,246 @@
+# docker-tizen-webos-sdk
+[Samsung Tizen CLI](https://developer.samsung.com/smarttv/develop/getting-started/using-sdk/command-line-interface.html)
+and [LG webOS CLI](http://webostv.developer.lge.com/sdk/tools/using-webos-tv-cli/) bundled as docker container.
+Allows to develop, build, launch and debug Smart TV apps without installing Tizen Studio and webOS SDK.
+Available CLI commands:
+* `tizen`
+* `sdb`
+* `ares-*`
+
+## Requirements
+* for Mac/Windows - [Docker Desktop](https://www.docker.com/products/docker-desktop)
+* for Linux - [Docker Engine](https://docs.docker.com/engine/install/)
+
+## Usage
+Run `bash` session inside container:
+```
+docker run -it --rm vitalets/tizen-webos-sdk bash
+```
+Now you have Ubuntu with `sdb`, `tizen`, and `ares-*` commands available:
+```
+$ tizen version
+Tizen CLI 2.5.21
+
+$ sdb version
+Smart Development Bridge version 4.2.12
+
+$ ares-setup-device --version
+Version: 1.10.4-j1703-k
+```
+### Samsung Tizen TV
+#### Get info about Samsung TV
+If you have Samsung TV with IP `192.168.1.66` in the same network as your host machine, you can get TV info:
+```
+curl http://192.168.1.66:8001/api/v2/
+```
+
+ Example response
+
+ {
+ "device":{
+ "FrameTVSupport":"false",
+ "GamePadSupport":"true",
+ "ImeSyncedSupport":"true",
+ "Language":"ru_RU",
+ "OS":"Tizen",
+ "PowerState":"on",
+ "TokenAuthSupport":"true",
+ "VoiceSupport":"false",
+ "WallScreenRatio":"0",
+ "WallService":"false",
+ "countryCode":"RU",
+ "description":"Samsung DTV RCR",
+ "developerIP":"192.168.1.64",
+ "developerMode":"1",
+ "duid":"uuid:88d68ee4-cffc-47c4-894f-6d46ca51333a",
+ "firmwareVersion":"Unknown",
+ "id":"uuid:88d68ee4-cffc-47c4-894f-6d46ca51333a",
+ "ip":"192.168.1.66",
+ "model":"19_MUSEL_UHD",
+ "modelName":"UE43RU7400UXRU",
+ "name":"[TV] Samsung 7 Series (43)",
+ "networkType":"wireless",
+ "resolution":"3840x2160",
+ "smartHubAgreement":"true",
+ "ssid":"94:4a:0c:86:c7:00",
+ "type":"Samsung SmartTV",
+ "udn":"uuid:88d68ee4-cffc-47c4-894f-6d46ca51333a",
+ "wifiMac":"B8:BC:5B:93:7E:D2"
+ },
+ "id":"uuid:88d68ee4-cffc-47c4-894f-6d46ca51333a",
+ "isSupport":"{\"DMP_DRM_PLAYREADY\":\"false\",\"DMP_DRM_WIDEVINE\":\"false\",\"DMP_available\":\"true\",\"EDEN_available\":\"true\",\"FrameTVSupport\":\"false\",\"ImeSyncedSupport\":\"true\",\"TokenAuthSupport\":\"true\",\"remote_available\":\"true\",\"remote_fourDirections\":\"true\",\"remote_touchPad\":\"true\",\"remote_voiceControl\":\"false\"}\n",
+ "name":"[TV] Samsung 7 Series (43)",
+ "remote":"1.0",
+ "type":"Samsung SmartTV",
+ "uri":"http://192.168.1.66:8001/api/v2/",
+ "version":"2.0.25"
+ }
+
+
+#### Connect to Samsung TV
+Please ensure that TV is in [Developer Mode](https://developer.samsung.com/smarttv/develop/getting-started/using-sdk/tv-device.html)
+and Developer IP equals to your host IP (check `developerMode` and `developerIP` in curl response).
+```
+$ sdb connect 192.168.1.66
+
+* Server is not running. Start it now on port 26099 *
+* Server has started successfully *
+connecting to 192.168.1.66:26101 ...
+connected to 192.168.1.66:26101
+```
+
+#### List connected TVs
+```
+$ sdb devices
+
+List of devices attached
+192.168.1.66:26101 device UE43RU7400UXRU
+```
+
+#### Get TV capabilities
+```
+$ sdb -s 192.168.1.66 capability
+
+secure_protocol:enabled
+intershell_support:disabled
+filesync_support:pushpull
+...
+```
+
+#### Get list of installed apps
+```
+$ sdb -s 192.168.1.66 shell 0 applist
+
+Application List for user 5001
+User's Application
+Name AppID
+=================================================
+'HdmiCec' 'org.tizen.hdmicec'
+'automation-app' 'org.tizen.automation-app'
+...
+```
+#### Launch app on TV
+```
+$ tizen run -s 192.168.1.66:26101 -p 9Ur5IzDKqV.TizenYouTube
+
+Launching the Tizen application...
+--------------------
+Platform log view
+--------------------
+... successfully launched pid = 1656 with debug 0
+Tizen application is successfully launched.
+```
+or
+```
+$ sdb -s 192.168.1.66:26101 shell 0 was_execute 9Ur5IzDKqV.TizenYouTube
+```
+
+#### Pack app
+Sample developer certificate is included, so you can pack your app without any setup (for development).
+Author.p12 / distributor.p12 password is `developer`.
+Run container with mounting app source `./src` into `/app`:
+```
+docker run -it --rm -v ./src:/app vitalets/tizen-webos-sdk bash
+```
+Create `wgt` package:
+```
+tizen package -t wgt -o /home/developer -- /app
+
+The active profile is used for signing. If you want to sign with other profile, please use '--sign' option.
+Author certficate: /home/developer/author.p12
+Distributor1 certificate : /home/developer/tizen-studio/tools/certificate-generator/certificates/distributor/tizen-distributor-signer.p12
+Excludes File Pattern: {.manifest.tmp, .delta.lst}
+Ignore File: /app/.manifest.tmp
+Package File Location: /home/developer/MyTvApp.wgt
+```
+
+#### Install app
+```
+$ tizen install -s 192.168.1.66:26101 --name MyTvApp.wgt -- /home/developer
+
+Transferring the package...
+Transferred the package: /home/developer/MyTvApp.wgt -> /home/owner/share/tmp/sdk_tools/tmp
+Installing the package...
+--------------------
+Platform log view
+--------------------
+install TESTABCDEF.MyTvApp
+package_path /home/owner/share/tmp/sdk_tools/tmp/MyTvApp.wgt
+was_install_app return WAS_TRUE
+app_id[TESTABCDEF.MyTvApp] install start
+...
+app_id[TESTABCDEF.MyTvApp] install completed
+spend time for wascmd is [1898]ms
+cmd_ret:0
+Installed the package: Id(TESTABCDEF.MyTvApp)
+Tizen application is successfully installed.
+Total time: 00:00:02.895
+```
+> You may need to rename wgt before installing
+> because `tizen install` does not work properly with spaces and non-latin symbols in wgt filename
+
+#### Debug app
+Launch app in debug mode:
+```
+$ sdb -s 192.168.1.66:26101 shell 0 debug TESTABCDEF.MyTvApp
+
+... successfully launched pid = 12915 with debug 1 port: 34541
+```
+Then open in chrome url `http://{TV_IP}:{PORT}` using port from previous command.
+
+#### Close app
+```
+$ sdb -s 192.168.1.66:26101 shell 0 kill TESTABCDEF
+```
+> Note using only `packageId` instead of full `appId`.
+
+#### Uninstall app
+```
+$ tizen uninstall -s 192.168.1.66:26101 -p TESTABCDEF.MyTvApp
+
+--------------------
+Platform log view
+--------------------
+uninstall TESTABCDEF.MyTvApp
+app_id[TESTABCDEF.MyTvApp] uninstall start
+...
+app_id[TESTABCDEF.MyTvApp] uninstall completed
+spend time for wascmd is [2027]ms
+cmd_ret:0
+Total time: 00:00:02.703
+```
+
+#### Pack, install and launch app on TV in single command
+App sources are in `./src`.
+The following env variables are used:
+- `TV_IP=192.168.1.66`
+- `APP_ID=TESTABCDEF.MyTvApp` (from config.xml)
+- `APP_NAME="My TV App"` (from config.xml)
+```
+docker run -it --rm \
+ -e TV_IP=192.168.1.66 \
+ -e APP_ID=TESTABCDEF.MyTvApp \
+ -e APP_NAME="My TV App" \
+ -v ./src:/app \
+ vitalets/tizen-webos-sdk /bin/bash -c '\
+ tizen package -t wgt -o . -- /app \
+ && mv "$APP_NAME.wgt" app.wgt \
+ && sdb connect $TV_IP \
+ && tizen install -s $TV_IP:26101 --name app.wgt -- . \
+ && tizen run -s $TV_IP:26101 -p $APP_ID'
+```
+
+### LG WebOS TV
+tbd
+
+## Development
+
+#### Build container
+```bash
+docker build -t vitalets/tizen-webos-sdk .
+```
+
+#### Publish to Docker Hub
+```bash
+docker push vitalets/tizen-webos-sdk
+```
diff --git a/test.sh b/test.sh
new file mode 100755
index 0000000..571e9e7
--- /dev/null
+++ b/test.sh
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+
+cmd() {
+ echo $(docker run -it --rm vitalets/tizen-webos-sdk $@) | tr -d '\r'
+}
+
+assert() {
+ local actual="$1"
+ local expected="$2"
+ if [ "$actual" == "$expected" ]; then
+ echo "OK: \"$expected\""
+ else
+ echo "ERROR: \"$actual\" != \"$expected\""
+ exit 1
+ fi
+}
+
+assert "$(cmd tizen version)" "Tizen CLI 2.5.21"
+assert "$(cmd sdb version)" "Smart Development Bridge version 4.2.12"
+assert "$(cmd ares-setup-device --version)" "Version: 1.10.4-j1703-k"
diff --git a/tizen-profile/author.p12 b/tizen-profile/author.p12
new file mode 100644
index 0000000..228ded1
Binary files /dev/null and b/tizen-profile/author.p12 differ
diff --git a/tizen-profile/profiles.xml b/tizen-profile/profiles.xml
new file mode 100644
index 0000000..4fbb126
--- /dev/null
+++ b/tizen-profile/profiles.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/vendor/webos_cli_tv.zip b/vendor/webos_cli_tv.zip
new file mode 100644
index 0000000..356a3a7
Binary files /dev/null and b/vendor/webos_cli_tv.zip differ