Nginx 自建CDN加速个人博客

首先我的博客服务器目前在美国,至于为什么在美国呢,因为便宜(黑五买的便宜VPS),但因为距离较远,博客的打开速度一直不理想(其实挂了Cloudflare我这个地区的打开速度还行,但有些地区很慢)。所以我就想自己搭建一个CDN来加速博客,我查了一下GitHub中的开源CDN项目也挺多的,但是对服务器要求有些高,并且我的微软学生免费账户的额度不是很高(这里感谢小费支援了一台香港服务器),所以我就选择直接使用Nginx来加速我的博客。

选择节点VPS

如果你有钱,请随便选…

节点docker安装

$ curl -fsSL https://get.docker.com -o get-docker.sh
$ sh get-docker.sh
如果你不想用 docker 请自行安装 nginx

docker-compose.yml

version: '3'
services:
  nginx:
    deploy:
      resources:
        limits:
          memory: 300M
    image: tengine:my
    #image: nginx:latest
    restart: always
    container_name: nginx
    ports:
      - '80:80'
      - '443:443'
    volumes:
      - ./nginx/logs:/etc/nginx/logs
      - ./nginx/certs:/etc/nginx/certs
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/web.conf:/etc/nginx/conf.d/web.conf
      - ./www:/www
      - ./nginx/hosts:/etc/hosts

tengine:my 是我将 ngx_cache_purge 模块添加进 tengine 生成的镜像

修改tengine的Dockerfile文件添加 ngx_cache_purge 模块

未修改tengine项目地址

修改的 Dockerfile

FROM alpine:3.16


ENV TENGINE_VERSION 2.3.3
ENV NGX_CACHE_PURGE_VERSION=2.3
# nginx: https://git.io/vSIyj

