一款通过 WebSocket 实时发送和接收消息的实时消息服务器软件——Gotify

其实早在一年多前就已经用其部署并使用些许时间,但一时之间想不起为什么不在当时就写成文章来水一篇?

眼看着这台部署有 Gotify 的机器欲放弃续费的打算,搜索着站内还未有相应记录的结果,遂决定在此时此刻做一番记录吧。

基于当时部署所在的那台服务器配置不是很高的样子,于是乎只好放弃使用常规的使用 Docker 部署的计划,而是使用比较平常的二进制可执行文件的方式部署吧。

Gotify

简介

用于发送和接收消息的简单服务器

  • 通过 REST-API 发送消息
  • 通过 WebSocket 连接订阅/接收消息
  • 管理用户、客户端和应用程序

安装

Docker

用 docker 来部署gotify/server非常简单,只需启动 docker 容器就可以开始了。

Docker Run

在启动gotify/server之前,您可以阅读 配置 来使用不同的数据库。

docker run -p 80:80 -v /var/gotify/data:/app/data gotify/server
# or via GitHub registry
docker run -p 80:80 -v /var/gotify/data:/app/data ghcr.io/gotify/server

gotify/serverghcr.io/gotify/server是多架构的 Docker 镜像,它们适用于以下架构:amd64i386arm64armv7riscv64

/app/data包含数据库文件(如果使用 SQLite)、应用程序镜像和证书文件(如果启用了 Let’s Encrypt)。在本例中,该目录挂载到/var/gotify/data目录应包含在备份中。

容器内的时区可通过以下方式进行配置: TZ环境变量:

docker run -p 80:80 -e TZ="Europe/Berlin" -v /var/gotify/data:/app/data gotify/server

Docker Compose

示例docker-compose.yaml:

---
services:
  gotify:
    image: gotify/server
    ports:
      - 8080:80
    environment:
      GOTIFY_DEFAULTUSER_PASS: 'admin'
    volumes:
      - './gotify_data:/app/data'
    # to run gotify as a dedicated user:
    # sudo chown -R 1234:1234 ./gotify_data
    # user: "1234:1234"

总的来说若是使用 Docker 部署,还是建议使用 Docker Compose 的方式更好。

二进制包

支持的平台

  • linux-amd64(64位)
  • linux-386(32位)
  • linux-arm-7(32位用于树莓派)
  • linux-arm64 (ARMv8)
  • windows-386.exe(32位)
  • Windows-amd64.exe (64位)

下载安装

  1. 从 Github 下载带二进制格式的zip

    需要根据具体架构平台下载对应的压缩包,替换 {VERSION}带有最新的版本和 {PLATFORM}使用支持的平台之一。

    wget https://github.com/gotify/server/releases/download/v{VERSION}/gotify-{PLATFORM}.zip
    
  2. 解压
    unzip gotify-{PLATFORM}.zip
    
  3. 修改权限

    赋予可执行权限

    chmod +x gotify-{PLATFORM}
    
  4. 启动

    默认情况下,gotify/服务器在端口80上启动,因此需要启动sudo

    ./gotify-{PLATFORM}
    

配置

可以根据配置文件和环境变量进行配置,使用docker时建议使用环境变量。

配置文件

在以下路径中查看配置文件:

  • ./config.yml
  • /etc/gotify/config.yml

配置文件/etc/gotify/config.yml可能包含敏感数据(例如初始管理员密码),使用它时应移除不拥有该文件的用户的读/写权限。

配置示例

server:
  keepaliveperiodseconds: 0 # 0 = use Go default (15s); -1 = disable keepalive; set the interval in which keepalive packets will be sent. Only change this value if you know what you are doing.
  listenaddr: '' # the address to bind on, leave empty to bind on all addresses. Prefix with "unix:" to create a unix socket. Example: "unix:/tmp/gotify.sock".
  port: 80 # the port the HTTP server will listen on

  ssl:
    enabled: false # if https should be enabled
    redirecttohttps: true # redirect to https if site is accessed by http
    listenaddr: '' # the address to bind on, leave empty to bind on all addresses. Prefix with "unix:" to create a unix socket. Example: "unix:/tmp/gotify.sock".
    port: 443 # the https port
    certfile: # the cert file (leave empty when using letsencrypt)
    certkey: # the cert key (leave empty when using letsencrypt)
    letsencrypt:
      enabled: false # if the certificate should be requested from letsencrypt
      accepttos: false # if you accept the tos from letsencrypt
      cache: data/certs # the directory of the cache from letsencrypt
      hosts: # the hosts for which letsencrypt should request certificates
  #     - mydomain.tld
  #     - myotherdomain.tld
  responseheaders: # response headers are added to every response (default: none)
  # X-Custom-Header: "custom value"
  trustedproxies: # IPs or IP ranges of trusted proxies. Used to obtain the remote ip via the X-Forwarded-For header. (configure 127.0.0.1 to trust sockets)
  #   - 127.0.0.1
  #   - 192.168.178.0/24
  #   - ::1

  cors: # Sets cors headers only when needed and provides support for multiple allowed origins. Overrides Access-Control-* Headers in response headers.
    alloworigins:
    # - ".+.example.com"
    # - "otherdomain.com"
    allowmethods:
    # - "GET"
    # - "POST"
    allowheaders:
  #   - "Authorization"
  #   - "content-type"

  stream:
    pingperiodseconds: 45 # the interval in which websocket pings will be sent. Only change this value if you know what you are doing.
    allowedorigins: # allowed origins for websocket connections (same origin is always allowed, default only same origin)
