Skip to content

Installation vi

SkimMail docs edited this page Sep 17, 2026 · 8 revisions

English · Tiếng Việt · 中文

Cài đặt

SkimMail có bốn cách cài: gói apt, image Docker, file docker-compose kéo image đó về, và binary tarball. Chọn một trong bốn — đây là bốn cách cài độc lập của cùng một bản build duy nhất (đã tích hợp sẵn SQLite + PostgreSQL + MySQL + S3; egress qua WireGuard là một plugin cài sau, từ Settings ▸ Plugins). Không có bản "lite" nào để phân vân chọn.

Build từ source không phải là thứ bạn làm được với repo công khai. SkimMail cấp phép theo Business Source License 1.1: source nằm trong một repo private, chỉ binary đã build sẵn được phân phối. github.com/lyquyduong/skimmail — repo công khai — chỉ chứa đúng ba file (README.md, README.vi.md, README.zh.md), không có source. Nếu bạn có quyền truy cập repo private, README.dev.md ở đó nói về build từ source, dev mode và setup VS Code; ở đây không có gì tương đương để đưa cho bạn, và không công thức nào dưới đây chạy được với repo công khai.

Nền tảng được hỗ trợ

Cách cài OS / kiến trúc
apt (.deb) Debian/Ubuntu, amd64, arm64
Docker / docker-compose Container Linux, amd64, arm64 (image multi-arch)
Binary tarball linux/amd64, linux/arm64, darwin/amd64, darwin/arm64

Chọn cách nào

Bạn muốn… Dùng
Một server Debian/Ubuntu bình thường, quản lý bằng systemd, cập nhật bằng apt upgrade apt
Một container host, hoặc bạn đã chạy mọi thứ bằng Docker Docker hoặc docker-compose
Một binary tự cập nhật, không cần package manager, không cần container runtime Binary tarball

Cả bốn cách đều in ra cùng một claim code dùng một lần ở lần khởi động đầu tiên và yêu cầu nó trước khi đăng nhập lần đầu — xem Security để biết vì sao. Lệnh chính xác để đọc claim code khác nhau theo từng cách cài, nêu cụ thể trong từng mục bên dưới.


apt (Debian / Ubuntu)

Yêu cầu trước

  • Debian hoặc Ubuntu trên amd64 hoặc arm64, có quyền sudo.
  • HTTPS ra ngoài tới lyquyduong.github.io (apt repo) và tới github.com/objects.githubusercontent.com (apt không tải gì trực tiếp từ đó, nhưng cùng đường mạng này cần cho việc kiểm tra self-update sau này).

Thêm repo và signing key

curl -fsSL https://lyquyduong.github.io/skimmail/apt/skimmail.gpg \
  | sudo tee /usr/share/keyrings/skimmail.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/skimmail.gpg] https://lyquyduong.github.io/skimmail/apt stable main" \
  | sudo tee /etc/apt/sources.list.d/skimmail.list
sudo apt update

Key bạn vừa tải là một khoá OpenPGP ed25519 ký lên file Release của repo (apt-ftparchive + gpg, được release pipeline build ra); apt sẽ từ chối repo nếu chữ ký không khớp, nên không còn gì phải tự kiểm tra thêm bằng tay.

Cài đặt

sudo apt install skimmail

Lệnh này tạo một system user riêng (skimmail, không có shell đăng nhập), đăng ký và khởi động skimmail.service, rồi in ra một banner ngắn kèm lệnh lấy claim code. Cấu hình nằm ở /etc/default/skimmail (một systemd EnvironmentFile — xem Configuration); dữ liệu nằm ở /var/lib/skimmail.

Kiểm tra đã chạy chưa

sudo systemctl status skimmail
curl http://localhost:8080/healthz

Instance khoẻ mạnh trả về {"status":"ok","version":"1.17.0"}. Log trực tiếp: sudo journalctl -u skimmail -f (còn có một file log xoay vòng ở /var/log/skimmail/skimmail.log, xem và chỉnh được ở Settings ▸ Logs sau khi đăng nhập).

Lần chạy đầu: claim code

Mở http://<server>:8080. Trước khi cho bạn tạo tài khoản hay passphrase đầu tiên, SkimMail hỏi claim code dùng một lần mà nó đã in ra ở lần khởi động đầu:

sudo journalctl -u skimmail | grep 'claim code'

sudo không phải tuỳ chọn ở đây. Thiếu nó, journalctl âm thầm giấu unit của user khác (service chạy dưới user hệ thống skimmail, không phải bạn) và in ra một dòng gợi ý thay vì claim code — đây là lỗi từng được báo lại trên bản 1.9.1 bởi những người chạy lệnh không có sudo, không thấy gì hữu ích, và tưởng rằng claim code chưa từng được in ra.

Mất code, hoặc log đã xoay vòng qua mất rồi? Tạo một code mới — code cũ ngừng dùng được ngay khi bạn làm việc này:

sudo -u skimmail skimmail --data-dir /var/lib/skimmail claim-code --rotate

--data-dir /var/lib/skimmail là bắt buộc. Lệnh này không đọc /etc/default/skimmail — file đó là một systemd EnvironmentFile, chỉ được truyền cho tiến trình khi chính systemd khởi động unit, không bao giờ truyền cho một lệnh shell gõ tương tác. Không có --data-dir, DATA_DIR sẽ rơi về mặc định ./data, tính theo thư mục bạn đang đứng lúc gõ lệnh — hoặc lỗi vì quyền truy cập, hoặc (tệ hơn) âm thầm tạo một database dùng-rồi-bỏ ở đó và in ra một code trông hoàn toàn hợp lệ mà server thật đang chạy sẽ không bao giờ chấp nhận. Từ 1.9.1, lệnh này từ chối chạy hẳn nếu thư mục đó không chứa instance nào, nên --data-dir sai giờ báo lỗi rõ ràng thay vì âm thầm làm điều trên.

Gỡ cài đặt

sudo apt purge skimmail        # dừng service, xoá binary, systemd unit
                                # và /etc/default/skimmail

apt purge không xoá thư của bạn — chưa từng có gì trong SkimMail làm việc đó. Thông báo khi gỡ package tự nói rõ dữ liệu đang nằm ở đâu. Nếu bạn thật sự muốn xoá sạch:

sudo rm -rf /var/lib/skimmail  # ⚠ xoá mọi tài khoản, mọi thư và master key
                                #   mã hoá — không thể khôi phục
sudo rm -rf /var/log/skimmail  # file log + các bản xoay vòng
sudo userdel skimmail          # system user được tạo lúc cài
sudo rm -f /etc/apt/sources.list.d/skimmail.list /usr/share/keyrings/skimmail.gpg
sudo apt update

Backup trước (Settings ▸ Backup) nếu còn khả năng bạn sẽ cần lại dữ liệu này.


Docker

Yêu cầu trước

  • Docker Engine (bản nào tương đối mới cũng được; image multi-arch linux/amd64 + linux/arm64, tự chọn đúng kiến trúc).

Chạy

docker run -d --name skimmail -p 8080:8080 -v skimmail-data:/data \
  -e AUTH_MODE=passphrase ghcr.io/lyquyduong/skimmail:latest

Đặt tên container là skimmail — các lệnh bên dưới giả định vậy. Image tự đặt DATA_DIR=/dataLISTEN_ADDR=:8080; skimmail-data là named volume để dữ liệu sống sót qua docker rm. Muốn ghim một bản cụ thể thay vì latest, dùng tag có tiền tố v, ví dụ ghcr.io/lyquyduong/skimmail:v1.17.0.

Kiểm tra đã chạy chưa

docker ps                              # skimmail hiện trạng thái Up
curl http://localhost:8080/healthz     # {"status":"ok","version":"1.17.0"}

Image này là distroless (không có shell, không có package manager bên trong) — docker exec skimmail sh sẽ không chạy được. docker exec skimmail /skimmail <command> chạy được, vì nó gọi thẳng binary SkimMail chứ không qua shell; bạn sẽ dùng đúng dạng này bên dưới.

Lần chạy đầu: claim code

docker logs skimmail 2>&1 | grep 'claim code'

Log driver của Docker bắt toàn bộ output của tiến trình duy nhất trong container, nên — khác với trường hợp apt/journalctl — không có chuyện phân quyền theo user ở đây; bạn không cần sudo cho lệnh này trên một bản cài Docker bình thường (chỉ cần cho trường hợp journalctl ở trên).

Mất code? Tạo code mới:

docker exec skimmail /skimmail claim-code --rotate

Không cần --data-dir ở đây: image đã đặt sẵn DATA_DIR=/data, nên docker exec — chạy bên trong chính môi trường của container — tự thấy được biến này. (So sánh với trường hợp apt ở trên, nơi file environment tương ứng không bao giờ được truyền cho một shell gõ tương tác.)

Gỡ cài đặt

docker rm -f skimmail
docker rmi ghcr.io/lyquyduong/skimmail:latest

Dữ liệu của bạn không bị đụng tới — nó nằm trong volume skimmail-data, không nằm trong container. Muốn xoá luôn cả nó (⚠ không thể khôi phục):

docker volume rm skimmail-data

Docker Compose

Yêu cầu trước

  • Docker Engine + plugin docker compose (Compose v2; binary docker-compose v1 vẫn chạy được nhưng không phải thứ các lệnh dưới đây giả định).

Lấy file compose và chạy

Không cần checkout source — file compose được publish kèm mỗi bản release:

curl -fsSLO https://lyquyduong.github.io/skimmail/docker-compose.yml
docker compose up -d

Lệnh này kéo ghcr.io/lyquyduong/skimmail:latest, publish port 8080, và tạo named volume cho /data. Muốn ghim phiên bản: SKIMMAIL_VERSION=v1.17.0 docker compose up -d. Bỏ comment BASE_URL, AUTH_MODE, hoặc DB_DRIVER/DATABASE_URL trong file này trước lần chạy đầu nếu bạn muốn dùng Postgres hoặc MySQL ngay từ đầu — xem Configuration để biết đổi database sau khi đã có dữ liệu đòi hỏi những gì.

