Skip to content

[feat] Workspaces Docker Interop #4594

Open
@felangel

Description

@felangel

Goal
As a developer, I want to be able to use Dart workspaces and have a convenient way to deploy server-side applications using Docker.

Problem
Currently, when using Dart workspaces, a pubspec.lock is generated at the root of the project (outside the context of a package) and there's no built-in way to generate a per-package pubspec.lock from the root pubspec.lock.

Migrating to workspaces results in the following error:

#9 [build 4/6] RUN dart pub get
#9 0.278 Found a pubspec.yaml at /app. But it has resolution `workspace`.
#9 0.278 But found no workspace root including it in parent directories.
#9 0.278 
#9 0.278 See https://dart.dev/go/pub-workspaces for more information.
#9 ERROR: process "/bin/sh -c dart pub get" did not complete successfully: exit code: 66
------
 > [build 4/6] RUN dart pub get:
0.278 Found a pubspec.yaml at /app. But it has resolution `workspace`.
0.278 But found no workspace root including it in parent directories.
0.278 
0.278 See https://dart.dev/go/pub-workspaces for more information.
------
Dockerfile:7
--------------------
   5 |     WORKDIR /app
   6 |     COPY pubspec.* ./
   7 | >>> RUN dart pub get
   8 |     
   9 |     # Copy app source code (except anything in .dockerignore) and AOT compile app.
--------------------
ERROR: failed to solve: process "/bin/sh -c dart pub get" did not complete successfully: exit code: 66
Error: Process completed with exit code 1.

For more context, see https://github.com/shorebirdtech/shorebird/actions/runs/15401908909/job/43336296033.

Workaround

There are ways to work around this like generating a pubspec_overrides.yaml which opts out of workspaces:

resolution: null

And then adding a manual step to copy the entire pubspec.lock from the workspace root into the package directory prior to doing a docker build:

cp ${{ inputs.workspace_root }}/pubspec.lock .
docker build -t ${{ inputs.container_registry }}/${{ inputs.project_id }}/us.gcr.io/${{ inputs.job }}:${{ github.sha }} -f ${{ inputs.working_directory}}/Dockerfile .
docker push ${{ inputs.container_registry }}/${{ inputs.project_id }}/us.gcr.io/${{ inputs.job }}:${{ github.sha }}

For more context see shorebirdtech/shorebird@ec728da

Proposed Solutions

Ideally there'd be built-in support for generating a lockfile for a specific package in a workspace via pub:

# Generate a partial monorepo with a pruned `pubspec.lock` for a target package:
dart pub workspace prune <package>

Inspired by Turbo Repo which has a prune command for this exact case:

# Generate a partial monorepo with a pruned lockfile for a target workspace.
RUN npm i -g turbo
RUN turbo prune console --docker

Related Issues

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

    Issue actions