#     - ".+.example.com"
#     - "otherdomain.com"
database: # see below
  dialect: sqlite3
  connection: data/gotify.db
defaultuser: # on database creation, gotify creates an admin user (these values will only be used for the first start, if you want to edit the user after the first start use the WebUI)
  name: admin # the username of the default user
  pass: admin # the password of the default user
passstrength: 10 # the bcrypt password strength (higher = better but also slower)
uploadedimagesdir: data/images # the directory for storing uploaded images
pluginsdir: data/plugins # the directory where plugin resides (leave empty to disable plugins)
registration: false # enable registrations

数据库

类型 连接字符串
sqlite3 path/to/database.db
mysql gotify:secret@tcp(localhost:3306)/gotifydb?charset=utf8&parseTime=True&loc=Local
Postgres host=localhost port=5432 user=gotify dbname=gotifydb password=secret

在不使用SSL的情况下使用postgres时,请sslmode=disable必须添加到连接字符串中。

当为mysqlpostgres时须确保设定的数据库存在,并且赋予对应的权限。

环境变量

列表或地图环境设置中的字符串(例如:GOTIFY_SERVER_RESPONSEHEADERSGOTIFY_SERVER_SSL_LETSENCRYPT_HOSTS) 需要转义。

示例

GOTIFY_SERVER_PORT=80
GOTIFY_SERVER_KEEPALIVEPERIODSECONDS=0
GOTIFY_SERVER_LISTENADDR=
GOTIFY_SERVER_SSL_ENABLED=false
GOTIFY_SERVER_SSL_REDIRECTTOHTTPS=true
GOTIFY_SERVER_SSL_LISTENADDR=
GOTIFY_SERVER_SSL_PORT=443
GOTIFY_SERVER_SSL_CERTFILE=
GOTIFY_SERVER_SSL_CERTKEY=
GOTIFY_SERVER_SSL_LETSENCRYPT_ENABLED=false
GOTIFY_SERVER_SSL_LETSENCRYPT_ACCEPTTOS=false
GOTIFY_SERVER_SSL_LETSENCRYPT_CACHE=certs
# GOTIFY_SERVER_SSL_LETSENCRYPT_HOSTS=[mydomain.tld, myotherdomain.tld]
# GOTIFY_SERVER_RESPONSEHEADERS={X-Custom-Header: "custom value", x-other: value}
# GOTIFY_SERVER_TRUSTEDPROXIES=[127.0.0.1,192.168.178.2/24]
# GOTIFY_SERVER_CORS_ALLOWORIGINS=[.+\.example\.com, otherdomain\.com]
# GOTIFY_SERVER_CORS_ALLOWMETHODS=[GET, POST]
# GOTIFY_SERVER_CORS_ALLOWHEADERS=[X-Gotify-Key, Authorization]
# GOTIFY_SERVER_STREAM_ALLOWEDORIGINS=[.+.example\.com, otherdomain\.com]
GOTIFY_SERVER_STREAM_PINGPERIODSECONDS=45
GOTIFY_DATABASE_DIALECT=sqlite3
GOTIFY_DATABASE_CONNECTION=data/gotify.db
GOTIFY_DEFAULTUSER_NAME=admin
GOTIFY_DEFAULTUSER_PASS=admin
GOTIFY_PASSSTRENGTH=10
GOTIFY_UPLOADEDIMAGESDIR=data/images
GOTIFY_PLUGINSDIR=data/plugins
GOTIFY_REGISTRATION=false

