Blog

  • Best VPN One Liner Setup

    Have been testing multiple VPN setups that can work in China and this one works best from my testing: https://github.com/233boy/v2ray

    Prerequisite

    • Ubuntu 22

    Quick start

    If NOT logged in as root, please run below command:

    sudo -s

    Now run below to complete setup:

    bash <(wget -qO- -o- https://git.io/v2ray.sh)

    It will generate vmess URL where you can copy and use in clients

    Clients

    • IOS
      • Shadowrocket
    • MacOS
      • V2Box

  • Regular Expression Benchmark – Which Language Is The Best?

    Source: https://github.com/mariomka/regex-benchmark

    As of today, here is the result:

    Docker image was run on: MacBook Pro (16-inch, 2019), 2.4 GHz Intel Core i9, 32 GB 2667 Mhz DDR4 with macOS Big Sur 11.2.3.

    LanguageEmail(ms)URI(ms)IP(ms)Total(ms)
    Nim Regex1.3226.927.8436.09
    Nim22.7021.496.7550.94
    Rust26.6625.705.2857.63
    PHP42.8746.305.1794.33
    C++ Boost44.9744.1315.13104.23
    Javascript59.0047.231.50107.73
    Perl94.9263.9620.37179.25
    Julia104.5886.555.01196.14
    C PCRE2126.10112.1713.10251.37
    Crystal128.19112.7013.18254.07
    C# .Net Core115.05106.0542.71263.81
    Dart104.10107.6476.51288.25
    D ldc165.46165.204.85335.51
    D dmd187.94189.925.32383.18
    Ruby233.88208.8543.14485.86
    Python PyPy2158.34139.70253.77551.81
    Dart Native278.54307.545.77591.85
    Python 2197.92131.74294.42624.08
    Kotlin186.20223.05287.49696.74
    Java198.33221.87287.81708.01
    Python PyPy3258.78221.89257.35738.03
    Python 3273.86190.79319.13783.78
    Go248.14241.28360.90850.32
    C++ STL433.09344.74245.661023.49
    C# Mono2859.052431.87145.825436.75

    Optimized

    The following results are for the optimized version.

    LanguageEmail(ms)URI(ms)IP(ms)Total(ms)
    Rust11.4311.405.1127.94
    Nim Regex1.3725.517.2734.15
    Nim22.7921.646.7751.21
    C PCRE246.2236.924.7387.87
    PHP43.1846.715.2395.12
    C++ Boost44.6844.5015.10104.28
    Javascript59.2047.671.61108.48
    C# .Net Core61.7647.8611.63121.25
    Perl96.0063.3920.59179.99
    Julia104.3187.985.16197.45
    Crystal129.52116.3313.12258.97
    Dart105.82107.7878.18291.78
    D ldc167.60165.715.07338.37
    D dmd187.66192.165.55385.37
    Ruby236.93206.5143.70487.14
    Python PyPy2161.33143.56258.06562.96
    Dart Native273.17306.145.89585.20
    Python 2200.54132.89290.26623.69
    Kotlin184.13220.31273.76678.21
    Java190.74223.77275.24689.75
    Python PyPy3268.41226.74261.17756.32
    Python 3273.70194.09322.09789.88
    Go244.14238.40365.27847.81
    C++ STL433.18341.07246.851021.10
    C# Mono1400.041189.50145.732735.28
  • Different Type Of Ad Blocking Software

    There are several types of ad blocking software available, each with its own approach to filtering out unwanted advertisements. Here are the main categories:

    Browser extensions

    Browser extensions are the most common type of ad blockers. They integrate directly into web browsers and filter content as pages load.

    Popular examples include:

    • AdBlock/AdBlockPlus: owned by eyeo, which are most popular ad blocking browser extensions.
      • eyeo does offer Acceptable Ads program which is a paid service to allowlist some ads.
    • uBlock Origin: fully open source and block ads extensively without compromise.
    • AdGuard: Cross-platform solutions

    Pros

    • Easy to install and use
    • Often free or low-cost
    • Can be quickly enabled/disabled with a few clicks
    • Regularly updated by developers
    • Highly customizable, allowing fine-grained control over blocked content
    • Can block ads http request as well as page html elements

    Cons

    • Only work within the specific browser they’re installed in
    • May need to be installed separately for each browser used
    • Some extensions can access sensitive browsing data
    • Potential for ownership changes or compromised developers

    Desktop applications

    These are standalone programs that run independently of the browser, often blocking ads across multiple applications.

    Popular examples include:

    • AdGuard: Cross-platform solutions. Available for Windows and Mac.
    • AdLock: Runs as a separate program to block ads in browsers and other applications like Skype or games.

    Pros

    • Block ads across multiple applications, not just browsers
    • Often include additional security features
    • Can protect against malicious websites and tracking
    • Some offer parental control features

    Cons

    • Require installation and configuration on each device
    • May need manual disabling when interfering with legitimate content
    • Often come with a cost for full features

    Mobile Ad Blockers

    Ad blocking solutions designed specifically for mobile devices:

    Popular examples include:

    • AdGuard: Cross-platform solutions. Available for iOS and Andriod.
    • AdBlock Browser for Android.

    Pros

    • Designed specifically for mobile devices
    • Can block ads in apps as well as browsers
    • Often include privacy-enhancing features

    Cons

    • May not be as comprehensive as desktop solutions
    • Can be limited by mobile operating system restrictions
    • Some require rooting or jailbreaking for full functionality

    VPN-based ad blockers

    A lot of VPN services include ad blocking features as part of their offering, like ExpressVPN, NordVPN and etc. They usually block ads through network requests across different type of applications.

    Pros

    • Block ads at the network level
    • Provide additional privacy and security benefits of a VPN
    • Work across all applications and browsers

    Cons

    • Generally less effective at blocking ads than dedicated solutions
    • May slow down internet connection due to VPN routing
    • Often more expensive than standalone ad blockers

    Browser with build-in ad blocking features

    Some browsers come with built-in ad blocking capabilities:

    • Opera: Includes ad blocking features without the need for additional extensions
    • Brave: A free browser with built-in ad blocking for desktop and mobile devices

    Pros

    • No need for additional installations
    • Integrated into the browser’s security features
    • Often optimized for performance

    Cons

    • Usually less customizable than third-party solutions
    • May not be as comprehensive in ad blocking
    • Limited to the specific browser with built-in blocking
  • Setup Multiple WordPress Sites Using Docker Compose (Traefik + MariaDB)

    Prerequisite

    Run below CLI to check if everything is installed properly.

    docker compose version

    Setup Traefik with Docker Compose

    Let’s first create a folder for Traefik reverse proxy.

    mkdir ~/traefik && cd ~/traefik

    Next we need to create network for Traefik to communicate with other containers, and it should be exposed externally.

    docker create network traefik

    Now, let’s create docker-compose.yml

    vi docker-compose.yml
    networks:
      traefik:
        external: true
    
    volumes:
      traefik-certificates:
    
    services:
      traefik:
        image: "traefik:latest"
        command:
          - "--log.level=DEBUG"
          - "--accesslog=true"
          - "--api.dashboard=true"
          - "--api.insecure=true"
          - "--ping=true"
          - "--ping.entrypoint=ping"
          - "--entryPoints.ping.address=:8082"
          - "--entryPoints.web.address=:80"
          - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
          - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
          - "--entryPoints.websecure.address=:443"
          - "--providers.docker=true"
          - "--providers.docker.endpoint=unix:///var/run/docker.sock"
          - "--providers.docker.exposedByDefault=false"
          - "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
          # For requesting dev cert (if prod cert has issue during development)
          # - "--certificatesresolvers.myhttpchallenge.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
          - "--certificatesresolvers.letsencrypt.acme.email=admin@bill-min.com"
          - "--certificatesresolvers.letsencrypt.acme.storage=/etc/traefik/acme/acme.json"
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
          - traefik-certificates:/etc/traefik/acme
        networks:
          - traefik
        ports:
          - "80:80"
          - "443:443"
        healthcheck:
          test: ["CMD", "wget", "http://localhost:8082/ping","--spider"]
          interval: 10s
          timeout: 5s
          retries: 3
          start_period: 5s
        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.dashboard.rule=Host(`traefik.your-domain.com`)"
          - "traefik.http.routers.dashboard.service=api@internal"
          - "traefik.http.routers.dashboard.entrypoints=websecure"
          - "traefik.http.routers.dashboard.tls=true"
          - "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
          - "traefik.http.routers.dashboard.middlewares=authtraefik"
          - "traefik.http.middlewares.authtraefik.basicauth.users=your_username:{SHA}your_hash"
        restart: unless-stopped

    Above config also adds Traefik Dashboard and https with letsencrypt.

    Replace your-domain with your actual domain name and setup correct DNS.

    Replace your_username and {SHA}your_hash with ones generated from https://hostingcanada.org/htpasswd-generator/

    Finally, lets start Traefik container.

    docker compose up -d

    Verify the container is running successfully

    docker ps

    You can also check Traefik dashboard by visiting https://traefik.your-domain.com. (you will need to enter the username and password used when generating htpasswd)

    Setup first wordpress site

    First, we need to create an internal network for communicating between wordpress and db (MariaDB in this tutorial).

    docker create network my-wp-1

    Then lets create new folder for each site we are building.

    mkdir ~/my-wp-1 && cd ~/my-wp-1

    Create docker-compose.yml.

    networks:
      my-wp-1:
      traefik:
        external: true
     
    volumes:
      mariadb-data:
     
    services:
      mariadb:
        image: mariadb:latest
        volumes:
          - mariadb-data:/var/lib/mysql
        environment:
          MARIADB_DATABASE: ${WORDPRESS_DB_NAME}
          MARIADB_USER: ${WORDPRESS_DB_USER}
          MARIADB_PASSWORD: ${WORDPRESS_DB_PASSWORD}
          MARIADB_RANDOM_ROOT_PASSWORD: "1"
        networks:
          - my-wp-1
        healthcheck:
          test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
          interval: 10s
          timeout: 5s
          retries: 3
          start_period: 60s
        restart: unless-stopped
     
      wordpress:
        image: wordpress:latest
        volumes:
          - ./wordpress-files:/var/www/html
        environment:
          WORDPRESS_DB_HOST: mariadb:3306
          WORDPRESS_DB_USER: ${WORDPRESS_DB_USER}
          WORDPRESS_DB_PASSWORD: ${WORDPRESS_DB_PASSWORD}
          WORDPRESS_DB_NAME: ${WORDPRESS_DB_NAME}
        networks:
          - my-wp-1
          - traefik
        healthcheck:
          test: timeout 10s bash -c ':> /dev/tcp/127.0.0.1/80' || exit 1
          interval: 10s
          timeout: 5s
          retries: 3
          start_period: 90s
        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.my-wp-1.rule=Host(`${WORDPRESS_HOSTNAME}`)"
          - "traefik.http.routers.my-wp-1.service=my-wp-1"
          - "traefik.http.routers.my-wp-1.entrypoints=websecure"
          - "traefik.http.services.my-wp-1.loadbalancer.server.port=80"
          - "traefik.http.services.my-wp-1.loadbalancer.passhostheader=true"
          - "traefik.http.routers.my-wp-1.tls=true"
          - "traefik.http.routers.my-wp-1.tls.certresolver=letsencrypt"
          - "traefik.http.routers.my-wp-1.middlewares=compresstraefik"
          - "traefik.http.middlewares.compresstraefik.compress=true"
          - "traefik.docker.network=traefik"
        restart: unless-stopped
        depends_on:
          mariadb:
            condition: service_healthy

    Also we need to create .env file for setting up some variables. (Replace values with proper ones)

    WORDPRESS_HOSTNAME=www.your-domain.com
    WORDPRESS_DB_NAME=wordpressdb
    WORDPRESS_DB_USER=myuser
    WORDPRESS_DB_PASSWORD=mypassword

    Then we should be able to start wordpress.

    docker compose up -d

    Now we should be able to visit https://www.your-domain.com to start using WordPress.

    Create more wordpress sites

    Simply repeat the steps we used to create our first site to create more sites, just need to change my-wp-1 to different value in docker-compose.yml and change values in .env file then run docker compose up -d.