encore icon indicating copy to clipboard operation
encore copied to clipboard

Go / docker container builds behaviour

Open lukaszraczylo opened this issue 9 months ago • 1 comments

Hi everyone, I have dozen of microservices written in encore.

I use following script to build the services:

#!/bin/bash
SEMVER=$(semver-gen generate -l | grep SEMVER | awk '{print $2}')
echo "Generating images with semver $SEMVER"
# find all directories with go files and execute command for each
find . -type f -name "*.go" -exec dirname {} \; | sort -u | while read directory; do
    ddir=$(echo $directory | xargs -n1 basename)
    encore build docker --config infra.json --services=$ddir --arch arm64 --os linux --push ghcr.io/xxx/$ddir:$SEMVER
done

There is ONE microservice which takes quite a bit of memory ( 350Mb+ ). Rest of the microservices usually take between 10-20Mb which is fine.

As far as I understand from brief read of the documentation, when specifying --services flag ONLY the specified microservice should be included in the build, not all of them. Unfortunately it looks like it's not exactly what happens. After I have added the "memory hungry" microservice to the codebase, now - when ALL of the microservices start - each of them takes 350Mb+ which points me towards:

despite of specifying SINGLE service flag for the docker build - all of the microservices are included in the build, despite of specifying SINGLE service flag for the docker build - ALL of the microservices start / load for some akward reason.,

Could anyone help me sorting out the separation / update the documentation as if I'm supposed to add more microservices - not only the docker container is currently on 150mb size (!) but I'd need to entirely abandon the idea of moving to encore because I'll run out of RAM in my cluster quite quickly.

Edit1:

As part of the test I built a test image with encore build docker --arch arm64 --os linux --services=main_microservice --base golang:bookworm --config ./infra.json ghcr.io/xxx/main_microservice:test

Then I have checked whats inside of the image and it looks like:

# du -hs encore_app_out
181M    encore_app_out

When I build this code and this code alone with standard http library - the binary size is about 4mb. In this case I am quite sure that ALL the microservices are included within the container build, and all of them start for some awkward reason which is FAR from optimal and definitely makes it more of a MACROSERVICES. Also I have tested the same command with the most memory hungry microservice excluded. The microservice is much further down the line and it's never accessed by the microservice I'm building. This - at least in theory should build only the microservice in question but nope, the docker build failed.

Edit2:

I have also built the image without services specified and size is exactly the same, which suggests that the --services flag is completely ignored

Edit3:

Final test:

package potato_service

import (
    "context"
)

type Response struct {
    Status string `json:"status"`
}

type CheckSentiment struct {
    Content string `json:"text_to_check"`
}

//encore:api private path=/potato/check
func CheckPotato(ctx context.Context, params *CheckSentiment) (*Response, error) {
    return &Response{Status: "ok"}, nil
}

Added as a service to other services. Note no dependencies on any other services whatsoever.

Build:

encore build docker --services=potato_service --base golang:bookworm --config ./infra.json ghcr.io/xxx/potato:test2

Result: 1.05GB image and

# du -hs encore_app_out
184M    encore_app_out

The size of binary grew by 3mb which would be +/- the size of microservice with http server and stuff.

( copy/pasted from discord for visibility: https://discord.com/channels/814482502336905216/1373389805282656296/1373389805282656296 )

lukaszraczylo avatar May 18 '25 11:05 lukaszraczylo

Facing the same issue with encorets

Discord Issue link

Adding the issue link from discord for reference

sanjay-complyance avatar Oct 15 '25 13:10 sanjay-complyance