Skip to content
This repository was archived by the owner on Jun 5, 2021. It is now read-only.
This repository was archived by the owner on Jun 5, 2021. It is now read-only.

Example for dockerized nodejs monorepo #13

Description

@enriched

I am trying to use Bazel to develop dockerized nodejs apps on a local kubernetes cluster.

Seems like the Bazel way is to compile all sources and dependencies down into a single js file and then add that to the container. That seems to work fairly well till:

  1. you have a native node module
  2. your IDE is not aware of node_modules installed by bazel
  3. your IDE is not aware of bazel dependencies (the ts language server is not aware of bazel deps from ts_library targets)

I am not sure how to solve issue 1 yet. Figuring out which of your node modules are native seems difficult, and then creating a docker image that has them compiled with the correct toolchain seems like something that Bazel isn't all that good at yet.

Issue 2 can be solved by running a yarn install at the workspace root as long as everyone is willing to put all npm dependencies in the package.json at the repo root.

The only way to solve issue 3 seems to be to use path mapping or project references in your tsconfig.json file.

I would really appreciate an example of a monorepo that produces nodejs docker images from someone more experienced in Bazel. Bonus points if it can use something like skaffold for quick development iteration.

Currently, for a dockerized nodejs app I am using something like:

./WORKSPACE

git_repository(
    name = "bazel_javascript",
    remote = "https://github.com/zenclabs/bazel-javascript.git",
    tag = "0.0.23",
)

git_repository(
    name = "build_bazel_rules_nodejs",
    remote = "https://github.com/bazelbuild/rules_nodejs.git",
    tag = "0.10.0",
)

load("@build_bazel_rules_nodejs//:defs.bzl", "node_repositories")

node_repositories(
    package_json = [],
)

load(
    "@io_bazel_rules_docker//container:container.bzl",
    "container_pull",
    container_repositories = "repositories",
)

container_repositories()

container_pull(
    name = "node_alpine_image",
    registry = "index.docker.io",
    repository = "library/node",
    tag = "8.11.3-alpine",
)

./BUILD.bazel

package(default_visibility = ["//visibility:public"])

exports_files(["tsconfig.json"])

load("@bazel_javascript//:defs.bzl", "npm_packages")

npm_packages(
    name = "packages",
    package_json = ":package.json",
    yarn_lock = ":yarn.lock",
)

./libs/shared-package/BUILD.bazel

package(default_visibility = ["//visibility:public"])
load("@bazel_javascript//:defs.bzl", "ts_library")

ts_library(
    name = "shared-package"
    srcs = glob("**/*.ts")
    tsconfig = "//:tsconfig.json"
)

./services/base-image/BUILD.bazel

package(default_visibility = ["//visibility:public"])

load("@io_bazel_rules_docker//container:container.bzl", "container_image", "container_push")

## The Backend Base Image
container_image(
    name = "service",
    base = "@node_alpine_image//image:image",
    labels = {
        "org.label-schema.schema-version": "1.0",
        "org.label-schema.vendor": "MyCompany",
        "org.label-schema.url": "http://my-company.com/",
        "org.label-schema.vcs-url": "https://github.com/MyCompany/this-repo",
        "org.label-schema.vcs-ref": "{GIT_COMMIT}",
    },
    stamp = True,
    workdir = "/app",
)

./services/my-service/BUILD.bazel

package(default_visibility = ["//visibility:public"])

load("@io_bazel_rules_docker//container:container.bzl", "container_image", "container_push")

container_image(
    name = "image",
    base = "//services/base-image:service",
    data_path = ".",
    directory = "/app",
    files = [
        "//services/my-service/server",
    ],
    labels = {
        "org.label-schema.vcs-ref": "{GIT_COMMIT}",
    },
    stamp = True,
)

container_push(
    name = "publish",
    format = "Docker",
    image = ":image",
    registry = "my.repo.com",
    repository = "my-service",
    stamp = True,
    tag = "{BUILD_USER}",
)

./services/my-service/server/BUILD.bazel

load("@bazel_javascript//:defs.bzl", "ts_library")

ts_library(
    name = "server_lib",
    srcs = glob(["**/*.ts"]),
    tsconfig = "//:tsconfig.json",
    deps = [
        "//:packages",
        "//libs/shared-package",
    ],
)

Activity

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions