Even with the growing popularity of cloud services, the need for running native applications still exists.
即使云服务越来越流行,仍然需要运行本机应用程序。
By using noVNC and TigerVNC, you can run native applications inside a Docker container and access them remotely using a web browser. Additionally, you can run your application on a server with more system resources than you might have available locally, which can provide increased flexibility when running large applications.
通过使用noVNC和TigerVNC ,您可以在Docker容器内运行本机应用程序,并使用Web浏览器远程访问它们。 此外,您可以在具有比本地可用资源更多的系统资源的服务器上运行应用程序,这可以在运行大型应用程序时提供更大的灵活性。
In this tutorial, you’ll containerize Mozilla Thunderbird, an email client, using Docker. Afterward, you’ll secure it and provide remote access using the Caddy web server.
在本教程中,您将使用Docker容器化Mozilla Thunderbird (电子邮件客户端)。 之后,您将保护它并使用Caddy Web服务器提供远程访问。
When you’re finished, you’ll be able to access Thunderbird from any device using just a web browser. Optionally, you’ll also be able to locally access the files from it using WebDAV. You’ll also have a fully self-contained Docker image that you can run anywhere.
完成后,您将可以仅使用Web浏览器从任何设备访问Thunderbird。 (可选)您还可以使用WebDAV从本地访问文件。 您还将拥有一个完全独立的Docker映像,可以在任何地方运行。
Before you begin this guide, you’ll need the following:
在开始本指南之前,您需要满足以下条件:
A non-root user with sudo
privileges.
具有sudo
特权的非root用户。
Docker set up on your server. You can follow the How To Install and Use Docker on Ubuntu 18.04.
在您的服务器上设置Docker。 您可以按照如何在Ubuntu 18.04上安装和使用Docker进行操作 。
supervisord
配置 (Step 1 — Creating the supervisord
Configuration)Now that your server is running and Docker is installed, you are ready to begin configuring your application’s container. Since your container consists of multiple components, you need to use a process manager to launch and monitor them. Here, you’ll be using supervisord
. supervisord
is a process manager written in Python that is often used to orchestrate complex containers.
现在您的服务器正在运行,并且已经安装了Docker,您可以开始配置应用程序的容器了。 由于您的容器包含多个组件,因此您需要使用流程管理器来启动和监视它们。 在这里,您将使用supervisord
。 supervisord
是用Python编写的过程管理器,通常用于编排复杂的容器。
First, create and enter a directory called thunderbird
for your container:
首先,为您的容器创建并输入一个名为thunderbird
的目录:
Now create and open a file called supervisord.conf
using nano
or your preferred editor:
现在,使用nano
或您喜欢的编辑器创建并打开一个名为supervisord.conf
的文件:
Now add this first block of code into supervisord.conf
, which will define the global options for supervisord:
现在,将这第一段代码添加到supervisord.conf
,这将为supervisord.conf
定义全局选项:
[supervisord]
nodaemon=true
pidfile=/tmp/supervisord.pid
logfile=/dev/fd/1
logfile_maxbytes=0
In this block, you are configuring supervisord
itself. You need to set nodaemon
to true
because it will be running inside of a Docker container as the entrypoint. Therefore, you want it to remain running in the foreground. You also are setting pidfile
to a path accessible by a non-root user (more on this later), and logfile
to stdout so you can see the logs.
在此块中,您将配置supervisord
本身。 您需要将nodaemon
设置为true
因为它将在Docker容器内作为入口运行。 因此,您希望它继续在前台运行。 您还将pidfile
设置为非root用户可访问的路径(稍后将对此进行详细介绍),而将logfile
为stdout以便可以查看日志。
Next, add another small block of code to supervisord.conf
. This block starts TigerVNC, which is a combined VNC/X11 server:
接下来,将另一小段代码添加到supervisord.conf
。 此块启动TigerVNC,它是组合的VNC / X11服务器:
...
[program:x11]
priority=0
command=/usr/bin/Xtigervnc -desktop "Thunderbird" -localhost -rfbport 5900 -SecurityTypes None -AlwaysShared -AcceptKeyEvents -AcceptPointerEvents -AcceptSetDesktopSize -SendCutText -AcceptCutText :0
autorestart=true
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true
In this block, you are setting up the X11 server. X11 is a display server protocol, which is what allows GUI applications to run. Note that in the future it will be replaced with Wayland, but remote access is still in development.
在此块中,您将设置X11服务器。 X11是显示服务器协议,它允许GUI应用程序运行。 请注意,将来它将被Wayland取代,但是远程访问仍在开发中。
For this container, you are using TigerVNC and its built-in VNC server. This has a number of advantages over using a separate X11 and VNC server:
对于此容器,您正在使用TigerVNC及其内置的VNC服务器。 与使用单独的X11和VNC服务器相比,这具有许多优点:
If you wish, you can change the argument for the -desktop
option from Thunderbird
to something else of your choosing. The server will display your choice as the title of the webpage used to access your application.
如果愿意,可以将-desktop
选项的参数从Thunderbird
更改为您选择的其他选项。 服务器将您的选择显示为用于访问您的应用程序的网页的标题。
Now, let’s add a third block of code to supervisord.conf
to start easy-novnc
:
现在,让我们向supervisord.conf
添加第三段代码以启动easy-novnc
:
...
[program:easy-novnc]
priority=0
command=/usr/local/bin/easy-novnc --addr :8080 --host localhost --port 5900 --no-url-password --novnc-params "resize=remote"
autorestart=true
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true
In this block, you are setting up easy-novnc
, a standalone server which provides a wrapper around noVNC. This server performs two roles. First, it provides a simple connection page which allows you to configure options for the connection, and allows you to set default ones. Second, it proxies VNC over WebSocket, which allows it to be accessed through an ordinary web browser.
在此块中,您将设置easy-novnc
,这是一个独立的服务器,提供了围绕noVNC的包装。 该服务器执行两个角色。 首先,它提供了一个简单的连接页面,该页面允许您配置连接选项,并可以设置默认选项。 其次,它通过WebSocket代理VNC,从而可以通过普通的Web浏览器对其进行访问。
Usually, resizing is done on the client side (i.e. image scaling), but you are using the resize=remote
option to take full advantage of TigerVNC’s remote resolution adjustments. This also provides lower latency on slower devices, such as lower-end Chromebooks:
通常,调整大小是在客户端完成的(即图像缩放),但是您正在使用resize=remote
选项来充分利用TigerVNC的远程分辨率调整。 这还可以在速度较慢的设备(例如低端Chromebook)上提供较低的延迟:
Note: This tutorial uses easy-novnc
. If you wish, you can use websockify
and a separate web server instead. The advantage of easy-novnc
is that the memory usage and startup time is significantly lower and that it’s self-contained. easy-novnc
also provides a cleaner connection page than the default noVNC one and allows setting default options that are helpful for this setup (such as resize=remote
).
注意:本教程使用easy-novnc
。 如果愿意,可以改用websockify
和单独的Web服务器。 easy-novnc
的优点是内存使用量和启动时间显着降低,并且是独立的。 easy-novnc
还提供了比默认noVNC更为整洁的连接页面,并允许设置有助于该设置的默认选项(例如resize=remote
)。
Now add the following block to your configuration to start OpenBox, the window manager:
现在,将以下块添加到您的配置中以启动窗口管理器OpenBox:
...
[program:openbox]
priority=1
command=/usr/bin/openbox
environment=DISPLAY=:0
autorestart=true
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true
In this block, you are setting up OpenBox, a lightweight X11 window manager. You could skip this step, but without it, you wouldn’t have title bars or be able to resize windows.
在此块中,您将设置OpenBox ,这是一个轻量级的X11窗口管理器。 您可以跳过此步骤,但是如果没有它,您将没有标题栏或无法调整窗口大小。
Finally, let’s add the last block to supervisord.conf
, which will start the main application:
最后,让我们将最后一个块添加到supervisord.conf
,这将启动主应用程序:
...
[program:app]
priority=1
environment=DISPLAY=:0
command=/usr/bin/thunderbird
autorestart=true
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true
In this final block, you are setting priority
to 1
to ensure that Thunderbird launches after TigerVNC, or it would encounter a race-condition and randomly fail to start. We also set autorestart=true
to automatically reopen the application if it mistakenly closes. The DISPLAY
environment variable tells the application to display on the VNC server you set up earlier.
在此最后一个块中,将priority
设置为1
以确保Thunderbird 在 TigerVNC 之后启动,否则它将遇到竞争条件并随机启动失败。 我们还设置了autorestart=true
以在错误关闭时自动重新打开该应用程序。 DISPLAY
环境变量告诉应用程序在您之前设置的VNC服务器上显示。
Here is what your completed supervisord.conf
will look like:
这是您完成的supervisord.conf
外观:
[supervisord]
nodaemon=true
pidfile=/tmp/supervisord.pid
logfile=/dev/fd/1
logfile_maxbytes=0
[program:x11]
priority=0
command=/usr/bin/Xtigervnc -desktop "Thunderbird" -localhost -rfbport 5900 -SecurityTypes None -AlwaysShared -AcceptKeyEvents -AcceptPointerEvents -AcceptSetDesktopSize -SendCutText -AcceptCutText :0
autorestart=true
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true
[program:easy-novnc]
priority=0
command=/usr/local/bin/easy-novnc --addr :8080 --host localhost --port 5900 --no-url-password --novnc-params "resize=remote"
autorestart=true
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true
[program:openbox]
priority=1
command=/usr/bin/openbox
environment=DISPLAY=:0
autorestart=true
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true
[program:app]
priority=1
environment=DISPLAY=:0
command=/usr/bin/thunderbird
autorestart=true
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true
If you want to containerize a different application, replace /usr/bin/thunderbird
with the path to your application’s executable. Otherwise, you are now ready to configure your GUI’s main menu.
如果要容器化其他应用程序,请用应用程序可执行文件的路径替换/usr/bin/thunderbird
。 否则,您现在就可以配置GUI的主菜单了。
Now that your process manager is configured, let’s set up the OpenBox menu. This menu allows us to launch applications inside the container. We will also include a terminal and process monitor for debugging if required.
现在已经配置了流程管理器,让我们设置“ OpenBox”菜单。 此菜单允许我们在容器内启动应用程序。 如果需要,我们还将包括用于调试的终端和过程监视器。
Inside your application’s directory, use nano
or your favorite text editor to create and open a new file called menu.xml
:
在应用程序目录中,使用nano
或您喜欢的文本编辑器创建并打开一个名为menu.xml
的新文件:
Now add the following code to menu.xml
:
现在将以下代码添加到menu.xml
:
<?xml version="1.0" encoding="utf-8"?>
<openbox_menu xmlns="http://openbox.org/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://openbox.org/ file:///usr/share/openbox/menu.xsd">
<menu id="root-menu" label="Openbox 3">
<item label="Thunderbird">
<action name="Execute">
<execute>/usr/bin/thunderbird</execute>
</action>
</item>
<item label="Terminal">
<action name="Execute">
<execute>/usr/bin/x-terminal-emulator</execute>
</action>
</item>
<item label="Htop">
<action name="Execute">
<execute>/usr/bin/x-terminal-emulator -e htop</execute>
</action>
</item>
</menu>
</openbox_menu>
This XML file contains the menu items that will appear when you right-click on the desktop. Each item consists of a label and an action.
该XML文件包含右键单击桌面时将显示的菜单项。 每个项目都包含一个标签和一个动作。
If you want to containerize a different application, replace /usr/bin/thunderbird
with the path to your application’s executable and change the label
of the item.
如果要容器化其他应用程序,则将/usr/bin/thunderbird
替换为应用程序可执行文件的路径,并更改项目label
。
Now that OpenBox is configured, you’ll be creating the Dockerfile, which ties everything together.
现在已经配置了OpenBox,您将创建Dockerfile,它将所有内容捆绑在一起。
Create a Dockerfile in your container’s directory:
在容器的目录中创建一个Dockerfile:
To begin, let’s add some code to build easy-novnc
:
首先,让我们添加一些代码来构建easy-novnc
:
FROM golang:1.14-buster AS easy-novnc-build
WORKDIR /src
RUN go mod init build && \
go get github.com/geek1011/easy-novnc@v1.1.0 && \
go build -o /bin/easy-novnc github.com/geek1011/easy-novnc
In the first stage, you are building easy-novnc
. This is done in a separate stage for simplicity and to save space — you don’t need the entire Go toolchain in your final image. Note the @v1.1.0
in the build command. This ensures that the result is deterministic, which is important because Docker caches the result of each step. If you had not specified an explicit version, Docker would reference the latest version of easy-novnc
at the time the image was first built. In addition, you want to ensure that you download a specific version of easy-novnc
, in case breaking changes are made to the CLI interface.
在第一阶段,您将构建easy-novnc
。 为了简化并节省空间,在单独的阶段中完成此操作-您在最终图像中不需要整个Go工具链。 注意build命令中的@v1.1.0
。 这样可以确保结果具有确定性,这一点很重要,因为Docker会缓存每个步骤的结果。 如果您未指定显式版本,则Docker将在首次构建映像时引用easy-novnc
的最新版本。 另外,您要确保下载了easy-novnc
的特定版本,以防CLI界面发生重大更改。
Now let’s create the second stage, which will become the final image. Here you will be using Debian 10 (buster) as the base image. Note that since this is running in a container, it will work regardless of the distribution you are running on your server.
现在让我们创建第二个阶段,它将成为最终图像。 在这里,您将使用Debian 10(破坏者)作为基本映像。 请注意,由于这是在容器中运行的,因此无论您在服务器上运行的分布如何,它都可以工作。
Next, add the following block to your Dockerfile
:
接下来,将以下代码块添加到您的Dockerfile
:
...
FROM debian:buster
RUN apt-get update -y && \
apt-get install -y --no-install-recommends openbox tigervnc-standalone-server supervisor gosu && \
rm -rf /var/lib/apt/lists && \
mkdir -p /usr/share/desktop-directories
In this instruction, you are installing Debian 10 as your base image and then installing the bare minimum required to run GUI applications in your container. Note that you run apt-get update
as part of the same instruction to prevent caching issues from Docker. To save space, you are also removing the package lists downloaded afterward (the cached packages themselves are removed by default). You are also creating /usr/share/desktop-directories
because some applications depend on the directory existing.
在此说明中,您将安装Debian 10作为基础映像,然后安装在容器中运行GUI应用程序所需的最低限度的内容。 请注意,您将apt-get update
作为同一指令的一部分运行,以防止Docker缓存问题。 为了节省空间,您还删除了以后下载的软件包列表( 默认情况下,将删除缓存的软件包本身)。 您还将创建/usr/share/desktop-directories
因为某些应用程序依赖于现有目录。
Let’s add another small block of code:
让我们添加另一小段代码:
...
RUN apt-get update -y && \
apt-get install -y --no-install-recommends lxterminal nano wget openssh-client rsync ca-certificates xdg-utils htop tar xzip gzip bzip2 zip unzip && \
rm -rf /var/lib/apt/lists
In this instruction, you are installing some useful general-purpose utilities and packages. Of particular interest here are xdg-utils
(which provides the base commands used by desktop applications on Linux) and ca-certificates
(which installs the root certificates to allow us to access HTTPS sites).
在此说明中,您将安装一些有用的通用实用程序和软件包。 这里特别令人感兴趣的是xdg-utils
(提供Linux上桌面应用程序使用的基本命令)和ca-certificates
(安装根证书以允许我们访问HTTPS站点)。
Now, we can add the instructions for the main application:
现在,我们可以添加主要应用程序的说明:
...
RUN apt-get update -y && \
apt-get install -y --no-install-recommends thunderbird && \
rm -rf /var/lib/apt/lists
As before, here we are installing the application. If you are containerizing a different application, you can replace these commands with the ones required to install your specific app. Some applications will require a bit more work to run inside Docker. For example, if you are installing an app that uses Chrome, Chromium, or QtWebEngine, you’ll need to use the command line argument --no-sandbox
because it won’t be supported within Docker.
和以前一样,这里我们正在安装应用程序。 如果要容器化其他应用程序,则可以将这些命令替换为安装特定应用程序所需的命令。 一些应用程序需要更多的工作才能在Docker中运行。 例如,如果要安装使用Chrome,Chromium或QtWebEngine的应用程序,则需要使用命令行参数--no-sandbox
因为Docker不支持该参数。
Next, let’s start adding the instructions to add the last few files to the container:
接下来,让我们开始添加说明,以将最后几个文件添加到容器中:
...
COPY --from=easy-novnc-build /bin/easy-novnc /usr/local/bin/
COPY menu.xml /etc/xdg/openbox/
COPY supervisord.conf /etc/
EXPOSE 8080
Here you are adding the configuration files you created earlier to the image and copying the easy-novnc
binary from the first stage.
在这里,您要将先前创建的配置文件添加到映像,并从第一阶段复制easy-novnc
二进制文件。
This next code block creates the data directory and adds a dedicated user for your app. This is important because some applications refuse to run as root. It’s also good practice not to run applications as root, even in a container.
下一个代码块创建数据目录,并为您的应用添加专用用户。 这很重要,因为某些应用程序拒绝以root用户身份运行。 最好不要以超级用户身份运行应用程序,即使在容器中也是如此。
...
RUN groupadd --gid 1000 app && \
useradd --home-dir /data --shell /bin/bash --uid 1000 --gid 1000 app && \
mkdir -p /data
VOLUME /data
To ensure a consistent UID/GID
for the files, you are explicitly setting both to 1000
. You are also mounting a volume on the data directory to ensure it persists between restarts.
为了确保文件的UID/GID
一致,您将两者明确设置为1000
。 您还将在数据目录上装载卷,以确保卷在两次重启之间仍然存在。
Finally, let’s add the instructions to launch everything:
最后,让我们添加说明以启动所有内容:
...
CMD ["sh", "-c", "chown app:app /data /dev/stdout && exec gosu app supervisord"]
By setting the default command to supervisord
, the manager will launch the processes required to run your application. In this case, you are using CMD
rather than ENTRYPOINT
. In most cases, it wouldn’t make a difference, but using CMD
is better-suited for this purpose for a few reasons. First, supervisord
doesn’t take any arguments that would be relevant to us, and if you provide arguments to the container, they replace CMD
and are appended to ENTRYPOINT
. Second, using CMD
allows us to provide an entirely different command (which will be executed by /bin/sh -c
) when passing arguments to the container, which makes debugging easier.
通过将默认命令设置为supervisord
,管理器将启动运行您的应用程序所需的过程。 在这种情况下,您将使用CMD
而不是ENTRYPOINT
。 在大多数情况下,这没有什么区别,但是出于某些原因,为此目的更适合使用CMD
。 首先, supervisord
不会接受任何与我们相关的参数,如果您向容器提供参数,它们将替换CMD
并附加到ENTRYPOINT
。 其次,使用CMD
允许我们在将参数传递到容器时提供一个完全不同的命令(将由/bin/sh -c
),这使调试更加容易。
And lastly, you need to run chown
as root before starting supervisord
to prevent permission issues on the data volume and to allow the child processes to open stdout
. This also means you need to use gosu
instead of the USER
instruction to switch the user.
最后,你需要运行chown
开始之前为根supervisord
以防止数据卷上的权限问题,并允许子进程开放stdout
。 这也意味着您需要使用gosu
而不是USER
指令来切换用户。
Here is what your completed Dockerfile
will look like:
这是您完成的Dockerfile
外观:
FROM golang:1.14-buster AS easy-novnc-build
WORKDIR /src
RUN go mod init build && \
go get github.com/geek1011/easy-novnc@v1.1.0 && \
go build -o /bin/easy-novnc github.com/geek1011/easy-novnc
FROM debian:buster
RUN apt-get update -y && \
apt-get install -y --no-install-recommends openbox tigervnc-standalone-server supervisor gosu && \
rm -rf /var/lib/apt/lists && \
mkdir -p /usr/share/desktop-directories
RUN apt-get update -y && \
apt-get install -y --no-install-recommends lxterminal nano wget openssh-client rsync ca-certificates xdg-utils htop tar xzip gzip bzip2 zip unzip && \
rm -rf /var/lib/apt/lists
RUN apt-get update -y && \
apt-get install -y --no-install-recommends thunderbird && \
rm -rf /var/lib/apt/lists
COPY --from=easy-novnc-build /bin/easy-novnc /usr/local/bin/
COPY menu.xml /etc/xdg/openbox/
COPY supervisord.conf /etc/
EXPOSE 8080
RUN groupadd --gid 1000 app && \
useradd --home-dir /data --shell /bin/bash --uid 1000 --gid 1000 app && \
mkdir -p /data
VOLUME /data
CMD ["sh", "-c", "chown app:app /data /dev/stdout && exec gosu app supervisord"]
Save and close your Dockerfile
. Now we are ready to build and run our container, and then access Thunderbird — a GUI application.
保存并关闭Dockerfile
。 现在我们准备构建并运行我们的容器,然后访问Thunderbird(一个GUI应用程序)。
The next step is to build your container and set it to run at startup. You’ll also set up a volume to preserve the application data between restarts and updates.
下一步是构建容器并将其设置为在启动时运行。 您还将设置一个卷,以在重新启动和更新之间保留应用程序数据。
First build your container. Make sure to run these commands in the ~/thunderbird
directory:
首先建立您的容器。 确保在~/thunderbird
目录中运行以下命令:
Now create a new network that will be shared between the app’s containers:
现在创建一个将在应用程序的容器之间共享的新网络:
Then create a volume to store the application data:
然后创建一个卷来存储应用程序数据:
Finally, run it and set it to restart automatically:
最后,运行它并将其设置为自动重启:
docker run --detach --restart=always --volume=thunderbird-data:/data --net=thunderbird-net --name=thunderbird-app thunderbird
docker run --detach --restart =总是--volume = thunderbird-data:/ data --net = thunderbird-net --name = thunderbird-app thunderbird
Note that if you want, you can replace the thunderbird-app
after the --name
option with a different name. Whatever you have chosen, your application is now containerized and running. Now let’s use the Caddy web server to secure it and remotely connect to it.
请注意,如果需要,可以将--name
选项后的thunderbird-app
替换为其他名称。 无论选择什么,您的应用程序现在都已容器化并正在运行。 现在,让我们使用Caddy Web服务器来保护它并远程连接到它。
In this step, you’ll set up the Caddy web server to provide authentication and, optionally, remote file access over WebDAV. For simplicity, and to allow you to use it with your existing reverse proxy, you’ll run it in another container.
在此步骤中,您将设置Caddy Web服务器以提供身份验证,并可以选择通过WebDAV进行远程文件访问。 为简单起见,并允许您将其与现有的反向代理一起使用,请在另一个容器中运行它。
Create a new directory and then move inside it:
创建一个新目录,然后在其中移动:
Now create a new Dockerfile
using nano
or your preferred editor:
现在使用nano
或您喜欢的编辑器创建一个新的Dockerfile
:
Then add the following directives:
然后添加以下指令:
FROM golang:1.14-buster AS caddy-build
WORKDIR /src
RUN echo 'module caddy' > go.mod && \
echo 'require github.com/caddyserver/caddy/v2 v2.1.1' >> go.mod && \
echo 'require github.com/mholt/caddy-webdav v0.0.0-20200523051447-bc5d19941ac3' >> go.mod
RUN echo 'package main' > caddy.go && \
echo 'import caddycmd "github.com/caddyserver/caddy/v2/cmd"' >> caddy.go && \
echo 'import _ "github.com/caddyserver/caddy/v2/modules/standard"' >> caddy.go && \
echo 'import _ "github.com/mholt/caddy-webdav"' >> caddy.go && \
echo 'func main() { caddycmd.Main() }' >> caddy.go
RUN go build -o /bin/caddy .
FROM debian:buster
RUN apt-get update -y && \
apt-get install -y --no-install-recommends gosu && \
rm -rf /var/lib/apt/lists
COPY --from=caddy-build /bin/caddy /usr/local/bin/
COPY Caddyfile /etc/
EXPOSE 8080
RUN groupadd --gid 1000 app && \
useradd --home-dir /data --shell /bin/bash --uid 1000 --gid 1000 app && \
mkdir -p /data
VOLUME /data
WORKDIR /data
CMD ["sh", "-c", "chown app:app /data && exec gosu app /usr/local/bin/caddy run -adapter caddyfile -config /etc/Caddyfile"]
This Dockerfile builds Caddy with the WebDAV plugin enabled, and then launches it on port 8080
with the Caddyfile
at /etc/Caddyfile
. Save and close the file.
该Dockerfile在启用了WebDAV插件的情况下构建Caddy,然后在端口8080
使用Caddyfile
在/etc/Caddyfile
启动它。 保存并关闭文件。
Next you will configure the Caddy web server. Create a file named Caddyfile
in the directory you just created:
接下来,您将配置Caddy Web服务器。 在刚刚创建的目录中创建一个名为Caddyfile
的文件:
Now add the following code block to your Caddyfile
:
现在将以下代码块添加到您的Caddyfile
:
{
order webdav last
}
:8080 {
log
root * /data
reverse_proxy thunderbird-app:8080
handle_path /files/* {
file_server browse
}
redir /files /files/
handle /webdav/* {
webdav {
prefix /webdav
}
}
redir /webdav /webdav/
basicauth /* {
{env.APP_USERNAME} {env.APP_PASSWORD_HASH}
}
}
This Caddyfile
proxies the root directory to the thunderbird-app
container you created in Step 4 (Docker resolves it into the correct IP). It will also serve a read-only web-based file browser on /files
and run a WebDAV server on /webdav
which you can mount locally to access your files. The username and password are read from the environment variables APP_USERNAME
and APP_PASSWORD_HASH
.
此Caddyfile
将根目录代理到您在步骤4中创建的thunderbird-app
容器(Docker将其解析为正确的IP)。 它还将在/files
上提供基于Web的只读文件浏览器,并在/webdav
上运行WebDAV服务器,您可以将其本地安装以访问文件。 用户名和密码是从环境变量APP_USERNAME
和APP_PASSWORD_HASH
。
Now build the container:
现在构建容器:
Caddy v.2 requires you to hash your desired password. Run the following command and remember to replace mypass
with a strong password of your choosing:
Caddy v.2要求您哈希所需的密码。 运行以下命令,并记住将mypass
替换为您选择的强密码:
docker run --rm -it thunderbird-caddy caddy hash-password -plaintext 'mypass'
搬运工运行--rm -IT雷鸟球童球童哈希密码-plaintext“ 为mypass”
This command will output a string of characters. Copy this to your clipboard in preparation of running the next command.
此命令将输出字符串。 将其复制到剪贴板,以准备运行下一个命令。
Now you are ready to run the container. Make sure to replace myuser
with a username of your choosing, and replace mypass-hash
with the output of the command you ran in the previous step. You can also change the port (8080
here) to access your server on a different port:
现在您可以运行容器了。 确保将myuser
替换为您选择的用户名,并将mypass-hash
替换为您在上一步中运行的命令的输出。 您还可以更改端口(此处为8080
)以使用其他端口访问服务器:
docker run --detach --restart=always --volume=thunderbird-data:/data --net=thunderbird-net --name=thunderbird-web --env=APP_USERNAME="myuser" --env=APP_PASSWORD_HASH="mypass-hash" --publish=8080:8080 thunderbird-caddy
docker run --detach --restart =总是--volume = thunderbird-data:/ data --net = thunderbird-net --name = thunderbird-web --env = APP_USERNAME =“ myuser ” --env = APP_PASSWORD_HASH =“ mypass-hash “ --publish = 8080 :8080 thunderbird-caddy
We are now ready to access and test our application.
现在,我们准备访问和测试我们的应用程序。
Let’s access your application and ensure that it’s working.
让我们访问您的应用程序并确保它可以正常工作。
First, open http://your_server_ip:8080
in a web browser, log in with the credentials you chose earlier, and click Connect.
首先,在网络浏览器中打开http:// your_server_ip : 8080
,使用先前选择的凭据登录,然后单击Connect 。
You should now be able to interact with the application, and it should automatically resize to fit your browser window.
现在,您应该能够与该应用程序进行交互,并且它应该自动调整大小以适合您的浏览器窗口。
If you right-click on the black desktop, you should see a menu that allows you to access a terminal. If you middle-click, you should see a list of windows.
如果在黑色桌面上单击鼠标右键,应该会看到一个菜单,该菜单可让您访问终端。 如果单击鼠标中键,应该会看到一个窗口列表。
Now open http://your_server_ip:8080/files/
in a web browser. You should be able to access your files.
现在,在网络浏览器中打开http:// your_server_ip : 8080 /files/
。 您应该能够访问您的文件。
Optionally, you can try mounting http://your_server_ip:8080/webdav/
in a WebDAV client. You should be able to access and modify your files directly. If you use the Map network drive option in Windows Explorer, you will either need to use a reverse proxy to add HTTPS or set HKLM\SYSTEM\CurrentControlSet\Services\WebClient\Parameters\BasicAuthLevel
to DWORD:2
.
(可选)您可以尝试在WebDAV客户端中安装http:// your_server_ip : 8080 /webdav/
。 您应该可以直接访问和修改文件。 如果在Windows资源管理器中使用“ 映射网络驱动器”选项,则需要使用反向代理来添加HTTPS或将HKLM\SYSTEM\CurrentControlSet\Services\WebClient\Parameters\BasicAuthLevel
为DWORD:2
。
In either case, your native GUI application is now ready for remote use.
无论哪种情况,您的本机GUI应用程序现在都可以远程使用。
You have now successfully set up a Docker container for Thunderbird and then, using Caddy, you’ve configured access to it through a web browser. Should you ever need to upgrade your app, stop the containers, run docker rm thunderbird-app thunderbird-web
, re-build the images, and then re-run the docker run
commands from the previous steps above. Your data will still be preserved since it is stored in a volume.
您现在已经成功为Thunderbird设置了Docker容器,然后使用Caddy配置了通过Web浏览器对其的访问。 如果您需要升级应用程序,请停止容器,运行docker rm thunderbird-app thunderbird-web
,重新构建映像,然后重新运行上述步骤中的docker run
命令。 由于数据存储在卷中,因此仍将保留。
If you want to learn more about basic Docker commands, you can read this tutorial or this cheatsheet. For longer-term use, you may also want to consider enabling HTTPS (this requires a domain) for additional security.
如果您想了解有关Docker基本命令的更多信息,可以阅读本教程或本备忘单 。 对于长期使用,您可能还需要考虑启用HTTPS(这需要一个域)以提高安全性。
Additionally, if you’re deploying more than one application, you may want to use Docker Compose or Kubernetes instead of starting each container manually. And remember, this tutorial can serve as a base for running any other Linux application on your server, including:
此外,如果要部署多个应用程序,则可能要使用Docker Compose或Kubernetes,而不是手动启动每个容器。 请记住,本教程可以作为在服务器上运行任何其他Linux应用程序的基础,包括:
Wine, a compatibility layer for running Windows applications on Linux.
Wine ,用于在Linux上运行Windows应用程序的兼容性层。
GIMP, an open-source image editor.
GIMP ,一个开源的图像编辑器。
Cutter, an open-source reverse engineering platform.
Cutter ,一个开源的逆向工程平台。
This last option demonstrates the great potential of containerizing and remotely accessing GUI applications. With this setup, you can now use a server with considerably more computing power than you might have locally to run resource-intensive tools like Cutter.
最后一个选项展示了容器化和远程访问GUI应用程序的巨大潜力。 通过此设置,您现在可以使用具有比本地强大得多的计算能力的服务器来运行诸如Cutter之类的资源密集型工具。