node.jsamazon-web-servicesdockeramazon-sqselastic-mq

Why is the Node.js AWS-SDK returning the wrong SQS queue URL when creating a local queue


I'm using ElasticMQ to simulate AWS SQS on my local dev machine. I'm running ElasticMQ inside a Docker container, using docker-osx-dev to host the Docker container on a Linux VM. This means that I access the local ElasticMQ instance at the IP of the VM, not my localhost IP.

When I try and create a queue in EMQ using the code below, it returns a queue URL at localhost and not the IP of the VM hosting the docker container.

var AWS = require('aws-sdk');
var config = {
  endpoint: new AWS.Endpoint('http://192.168.59.103:9324'),
  accessKeyId: 'na',
  secretAccessKey: 'na',
  region: 'us-west-2'
}
var sqs = new AWS.SQS(config);
var params = {
  QueueName: 'test_queue'
};
sqs.createQueue(params, function(err, data) {
  if (err) {
    console.log(err);
  } else {
    console.log(data.QueueUrl);
  }
});

Currently this code returns: http://localhost:9324/queue/test_queue, but it should return http://192.168.59.103:9324/queue/test_queue. If I replace 'localhost' in the URL with the actual IP address, I can access the queue with that URL successfully, indicating that it was indeed created, but this is a pretty nasty hack. What do I need to change in the code above to correct this issue?

Update: Invalid Endpoint I returned to this after another issue came up using an ElasticMQ simulation container. This time it was part of a docker-compose file and another container was accessing it by it's docker hostname. SQS will not accept host names with underscores in them. This will mess with most peoples docker-compose files as underscores are common. If you get an error message about invalid endpoints, try renaming your container in the compose file with a hyphen instead of an underscore (i.e. http://sqs_local:9324 will fail, http://sqs-local:9324 will be fine).


Solution

  • The problem you're facing it that ElasticMq is exposing the host and port of the container it's running in. This is a problem I've faced before and fixed it by creating a custom Docker container that lets you set the host and port programmatically.

    I've written a blog post on how to fix it, but in essence what you need to do is:

    Ultimately your command line for this is:

    $ docker run -e NODE_HOST=`docker-machine ip default` -e NODE_PORT=8000 -p 8000:9324 tddmonkey/elasticmq