[GH-ISSUE #4746] [Bug]: Build from source went from ~160MiB to 1.8GiB #16251

Closed
opened 2026-04-14 19:22:55 -05:00 by GiteaMirror · 3 comments
Owner

Originally created by @pogman-code on GitHub (Apr 5, 2025).
Original GitHub issue: https://github.com/actualbudget/actual/issues/4746

Verified issue does not already exist?

  • I have searched and found no existing issue

What happened?

Hello,
I noticed in the documentation, while updating from 25.3.1 to 25.4.0, that the install process has changed from:

yarn workspaces focus @actual-app/sync-server --production

to:

yarn install
yarn build:server

But this change result in a drastic change of the install size (25.3.1 is around 160MiB while 25.4.0 skyrocketed to 1.8GiB.

I guess this is due to yarn install pulling all the dependencies but is it possible to change this back to the previous install process?

How can we reproduce the issue?

Follow the "build from source" process from the documentation: https://actualbudget.org/docs/install/build-from-source

Where are you hosting Actual?

Self-hosted

What browsers are you seeing the problem on?

N/A

Operating System

Arch Linux 6.13.8

Originally created by @pogman-code on GitHub (Apr 5, 2025). Original GitHub issue: https://github.com/actualbudget/actual/issues/4746 ### Verified issue does not already exist? - [x] I have searched and found no existing issue ### What happened? Hello, I noticed in the documentation, while updating from 25.3.1 to 25.4.0, that the install process has changed from: ``` yarn workspaces focus @actual-app/sync-server --production ``` to: ``` yarn install yarn build:server ``` But this change result in a drastic change of the install size (25.3.1 is around 160MiB while 25.4.0 skyrocketed to 1.8GiB. I guess this is due to `yarn install` pulling all the dependencies but is it possible to change this back to the previous install process? ### How can we reproduce the issue? Follow the "build from source" process from the documentation: https://actualbudget.org/docs/install/build-from-source ### Where are you hosting Actual? Self-hosted ### What browsers are you seeing the problem on? N/A ### Operating System Arch Linux 6.13.8
GiteaMirror added the bug label 2026-04-14 19:22:55 -05:00
Author
Owner

@pogman-code commented on GitHub (Apr 7, 2025):

Based of of sync-server.Dockerfile, I made a shell script that builds Actual similarily to what is provided in the Docker container:

#!/usr/bin/env bash

# Fail the script if any command fails
set -e

# Set the project root directory
PROJECT_ROOT=~/actual-src

# Step 1: Dependency Installation

# Create a temporary directory for building
BUILD_DIR=~/actual-build
mkdir -p $BUILD_DIR

# Set the working directory to the project root
cd $PROJECT_ROOT

# Copy necessary files (mimicking the Dockerfile's COPY steps)
echo "Copying necessary files..."
mkdir -p $BUILD_DIR/.yarn $BUILD_DIR/packages/{api,component-library,crdt,desktop-client,desktop-electron,eslint-plugin-actual,loot-core,sync-server} $BUILD_DIR/bin

cp -r .yarn $BUILD_DIR/
cp yarn.lock package.json .yarnrc.yml tsconfig.json $BUILD_DIR/
cp packages/api/package.json $BUILD_DIR/packages/api/package.json
cp packages/component-library/package.json $BUILD_DIR/packages/component-library/package.json
cp packages/crdt/package.json $BUILD_DIR/packages/crdt/package.json
cp packages/desktop-client/package.json $BUILD_DIR/packages/desktop-client/package.json
cp packages/desktop-electron/package.json $BUILD_DIR/packages/desktop-electron/package.json
cp packages/eslint-plugin-actual/package.json $BUILD_DIR/packages/eslint-plugin-actual/package.json
cp packages/loot-core/package.json $BUILD_DIR/packages/loot-core/package.json
cp packages/sync-server/package.json $BUILD_DIR/packages/sync-server/package.json
cp bin/package-browser $BUILD_DIR/bin/package-browser

# Install dependencies using Yarn
echo "Running yarn install..."
cd $BUILD_DIR
yarn install

# Step 2: Building the Application

# Copy packages directory
cp -r $PROJECT_ROOT/packages $BUILD_DIR/

# Run the build command for browser
echo "Building the browser version..."
yarn build:browser

# Focus on the sync-server workspace and install production dependencies
echo "Focusing on @actual-app/sync-server workspace..."
yarn workspaces focus @actual-app/sync-server --production

# Remove symbolic links for unnecessary packages
echo "Removing symbolic links for @actual-app/web and @actual-app/sync-server..."
rm -rf node_modules/@actual-app/web node_modules/@actual-app/sync-server

# Copy the @actual-app/web artifacts manually
echo "Copying @actual-app/web artifacts..."
mkdir -p node_modules/@actual-app/web
cp packages/desktop-client/package.json node_modules/@actual-app/web/package.json
cp -r packages/desktop-client/build node_modules/@actual-app/web/

# Step 3: Production Setup

# Create the production directory structure
PROD_DIR=~/actual-prod
mkdir -p $PROD_DIR

echo "Setting up production directory..."
cp -r $BUILD_DIR/node_modules $PROD_DIR/
cp $BUILD_DIR/packages/sync-server/{package.json,app.js} $PROD_DIR/
cp -r $BUILD_DIR/packages/sync-server/src $PROD_DIR/
cp -r $BUILD_DIR/packages/sync-server/migrations $PROD_DIR/

It ends up being the expected hundred something MiB:

$ du -sh actual-*
545M	actual-build
116M	actual-prod
280M	actual-src

I have not put much thoughts into it and recreated it almost one-to-one an copying things like that is probably not the most efficient but you get the jist of it.

Maybe it would be nice to have something similar with the bin folder in order to build a production ready server, don't you think?

<!-- gh-comment-id:2782859220 --> @pogman-code commented on GitHub (Apr 7, 2025): Based of of [sync-server.Dockerfile](https://github.com/actualbudget/actual/blob/v25.4.0/sync-server.Dockerfile), I made a shell script that builds Actual similarily to what is provided in the Docker container: ```bash #!/usr/bin/env bash # Fail the script if any command fails set -e # Set the project root directory PROJECT_ROOT=~/actual-src # Step 1: Dependency Installation # Create a temporary directory for building BUILD_DIR=~/actual-build mkdir -p $BUILD_DIR # Set the working directory to the project root cd $PROJECT_ROOT # Copy necessary files (mimicking the Dockerfile's COPY steps) echo "Copying necessary files..." mkdir -p $BUILD_DIR/.yarn $BUILD_DIR/packages/{api,component-library,crdt,desktop-client,desktop-electron,eslint-plugin-actual,loot-core,sync-server} $BUILD_DIR/bin cp -r .yarn $BUILD_DIR/ cp yarn.lock package.json .yarnrc.yml tsconfig.json $BUILD_DIR/ cp packages/api/package.json $BUILD_DIR/packages/api/package.json cp packages/component-library/package.json $BUILD_DIR/packages/component-library/package.json cp packages/crdt/package.json $BUILD_DIR/packages/crdt/package.json cp packages/desktop-client/package.json $BUILD_DIR/packages/desktop-client/package.json cp packages/desktop-electron/package.json $BUILD_DIR/packages/desktop-electron/package.json cp packages/eslint-plugin-actual/package.json $BUILD_DIR/packages/eslint-plugin-actual/package.json cp packages/loot-core/package.json $BUILD_DIR/packages/loot-core/package.json cp packages/sync-server/package.json $BUILD_DIR/packages/sync-server/package.json cp bin/package-browser $BUILD_DIR/bin/package-browser # Install dependencies using Yarn echo "Running yarn install..." cd $BUILD_DIR yarn install # Step 2: Building the Application # Copy packages directory cp -r $PROJECT_ROOT/packages $BUILD_DIR/ # Run the build command for browser echo "Building the browser version..." yarn build:browser # Focus on the sync-server workspace and install production dependencies echo "Focusing on @actual-app/sync-server workspace..." yarn workspaces focus @actual-app/sync-server --production # Remove symbolic links for unnecessary packages echo "Removing symbolic links for @actual-app/web and @actual-app/sync-server..." rm -rf node_modules/@actual-app/web node_modules/@actual-app/sync-server # Copy the @actual-app/web artifacts manually echo "Copying @actual-app/web artifacts..." mkdir -p node_modules/@actual-app/web cp packages/desktop-client/package.json node_modules/@actual-app/web/package.json cp -r packages/desktop-client/build node_modules/@actual-app/web/ # Step 3: Production Setup # Create the production directory structure PROD_DIR=~/actual-prod mkdir -p $PROD_DIR echo "Setting up production directory..." cp -r $BUILD_DIR/node_modules $PROD_DIR/ cp $BUILD_DIR/packages/sync-server/{package.json,app.js} $PROD_DIR/ cp -r $BUILD_DIR/packages/sync-server/src $PROD_DIR/ cp -r $BUILD_DIR/packages/sync-server/migrations $PROD_DIR/ ``` It ends up being the expected hundred something MiB: ``` $ du -sh actual-* 545M actual-build 116M actual-prod 280M actual-src ``` I have not put much thoughts into it and recreated it almost one-to-one an copying things like that is probably not the most efficient but you get the jist of it. Maybe it would be nice to have something similar with the `bin` folder in order to build a production ready server, don't you think?
Author
Owner

@pogman-code commented on GitHub (Apr 7, 2025):

A striped down version that has the same outcome:

#!/usr/bin/env bash
set -e

yarn install
yarn build:browser
yarn workspaces focus @actual-app/sync-server --production

BUILD_DIR=build
mkdir -p $BUILD_DIR
cp -r node_modules $BUILD_DIR/
cp packages/sync-server/{package.json,app.js} $BUILD_DIR/
cp -r packages/sync-server/src $BUILD_DIR/
cp -r packages/sync-server/migrations $BUILD_DIR/

# Remove symbolic links for unnecessary packages
rm -rf $BUILD_DIR/node_modules/@actual-app/web $BUILD_DIR/node_modules/@actual-app/sync-server

# Copy the @actual-app/web artifacts manually
mkdir -p $BUILD_DIR/node_modules/@actual-app/web
cp packages/desktop-client/package.json $BUILD_DIR/node_modules/@actual-app/web/package.json
cp -r packages/desktop-client/build $BUILD_DIR/node_modules/@actual-app/web/
<!-- gh-comment-id:2782859565 --> @pogman-code commented on GitHub (Apr 7, 2025): A striped down version that has the same outcome: ```bash #!/usr/bin/env bash set -e yarn install yarn build:browser yarn workspaces focus @actual-app/sync-server --production BUILD_DIR=build mkdir -p $BUILD_DIR cp -r node_modules $BUILD_DIR/ cp packages/sync-server/{package.json,app.js} $BUILD_DIR/ cp -r packages/sync-server/src $BUILD_DIR/ cp -r packages/sync-server/migrations $BUILD_DIR/ # Remove symbolic links for unnecessary packages rm -rf $BUILD_DIR/node_modules/@actual-app/web $BUILD_DIR/node_modules/@actual-app/sync-server # Copy the @actual-app/web artifacts manually mkdir -p $BUILD_DIR/node_modules/@actual-app/web cp packages/desktop-client/package.json $BUILD_DIR/node_modules/@actual-app/web/package.json cp -r packages/desktop-client/build $BUILD_DIR/node_modules/@actual-app/web/ ```
Author
Owner

@MikesGlitch commented on GitHub (Apr 15, 2025):

Hey 👋

I've mentioned this already in your PR, but I'll summarise here in case anyone's stumbling on this in the future.

The maintainers have been discussing ways to make the process simpler for folks who just want to run actual server without docker or going through the hassle of building from source. We've developed a CLI tool that does that, which we'll support going forward.

When it's released, it will be as easy as installing one npm package and running it - it should be roughly around 75MB in total.

Hopefully the package will resolve this issue - it will be released in 25.5.0 - so early May. More info to come in the next release announcement!

<!-- gh-comment-id:2807392828 --> @MikesGlitch commented on GitHub (Apr 15, 2025): Hey 👋 I've mentioned this already in your PR, but I'll summarise here in case anyone's stumbling on this in the future. The maintainers have been discussing ways to make the process simpler for folks who just want to run actual server without docker or going through the hassle of building from source. We've developed a CLI tool that does that, which we'll support going forward. When it's released, it will be as easy as installing one npm package and running it - it should be roughly around 75MB in total. Hopefully the package will resolve this issue - it will be released in 25.5.0 - so early May. More info to come in the next release announcement!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/actual#16251