diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml
index d41d3a2a1ce..66fc9aacb98 100644
--- a/.github/workflows/ubuntu.yml
+++ b/.github/workflows/ubuntu.yml
@@ -79,6 +79,13 @@ jobs:
           name: open3d-devel-linux-x86_64
           path: open3d-devel-*.tar.xz
           if-no-files-found: error
+      - name: Upload viewer to GitHub artifacts
+        if: ${{ env.BUILD_SHARED_LIBS == 'OFF' }}
+        uses: actions/upload-artifact@v3
+        with:
+          name: open3d-viewer-Linux
+          path: open3d-viewer-*-Linux.deb
+          if-no-files-found: error
       - name: GCloud CLI auth
         if: ${{ github.ref == 'refs/heads/master' }}
         uses: 'google-github-actions/auth@v1'
diff --git a/README.md b/README.md
index ced7235af9f..b3d713a42d2 100644
--- a/README.md
+++ b/README.md
@@ -87,8 +87,8 @@ To use Open3D in your C++ project, checkout the following examples
 
 <img width="480" src="https://raw.githubusercontent.com/isl-org/Open3D/master/docs/_static/open3d_viewer.png">
 
-Open3D-Viewer is a standalone 3D viewer app available on Ubuntu and macOS.
-Please stay tuned for Windows. Download Open3D Viewer from the
+Open3D-Viewer is a standalone 3D viewer app available on Debian (Ubuntu), macOS
+and Windows. Download Open3D Viewer from the
 [release page](https://github.com/isl-org/Open3D/releases).
 
 ## Open3D-ML
diff --git a/cmake/Open3DPackaging.cmake b/cmake/Open3DPackaging.cmake
index 1178cdd5376..e6ce4a3c15c 100644
--- a/cmake/Open3DPackaging.cmake
+++ b/cmake/Open3DPackaging.cmake
@@ -1,3 +1,6 @@
+# This is packaging for the Open3D library. See
+# cpp/apps/Open3DViewer/Debian/CMakeLists.txt for packaging the Debian Open3D
+# viewer
 set(CPACK_GENERATOR TXZ)
 if(WIN32)
     set(CPACK_GENERATOR ZIP)
diff --git a/cpp/apps/CMakeLists.txt b/cpp/apps/CMakeLists.txt
index 6380f272b2d..990ccc23b81 100644
--- a/cpp/apps/CMakeLists.txt
+++ b/cpp/apps/CMakeLists.txt
@@ -72,8 +72,17 @@ macro(open3d_add_app_gui SRC_DIR APP_NAME TARGET_NAME)
                     RENAME "${APP_NAME}.xml")
             # Various caches need to be updated for the app to become visible
             install(CODE "execute_process(COMMAND ${SOURCE_DIR}/postinstall-linux.sh)")
+            configure_file("${SOURCE_DIR}/Debian/CMakeLists.in.txt"
+                "${CMAKE_BINARY_DIR}/package-${TARGET_NAME}-deb/CMakeLists.txt" @ONLY)
+            add_custom_target(package-${TARGET_NAME}-deb
+                COMMAND cp -a "${CMAKE_BINARY_DIR}/${APP_NAME}" .
+                COMMAND cp "${SOURCE_DIR}/icon.svg" "${APP_NAME}/${APP_NAME}.svg"
+                COMMAND cp "${SOURCE_DIR}/${TARGET_NAME}.xml" "${CMAKE_BINARY_DIR}/${APP_NAME}/"
+                COMMAND "${CMAKE_COMMAND}" -S .
+                COMMAND "${CMAKE_COMMAND}" --build . -t package
+                WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/package-${TARGET_NAME}-deb/"
+                DEPENDS ${TARGET_NAME})
         elseif (WIN32)
-            # Don't create a command window on launch
             target_sources(${TARGET_NAME} PRIVATE "${SOURCE_DIR}/icon.rc")   # add icon
 
             # MSVC puts the binary in bin/Open3D/Release/Open3D.exe
