skip to Main Content

I have a local deployment using AWS Lambda, MySQL, and Localstack using Docker compose. So the Lambda is a simple javascript code accessing MySQL.

var mysql = require('mysql');

var con = mysql.createConnection({
    host: "mariadb",
    user: "root",
    password: "password",
    database: "database"
});

exports.handler =  async function(event, context) {    

    con.connect(function(err) {
        if (err) throw err;
        console.log("Connected!");
    });

    return {
        statusCode: 200,
        body: `Received: ${event.message}`
    };
}

The docker compose is like below.

version: '3.3'
services:
  localstack:
    image: localstack/localstack:latest
    environment:
     - DEFAULT_REGION=ap-southeast-3
     - SERVICES=s3,lambda
    ports:
     - '4566-4583:4566-4583'
  mariadb:
    image: mariadb:latest
    ports:
      - "3306:3306"
    environment:
      - MYSQL_ROOT_PASSWORD=password
      - MYSQL_DATABASE=database
    restart: always

I have a simple script to bundle the Lambda, creating and uploading the function to localstack, then invoking it.

The deploy script looks like below

#!/usr/bin/env bash
echo "Bundling Function"
cd lambda
zip -r ../lambda.zip *
cd ..

echo "Creating Function"
aws lambda create-function 
    --endpoint-url http://localhost:4566 
    --function-name lambda 
    --runtime nodejs14.x 
    --role arn:aws:iam::000000000000:role/lambda 
    --handler index.handler 
    --zip-file fileb://lambda.zip
    
echo "Invoking Function"
aws lambda invoke 
    --endpoint-url http://localhost:4566 
    --function-name lambda 
    --payload fileb://payload.json 
    output.json

I have successfully deploy the Lambda to localstack. However the script failed at invocation.

I tried adding the configuration LAMBDA_DOCKER_NETWORK to bridge, host, or <project>_default but it fails at the Lambda uploading. I couldn’t find a simplest code everywhere to showcase Lambda accessing other container in Docker compose. In case you want to reproduce, I uploaded to code here https://github.com/petrabarus/lambda-localstack-database.

What did I miss?

2

Answers


  1. Chosen as BEST ANSWER

    It turns out that I have to mount the docker socket in the container. This works like charm.

    version: '3.3'
    services:
      localstack:
        container_name: "${LOCALSTACK_DOCKER_NAME-localstack_main}"
        image: localstack/localstack:latest
        environment:
         - DEFAULT_REGION=ap-southeast-3
         - SERVICES=s3,lambda
         - DEBUG=${DEBUG-}
         - PERSISTENCE=${PERSISTENCE-}
         - LAMBDA_EXECUTOR=${LAMBDA_EXECUTOR-}
        ports:
         - "127.0.0.1:4566:4566"
         - "127.0.0.1:4510-4559:4510-4559"
        volumes:
          - "${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack"
          - "/var/run/docker.sock:/var/run/docker.sock"
      postgres:
        image: postgres:alpine
        ports:
          - "5432:5432"
        volumes:
          - ./volume/postgres:/var/lib/postgresql/data
        environment:
          - POSTGRES_USER=postgres
          - POSTGRES_PASSWORD=postgres
          - POSTGRES_DB=postgres
        restart: always
    

  2. I had the same problem and the solution was adding:

    environment:
           - DOCKER_HOST=unix:///var/run/docker.sock
    volumes:
          - "/var/run/docker.sock:/var/run/docker.sock"
    

    Docker daemon process was missing in first place.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search