Skip to content

prepare a Dart app for server-side deployment #15731

@sethladd

Description

@sethladd
Contributor

Right now, pub build is optimized for web apps. Dart server-side is growing up, and we need a way to build a Dart app for server deployment.

We think this means create a snapshot of the app.

We think this also means we need pub build to support a package with both web/ entry points and bin/ entry points. Often, the server will live in bin/ and it will serve up resources from web/

Activity

nex3

nex3 commented on Dec 19, 2013

@nex3
Member

What benefit does compiling a server-side app to a snapshot provide?

sethladd

sethladd commented on Dec 19, 2013

@sethladd
ContributorAuthor

Today, to run a server app "in the cloud", you need to get the code up to the hosting provider and then run pub install (to set up all the symlinks). This has a couple of issues:

pub install can be slow
no guarantee that the exact same bits you tested in QA are what you are running in prod (assumption: moving a snapshot around is easier to control than source + various pub installs)
generally adds complexity to the deployment process
the app starts faster from a snapshot, thus decreasing time to spawn up new instances

nex3

nex3 commented on Dec 19, 2013

@nex3
Member

So the goal is to compile to a snapshot and then upload only the snapshot to the server? How does this work when you want to serve files as well? If you have a dart webapp in web/, what structure of build output are you imagining? It seems like this is getting into the territory of server-specific paths which are difficult to standardize.

no guarantee that the exact same bits you tested in QA are what you are running in prod

"pub install" is designed to offer this guarantee.

sethladd

sethladd commented on Dec 19, 2013

@sethladd
ContributorAuthor

We do need to figure out how to deploy a package that contains a server and a client. I'd like to minimize the amount of work the container/host needs to do. Ideally, I give it bits and it knows what process to start. Currently, I need to build on the server, which adds complexity and time to deployment.

I would imagine the entry points in bin/ have snapshots generated for them. I would also imagine I would be able to tell my container/host that, when it receives a new bundle, to run dart bin/app.snapshot path/to/web/root or similar.

Snapshots have their own merits, but the overarching issue is I'd like a simple process for creating a deployable bundle of both server and client Dart code. I'd like that process not to require any build steps on the server (sometimes, containers/hosts can't run arbitrary processes on a deploy request)

nex3

nex3 commented on Dec 19, 2013

@nex3
Member

The problem is the way that the Dart server interacts with the files in the "web/" directory is not well-defined, and in fact may vary from server to server. This means that the desired behavior of pub for these sorts of server-side apps is unclear and possibly varies based on what server or framework the user is using.

sethladd

sethladd commented on Dec 19, 2013

@sethladd
ContributorAuthor

Can we assume that pub build produces a build/ dir? Therefore, if we assume that the server lives in bin/ and the files to be served live in build/, that might be enough convention to get us started.

For my apps, I serve build/

I know there may be slightly different ways to tell your Dart server framework which directory to serve. I don't think we need to standardize that. However, we should have a workflow that produces bits to serve (the stuff in build/) and server code in bin/ that is ready to go without further processing on the server.

The "what is the actual run command and args to start the server" can be left up to the container, and is not a pub concern.

nex3

nex3 commented on Dec 19, 2013

@nex3
Member

If we were to support building both the client and the server at once, we'd have to answer the following questions:

* Where does the compiled output of "bin/" vs "web/" go? They can't both go in the root of the "build/" directory.

  • Where do packages' assets go?
  • How do we tell which assets are used by the server vs which are used by the client?
  • How does the Dart server interact with barback/pub serve during development?
  • With all this rewriting and shuffling, how can the user be confident that what they run during development reflects what gets run when they deploy their app?
sgjesse

sgjesse commented on Dec 20, 2013

@sgjesse
Contributor

I think the important part of adding some kind of server deployment is that it should be easy to get started. We define the supported directory structure, and generate a directory structure which can be copied to the Dart server (and maybe also to a frontend server serving the static content when the Dart server is accessed through a reverse proxy).

The generated directory structure we should keep it as close to the directory structure the developer see in the editor to limit confusion.

Basically having the following code in the bin/ entrypoint (main.dart):

import 'dart:io';
import 'package:http_server/http_server.dart' as http_server;
import 'package:route/server.dart' show Router;

main() {
  HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, port).then((server) {
    var router = new Router(server);
    var virDir = new http_server.VirtualDirectory('web');
    virDir.serve(router.defaultStream);
  });
}