RUN rm -rf /var/cache/apk/* && \
    rm -rf /tmp/*

ENV CONFIG "\
        --prefix=/etc/nginx \
        --sbin-path=/usr/sbin/nginx \
        --modules-path=/usr/lib/nginx/modules \
        --conf-path=/etc/nginx/nginx.conf \
        --error-log-path=/var/log/nginx/error.log \
        --http-log-path=/var/log/nginx/access.log \
        --pid-path=/var/run/nginx.pid \
        --lock-path=/var/run/nginx.lock \
        --http-client-body-temp-path=/var/cache/nginx/client_temp \
        --http-proxy-temp-path=/var/cache/nginx/proxy_temp \
        --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
        --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
        --http-scgi-temp-path=/var/cache/nginx/scgi_temp \
        --user=nginx \
        --group=nginx \
        --with-http_ssl_module \
        --with-http_realip_module \
        --with-http_addition_module \
        --with-http_sub_module \
        --with-http_dav_module \
        --with-http_flv_module \
        --with-http_mp4_module \
        --with-http_gunzip_module \
        --with-http_gzip_static_module \
        --with-http_random_index_module \
        --with-http_secure_link_module \
        --with-http_stub_status_module \
        --with-http_auth_request_module \
        --with-http_xslt_module=dynamic \
        --with-http_image_filter_module=dynamic \
        --with-http_geoip_module=dynamic \
        --with-threads \
        --with-stream \
        --with-stream_ssl_module \
        --with-stream_ssl_preread_module \
        --with-stream_realip_module \
        --with-stream_geoip_module=dynamic \
        --with-http_slice_module \
        --with-mail \
        --with-mail_ssl_module \
        --with-compat \
        --with-file-aio \
        --with-http_v2_module \
        --add-module=/usr/src/ngx_cache_purge \
        --add-module=modules/ngx_http_upstream_check_module \
        --add-module=modules/headers-more-nginx-module-0.33 \
        --add-module=modules/ngx_http_upstream_session_sticky_module \
        "
RUN     addgroup -S nginx \
        && adduser -D -S -h /var/cache/nginx -s /sbin/nologin -G nginx nginx \
        && adduser -u 82 -D -S -G www-data www-data \
        && apk add --no-cache --virtual .build-deps \
                gcc \
                libc-dev \
                make \
                openssl-dev \
                pcre-dev \
                zlib-dev \
                linux-headers \
                curl \
                libxslt-dev \
                gd-dev \
                geoip-dev \
        && curl -L "https://github.com/alibaba/tengine/archive/$TENGINE_VERSION.tar.gz" -o tengine.tar.gz \
        && curl -fSL http://labs.frickle.com/files/ngx_cache_purge-$NGX_CACHE_PURGE_VERSION.tar.gz -o ngx_cache_purge.tar.gz \
        && mkdir -p /usr/src \
        && tar -zxC /usr/src -f tengine.tar.gz \
        && rm tengine.tar.gz \
&& tar -zxC /usr/src -f ngx_cache_purge.tar.gz \
    && mv /usr/src/ngx_cache_purge-$NGX_CACHE_PURGE_VERSION /usr/src/ngx_cache_purge \
    && rm ngx_cache_purge.tar.gz \
        && cd /usr/src/tengine-$TENGINE_VERSION \
        && curl -L "https://github.com/openresty/headers-more-nginx-module/archive/v0.33.tar.gz" -o more.tar.gz \
        && tar -zxC /usr/src/tengine-$TENGINE_VERSION/modules -f more.tar.gz \
        && rm  more.tar.gz \
        && ls -l /usr/src/tengine-$TENGINE_VERSION/modules \
        && ./configure $CONFIG --with-debug \
        && make -j$(getconf _NPROCESSORS_ONLN) \
        && mv objs/nginx objs/nginx-debug \
        && mv objs/ngx_http_xslt_filter_module.so objs/ngx_http_xslt_filter_module-debug.so \
        && mv objs/ngx_http_image_filter_module.so objs/ngx_http_image_filter_module-debug.so \
        && mv objs/ngx_http_geoip_module.so objs/ngx_http_geoip_module-debug.so \
        && mv objs/ngx_stream_geoip_module.so objs/ngx_stream_geoip_module-debug.so \
        && ./configure $CONFIG \
        && make -j$(getconf _NPROCESSORS_ONLN) \
        && make install \
        && rm -rf /etc/nginx/html/ \
        && mkdir /etc/nginx/conf.d/ \
        && mkdir -p /usr/share/nginx/html/ \
        && install -m644 html/index.html /usr/share/nginx/html/ \
        && install -m644 html/50x.html /usr/share/nginx/html/ \
        && install -m755 objs/nginx-debug /usr/sbin/nginx-debug \
        && install -m755 objs/ngx_http_xslt_filter_module-debug.so /usr/lib/nginx/modules/ngx_http_xslt_filter_module-debug.so \
        && install -m755 objs/ngx_http_image_filter_module-debug.so /usr/lib/nginx/modules/ngx_http_image_filter_module-debug.so \
        && install -m755 objs/ngx_http_geoip_module-debug.so /usr/lib/nginx/modules/ngx_http_geoip_module-debug.so \
        && install -m755 objs/ngx_stream_geoip_module-debug.so /usr/lib/nginx/modules/ngx_stream_geoip_module-debug.so \
        && ln -s ../../usr/lib/nginx/modules /etc/nginx/modules \
        && strip /usr/sbin/nginx* \
        && strip /usr/lib/nginx/modules/*.so \
        && rm -rf /usr/src/tengine-$NGINX_VERSION \
        \
        # Bring in gettext so we can get `envsubst`, then throw
        # the rest away. To do this, we need to install `gettext`
        # then move `envsubst` out of the way so `gettext` can
        # be deleted completely, then move `envsubst` back.
        && apk add --no-cache --virtual .gettext gettext \
        && mv /usr/bin/envsubst /tmp/ \
        \
        && runDeps="$( \
                scanelf --needed --nobanner --format '%n#p' /usr/sbin/nginx /usr/lib/nginx/modules/*.so /tmp/envsubst \
                        | tr ',' '\n' \
                        | sort -u \
                        | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
        )" \
        && apk add --no-cache --virtual .nginx-rundeps $runDeps \
        && apk del .build-deps \
        && apk del .gettext \
        && mv /tmp/envsubst /usr/local/bin/ \
        \
        # Bring in tzdata so users could set the timezones through the environment
        # variables
        && apk add --no-cache tzdata \
        \
        # forward request and error logs to docker log collector
        && ln -sf /dev/stdout /var/log/nginx/access.log \
        && ln -sf /dev/stderr /var/log/nginx/error.log

COPY nginx.conf /etc/nginx/nginx.conf

EXPOSE 80 443

STOPSIGNAL SIGTERM

CMD ["nginx", "-g", "daemon off;"]

创建镜像

docker build -t tengine:my .

镜像创建完成后,需要编写配置文件,目前路径结构

├── docker-compose.yml
├── nginx
│   ├── certs
│   │   ├── domain.crt
│   │   ├── domain_nopass.key
│   │   ├── fullchain.pem
│   │   └── privkey.pem
│   ├── hosts
│   ├── logs
│   │   ├── access.log
│   │   ├── error.log
│   │   └── ip_access.log
│   ├── nginx.conf
│   └── web.conf
└── tengine
    ├── Dockerfile
    ├── README.md
    ├── example.com.conf
    └── nginx.conf

其中 nginx.conf

user  nginx;
# This number should be, at maximum, the number of CPU cores on your system.
worker_processes auto;

error_log  /etc/nginx/logs/error.log error;
pid        /var/run/nginx.pid;

events {
    # The effective method, used on Linux 2.6+, optmized to serve many clients with each thread.
    use epoll;
    # Determines how many clients will be served by each worker process.
    worker_connections 4000;
    # Accept as many connections as possible, after nginx gets notification about a new connection.
    multi_accept on;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    #long time
    #check_shm_size 5M;
    # Allow the server to close the connection after a client stops responding.
    reset_timedout_connection on;
    client_header_timeout 15;
    # Send the client a "request timed out" if the body is not loaded by this time.
    client_body_timeout 10;
    # If the client stops reading data, free up the stale client connection after this much time.
    send_timeout 15;
    # Timeout for keep-alive connections. Server will close connections after this time.
    keepalive_timeout 30;
    # Number of requests a client can make over the keep-alive connection.
    keepalive_requests 30;

    log_format  main    '[$http_x_forwarded_for] $remote_addr - $remote_user [$time_local] "$request" '
                        '$status $body_bytes_sent "$http_referer" '
                        '"$http_user_agent" "$http_x_forwarded_for"';


    client_body_buffer_size 128k;
    client_max_body_size 10m;
    proxy_read_timeout 180s;
    # Compression.
    gzip on;
    gzip_min_length 10240;
    gzip_proxied expired no-cache no-store private auth;
    gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml;
    gzip_disable "msie6";

    limit_conn_zone $binary_remote_addr zone=perip:10m;
    limit_conn_zone $server_name zone=perserver:10m;
    # Sendfile copies data between one FD and other from within the kernel.
    sendfile on;
    # Don't buffer data-sends (disable Nagle algorithm).
    tcp_nodelay on;
    # Causes nginx to attempt to send its HTTP response head in one packet,  instead of using partial frames.
    tcp_nopush on;
    # Hide web server information
    server_tokens off;
    #server_info off;
    #server_tag off;

    # redirect server error pages to the static page
    error_page 404             /404.html;
    error_page 500 502 503 504 /50x.html;
    map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
                }
    server {
     listen 80 default_server;
     listen 443 ssl default_server;
     server_name _ ;
     ssl on;
     ssl_certificate    /etc/nginx/certs/domain.crt;
     ssl_certificate_key /etc/nginx/certs/domain_nopass.key;
     access_log  /etc/nginx/logs/ip_access.log main;


return 444;
}
    include /etc/nginx/conf.d/*.conf;
}

web.conf

proxy_connect_timeout 5;
proxy_send_timeout 5;
proxy_buffer_size 16k;
proxy_buffers 4 64k;
proxy_busy_buffers_size 128k;
proxy_temp_file_write_size 128k;

proxy_cache_path /etc/nginx/data levels=1:2 keys_zone=enjoy:500m inactive=300m max_size=500m;
proxy_temp_path /etc/nginx/temp;
proxy_cache_key $request_uri;

server {
    listen 80;
    listen 443 ssl;
    server_name mcenjoy.cn www.mcenjoy.cn;
    limit_conn perserver 300;
    limit_conn perip 25;
    limit_rate 512k;
    #HTTP_TO_HTTPS_START
    if ($server_port !~ 443){
        rewrite ^(/.*)$ https://$host$1 permanent;
    }
    ssl on;
    # 启用OCSP stapling
    #ssl_stapling on;
    # valid表示缓存5分钟,resolver_timeout表示网络超时时间
    resolver 127.0.0.11 valid=300s;
    resolver_timeout 5s;
    # 启用OCSP响应验证,OCSP信息响应适用的证书
    # ssl_stapling_verify on;
    # ssl_trusted_certificate     /etc/nginx/certs/fullchain.pem;
    ssl_certificate             /etc/nginx/certs/fullchain.pem;
    ssl_certificate_key         /etc/nginx/certs/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
    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;
    set $skip_cache 0;
    #post访问不缓存
    if ($request_method = POST) {
        set $skip_cache 1;
    }
    #动态查询不缓存
    if ($query_string != "") {
#        set $skip_cache 1;
    }
    #后台等特定页面不缓存(其他需求请自行添加即可)
    if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
        set $skip_cache 1;
    }
    if ($query_string ~* "preview=true") {
        set $skip_cache 1;
    }
    #对登录用户、评论过的用户不展示缓存
    if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
#        set $skip_cache 1;
    }

    location / {
        proxy_pass https://<源服务器ip>/;
        proxy_ssl_verify_depth 0;
        proxy_next_upstream error;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_cache_valid  200 304  60m;
        proxy_cache_valid  301 24h;
        proxy_cache_valid  500 502 503 504 0s;
        proxy_cache_valid any 1s;
        proxy_cache enjoy;
        proxy_redirect off;
        proxy_cache_min_uses 1;
        proxy_cache_bypass $skip_cache;
        expires 12h;
        add_header X-Cache $upstream_cache_status;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Host $http_host;
        proxy_set_header X-Forwarded-For $http_x_forwarded_for;
        proxy_set_header X-URI $uri;
        proxy_set_header X-ARGS $args;
        proxy_set_header Refer $http_refer;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
    location ~ /clear_cache(/.*) {
        allow <你的源服务器IP>;
        deny all;
        proxy_cache_purge enjoy $1$is_args$args;
    }
    access_log  /etc/nginx/logs/access.log main;
    #access_log syslog:server=127.0.0.1:9996 main;
    #error_log  /etc/nginx/logs/error.log;
}

上面请自行修改你需要的缓存配置,certs文件夹为证书存放的文件夹,请自行添加

配置完成后就可以直接启动node节点了

docker compose up -d

启动完成就可以访问了,你可以修改系统的 hosts 文件来测试节点的工作情况

当你访问几次页面后,查看响应标头,会出现 HIT 就表示目前节点缓存工作良好

DNS解析配置

目前我使用腾讯的dnspod进行配置,国外使用Cloudflare加速,国内电信选择香港节点,其他线路随机

缓存更新

因为前面对请求接口的IP进行了限制,目前我们可以使用源服务器访问节点的接口进行手动缓存更新,此时假如我们更新头像缓存

curl -k -H "host: mcenjoy.cn" -I https://******/clear_cache/avatar
注意
200表示更新缓存成功
404表示缓存并不存在

自动化更新缓存

后面因为涉及到wordpress插件的修改,我们单独再写一篇文章
广告 广告位招租

评论

  1. Windows Chrome
    广东省广州市
    3周前
    2022-9-03 13:17:34

    感觉是我一直要找的东西,以后有时间研究一下。谢谢分享!

  2. Windows Chrome
    山东省淄博市
    1月前
    2022-8-19 15:56:15

    感谢分享,赞一个

  3. Macintosh Firefox
    广东省深圳市
    1月前
    2022-8-17 0:55:01

    不错呀,用 Nginx 自建 CDN,不过为啥把 OCSP Stapling 注释掉呢?

    • Avatar photo
      enjoy
      博主
      二花
      Android Firefox
      贵州省
      1月前
      2022-8-17 8:06:37

      因为之前服务器dns出现问题,在调试的时候注释掉了,用的时候可以取消注释,加快客户端访问欧~

发送评论 编辑评论


|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
小黄脸
上一篇
下一篇