以 service 的方式运行

  1. 移动 gotify 二进制包
    mv gotify-{PLATFORM} /usr/local/bin/gotify
    
  2. 创建/etc/systemd/system/gotify.service文件
    [Unit]
    Description=Gotify
    Requires=network.target
    After=network.target
    
    [Service]
    Type=simple
    User=root
    WorkingDirectory=/var/log/gotify
    ExecStart=/usr/local/bin/gotify
    StandardOutput=append:/var/log/gotify/gotify.log
    StandardError=append:/var/log/gotify/gotify-error.log
    Restart=always
    RestartSec=3
    
    [Install]
    WantedBy=multi-user.target
    
  3. 微调配置文件/etc/gotify/config.yml
    ...
      port: 11180 # the port the HTTP server will listen on
        port: 11443 # the https port
        certfile: "/usr/local/openresty/nginx/ssl/cyzwb.com.pem" # the cert file (leave empty when using letsencrypt)
        certkey: "/usr/local/openresty/nginx/ssl/cyzwb.com.key" # the cert key (leave empty when using letsencrypt)
    database: # see below
      dialect: sqlite3
      connection: /home/gotify-data/gotify.db
    dit the user after the first start use the WebUI)
      name: admin # the username of the default user
      pass: admin # the password of the default user
    
    ...
    
  4. 使systemd能够在启动时启动Gotify:
    mkdir /var/log/gotify
    systemctl daemon-reload
    systemctl enable gotify
    

使用

第一次登录

启动后,您可以登录到 WebUI。首次启动时会创建一个初始帐户,以便您可以登录。如果您没有重置配置中的默认设置,请使用用户名:admin、密码:admin

登录后,您可以创建自己的用户,如果需要,还可以删除默认帐户(在创建单独的管理员帐户后)。您还可以删除配置中的任何用户名/密码重置,因为它们仅用于初始创建此帐户。

如果您选择保留默认帐户,请务必更改密码!

推送消息

只有创建应用程序的用户才能看到其消息,应用程序可以通过以下方法添加top

  • WebUI:点击右上角apps标签,添加Applications
  • REST-API:curl -u admin:admin https://yourdomain.com/application -F "name=test" -F "description=tutorial"

推送消息:

curl "https://push.example.de/message?token=<apptoken>" -F "title=my title" -F "message=my message" -F "priority=5"

Nginx反向代理

为方便无需加端口即可访问,鉴于同一机器运行多个服务,特须使用类似于 Nginx 这样的软件反向代理。

示例:

    upstream gotify {
        # Set the port to the one you are using in gotify
        server 127.0.0.1:11443;
        }

    server {
        listen       443 ssl;
        http2 on;
        server_name  gotify.cyzwb.com;

        ssl_certificate      /usr/local/openresty/nginx/ssl/gotify.cyzwb.com.pem;
        ssl_certificate_key  /usr/local/openresty/nginx/ssl/gotify.cyzwb.com.key;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
             # We set up the reverse proxy
             proxy_pass         https://gotify;
             proxy_http_version 1.1;
             
             # Ensuring it can use websockets
             proxy_set_header   Upgrade $http_upgrade;
             proxy_set_header   Connection "upgrade";
             proxy_set_header   X-Real-IP $remote_addr;
             proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
             proxy_set_header   X-Forwarded-Proto http;
             proxy_redirect     http:// $scheme://;
             
             # The proxy must preserve the host because gotify verifies the host with the origin
             # for WebSocket connections
             proxy_set_header   Host $http_host;
             
             
             # These sets the timeout so that the websocket can stay alive
             proxy_connect_timeout   1m;
             proxy_send_timeout      1m;
             proxy_read_timeout      1m;
        }
    }

题外话

根据文件时间以及推送消息的记录所知当时安装的时间:

root@ChiuYut-VM:~# ls -l --time-style=long-iso --time=ctime /usr/local/bin/gotify 
-rwxr-xr-x 1 root root 25539424 2024-11-13 05:31 /usr/local/bin/gotify
root@ChiuYut-VM:~# ls -l --time-style=long-iso --time=ctime /etc/gotify/config.yml 
-rw-r--r-- 1 root root 2991 2024-11-13 05:54 /etc/gotify/config.yml
root@ChiuYut-VM:~# ls -l --time-style=long-iso --time=ctime /home/gotify-data/gotify.db 
-rw-r--r-- 1 root root 1908736 2026-05-10 14:43 /home/gotify-data/gotify.db

安装时的版本还是Starting Gotify version 2.5.0@2024-06-23-17:12:59的,现在都到Starting Gotify version 2.9.1@2026-02-28-19:13:51版本了。

参考

  • Gotifyhttps://gotify.net/
  • A simple server for sending and receiving messages in real-time per WebSocket. (Includes a sleek web-ui)https://github.com/gotify/server/releases

ChiuYut

2026年05月10日

发布者

ChiuYut

咦?我是谁?这是什么地方? Ya ha!我是ChiuYut!这里是我的小破站!