You then run the pub command, copy the generated directory structure to the server and run

  $ dart main.snapshot

We should make writing this 10-line boilerplate server app using the http-server package with client side Dart just work. I don't envision that we will support all kind of configuration options. When a project reaches a certain size one most likely need to have a custom deployment system anyway.

munificent

munificent commented on Jan 6, 2014

@munificent
Member

Removed Priority-Unassigned label.
Added Priority-Medium label.

DartBot

DartBot commented on Jan 7, 2014

@DartBot

This comment was originally written by nistv...@gmail.com


I've faced the similar problem on the past week and opened a StackOverflow question which redirected me here. http://stackoverflow.com/questions/20884103/how-to-organize-mixed-http-server-web-client-dart-project-files
The question details what i'm expecting from a hybrid server/client Dart project, please take a look.

I think there's two way to solve this:

  • Create a web container on top of server side Dart which has a directory where built client applications can be inserted and it will serve them automatically (just like Tomcat or Jetty does this in Javaland). This requires some kind of descriptor in the client project like web.xml in Java (or maybe a Dart script which configures the webapp in the container).
  • Support creating a standalone project where the server and client projects are closely fused together and the server can serve the client projects web files. This is what i'm looking for.

I think the later one is more preferred since then you can just fire up the Dart Editor, run and debug the project without any external server setup. Also because the DartVM has a HTTP Server built-in it makes the project overhead minimal if we embed it into the project, while making it very flexible.

I think separating the client and server project files is a have to. Fusing the projects introduces problems like the dependencies have to be shared between the server and client. I think that's not a good practice, the client and server side should have clearly separated dependencies.

What came to my mind is to define the client project as a special dependency of the server and provide the server access to the client project files through Pub's resolving capability. In Eclipse by Maven projects i can open two projects next to each other and they are automatically configured in a way that the depending projects classpath automatically includes the dependent project's target directory. This makes the development easy, since i can changes in both projects and they are reflected instantly in the development runtime. I know that Pub and Dart Editor misses this functionality, but i think it would be a good way.

DartBot

DartBot commented on Jan 12, 2014

@DartBot

This comment was originally written by renan.je...@gmail.com


I need an easy all in one server/client project, waiting this to start using dart.

munificent

munificent commented on Apr 9, 2014

@munificent
Member

I'm going to close this out as fixed because pub build now supports building your bin/ directory (and any other directories you want), so it should now be possible to use that and support packages that have both a server and client side component.

We don't have any plans to build actual snapshots. My understanding is the snapshot format changes frequently and isn't really a reliable serialization format. Instead, we're more inclined to use dart2dart if we want to "compile" a server-side application to a single file that can be run.

I know there's still a lot of other stuff we can do to smooth the server-side development experience, but this bug is a bit open-ended so it isn't clear what "done" means. I'd rather close this and file more specific bugs for other features as they come in.

(Of course, I care about the holistic experience too, but a large nebulous bug isn't the best way to track that.)


Added Fixed label.

DartBot

DartBot commented on Apr 9, 2014

@DartBot

This comment was originally written by @Fox32


Are the dart files now outputed if I build in release mode? I was only able to use the debug mode in combination with bin until now.

DartBot

DartBot commented on May 20, 2015

@DartBot

This comment was originally written by @zoechi


I wasn't able to make pub build bin do anything useful. The files from bin aren't copied to build/bin and the packages copied to build/bin/packages are mostly browser related (browser, polymer, ...)

DartBot

DartBot commented on May 20, 2015

@DartBot

This comment was originally written by @zoechi


I forgot to add that I use

transformers:
  - $dart2js:
      $exclude: "bin

10 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-enhancementA request for a change that isn't a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @nex3@sethladd@kevmoo@munificent@sgjesse

        Issue actions

          prepare a Dart app for server-side deployment · Issue #15731 · dart-lang/sdk