Kiểm tra đã chạy chưa

docker compose ps
curl http://localhost:8080/healthz     # {"status":"ok","version":"1.17.0"}

Lần chạy đầu: claim code

docker compose logs skimmail 2>&1 | grep 'claim code'

Dùng docker compose logs <service>, gọi theo tên service (skimmail, như đặt trong file compose) — không phải docker logs skimmail. Compose không đặt tên container là skimmail: với project name name: skimmail trong file được publish và một service cũng tên skimmail, container thật sự tên là skimmail-skimmail-1, nên docker logs skimmail trần trụi sẽ báo lỗi "No such container". docker compose logs tra service theo đúng tên trong file compose bất kể tên container thật là gì, đó là lý do dùng dạng này ở đây.

Mất code? Tạo code mới theo cùng cách, qua service:

docker compose exec skimmail /skimmail claim-code --rotate

Gỡ cài đặt

docker compose down            # dừng và xoá container
rm docker-compose.yml          # file bạn đã tải về

Dữ liệu vẫn còn trong named volume. Muốn xoá tất cả (⚠ không thể khôi phục):

docker compose down -v

Binary tarball

Yêu cầu trước

  • linux/amd64, linux/arm64, darwin/amd64 hoặc darwin/arm64.
  • Không cần database, không cần container runtime, không cần package manager — SQLite đã nằm sẵn trong binary.

Tải về và chạy

Lấy đúng file cho OS và kiến trúc của bạn từ GitHub Releases — tên file theo mẫu skimmail_<version>_<os>_<arch>.tar.gz, ví dụ với bản hiện tại trên Linux/amd64:

curl -fsSLO https://github.com/lyquyduong/skimmail/releases/download/v1.17.0/skimmail_v1.17.0_linux_amd64.tar.gz
tar xzf skimmail_v1.17.0_linux_amd64.tar.gz

Lệnh này giải nén ra đúng một file thực thi, đã mang tên theo phiên bản và nền tảng của chính nó (ví dụ skimmail_v1.17.0_linux_amd64) và đã có sẵn quyền thực thi — không cần chmod +x. Đổi tên nếu bạn muốn gõ ngắn hơn:

mv skimmail_v1.17.0_linux_amd64 skimmail
DATA_DIR=./skimmail-data ./skimmail

Đặt DATA_DIR rõ ràng (như trên) thay vì để mặc định ./data — mặc định này tính theo thư mục bạn đang đứng lúc chạy, và điều đó có ý nghĩa ngay khi bạn chạy từ một chỗ khác (một cron job, một terminal khác, một systemd unit tự viết) rồi vô tình có thêm một instance rỗng thứ hai.

Không có sẵn service definition nào cho cách cài này — bạn tự nối binary vào bất cứ thứ gì đang giám sát tiến trình chạy dài trên hệ thống của mình (systemd unit tự viết trên Linux, launchd trên macOS, một process manager, hoặc đơn giản là nohup …/screen/tmux để thử nhanh). Một systemd unit tối thiểu chỉ cần User=, ExecStart= trỏ vào binary kèm --data-dir rõ ràng, và Restart=on-failure; không có gì trong cách cài này tự cài đặt sẵn một unit như gói apt làm.

Kiểm tra đã chạy chưa

curl http://localhost:8080/healthz     # {"status":"ok","version":"1.17.0"}

Lần chạy đầu: claim code

Binary in log ra stdout, nên đọc bất cứ thứ gì đang bắt output đó (terminal của bạn, journalctl của một systemd unit, hay file log mà process manager của bạn ghi ra):

journalctl -u <ten-unit-cua-ban> | grep 'claim code'   # nếu bạn tự viết systemd unit
# hoặc chỉ cần nhìn vào terminal đã chạy lệnh

Mất code? Tạo code mới, chỉ đúng DATA_DIR bạn đã dùng lúc chạy:

./skimmail --data-dir ./skimmail-data claim-code --rotate

Gỡ cài đặt

Dừng tiến trình (theo cách bạn đã chạy hoặc giám sát nó), rồi xoá binary và thư mục dữ liệu:

rm ./skimmail
rm -rf ./skimmail-data          # ⚠ xoá mọi tài khoản, mọi thư và master key
                                 #   mã hoá — không thể khôi phục

Nếu bạn có tự viết systemd unit hay supervisor khác, xoá luôn cái đó.


Tiếp theo

  • Configuration — mô hình cấu hình ba mặt phẳng, và toàn bộ biến môi trường.
  • Security — claim code chi tiết hơn, screen lock, trusted proxy, và encryption at rest thực sự phủ tới đâu.

SkimMail · skimmail@base101.app · 2026-09-17 · commit 97c7846

Clone this wiki locally