Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamodb Error: Nodejs App with dynamodb does not work in docker but works without it #216

Open
helloravi opened this issue Jun 29, 2017 · 6 comments

Comments

@helloravi
Copy link

helloravi commented Jun 29, 2017

I made a simple nodejs app with only one table in dynamodb. I am using Vogels as the datawrapper. It works very well if I do not dockerize it.

I tried running the docker exactly the way I run the app in development mode too. That too did not work.

Here is the code I use to create tables:

module.exports = function () {
	const vogels = require('vogels');
    // const AWS= require('aws-sdk');
    const Lr = require("../api/models/LRModel");
    if (process.env.NODE_ENV === "test") {
        AWS.config.update({ accessKeyId: "myKeyId", secretAccessKey: "secretKey", region: "us-west-2" });
        vogels.dynamoDriver(new AWS.DynamoDB({ endpoint: 'http://localhost:8000' }));
    } else {
        console.log("AWS access key=", process.env.AWS_ACCESS_KEY, "AWS Secret key=", process.env.AWS_SECRET_KEY, "AWS Region =", process.env.AWS_REGION);
        vogels.AWS.config.update({accessKeyId: process.env.AWS_ACCESS_KEY, secretAccessKey: process.env.AWS_SECRET_KEY, region: process.env.AWS_REGION, sslEnabled: false });

    }

	vogels.createTables({
		'lrs': {readCapacity: 10, writeCapacity: 10}
	}, function(err) {
		if (err) {
			console.log('Error creating tables: ', err);
		} else {
			console.log('Tables have been created');
		}
	});
}

Here is the error I get in docker:

server-0   | Error creating tables:  { TimeoutError: Missing credentials in config
server-0   |     at ClientRequest.<anonymous> (/app/node_modules/vogels/node_modules/aws-sdk/lib/http/node.js:61:34)
server-0   |     at ClientRequest.g (events.js:291:16)
server-0   |     at emitNone (events.js:86:13)
server-0   |     at ClientRequest.emit (events.js:185:7)
server-0   |     at Socket.emitTimeout (_http_client.js:626:10)
server-0   |     at Socket.g (events.js:291:16)
server-0   |     at emitNone (events.js:86:13)
server-0   |     at Socket.emit (events.js:185:7)
server-0   |     at Socket._onTimeout (net.js:339:8)
server-0   |     at ontimeout (timers.js:365:14)
server-0   |   message: 'Missing credentials in config',
server-0   |   code: 'CredentialsError',
server-0   |   time: 2017-06-29T05:36:23.724Z,
server-0   |   originalError:
server-0   |    { message: 'Could not load credentials from any providers',
server-0   |      code: 'CredentialsError',
server-0   |      time: 2017-06-29T05:36:23.724Z,
server-0   |      originalError:
server-0   |       { message: 'Missing credentials in config',
server-0   |         code: 'CredentialsError',
server-0   |         time: 2017-06-29T05:36:23.721Z,
server-0   |         originalError: [Object] } } }

One thing I clearly notice when I run it WITHOUT docker is that the dynamodb end point is a httpS end point. Here is the endpoint logged from https://github.com/aws/aws-sdk-js/blob/8904e9c730fb2fccf9d201f66266a6e2cbb75348/lib/http/node.js
(line number 13).

server-0   |   Endpoint {
server-0   |   protocol: 'https:',
server-0   |   host: 'dynamodb.us-west-1.amazonaws.com',
server-0   |   port: 443,
server-0   |   hostname: 'dynamodb.us-west-1.amazonaws.com',
server-0   |   pathname: '/',
server-0   |   path: '/',
server-0   |   href: 'https://dynamodb.us-west-1.amazonaws.com/',
server-0   |   constructor: { [Function: Endpoint] __super__: [Function: Object] } }

When I run it WITH docker is that the dynamodb end point is a http end point. Here is the endpoint logged from https://github.com/aws/aws-sdk-js/blob/8904e9c730fb2fccf9d201f66266a6e2cbb75348/lib/http/node.js
(line number 13).

server-0   |   Endpoint {
server-0   |   protocol: 'http:',
server-0   |   host: '169.254.169.254',
server-0   |   port: 80,
server-0   |   hostname: '169.254.169.254',
server-0   |   pathname: '/latest/meta-data/iam/security-credentials/',
server-0   |   path: '/latest/meta-data/iam/security-credentials/',
server-0   |   href: 'http://169.254.169.254/latest/meta-data/iam/security-credentials/' }

Where am I going wrong with this?

@set-killer
Copy link

What is the output of:

console.log("AWS access key=", process.env.AWS_ACCESS_KEY, "AWS Secret key=", process.env.AWS_SECRET_KEY, "AWS Region =", process.env.AWS_REGION);

Are there any values for those environment variables?
If their values are not setted you should configure your user (which runs your docker) to set those environment variables from somewhere.

Also try to put the credential keys directly in the code instead of getting them from the user's environment... Probably it is an environment issue.

@helloravi
Copy link
Author

All the values work. I hard coded them to check. That did not work either with docker.

I have been struggling with this for a couple of days. Let me know if i have to add any other details to this. Thanks for taking the time to respond

@set-killer
Copy link

In that case I guess you have 2 options:
process.env.NODE_ENV === "test" equals true so it tries to connect to the local aws,
Or your access keys are incorrect. You may try to issue new keys.

If you run env inside the docker with the user which is going to run the application you should see your access keys... And why are putting this option: sslEnabled: false

@helloravi
Copy link
Author

There is a point of analysis which I did not highlight it enough.

  1. It works very well if I dont dockerize it. Just run it with `npm run dev'.
  2. Initially I did not put sslEnabled: false. After I saw the end point log from node.js in aws-sdk I wanted to make both the calls http(without S). There is no change with or without sslEnabled.

@set-killer
Copy link

Well then, the problem is in your docker configuration. Perhaps you should ask their community.

As you know the docker container runs in sandboxed environment, which means it does not have access to the outside "world". You should put your AWS credentials inside the docker container and configure the user which runs the APP inside the container to have those environment credentials...

Also ssl enabled is highly recommended since you may have sensitive information transferred from dynamoDB to your server such as users password and etc...

@avtaniket
Copy link

@helloravi If you are using EC2, recommended way is to use IAM role to allow DynamoDB access and this will work for Docker apps.
Using roles you don't need to pass Access key, Vogels will detect it automatically.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants