Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,9 @@

[env]
TS_RS_EXPORT_DIR = { value = "clients/javascript/lib/gen_types", relative = true }

[target.x86_64-unknown-linux-gnu]
rustflags = ["-C", "link-arg=-fuse-ld=mold"]

[target.aarch64-unknown-linux-gnu]
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
5 changes: 5 additions & 0 deletions .github/workflows/js-client-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ jobs:
with:
toolchain: ${{ env.RUST_VERSION }}

- name: Install mold
run: |
sudo apt-get update
sudo apt-get install -y mold

- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/server-code-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v2

- name: Install mold
run: |
sudo apt-get update
sudo apt-get install -y mold

- uses: actions/cache@v2
with:
path: |
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/server-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ jobs:
toolchain: ${{ env.RUST_VERSION }}
components: clippy

- name: Install mold
run: |
sudo apt-get update
sudo apt-get install -y mold

- uses: actions/cache@v4
with:
path: |
Expand Down
12 changes: 7 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ unwrap_used = "deny"
expect_used = "deny"

[profile.release]
# Can improve slightly the performance at the cost of increased compile time
# https://doc.rust-lang.org/cargo/reference/profiles.html#lto
lto = "thin"
# https://doc.rust-lang.org/cargo/reference/profiles.html#codegen-units
codegen-units = 1
# Add basic debug information, at the cost of binary size
# See https://doc.rust-lang.org/cargo/reference/profiles.html#debug
strip = "symbols"

[profile.release-dd]
inherits = "release"
lto = "thin"
codegen-units = 1
debug = 1
strip = "none"
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ This project uses [Just](https://github.com/casey/just) as a task manager. To in
brew install just
```

On Linux, including WSL, install [`mold`](https://github.com/rui314/mold) too. The repository Cargo config uses it as the linker for Linux builds.

```sh
sudo apt install mold
```

Once Rust and Just are installed, a few more utility tools can be installed by running

```sh
Expand Down
41 changes: 23 additions & 18 deletions alpine.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,38 +1,47 @@
# Usage:
# docker buildx build -f alpine.Dockerfile -t image:tag --build-arg='ARCH=x86_64' --platform linux/amd64 .
# docker buildx build -f alpine.Dockerfile -t image:tag --build-arg='ARCH=aarch64' --platform linux/arm64 .
# docker buildx build -f alpine.Dockerfile -t image:tag --platform linux/amd64 .
# docker buildx build -f alpine.Dockerfile -t image:tag --platform linux/arm64 .

ARG ARCH=x86_64
FROM messense/rust-musl-cross:${ARCH}-musl AS builder
ARG TARGETARCH=amd64

FROM messense/rust-musl-cross:x86_64-musl AS builder-amd64
ENV MUSL_TARGET=x86_64-unknown-linux-musl

FROM messense/rust-musl-cross:aarch64-musl AS builder-arm64
ENV MUSL_TARGET=aarch64-unknown-linux-musl

FROM builder-${TARGETARCH} AS builder

ARG ARCH=x86_64
ARG APP_NAME=nittei
ARG RUST_VERSION=1.96.0
ENV BUILD_PROFILE=release

# Install and set the specific Rust version
RUN rustup install ${RUST_VERSION} && rustup default ${RUST_VERSION}

# Install the musl target for the correct architecture
RUN rustup target add ${ARCH}-unknown-linux-musl
RUN rustup target add ${MUSL_TARGET}

# Verify the Rust and target setup
RUN rustc --version && rustup show

# Copy source code
COPY .cargo .cargo
COPY ./Cargo.toml ./Cargo.lock ./
COPY ./crates ./crates
COPY ./bins ./bins
COPY ./clients/rust ./clients/rust

# Build application
RUN cargo build --release --target ${ARCH}-unknown-linux-musl && \
cp ./target/${ARCH}-unknown-linux-musl/release/${APP_NAME} /${APP_NAME}
RUN cargo build --locked --profile ${BUILD_PROFILE} --target ${MUSL_TARGET} \
--bin nittei \
--bin nittei-migrate

# Build migrate binary
RUN cargo build --release --bin nittei-migrate --target ${ARCH}-unknown-linux-musl && \
cp ./target/${ARCH}-unknown-linux-musl/release/nittei-migrate /nittei-migrate
RUN mkdir -p /out \
&& cp ./target/${MUSL_TARGET}/${BUILD_PROFILE}/nittei /out/nittei \
&& cp ./target/${MUSL_TARGET}/${BUILD_PROFILE}/nittei-migrate /out/nittei-migrate

#Create a new stage with a minimal image
# Create a new stage with a minimal image
FROM alpine:3.23.4

# Set the git repository url and commit hash for DD
Expand All @@ -47,10 +56,6 @@ ENV DD_SOURCE_CODE_PATH_MAPPING="/app/nittei/bins:/bins,/app/nittei/crates:/crat
ARG RUST_BACKTRACE=1
ENV RUST_BACKTRACE=${RUST_BACKTRACE}

ARG APP_NAME=nittei
ENV APP_NAME=${APP_NAME}

COPY --from=builder /${APP_NAME} /${APP_NAME}
COPY --from=builder /nittei-migrate /nittei-migrate
COPY --from=builder /out/ /

CMD ["/bin/sh", "-c", "exec /${APP_NAME}"]
CMD ["/nittei"]
51 changes: 28 additions & 23 deletions alpineWithDD.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,50 +1,59 @@
# This Dockerfile is based on the alpine.Dockerfile and adds the ddprof tool to the image.
#
# Usage:
# docker buildx build -f alpineWithDD.Dockerfile -t image:tag --build-arg='ARCH=x86_64' --platform linux/amd64 .
# docker buildx build -f alpineWithDD.Dockerfile -t image:tag --build-arg='ARCH=aarch64' --platform linux/arm64 .
# docker buildx build -f alpineWithDD.Dockerfile -t image:tag --platform linux/amd64 .
# docker buildx build -f alpineWithDD.Dockerfile -t image:tag --platform linux/arm64 .

ARG ARCH=x86_64
FROM messense/rust-musl-cross:${ARCH}-musl AS builder
ARG TARGETARCH=amd64

ARG ARCH=x86_64
ARG APP_NAME=nittei
FROM messense/rust-musl-cross:x86_64-musl AS builder-amd64
ENV MUSL_TARGET=x86_64-unknown-linux-musl

FROM messense/rust-musl-cross:aarch64-musl AS builder-arm64
ENV MUSL_TARGET=aarch64-unknown-linux-musl

FROM builder-${TARGETARCH} AS builder

ARG TARGETARCH
ARG RUST_VERSION=1.96.0
ENV BUILD_PROFILE=release-dd
ENV RUSTFLAGS="-C force-frame-pointers=yes"

# Install and set the specific Rust version
RUN rustup install ${RUST_VERSION} && rustup default ${RUST_VERSION}

# Install the musl target for the correct architecture
RUN rustup target add ${ARCH}-unknown-linux-musl
RUN rustup target add ${MUSL_TARGET}

# Verify the Rust and target setup
RUN rustc --version && rustup show

# Copy source code
COPY .cargo .cargo
COPY ./Cargo.toml ./Cargo.lock ./
COPY ./crates ./crates
COPY ./bins ./bins
COPY ./clients/rust ./clients/rust

# Build application
RUN cargo build --release --target ${ARCH}-unknown-linux-musl && \
cp ./target/${ARCH}-unknown-linux-musl/release/${APP_NAME} /${APP_NAME}
RUN cargo build --locked --profile ${BUILD_PROFILE} --target ${MUSL_TARGET} \
--bin nittei \
--bin nittei-migrate

# Build migrate binary
RUN cargo build --release --bin nittei-migrate --target ${ARCH}-unknown-linux-musl && \
cp ./target/${ARCH}-unknown-linux-musl/release/nittei-migrate /nittei-migrate
RUN mkdir -p /out \
&& cp ./target/${MUSL_TARGET}/${BUILD_PROFILE}/nittei /out/nittei \
&& cp ./target/${MUSL_TARGET}/${BUILD_PROFILE}/nittei-migrate /out/nittei-migrate

# Install ddprof
RUN ARCH_IN_URL=$(case "${ARCH}" in \
x86_64) echo "amd64" ;; \
aarch64) echo "arm64" ;; \
RUN ARCH_IN_URL=$(case "${TARGETARCH}" in \
amd64) echo "amd64" ;; \
arm64) echo "arm64" ;; \
*) echo "unsupported-arch" && exit 1 ;; \
esac) && \
curl -Lo ddprof-linux.tar.xz https://github.com/DataDog/ddprof/releases/latest/download/ddprof-${ARCH_IN_URL}-linux.tar.xz && \
tar xvf ddprof-linux.tar.xz && \
mv ddprof/bin/ddprof /ddprof

#Create a new stage with a minimal image
# Create a new stage with a minimal image
FROM alpine:3.23.4

# Set the git repository url and commit hash for DD
Expand All @@ -59,11 +68,7 @@ ENV DD_SOURCE_CODE_PATH_MAPPING="/app/nittei/bins:/bins,/app/nittei/crates:/crat
ARG RUST_BACKTRACE=1
ENV RUST_BACKTRACE=${RUST_BACKTRACE}

ARG APP_NAME=nittei
ENV APP_NAME=${APP_NAME}

COPY --from=builder /${APP_NAME} /${APP_NAME}
COPY --from=builder /nittei-migrate /nittei-migrate
COPY --from=builder /out/ /
COPY --from=builder /ddprof /ddprof

CMD ["/bin/sh", "-c", "exec /ddprof --preset cpu_live_heap /${APP_NAME}"]
CMD ["/ddprof", "--preset", "cpu_live_heap", "/nittei"]
26 changes: 16 additions & 10 deletions debian.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
# Usage:
# docker buildx build -f debian.Dockerfile -t image:tag --build-arg='ARCH=x86_64' --platform linux/amd64 .
# docker buildx build -f debian.Dockerfile -t image:tag --build-arg='ARCH=aarch64' --platform linux/arm64 .
# docker buildx build -f debian.Dockerfile -t image:tag --platform linux/amd64 .
# docker buildx build -f debian.Dockerfile -t image:tag --platform linux/arm64 .

FROM rust:1.96.0-slim-trixie AS builder

WORKDIR /app/nittei
ARG TARGETARCH
ENV BUILD_PROFILE=release
# cargo-sonic intentionally does not reuse payload RUSTFLAGS / CARGO_*_RUSTFLAGS
# for its small generated loader build. Tell it to use mold for the loader too,
# matching the payload link step configured in .cargo/config.toml.
ENV CARGO_SONIC_LOADER_RUSTFLAGS="-C link-arg=-fuse-ld=mold"

RUN apt update \
&& apt install -y --no-install-recommends curl openssl ca-certificates pkg-config build-essential libssl-dev \
&& apt install -y --no-install-recommends curl openssl ca-certificates pkg-config build-essential libssl-dev mold \
&& apt clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

COPY ./Cargo.toml ./Cargo.lock .cargo ./
RUN cargo install cargo-sonic --version 0.2.0 --locked

COPY .cargo .cargo
COPY ./Cargo.toml ./Cargo.lock ./
COPY ./clients/rust ./clients/rust
COPY ./crates ./crates
COPY ./bins ./bins
COPY ./scripts ./scripts

RUN cargo build --locked --release && \
cp ./target/release/nittei /nittei && \
cargo build --locked --release --bin nittei-migrate && \
cp ./target/release/nittei-migrate /nittei-migrate
RUN ./scripts/build_release.sh

# Use the distroless base image for final image
FROM gcr.io/distroless/cc-debian13
Expand All @@ -38,7 +45,6 @@ ENV RUST_BACKTRACE=${RUST_BACKTRACE}

USER nonroot:nonroot

COPY --from=builder --chown=nonroot:nonroot /nittei /nittei
COPY --from=builder --chown=nonroot:nonroot /nittei-migrate /nittei-migrate
COPY --from=builder --chown=nonroot:nonroot /tmp/nittei-build/ /

CMD ["/nittei"]
36 changes: 21 additions & 15 deletions debianWithDD.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,35 +1,42 @@
# This Dockerfile is based on the debian.Dockerfile and adds the ddprof tool to the image.

