Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add deno serve subcommand #23511

Merged
merged 3 commits into from
Apr 24, 2024
Merged

feat: Add deno serve subcommand #23511

merged 3 commits into from
Apr 24, 2024

Conversation

mmastrac
Copy link
Contributor

@mmastrac mmastrac commented Apr 23, 2024

By default, deno serve will assign port 8000 (like Deno.serve). Users may choose a different port using --port.

deno serve /tmp/file.ts

server.ts:

export default {
  fetch(req) {
    return new Response("hello world!\n");
  },
};

@mmastrac mmastrac changed the title feat(cli): Implement deno serve [WIP] feat(cli): Implement deno serve Apr 23, 2024
cli/args/flags.rs Outdated Show resolved Hide resolved
cli/args/flags.rs Show resolved Hide resolved
cli/args/mod.rs Outdated Show resolved Hide resolved
runtime/js/99_main.js Show resolved Hide resolved
@mmastrac mmastrac force-pushed the main_mode branch 2 times, most recently from b1cdef1 to 67607fb Compare April 24, 2024 14:58
@bartlomieju bartlomieju changed the title feat(cli): Implement deno serve feat: Add deno serve subcommand Apr 24, 2024
@mmastrac mmastrac merged commit 2f8825a into denoland:main Apr 24, 2024
17 checks passed
@jsejcksn
Copy link
Contributor

jsejcksn commented May 1, 2024

Is the documentation currently in a nascent state?

% deno help serve
Run a server defined in a main module

The serve command uses the default exports of the main module to determine which
servers to start.

See https://docs.deno.com/runtime/manual/tools/serve for
more detailed information.

---snip---

I don't see much at the linked URL — it's currently void of any schema, types, etc.

Content of the current documentation

source

deno serve, declarative way to write servers

In addition to deno run, Deno offers a deno serve command-line option that
automatically configures servers based on the exports of your main module.

Here's an example of how you can create a simple HTTP server using the serve
subcommand:

export default {
  async fetch(request) {
    return new Response("Hello world!");
  },
};

In this example, the fetch function is used to handle incoming HTTP requests.

The logic inside the fetch function can be customized to handle different
types of requests and serve content accordingly:

export default {
  async fetch(request) {
    if (request.url.startsWith("/json")) {
      return Response.json({ hello: "world" });
    }

    return new Response("Hello world!");
  },
};

@josephrocca
Copy link
Contributor

The prospect of built-in load balancing is really exciting! I'm guessing this is a very basic feature of any load balancer, but just in case it's worth mentioning: In my case I need a setting for IP-hash-based load balancing, and I need an env variable so an instance can know its own load-balancing index/id.

(Also, for those interested in this general "production tooling for Deno" area, Pup looks like a great project to follow: https://github.com/Hexagon/pup - maybe @Hexagon can integrate deno serve functionality into Pup, or maybe it's simple enough, implementation-wise, that there's no real utility in that. I literally do not know enough about this area to comment, but again just mentioning/pinging in case it's worth considering how this command interacts with community tooling.)

@Hexagon
Copy link

Hexagon commented May 1, 2024

@josephrocca Interesting, thanks for the ping!

@mmastrac Would it be possible to assign a port using environment variables instead of cli? As of now, Pup's clustering require a custom server script utilizing the PUP_CLUSTER_PORT environment variable.

However, if deno serve could pick up the port from an environment variable, let's say SERVE_PORT or just PORT - Pup could support creating deno serve clusters by assigning PORT or SERVE_PORT to each process, using a pup.json like:

{
  "processes": [
    {
      "id": "my-scalable-app",
      "cmd": "deno serve script.ts",
      "autostart": true,
      "cluster": {
        "instances": 4,
        "startPort": 8000
      }
    }
  ]
}

The same scenario using Pup's built in load balancer:

(For the record, I'll always recommend a dedicated load balancer, or something like nginx, for production scenarios.)

{
  "processes": [
    {
      "id": "my-scalable-app",
      "cmd": "deno serve script.ts",
      "autostart": true,
      "cluster": {
        "instances": 4,
        "commonPort": 3000,
        "startPort": 8000,
        "strategy": "ip-hash"
      }
    }
  ]
}

@mmastrac
Copy link
Contributor Author

mmastrac commented May 1, 2024

We could definitely use *PORT and *HOSTNAME env vars as aliases. Given the existing env vars, it's probably best if we prefix them as DENO_SERVE_PORT and DENO_SERVE_HOSTNAME.

If we add them, we can also probably also set the default port/hostname for Deno.serve using those.

@ry
Copy link
Member

ry commented May 1, 2024

ref denoland/docs#440

@josephrocca
Copy link
Contributor

josephrocca commented May 4, 2024

I'm wondering... I often end up reaching for python3 -m http.server just because it's short and simple (much more so than deno install --allow-net --allow-read https://deno.land/std/http/file_server.ts && file_server on a fresh cloud machine). Is there any possibility that deno serve (without any other arguments) could simply serve the current directory as static files on 3000/8000/8080 (or maybe the first available port incrementing up from 3000 or 8000), or something?

I haven't thought this through at all, and don't know enough about deno serve to properly assess feasibility, but anything similarly short/easy would be really nice. E.g. deno serve --static or deno serve static.

(Note that python3 -m http.server adds a directory listing if no index.html is found at a path. Not sure if a built-in deno static serving command should have this, but just mentioning it as a design consideration.)

@dsherret
Copy link
Member

dsherret commented May 6, 2024

@josephrocca a bit shorter:

deno run --allow-net --allow-read=. jsr:@std/http/file-server

@josephrocca
Copy link
Contributor

True, but ooof 😅 the Python command is already slightly too long for my liking. Should be able to type it out in a few keystrokes imo. Deno could make this common DX delightful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants