Lambda Localstack Cannot Access Mysql Container in Docker Compose

Viewed 93

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?

1 Answers

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
Related