cloudflare / speedtest

Component to perform network speed tests against Cloudflare's edge network
https://speed.cloudflare.com
MIT License
385 stars 28 forks source link

Self-host on docker #13

Open jerrywoo96 opened 1 year ago

jerrywoo96 commented 1 year ago

Will there be a possibility of publishing an official docker image to self-host on our docker machines to check network speed to the docker machine from other devices?

vasturiano commented 1 year ago

@jerrywoo96 thanks for reaching out.

This module is only the client side where the measurements are initiated from (expected to run in a modern browser environment). By default it targets endpoints on the Cloudflare edge, but you can configure it to send requests against a different target, as long as they behave the same.

Please see the downloadApiUrl and uploadApiUrl fields on the docs.

jerrywoo96 commented 1 year ago

So, if this project contains only the files required to run on the browser side, May i know where can i get the server side files or project to self-host and run the endpoint server?

vasturiano commented 1 year ago

We use Cloudflare workers to host the target endpoints for download and upload requests.

You can find in this other repo a template of the workers code that includes the required endpoints.

jerrywoo96 commented 1 year ago

Will there be an opportunity for the team to create an all-in-one docker image that host the browser side files and the endpoint server? Such that it is deployment friendly in homelab environments. Apologies, I'm not well-versed with Cloudflare workers 😅.

For example,

https://hub.docker.com/r/openspeedtest/latest https://hub.docker.com/r/adolfintel/speedtest

Note: I've tried those 2, and am looking for other alternatives with enhancements, thus stumbled onto this project.

carlosefr commented 1 year ago

Whether or not Cloudflare provides such a self-hosted option in the future, you could most likely build one on your own combining the template @vasturiano mentioned with https://github.com/cloudflare/workerd.

The wrangler tool can run things locally, but with workerd you'd get a proper application server.

jamesthesken commented 11 months ago

Posting this here on the topic of self-hosted speedtest tools:

It was pretty straightforward to get the Cloudflare worker setup using the provided template. Purchased a domain and got routes setup to avoid any CORS issues.

My setup:

My configuration:

  const config = {
    autoStart: true,
    downloadApiUrl: "https://mydomain.com/down",
    uploadApiUrl: "https://mydomain.com/up",
    measurements: [
      { type: "latency", numPackets: 1 }, // initial latency estimation
      { type: "download", bytes: 1e5, count: 1, bypassMinDuration: true }, // initial download estimation
      { type: "latency", numPackets: 20 },
      { type: "download", bytes: 1e5, count: 9 },
      { type: "download", bytes: 1e6, count: 8 },
      { type: "upload", bytes: 1e5, count: 8 },
      { type: "packetLoss", numPackets: 1e3, responsesWaitTime: 3000 },
      { type: "upload", bytes: 1e6, count: 6 },
      { type: "download", bytes: 1e7, count: 6 },
      { type: "upload", bytes: 1e7, count: 4 },
      { type: "download", bytes: 2.5e7, count: 4 },
      { type: "upload", bytes: 2.5e7, count: 4 },
      { type: "download", bytes: 1e8, count: 3 },
      { type: "upload", bytes: 5e7, count: 3 },
      { type: "download", bytes: 2.5e8, count: 2 },
    ],
  };

However, there is still a sizable difference in download speeds on Safari based browsers when I test. I believe I still get the estimated results per #18 so maybe I am missing something.

Is the default configuration used on speed.cloudflare.com the same as in the readme? @carlosefr

Edit: I probably just have a misunderstanding of CORS and Cloudflare workers. When I look at the request headers in the Network inspector on Safari:

Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin

Would I want Sec-Fetch-Mode to be same-origin?

carlosefr commented 11 months ago

~The client version you're using, how recent is it? Does it include the fix in PR #18?~ I see from your previous comment that it does.

Is the client application running from the same domain as the up/down endpoints? Safari may send cross-domain requests through Private Relay when the "hide IP address from trackers" setting is enabled (which is the default).

jamesthesken commented 11 months ago

Thank you @carlosefr. The client application is on the same domain as the up/down endpoints. The client is hosted on Vercel, so I have an A record with that IP address and Proxy Status enabled.

I set up Worker routes to handle the up/down endpoints:

Screenshot 2023-07-03 at 8 15 11 AM

I do see that my site has 1 tracker cloudflare.com detected by Safari. How come speed.cloudflare.com does not do the same?

Thank you for your time.

carlosefr commented 11 months ago

I've tried your version in Chrome, Firefox, and Safari. The first two give identical results, but all of them show values significantly below those of speed.cloudflare.com (where I get identical values for all browsers, all matching my connection's specs).

There are a few things to take into consideration here...

When using this speedtest client against the default endpoints and using the default test configuration, the results should be the same as those reported by https://speed.cloudflare.com itself. If they aren't it might be a bug. The exception is Safari. Safari, by default, sends some cross-domain requests through Apple Private Relay and that will affect results.

To confirm this:

  1. Open Safari's Web Inspector;
  2. Go to the "Network" tab;
  3. Click on a cross-domain request;
  4. Look at the "Address" in "Headers -> Summary". Private Relay requests will end with "(Proxy)".

When using this speedtest client against custom endpoints (regardless of the test configuration), results may be impacted by many factors, including:

  1. The HTTP protocol used (e.g. the default endpoints currently use HTTP/1.1 to prevent browsers from multiplexing requests that measure latency and requests that measure throughput over the same logical connection);
  2. Where those endpoints are served from (if they're more distant, that will impact both latency and throughput);
  3. The amount of time the endpoints themselves take until the first byte is served (will impact latency numbers).

If you're self-hosting the reference worker implementation under workerd, then you can more or less control all of these factors with some additional effort — e.g. if your web server sends back a Server-Timing response header, the speedtest client will subtract its value when calculating latency.

If you're hosting the reference worker implementation in your own Cloudflare account, you should consider that the type of account will also affect where it's served from.

alexjustesen commented 11 months ago

Will there be an opportunity for the team to create an all-in-one docker image that host the browser side files and the endpoint server? Such that it is deployment friendly in homelab environments. Apologies, I'm not well-versed with Cloudflare workers 😅.

For example,

https://hub.docker.com/r/openspeedtest/latest https://hub.docker.com/r/adolfintel/speedtest

Note: I've tried those 2, and am looking for other alternatives with enhancements, thus stumbled onto this project.

If you're looking for something self-hosted, shameless plug to check out https://github.com/alexjustesen/speedtest-tracker. I've got integrating Cloudflare Speedtest on the to-do list.

jerrywoo96 commented 11 months ago

Will there be an opportunity for the team to create an all-in-one docker image that host the browser side files and the endpoint server? Such that it is deployment friendly in homelab environments. Apologies, I'm not well-versed with Cloudflare workers 😅.

For example,

https://hub.docker.com/r/openspeedtest/latest https://hub.docker.com/r/adolfintel/speedtest

Note: I've tried those 2, and am looking for other alternatives with enhancements, thus stumbled onto this project.

If you're looking for something self-hosted, shameless plug to check out https://github.com/alexjustesen/speedtest-tracker. I've got integrating Cloudflare Speedtest on the to-do list.

I've came across b4, but this topic is about measuring speed between self-hosted server and client devices. If i'm not wrong, the project u linked to is measuring speed between self-hosted server to ookla servers yup?

jamesthesken commented 11 months ago

I've tried your version in Chrome, Firefox, and Safari. The first two give identical results, but all of them show values significantly below those of speed.cloudflare.com (where I get identical values for all browsers, all matching my connection's specs).

There are a few things to take into consideration here...

When using this speedtest client against the default endpoints and using the default test configuration, the results should be the same as those reported by https://speed.cloudflare.com itself. If they aren't it might be a bug. The exception is Safari. Safari, by default, sends some cross-domain requests through Apple Private Relay and that will affect results.

To confirm this:

  1. Open Safari's Web Inspector;
  2. Go to the "Network" tab;
  3. Click on a cross-domain request;
  4. Look at the "Address" in "Headers -> Summary". Private Relay requests will end with "(Proxy)".

When using this speedtest client against custom endpoints (regardless of the test configuration), results may be impacted by many factors, including:

  1. The HTTP protocol used (e.g. the default endpoints currently use HTTP/1.1 to prevent browsers from multiplexing requests that measure latency and requests that measure throughput over the same logical connection);
  2. Where those endpoints are served from (if they're more distant, that will impact both latency and throughput);
  3. The amount of time the endpoints themselves take until the first byte is served (will impact latency numbers).

If you're self-hosting the reference worker implementation under workerd, then you can more or less control all of these factors with some additional effort — e.g. if your web server sends back a Server-Timing response header, the speedtest client will subtract its value when calculating latency.

If you're hosting the reference worker implementation in your own Cloudflare account, you should consider that the type of account will also affect where it's served from.

Thank you. I think I will go back to using the default endpoints and put a "warning" on the website that Safari users may not have accurate readings. This is my first time using Cloudflare workers - are usage limits pretty easy to setup for something like this? I was nervous that with a pay-as-you-go plan we might run into trouble.

Our site will primarily be used for informational purposes anyway. Originally we wanted to build something similar to https://business.utah.gov/broadband/speed-test/.

alexjustesen commented 11 months ago

I've came across b4, but this topic is about measuring speed between self-hosted server and client devices. If i'm not wrong, the project u linked to is measuring speed between self-hosted server to ookla servers yup?

At the moment that's correct, however I'll be adding support for iPerf and Cloudflare's Speedtest later this summer.

jerrywoo96 commented 11 months ago

I've came across b4, but this topic is about measuring speed between self-hosted server and client devices. If i'm not wrong, the project u linked to is measuring speed between self-hosted server to ookla servers yup?

At the moment that's correct, however I'll be adding support for iPerf and Cloudflare's Speedtest later this summer.

i'm looking forward to it. if it is as detailed as the one cloudflare is serving and as beautiful as yours, i'll be happy to self-host your image :)