2

I am using LocalStack Docker and AWS CDK v2 image and I want to hot reload Lambda functions after file saves

services:
  backend:
    container_name: "${LOCALSTACK_DOCKER_NAME:-backend}"
    image: localstack/localstack
    ports:
      - "127.0.0.1:4566:4566"            # LocalStack Edge Proxy
      - "127.0.0.1:4510-4559:4510-4559"  # External services ports
      - "127.0.0.1:8080:8080"            # LocalStack Web UI (optional)
      - "127.0.0.1:4000:4000"            # LocalStack Web UI (optional)
    environment:
      - DEBUG=1
      - SERVICES=dynamodb,lambda,apigateway,appsync,events,ssm,secretsmanager,s3,sqs,sns,cloudformation,iam,logs
      - DEFAULT_REGION=us-east-1
      - LAMBDA_DOCKER_NETWORK=app_network  # Critical for Lambda networking
      - HOSTNAME_EXTERNAL=backend   # For local service discovery
      - DOCKER_HOST=unix:///var/run/docker.sock
      - START_WEB=1             # Explicitly enable Web UI
      - PERSISTENCE=1           # Enable data persistence
      - LOCALSTACK_HOST=0.0.0.0
      - LOCALSTACK_MOUNT_CODE=true
      - LAMBDA_EXECUTOR=docker-reuse
      - LAMBDA_REMOTE_DOCKER=false
      - LAMBDA_RELOAD_CODE=True  # 👈 Critical new line
      - LAMBDA_CODE_MOUNT_DIR=/var/task  # Correct Lambda directory
      - LAMBDA_REMOVE_CONTAINERS=True  # 👈 Destroy containers after each invoke
      - LAMBDA_DOCKER_FLUSH=1          # Force fresh pulls
    volumes:
      - "${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack"
      - "/var/run/docker.sock:/var/run/docker.sock"
      - "./functions/build:/var/task:rw,cached"  # macOS/Windows optimization
    networks:
      - app_network

I am using this script to generate minified code inside /functions/build:

    "watch": "esbuild functions/*.ts --bundle --minify --sourcemap --platform=node --target=es2020 --outdir=functions/build --watch"

This is the function constructor

new CustomFunction(scope, id, {
    runtime,
    environment: props.environment,
    code: Code.fromAsset(LAMBDA_MOUNT_DIR),
    handler: `${fileName}.${handler}`,
})

This is how you instantiate it

const fnHello = new lambda.NodejsFunction(this, "FnHello", {
  handler: "handler",
  entry: path.join(__dirname, "../functions/hello.ts"),
  environment: {
    TABLE_NAME: table.tableName,
  },
});

I tried those options

- "./functions/build:/var/task"
- "./functions/build:/var/task:rw"
- "./functions/build:/var/task:rw,cached"

and also tweaked many values inside docker-compose.yml

The result generates the correct files /functions/build

- functions
  - build
    - hello.js
    - hello.js.map

And inside /var/task in the backend Docker container (which is the LocalStack one), it maps the files

- var
 - task
   - hello.js
   - hello.js.map

It even gets the newest updates, so when I change the code of /functions/hello.ts it updates /var/task/hello.js inside the Docker container

The problem is that when I invoke the function, I get the old response.

1 Answer 1

2

AWS CDK, when it creates the Lambda using Code.fromAsset(), packages the code into a ZIP archive during deployment. This ZIP is uploaded to LocalStack (which mocks S3 behind the scenes), and from then on, LocalStack uses that uploaded copy of your code, not the updated file on disk.

Once deployed to LocalStack, the Lambda gets snapshotted into the LocalStack state and is no longer linked to the live filesystem. That's why when you invoke the function, you get the old response.

What you can do is: deploy once the lambda, and don't redeploy the CDK after that: update only the file. Use the update-function-code in the existing Lambda code using awslocal:

awslocal lambda update-function-code \
  --function-name yourFunction \
  --zip-file fileb://functions/build/hello.zip

Why? Because redeploying via CDK re-uploads the code, and defeats the point of hot reloading. The above snippet tells LocalStack: replace the code for this Lambda with the new ZIP I give you.

Reference:

https://docs.aws.amazon.com/cli/latest/reference/lambda/update-function-code.html

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your reply, but even this would require a terminal and manual update... The issue is I will be updating a bunch of functions so it also won't be hot reloading as well... I was thinking of a solution on file save or not involving any manual interaction. What maybe I can be doing is find a way to look for the function using a script based on the file name an then execute the command on save or post-ES build
Thank you, based on your approach, I created a GitHub Gist to do it automatically gist.github.com/sofiennelassoued/… This is a video showcasing it loom.com/share/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.