diff --git a/cpp/apps/Open3DViewer/Debian/CMakeLists.in.txt b/cpp/apps/Open3DViewer/Debian/CMakeLists.in.txt
new file mode 100644
index 00000000000..c318c212612
--- /dev/null
+++ b/cpp/apps/Open3DViewer/Debian/CMakeLists.in.txt
@@ -0,0 +1,36 @@
+# Create Debian package
+cmake_minimum_required(VERSION 3.8.0)
+project("Open3D-Debian")
+
+message(STATUS "Building package for Debian")
+
+# Install assets
+install(DIRECTORY   "Open3D"
+        DESTINATION share
+        USE_SOURCE_PERMISSIONS
+        PATTERN     "Open3D/Open3D.svg" EXCLUDE
+        PATTERN     "Open3D/Open3D.desktop" EXCLUDE
+        PATTERN     "Open3D/Open3DViewer.xml" EXCLUDE
+        PATTERN     "Open3D/Open3D" EXCLUDE
+        PATTERN     "Open3D/CMakeLists.txt" EXCLUDE
+)
+install(FILES "Open3D/Open3D.desktop" DESTINATION /usr/share/applications)
+install(FILES "Open3D/Open3DViewer.xml" DESTINATION /usr/share/mime/packages)
+install(FILES "Open3D/Open3D.svg" DESTINATION /usr/share/icons/hicolor/scalable/apps)
+install(PROGRAMS "Open3D/Open3D" DESTINATION bin)
+
+# CPACK parameter
+set(CPACK_GENERATOR "DEB")
+set(CPACK_PACKAGE_NAME "open3d-viewer")
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Open3D Viewer for 3D files")
+set(CPACK_PACKAGE_CONTACT "Open3D team <@PROJECT_EMAIL@>")
+set(CPACK_DEBIAN_PACKAGE_SECTION "Graphics")
+set(CPACK_PACKAGE_VERSION "@OPEN3D_VERSION@")
+set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc++1, libgomp1, libpng16-16, libglfw3")
+set(CPACK_PACKAGE_HOMEPAGE_URL "@PROJECT_HOMEPAGE_URL@")
+
+# How to set cpack prefix: https://stackoverflow.com/a/7363073/1255535
+set(CPACK_SET_DESTDIR true)
+set(CPACK_INSTALL_PREFIX /usr/local)
+
+include(CPack)
diff --git a/cpp/apps/Open3DViewer/postinstall-linux.sh b/cpp/apps/Open3DViewer/postinstall-linux.sh
index 701af849adf..1310d306809 100755
--- a/cpp/apps/Open3DViewer/postinstall-linux.sh
+++ b/cpp/apps/Open3DViewer/postinstall-linux.sh
@@ -1,4 +1,4 @@
-#/bin/bash
+#!/bin/sh
 
 if [ $(id -u) = 0 ]; then
     update-mime-database /usr/share/mime # add new MIME types
diff --git a/docker/Dockerfile.ci b/docker/Dockerfile.ci
index 5474b1aee58..98d97c06f3a 100644
--- a/docker/Dockerfile.ci
+++ b/docker/Dockerfile.ci
@@ -201,7 +201,8 @@ RUN if [ "${BUILD_PYTORCH_OPS}" = "ON" ] || [ "${BUILD_TENSORFLOW_OPS}" = "ON" ]
  && make VERBOSE=1 -j$(nproc) \
  && make install-pip-package -j$(nproc) \
  && make install -j$(nproc) \
- && if [ "${PACKAGE}" = "ON" ]; then make package; fi
+ && if [ "${PACKAGE}" = "ON" ]; then make package; fi \
+ && if [ "${PACKAGE}" = "VIEWER" ]; then make package-Open3DViewer-deb; fi
 
 # Compress ccache folder, move to / directory
 RUN ccache -s \
@@ -211,6 +212,7 @@ RUN ccache -s \
  && cd ${CCACHE_DIR_PARENT} \
  && tar -czf /${CCACHE_TAR_NAME}.tar.gz ${CCACHE_DIR_NAME} \
  && if [ "${PACKAGE}" = "ON" ]; then mv /root/Open3D/build/package/open3d-devel*.tar.xz /; fi \
+ && if [ "${PACKAGE}" = "VIEWER" ]; then mv /root/Open3D/build/package-Open3DViewer-deb/open3d-viewer-*-Linux.deb /; fi \
  && ls -alh /
 
 RUN echo "Docker build done."
diff --git a/docker/docker_build.sh b/docker/docker_build.sh
index c30d6571788..ddc89503231 100755
--- a/docker/docker_build.sh
+++ b/docker/docker_build.sh
@@ -354,7 +354,7 @@ cpu-static_export_env() {
     export BUILD_CUDA_MODULE=OFF
     export BUILD_TENSORFLOW_OPS=OFF
     export BUILD_PYTORCH_OPS=OFF
-    export PACKAGE=OFF
+    export PACKAGE=VIEWER
     export BUILD_SYCL_MODULE=OFF
 }