# Usage:
# docker buildx build -f debianWithDD.Dockerfile -t image:tag --build-arg='ARCH=x86_64' --platform linux/amd64 .
# docker buildx build -f debianWithDD.Dockerfile -t image:tag --build-arg='ARCH=aarch64' --platform linux/arm64 .
# docker buildx build -f debianWithDD.Dockerfile -t image:tag --platform linux/amd64 .
# docker buildx build -f debianWithDD.Dockerfile -t image:tag --platform linux/arm64 .

FROM rust:1.96.0-slim-trixie AS builder

WORKDIR /app/nittei

ARG ARCH=x86_64

ARG TARGETARCH
ENV BUILD_PROFILE=release-dd
ENV RUSTFLAGS="-C force-frame-pointers=yes -C link-arg=-fuse-ld=mold"
# cargo-sonic intentionally does not reuse payload RUSTFLAGS / CARGO_*_RUSTFLAGS
# for its small generated loader build. Tell it to use mold for the loader too,
# matching the payload link step. Frame pointers are not needed on the launcher
# (ddprof profiles the payload process, not the loader).
ENV CARGO_SONIC_LOADER_RUSTFLAGS="-C link-arg=-fuse-ld=mold"

RUN apt update \
&& apt install -y --no-install-recommends curl openssl ca-certificates pkg-config build-essential libssl-dev \
&& apt install -y --no-install-recommends curl openssl ca-certificates pkg-config build-essential libssl-dev mold \
&& apt clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

COPY ./Cargo.toml ./Cargo.lock .cargo ./
RUN cargo install cargo-sonic --version 0.2.0 --locked

COPY .cargo .cargo
COPY ./Cargo.toml ./Cargo.lock ./
COPY ./clients/rust ./clients/rust
COPY ./crates ./crates
COPY ./bins ./bins
COPY ./scripts ./scripts

RUN cargo build --locked --release && \
cp ./target/release/nittei /nittei && \
cargo build --locked --release --bin nittei-migrate && \
cp ./target/release/nittei-migrate /nittei-migrate
RUN ./scripts/build_release.sh

# Install ddprof
RUN ARCH_IN_URL=$(case "${ARCH}" in \
x86_64) echo "amd64" ;; \
aarch64) echo "arm64" ;; \
RUN ARCH_IN_URL=$(case "${TARGETARCH:-$(uname -m)}" in \
amd64|x86_64) echo "amd64" ;; \
arm64|aarch64) echo "arm64" ;; \
*) echo "unsupported-arch" && exit 1 ;; \
esac) && \
curl -Lo ddprof-linux.tar.xz https://github.com/DataDog/ddprof/releases/latest/download/ddprof-${ARCH_IN_URL}-linux.tar.xz && \
Expand All @@ -53,8 +60,7 @@ ENV RUST_BACKTRACE=${RUST_BACKTRACE}

USER nonroot:nonroot

COPY --from=builder --chown=nonroot:nonroot /nittei /nittei
COPY --from=builder --chown=nonroot:nonroot /nittei-migrate /nittei-migrate
COPY --from=builder --chown=nonroot:nonroot /tmp/nittei-build/ /
COPY --from=builder --chown=nonroot:nonroot /ddprof /ddprof

CMD ["/ddprof", "--preset", "cpu_live_heap", "/nittei"]
12 changes: 12 additions & 0 deletions docs/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@ Or build from source:
cargo run --release
```

### mold

The production Docker builds install [`mold`](https://github.com/rui314/mold) and configure Rust to use it as the linker. This keeps release and profiling builds faster, especially when LTO is enabled.

### cargo-sonic

The Debian Docker images use [`cargo-sonic`](https://docs.rs/crate/cargo-sonic/latest) to build CPU-dispatched binaries. The image contains a baseline payload plus an optimized payload for the target architecture: `x86-64-v3` on `amd64`, and `neoverse-n1` on `arm64`.

The build uses `--loader=bundle`, so the final image must include both the launcher binaries and their adjacent `.bundle` directories.

### Database

Then set up a postgres db with the init script specified [here](../crates/infra/migrations/dbinit.sql).
Lastly provide the following environment variables to the `nittei` server:

Expand Down
Loading
Loading