WordPress + Cloudflared + V2ray 異地組網並隱藏流量

目標

  • 異地組網, 遠程訪問家中環境
  • 結合海外 VPS 翻牆 ( 不在此篇討論 )
  • 使用 V2Ray TLS 加密流量
  • 將 TLS 流量隱藏在正常的 HTTPS 流量中達到混淆目的
  • 使用 Cloudflare 的內網穿透服務, 達到防探測目的 ( 服務器直接和 CF 溝通, 沒有端口暴露 )
  • 使用 Cloudflare 的 CDN 服務, 達到防牆、加速作用

如果你並不是想要做異地組網, 而是想要在 VPS 上跑 (Nginx/Caddy/Apache) + WP + V2Ray, 那麼你其實用不著這麼複雜. 你只需要看這篇文章就可以了.

(這篇博文主要是討論一個沒多少人做過的方案的可行性, 所以你會看到後面還有一大通廢話; 作為教程本文是不合格的, 如果想要尋找教程請出門右轉谷歌搜索. )

網絡拓墣示意圖

準備環境

  • 一台聯網、24×7 運行的機器, 內存 4G+, 空間 8G+
  • 安裝有 Linux 系統 ( 推薦 Openwrt, 或者 樹莓派安裝 PiOS )
  • Cloudflare 帳戶, 託管在 CF 上的域名

執行以下操作準備所需鏡像.

docker pull wordpress
docker pull mariadb
docker pull teddysun/v2ray

使用以下 Dockerfile 構建 Cloudflared 鏡像

FROM debian:latest
VOLUME ["/etc/cloudflared"]
WORKDIR /etc/cloudflared
RUN ln -s /etc/cloudflared /root/.cloudflared
RUN apt update && apt install wget -y
RUN wget https://github.com/cloudflare/cloudflared/releases/download/2021.5.10/cloudflared-linux-amd64 \
    && mv cloudflared-linux-amd64 /usr/local/bin/cloudflared \
    && chmod +x /usr/local/bin/cloudflared

配置 Nginx + WordPress

如果你已經配置好了, 可以直接跳過. 我在這裡貼出我的啟動參數:

docker run --name wordpress \
-v /www/wordpress:/var/www/html \
-p 443:443/tcp \
-p 80:80/tcp \
--net wpblog \
--restart always \
-h wordpress \
--expose 443/tcp \
--expose 80/tcp \
-e 'WORDPRESS_TABLE_PREFIX=wp_' \
-e 'WORDPRESS_DB_HOST=db' \
-e 'WORDPRESS_DB_USER=root'\
-e 'WORDPRESS_DB_PASSWORD=password' \
-e 'WORDPRESS_DB_NAME=wordpress' \
-d wordpress:latest
docker run --name wordpressdb \
-v wordpressdb_data:/var/lib/mysql \
-p 3306:3306/tcp \
--net wpblog \
--restart always \
-h db \
--expose 3306/tcp \
-e 'MARIADB_ROOT_PASSWORD=password' \
-e 'MARIADB_DATABASE=wordpress' \
-d mariadb:latest

V2Ray

V2Ray 啟動參數:

docker run --name v2ray \
-v /etc/v2ray:/etc/v2ray \
--net host \
--restart always \
-d teddysun/v2ray

V2Ray 配置文件:

{
  "inbounds": [
    {
      "port": 9999,
      "listen":"127.0.0.1",
      "protocol": "vmess",
      "settings": {
        "clients": [
          {
            "id": "myawesomepassword",
            "alterId": 0
          }
        ]
      },
      "streamSettings": {
        "network": "ws",
        "wsSettings": {
        "path": "/myawesomepath"
        }
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "freedom",
      "settings": {}
    }
  ]
}

Cloudflared

Cloudflared 的配置有一點點煩. 我先開了一個 Debian 容器生成了 Cloudflared 的配置文件:

docker run --rm \
-v /etc/cloudflared:/root/.cloudflared \
-it debian:latest

然後在 Debian 中執行:

apt update && apt install wget -y
wget https://github.com/cloudflare/cloudflared/releases/download/2021.5.10/cloudflared-linux-amd64 \
    && mv cloudflared-linux-amd64 /usr/local/bin/cloudflared \
    && chmod +x /usr/local/bin/cloudflared
cloudflared login
cloudflared tunnel create mytunnel
exit

/etc/cloudflared 中新建 config.yml, 寫入:

tunnel: tunnel-id-here
credentials-file: /etc/cloudflared/tunnel-id-here.json

ingress:
  - hostname: myawesomesite.com
    path: /myawesomepath
    service: http://localhost:9999
  - hostname: myawesomesite.com
    service: http://localhost:80
  - service: http_status:404

使用如下啟動參數啟動容器:

docker run --name cloudflared \
-v /etc/cloudflared:/etc/cloudflared \
--net host \
--restart always \
-d cloudflared:latest '/usr/local/bin/cloudflared' '--no-autoupdate' '--config' '/etc/cloudflared/config.yml' 'tunnel' 'run' 'tunnel-id-here'

DNS 配置

打開 Cloudflare, 新建一條 CNAME 紀錄, 如下配置:

| TYPE  | NAME |            CONTENT              | TTL |  Proxy State|
| CNAME |  @   | tunnel-id-here.cfargotunnel.com | auto|   Proxied   |

驗證

$ curl https://myawesomesite.com/myawesomepath                             
Bad Request

後記

使用場景

之所以會有這樣的主意, 是因為我早就將所有文件都掛在 NAS 中了, 我隨身攜帶的筆記本、手機裡面基本沒有任何文件. 那麼當我出遠門的時候, 如果沒有一個可靠的組網方案, 難不成我還得把硬盤拆下來帶著走? ( 主要是留學場景 )

那麼只有 VPN 方案了. 眾所週知天朝的網絡環境超級奇葩, 要滿足搭建 VPN 的條件得開放公網 IP、配置 DDNS、配置端口轉發等一系列操作, 搞不好哪天運營商給妳封了還得重搞. 而且明擺著 VPN 流量流進流出也很不放心.

所以要配置這樣一個 VPN 還是得靠內網穿透. 問題是自己配 VPS + FRP 會被牆, 購買現成的方案性價比低, 好像真的走到僵局了. 當 4月份 CF 宣布 Argo Tunnel 開放之後我就一直在尋找利用它的方法: Cloudflare 現在遍地開花, 和 Cloudflare 長期的 TLS 流量是唯一不會被懷疑 + 不會被牆掉的. 而且有 CF 的 Edge Network 加持, 網絡延遲可能還比自己搭建 VPS 搞內網穿透要小.

剩下的問題就是偽裝問題了. 自然而然的, 我想到了流量 TLS 加密後混在正常的 HTTPS 流量中, 那麼 V2 + WP + CF 的方案就確定下來了.

注意事項

我在網絡拓墣圖裡並沒有畫出來, 那個 Home Lan 其實是走過一個 Openwrt 網關的, Openwrt 上有配置 Passwall 鏈接到我的翻牆 VPS 來保證速度. (大部分配置有軟路由的人也基本就是這麼玩的, 保證全家翻牆)

既然有翻牆這一個環節, 那麼就肯定要注意被牆的問題. 首先我們複習一下牆的手段: 針對網站有 DNS 污染和匹配SNI, 針對 IP 就比較簡單, 直接截下流量就可以了.

因為我們使用 Cloudflared 做內網穿透, 針對 IP 的威脅可以忽視. DNS 污染可以使用 DoH、DoT、dnsProxy, 匹配 SNI 我們可以用 ESNI 嘛. 而且如果是海外訪問(留學), 連牆都不用過.

要在家啟用 dnsProxy, 可以在 Openwrt 中配置 dns2socks ( dns 流量走代理 ); 要使用 DoH、DoT, 參考 Cloudflare 的這篇教程; 配置 ESNI 得先配置加密 DNS, 然後在瀏覽器裡找到對應選項開啟.

推薦的作法

剩下就是路由器用來翻牆的 VPS 會不會被牆. 因為很多沒有被牆的網站 (如 Github ) 訪問速度也和被牆了差不多, 所以我默認是開啟 IP 白名單的. 就是說, 如果 VPS 失效, Cloudflare 也會訪問不了. 如果人在家當然很好辦, 如果人在遠門或者在國外 (留學場景), 要注意把路由器設為 GFWlist 模式.

另外, 在牆內老是訪問同一個域名可能會導致身份關聯 ( 盡量不要在牆內這麼用 ). 如果非要這麼做, 建議配合 Tor 使用或者確保 DoH、ESNI 工作正常. (就是絕對不要在手機上亂用的意思)

Docker 無縫切換鏡像

警告: 我只是一個正在學習 Docker 的中學生,
一切在生產環境嘗試本文所述技巧所導致的損失都是自作自受.

有的時候, Docker 鏡像更新了, 但是容器並沒有更新, 你想要用更新過後的鏡像來部署容器; 奈何你並沒有像 Portainer 這樣的 GUI 介面, 你早就不記得當初部署容器時執行的指令了, 碰到這種情況應該怎麼辦?

下文便以更新 Portainer 為例來演示簡單的無縫切換鏡像.

解決方案

第一步當然是要先拉取更新的鏡像.

docker pull portainer/portainer-ce:latest

接著, 使用 rekcod 這個工具來獲取部署容器時輸入的命令.

$ docker run --rm -i -v /var/run/docker.sock:/var/run/docker.sock nexdrew/rekcod <container>

# 樹莓派玩家
# docker run --rm -v /var/run/docker.sock:/var/run/docker.sock nexdrew/rekcod:3.0.0arm

# 為該命令設別名
# alias rekcod="docker run --rm -v /var/run/docker.sock:/var/run/docker.sock nexdrew/rekcod:3.0.0arm"

短暫刪除舊的容器, 然後部署上新的.

$ docker stop <container>
$ docker rm <container>
$ <執行 rekcod 得到的結果>

至此, 新的容器就部署好了, 而當機時間不會超過幾秒鐘👌

最後別忘了刪除掉舊的鏡像喔.

樹莓派 4B 安裝 Arm64 PiOS

安裝系統

  1. 在 Ubuntu 中安裝 Rpi-imager 來準備鏡像
sudo apt update -y && sudo apt upgrade -y
sudo snap install rpi-imager

2. 從 清華大學鏡像 下載 Arm64 的 PiOS_Lite.

3. 使用 Rpi-Imager 刷入鏡像. 使用 Ubuntu 自帶的磁碟工具擴展 rootfs 容量到最大. (也可以不要, 最新版本的系統第一次開機會自動 Resize Partitions 將 / 分區擴到最大)

4. 在 boot 目錄下新建空白的 ssh 文件

cd ~/media/boot/
touch ssh
  1. 彈出 SD 卡, 插入樹莓派並通電.

基礎配置

0. 連線到樹莓派.

ssh [email protected] #raspberry
  1. 修改登錄方式
# 設置密碼
sudo passwd pi
sudo passwd root
​
# 配置 SSH 登錄
su
cd ~/
mkdir .ssh
chmod 700 .ssh
vi /root/.ssh/authorized_keys # 複製你的公鑰進去
chmod 644 /root/.ssh/authorized_keys
vi /etc/ssh/sshd_config # 配置ssh登錄

2. 在 sshd_config 中修改以下幾句.

LoginGraceTime 10m                 # afk達10min自動登出
PermitRootLogin prohibit-password  # 只允許root用ssh登錄
MaxAuthTries 6                     # 最多允許三次錯誤登錄嘗試
MaxSessions 10                     # 最多允許三個client同時登錄
​
PubkeyAuthentication yes           # 開啓公鑰登錄
​
AuthorizedKeysFile      .ssh/authorized_keys #開啓公鑰
​
PasswordAuthentication no          # 不允許任何用戶使用密碼登錄
PermitEmptyPasswords no            # 不允許任何空密碼用戶登錄

3. 繼續執行一下語句, 確定 status 沒有報錯之後登出.

systemctl restart sshd.service
systemctl status sshd.service
exit

4. 重新以 root 身份登錄.

5. 更新/設置系統

apt update && apt upgrade -y
​
# 更新系統 (可跳過)
rpi-update # 更新 Kernel
reboot
rpi-eeprom-update # 更新 Bootloader
raspi-config # 6 -> A7 -> E1
​
# 設置系統
raspi-config
​
# 重新登錄
exit

設置系統的部分自己選擇, 畢竟選項和提示都寫的很清楚.

我是比較喜歡開啟 Overlay Filesystem + ReadOnly Boot Partition 的, 前者就是一個開機一鍵還原, 後者是防止突然斷電破壞 boot 分區. 我覺得這兩個都比較實用, 建議全部設置完之後開啟.

至於語言 (Locale) 設定, 我喜歡把所有 zh 開頭的都勾上, 然後選用 zh_CN.UTF8, 可以保證亂碼不會出現.

至於測試的話, 只要 mkdir 測試, 然後 ls 一看看一看中文是否正常顯示就可以了.

軟件安裝

  1. 基本設置於基礎軟件安裝
# 安裝基本軟件
apt install vim git make wget -y

# 設置 UFW
apt install ufw -y
ufw allow from 192.168.10.1/24
ufw default deny
ufw enable
ufw status

# 設置 NTP 服務
apt install ntpdate -y
echo '@reboot ntpdate 192.168.10.1' >> /etc/crontab

# 設置 開機掛載硬盤
mkdir /mnt/data
mount /dev/sda1 /mnt/data
blkid # 複製顯示的 uuid 和 type
echo 'UUID=2e2e58b1-8fe8-4f5c-9478-f5eef65c5aa5 /mnt/data ext4 defaults 1 2' >> /etc/fstab
mount -a # 確定沒有報錯!

# 開機掛載網絡硬盤
sudo apt install -y curlftpfs
echo '@reboot curlftpfs -o rw,allow_other ftp://username:[email protected]/ /media/ftpdrive' >> /etc/crontab

# 安裝 ZSH & OH MY ZSH
apt install zsh -y
sh -c "$(wget https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh -O -)"

# 重啟
reboot

簡單的解釋一下為什麼我上面是這樣配置:

  • 我因為樹莓派完全運行在家庭網絡裡面, 所有流量都要經過轉發, 所以防火牆只允許家裡設備訪問最穩妥.
  • 因為路由器的系統是 Openwrt, 開著 NTP 服務, 所以可以直接向它更新時間.
  • 插上硬盤之後, 最新的系統應該會自動創建一個掛載點 /media/pi/... , 我不想要它, 所以已經把它 unmount 掉了.

2. 安裝 Docker

# 安裝 Docker
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
docker -v
systemctl enable docker.service
systemctl enable containerd.service

# 將 Docker 數據卷掛到外接硬盤
systemctl stop docker
systemctl stop containerd

# 第一次使用這個方法
mv /var/lib/docker /mnt/data/
mv /var/lib/containerd /mnt/data/containerd
# 如果重裝過系統想要恢復數據
# mv /var/lib/docker /var/lib/docker.bak
# mv /var/lib/containerd /var/lib/containerd.bak
ln -s /mnt/data/docker /var/lib/docker
ln -s /mnt/data/containerd /var/lib/containerd

systemctl start docker
systemctl start containerd

3. 安裝 Docker-compose ( 使用 pip3 因為 Github 上下載不到針對 Arm 的二進制包 )

apt install pip3 -y
apt install libffi-dev # 構建環境, 完成後可以卸載掉
pip3 install docker-compose
docker-compose -v

# 刪除構建緩存
rm -r ~/.cache/pip

4. 最後可以啟用 Overlay Filesystem + ReadOnly Boot Partition 了. 之後要是想裝東西可以直接使用 Docker, 改動會保存在外接硬碟中, 就算重裝系統也可以輕鬆恢復數據, 是目前我找到的最好的方案.

raspi-config

5月26日附: 在插拔 HDMI 线的时候不小心把电源也带出来了,赶紧插上,开机没发现任何问题,一分钟后博客恢复访问,lost+found下没添加任何文件。Overlay filesystem 确实是,高!

為官方 Nginx 鏡像安裝 Extras 插件

要用到 Nginx 的額外功能, 我需要安裝插件合集 nginx-extras . 但是官方 Nginx 鏡像並不提供插件功能, 而我也不想就為了這麽一個小功能就去用別人自己 Build 的鏡像, 鬼知道裡面有什麼東西.

我了解到 官方 Nginx, 如果沒有特殊指定的話, 是基於 Debian 的. 那麼在 Debian 裡面如果我想要安裝這個插件, 我只需要執行以下命令, 就可以用了

apt-get update && apt-get install -y nginx-extras

經過簡單的搜索, 我發現 Docker 提供 Dockerfile 的方法來構建自己的鏡像. 就是一個小腳本, 有點像 Git Actions 那樣的小腳本, 不過比那個還簡單.

Dockerfile Cheatsheet, 截取自 devhints.io

知道了 Dockerfile 怎麼使用之後, 就可以上手了

FROM nginx:latest
RUN apt-get update
RUN apt-get install -y nginx-extras
docker build -t nginx_extras .
docker image ls

因為我用了 Portainer, 我可以直接替換鏡像為我自己構建的 nginx_extras .

你也可以手動 rm 掉舊的容器然後用新的鏡像創建容器

到此為止, Nginx 已經可以用上這些插件了.

Docker 默認網段巨坑

簡單的紀錄一下我瞎搞Docker的時候碰到的一個坑:
我現在要配置一個Nginx, 跑在路由器上, 地址是 192.168.10.1 ;
我要用 Nginx 反向代理一個網站, 跑在這個局域網裡面, 地址是 192.168.10.10
這其實根本就超簡單, 正常情況下沒有 Docker, 我們就直接編輯 /etc/nginx/conf.d/default.conf, 然後在裡面扔以下配置, 就直接 Ok (緩存啥的都有照顧到, 我就拿這個作為模板)

server {
    listen 80;
    listen 443 ssl http2;
    server_name 127.0.0.1;

    ssl_certificate /etc/ssl/fullchain.pem;
    ssl_certificate_key /etc/ssl/private.key;
    ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    add_header Strict-Transport-Security "max-age=31536000";
    error_page 497 https://$host$request_uri;


    location / {
        proxy_pass https://justin.education;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header REMOTE-HOST $remote_addr;

        add_header X-Cache $upstream_cache_status;

        #Set Nginx Cache

        proxy_set_header Accept-Encoding "";
        sub_filter "http://192.168.10.10" "https://192.168.10.1";
        sub_filter "https://192.168.10.10" "https://192.168.10.1";
        sub_filter_once off;


        proxy_ignore_headers Set-Cookie Cache-Control expires;
        proxy_cache_key $host$uri$is_args$args;
        proxy_cache_valid 200 304 301 302 10m;
    }
}

然後就一直提示我 502 Bad Gateway, 我就 …

光看截圖你就知道我該有多 Mad

愣是浪費我整整一個小時時間來檢查哪裡有問題, 所以說思維定勢真的不可取, 你說他每次用都好好的, 怎麼一到 Docker 上面就出問題?

不過萬幸的是我想起來起看了一眼日誌 (日誌一定得看啊) , 然後發現一直提示訪問 172.17.0.1 報錯…

於是我去谷歌上面搜了一下 鏈接 , 發現 172.17.0.1/16 是 Docker 自己的一個網段, 是通過 NAT 橋接到 Host 網絡的.

這就… 怪不得. 都不在一個網段裡面, 訪問得到才有鬼

知道就好辦, 直接在 Portainer 裡面從 Bridge 改為 Host 就解決了問題.

Docker 日誌塞滿服務器修復

早晨我例行的摸了一下鏈接到樹莓派的硬盤,結果發現它不轉了。Nani?
於是我立即嘗試登錄寶塔面板,結果發現卡在登錄頁面。
使用SSH重啓之後根本重連不上,網關提示根本沒給它分配IP,就是說它現在不能聯網。
我把樹莓派強制斷電後插電,可以連上了,但是提示的消息卻讓我比較震驚…

空間佔用 100% ?

於是我決心把他弄懂。

問題初步排查

首先肯定是要確定磁盤佔用是這樣…

$ df -h

Filesystem                                     Size  Used Avail Use% Mounted on
tmpfs                                          782M   60M  723M   8% /run
/dev/mmcblk0p2                                 117G  117G     0 100% /
tmpfs                                          3.9G     0  3.9G   0% /dev/shm
tmpfs                                          5.0M     0  5.0M   0% /run/lock
tmpfs                                          4.0M     0  4.0M   0% /sys/fs/cgroup
/dev/mmcblk0p1                                 253M  152M  101M  60% /boot/firmware
/dev/sda1                                      916G   95G  776G  11% /media/backup
tmpfs                                          782M  4.0K  782M   1% /run/user/0

是這樣沒錯,然後要定位到主目錄,看看到底那個文件夾出了問題。

$ cd /
$ du -h -x --max-depth=1 

74M    ./home
2.9G    ./usr
8.0K    ./.disk
24K    ./snap
4.0K    ./mnt
4.0K    ./srv
114M    ./root
72K    ./tmp
117M    ./boot
16K    ./opt
8.0K    ./patch
6.1M    ./etc
4.0K    ./media
4.1G    ./www
110G    ./var       <- 問題根源
16K    ./lost+found
117G    .

經過一番定位之後,現在可以發現問題的根源在這個文件夾裏:

/var/lib/docker/containers/6c8a****13f4/

進一步定位那個文件出了問題:

$ ll


total 112907424
drwx------ 4 root root         4096 Jan  7 04:41 ./
drwx------ 4 root root         4096 Feb  3 21:06 ../
-rw-r----- 1 root root 115617058816 Feb 18 13:05 6c8a****13f4-json.log
drwx------ 2 root root         4096 Feb  3 16:33 checkpoints/
-rw------- 1 root root         3958 Jan  7 04:41 config.v2.json
-rw-r--r-- 1 root root         1513 Jan  7 04:41 hostconfig.json
-rw-r--r-- 1 root root           13 Feb  5 13:29 hostname
-rw-r--r-- 1 root root          174 Feb  5 13:29 hosts
drwx------ 3 root root         4096 Feb  3 16:33 mounts/
-rw-r--r-- 1 root root          612 Feb  5 13:29 resolv.conf
-rw-r--r-- 1 root root           71 Feb  5 13:29 resolv.conf.hash

恐怖的發現…這個日誌文件竟然佔了這麼多的大小…

修復問題

看了一下日誌,整個日誌基本全是 P2P文件交換的記錄。
離譜的是這個日誌居然是以毫秒記錄的,有的地方甚至一毫秒幾十行…這個樹莓派是怎麼支撐過來的?
因爲沒有值得注意的東西,我就直接 rm 掉了。瞬間執行,滿足感還是很高的, WinServer不知道刪到猴年馬月去。
(Ext4文件系統刪除文件時並沒有對數據進行操作,我的理解中是將記錄文件信息的索引釋放掉了,在系統的想法裏這片空間又變回可寫的了)

$ df -h

Filesystem                                     Size  Used Avail Use% Mounted on
tmpfs                                          782M   79M  703M  11% /run
/dev/mmcblk0p2                                 117G  9.3G  103G   9% /
tmpfs                                          3.9G     0  3.9G   0% /dev/shm
tmpfs                                          5.0M     0  5.0M   0% /run/lock
tmpfs                                          4.0M     0  4.0M   0% /sys/fs/cgroup
/dev/mmcblk0p1                                 253M  152M  101M  60% /boot/firmware
/dev/sda1                                      916G   95G  776G  11% /media/backup
tmpfs                                          782M  4.0K  782M   1% /run/user/0

很好,空間佔用回到正常了。

防止問題重複

既然知道了是日誌文件的問題,現在就要搞清楚到底那個容器出了問題。

$ docker ps -a

CONTAINER ID        IMAGE
84e1a7934eb6        linuxserver/syncthing:latest
6c8a506e5aca        linuxserver/resilio-sync:latest

現在就知道哪裡出現問題了。可以看到,resilio-sync 的id對應了那個日誌文件的開頭。

我更改了resilio sync中的設置,分別更改爲

log_size = 0
log_ttl = 0
disk_low_priority = true

希望這樣可以有效果,我會在幾天後再來查看。

实测这样子并没有效果,看起來是Docker鏡像製作時留下來的問題, 直接在容器裡更改配置不起作用.

那這不簡單.

docker pause ResilioSync
rm 6c8a****13f4-json.log
ln -s /dev/null 6c8a****13f4-json.log
$ ll

總計 36K
drwx------ 2 root root 4.0K  1月  1  2038 checkpoints
-rw------- 1 root root 4.9K  5月  5 10:25 config.v2.json
lrwxrwxrwx 1 root root    9  5月  5 10:26 6c8a****13f4-json.log -> /dev/null
-rw-r--r-- 1 root root 2.2K  5月  5 10:25 hostconfig.json
-rw-r--r-- 1 root root   13  5月  4 22:14 hostname
-rw-r--r-- 1 root root  174  5月  4 22:14 hosts
drwx-----x 2 root root 4.0K  1月  1  2038 mounts
-rw-r--r-- 1 root root   61  5月  4 22:14 resolv.conf
-rw-r--r-- 1 root root   71  5月  4 22:14 resolv.conf.hash
docker unpause ResilioSync

问题到此解决

沒解決.

這樣做之後確實一時爽, 但是過了一天我回來看, 發現容器停止運行, 原因是

/mnt/data/docker/containers/6c8a****13f4-json.log/dev/null no file or directory

所以問題到底怎麼解決呢?

經過一番搜索(現在才想起來有谷歌這回事)之後, 我得到了結果, 問題完美解決.

原來是可以通過配置 docker-compose 來限制logsize的, 比如說我要限制 nginx 的 logsize 為5g, 我可以

nginx: 
  image: 
  restart: always 
  logging: 
    driver: “json-file” 
    options: 
      max-size: “5g” 

那麼我是用portainer管理docker的, 我可以

問題到此真正完美解決.

MacArm 用 Docker 安裝 WebAssembly 環境

需求

我正在配置 Qt wasm環境,
但是 emsdk 不支持 apple m1 issue 769 使用 Homebrew 安裝的 emsdk 一直報錯,
沒找到源碼編譯的 Guide 只好使用 Docker.

環境
MacOS Bigsur M1, nodejs

安裝 Docker Arm

官網指南: 點擊前往

根據官網的描述, Docker 是使用了 QEMU 來虛擬出 AMD/x86 的環境, 反正能正常工作.

首先需要安裝 Rosetta2, 應該都已經有了

 softwareupdate --install-rosetta

然後點擊下載 Docker Desktop RC3, 簡單的安裝後啟動, 會要求獲取 root 權限.

點擊 settings - Docker Engine, 在頁面中間的框框裡面加入這麼一行, 配置科大鏡像:

  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn/"
  ],
Docker 鏡像源的配置

至此, Docker 配置完畢了.

安裝 emsdk

emscripten/emsdk : Docker Hub

以上是兩個所需鏡像, 第二個是可選項. 如果你不是配合 qt 使用的話, 只選第一個就可以了.

但是如果你要配合 qt 使用, 兩個都得裝, 原因會在下文提及.

首先先 拉取 emsdk 的鏡像, 根據 Qt官網 的描述, 我需要的版本是 1.39.8 , 所以我的命令是:

docker pull emscripten/emsdk:1.39.8

沒有特殊要求的話, 後面的 :1.39.8 可以改成 :latest, 或者根本不加, 直接拉取最新版本.

測試一下鏡像:

cd /tmp

# create helloworld.cpp
cat << EOF > helloworld.cpp
#include <iostream>
int main() {
  std::cout << "Hello World!" << std::endl;
  return 0;
}
EOF

# compile with docker image
docker run \
  --rm \
  -v $(pwd):$(pwd) \
  -u $(id -u):$(id -g) \
  emscripten/emsdk \
  emcc helloworld.cpp -o helloworld.js

# execute on host machine
node helloworld.js

如果看到 輸出 Hello World! 的話, 配置成功了.

設置快捷方式

每次使用打這麼一大串肯定不現實, 一般的思路是寫一個別名:

# vim ~/.zshrc
alias emcc='docker run \
  --rm \
  -v $(pwd):$(pwd) \
  -u $(id -u):$(id -g) \
  emscripten/emsdk \
  emcc'
alias em++='docker run \
  --rm \
  -v $(pwd):$(pwd) \
  -u $(id -u):$(id -g) \
  emscripten/emsdk \
  em++'

# 應用配置
source ~/.zshrc

這樣手敲就沒問題了, 但是用諸如 vscode 之類的工具配置環境會比較煩, 更加穩妥的方式是將其寫進 bash 腳本裡面:

echo '#!/bin/bash
/usr/local/bin/docker run \
  --rm \
  -v $(pwd):$(pwd) \
  -u $(id -u):$(id -g) \
  emscripten/emsdk \
  emcc $*' > /usr/local/bin/emcc

echo '#!/bin/bash
/usr/local/bin/docker run \
  --rm \
  -v $(pwd):$(pwd) \
  -u $(id -u):$(id -g) \
  emscripten/emsdk \
  em++ $*' > /usr/local/bin/em++

sudo chmod +x /usr/local/bin/emcc
sudo chmod +x /usr/local/bin/em++

至此, emsdk 的安裝已經基本完成.