How to use greenlock-express with docker? (without renewing on each container start?) #58

Open
opened 2020-08-14 06:25:26 +00:00 by Ghost · 6 comments

I've been wasting past 20 hours non stop trying to figure out how to setup ssl with auto renew.. I'm only writting because I noticed (from the many issues) you really care about making an easy to use api (at contrary of letsencrypt and certbot maintainers).

So here #13 (comment) you said that

The CLI is something I created in particular to ease some of the Docker frustrations - so that you can just put a line right after npm install, perhaps with an environment variables and, boom, be done.

But how you will fix the issue that will get a new certificate every time a docker starts?

I'd imagine the best way to manage docker + node would be like this:

let certs = await getCertsFromDatabase()
if(certs){
    // check if is still valid
	startApp(certs)
}else{
    certs = greenlock.createCerts({domains: ['a.com']})
    await saveCertsToDatabase(certs)
}
// somehow renew every X days

If you’re layering a lot of complexity with dev ops tools, but you don’t really understand the tools that well (i.e. Docker), either use ENVIRONMENT variables or put the npx greenlock ... commands in your setup script. You MUST use a database for lambda “cloud functions” and such.

So here you say to use env vars... but doesn't really solve the problem of how to save the certs to database? Again npx greenlock ... commands in your setup script using this it will renew on every image start.

I've been wasting past 20 hours non stop trying to figure out how to setup ssl with auto renew.. I'm only writting because I noticed (from the many issues) you really care about making an easy to use api (at contrary of letsencrypt and certbot maintainers). So here https://git.rootprojects.org/root/greenlock-express.js/issues/13#issuecomment-9107 you said that > The CLI is something I created in particular to ease some of the Docker frustrations - so that you can just put a line right after npm install, perhaps with an environment variables and, boom, be done. But how you will fix the issue that will get a new certificate every time a docker starts? I'd imagine the best way to manage docker + node would be like this: ``` let certs = await getCertsFromDatabase() if(certs){ // check if is still valid startApp(certs) }else{ certs = greenlock.createCerts({domains: ['a.com']}) await saveCertsToDatabase(certs) } // somehow renew every X days ``` > If you’re layering a lot of complexity with dev ops tools, but you don’t really understand the tools that well (i.e. Docker), either use ENVIRONMENT variables or put the npx greenlock ... commands in your setup script. You MUST use a database for lambda “cloud functions” and such. So here you say to use env vars... but doesn't really solve the problem of how to save the certs to database? Again `npx greenlock ... commands in your setup script` using this it will renew on every image start.
Owner

you really care about making an easy to use api (at contrary of letsencrypt and certbot maintainers)

Thank you, but don't write them off just yet. There's a lot of nuance to the security handshakes and so the ACME APIs are complicated because they're complicated, but they're also kind of genious.

I think that we need newer, modern versions of tool like curl that have jose and jwt built in - and that programming language stacks need to up their game.

Possible Solutions

  1. Can you use a mounted volume?

That would be the absolute simplest way to go about this.

  1. Would the sequelize store work for you?

https://git.rootprojects.org/root/greenlock-store-sequelize.js

  1. If not, could you define the set and get callbacks using this?

https://git.rootprojects.org/root/greenlock-store-test.js

Note that you absolutely could create a single table and use it as a key/value store, and then fill out the various functions by tagging the keys and certs appropriately with a type column.

> you really care about making an easy to use api (at contrary of letsencrypt and certbot maintainers) Thank you, but don't write them off just yet. There's a lot of nuance to the security handshakes and so the ACME APIs are complicated because they're complicated, but they're also kind of genious. I think that we need newer, modern versions of tool like `curl` that have `jose` and `jwt` built in - and that programming language stacks need to up their game. ## Possible Solutions 1. Can you use a mounted volume? That would be the absolute simplest way to go about this. 2. Would the sequelize store work for you? https://git.rootprojects.org/root/greenlock-store-sequelize.js 3. If not, could you define the set and get callbacks using this? https://git.rootprojects.org/root/greenlock-store-test.js Note that you absolutely could create a single table and use it as a key/value store, and then fill out the various functions by tagging the keys and certs appropriately with a `type` column.
Owner

you really care about making an easy to use api (at contrary of letsencrypt and certbot maintainers)

Thank you, but don't write them off just yet. There's a lot of nuance to the security handshakes and so the ACME APIs are complicated because they're complicated, but they're also kind of genious.

I think that we need newer, modern versions of tool like curl that have jose and jwt built in - and that programming language stacks need to up their game.

Possible Solutions

  1. Can you use a mounted volume?

That would be the absolute simplest way to go about this.

  1. Would the sequelize store work for you?

https://git.rootprojects.org/root/greenlock-store-sequelize.js

  1. If not, could you define the set and get callbacks using this?

https://git.rootprojects.org/root/greenlock-store-test.js

Note that you absolutely could create a single table and use it as a key/value store, and then fill out the various functions by tagging the keys and certs appropriately with a type column.

Also note that although the docs show usage examples for Greenlock v2.7+, the tests should be valid for Greenlock v3/v4.

> you really care about making an easy to use api (at contrary of letsencrypt and certbot maintainers) Thank you, but don't write them off just yet. There's a lot of nuance to the security handshakes and so the ACME APIs are complicated because they're complicated, but they're also kind of genious. I think that we need newer, modern versions of tool like `curl` that have `jose` and `jwt` built in - and that programming language stacks need to up their game. ## Possible Solutions 1. Can you use a mounted volume? That would be the absolute simplest way to go about this. 2. Would the sequelize store work for you? https://git.rootprojects.org/root/greenlock-store-sequelize.js 3. If not, could you define the set and get callbacks using this? https://git.rootprojects.org/root/greenlock-store-test.js Note that you absolutely could create a single table and use it as a key/value store, and then fill out the various functions by tagging the keys and certs appropriately with a `type` column. Also note that although the docs show usage examples for Greenlock v2.7+, the tests should be valid for Greenlock v3/v4.
Author

Wow! thanks for the quick response!

Thank you, but don’t write them off just yet. There’s a lot of nuance to the security handshakes and so the ACME APIs are complicated because they’re complicated, but they’re also kind of genious.

They are saying is the easiest way to setup, but I think they didn't do a count on the amount of questions made to setup and don't consider people like me that don't even post a question - because many questions are not even answered.

IMO is complicated if you don't use a managed solution and in that case they push you to their paid alternatives... where guess what... I managed to get a cert in minutes! Of course, no auto renew. The interesing fact is that 3m certs are free, but 12m are paid. And on their website say that 3m certs are better (more secure). If that would be true, the pricing should be reversed I'd say.

I'm sure many people would be happy with manual renewal every 1-3 years. For low security apps, it's not worth it to do it every 3 months. I gave up some projects beacuse SSL renewal is too painful.


I could use 1) but I'm using ECS, with EC2. I only use 1 machine, but I might have more later. How would it work if I setup a mounted volume and I have 2 machines? each will get their own ssl certs and keep renewing?

I rather use a database for this. I'm planning to drop sequelize because future doesn't look bright and last versions are broken.

Maybe option 3 is the best, but I can consider option 2 for short term.

For option 2 I can see store: require('greenlock-store-sequelize').create({ storeDatabaseUrl: dbUrl }) looks good and easy to implement actually. But is using Greenlock and not Greenlock-express. not sure how to pass the store, just set as manager key?

Option 3: do you have some example e2e with Greenlock-express? https://git.rootprojects.org/root/greenlock-store-test.js seems to be a repo to test my manager/store. Ah.. so I need to implement that api and pass it to the store for the config? But not sure why there are so many configs https://git.rootprojects.org/root/greenlock-store-test.js#user-content-overview - I'd expect to give me a JSON and I give you back a JSON.

Wow! thanks for the quick response! > Thank you, but don’t write them off just yet. There’s a lot of nuance to the security handshakes and so the ACME APIs are complicated because they’re complicated, but they’re also kind of genious. They are saying is the easiest way to setup, but I think they didn't do a count on the amount of questions made to setup and don't consider people like me that don't even post a question - because many questions are not even answered. IMO is complicated if you don't use a managed solution and in that case they push you to their paid alternatives... where guess what... I managed to get a cert in minutes! Of course, no auto renew. The interesing fact is that 3m certs are free, but 12m are paid. And on their website say that 3m certs are better (more secure). If that would be true, the pricing should be reversed I'd say. I'm sure many people would be happy with manual renewal every 1-3 years. For low security apps, it's not worth it to do it every 3 months. I gave up some projects beacuse SSL renewal is too painful. ------- I could use 1) but I'm using ECS, with EC2. I only use 1 machine, but I might have more later. How would it work if I setup a mounted volume and I have 2 machines? each will get their own ssl certs and keep renewing? I rather use a database for this. I'm planning to drop sequelize because future doesn't look bright and last versions are broken. Maybe option 3 is the best, but I can consider option 2 for short term. For option 2 I can see `store: require('greenlock-store-sequelize').create({ storeDatabaseUrl: dbUrl })` looks good and easy to implement actually. But is using `Greenlock` and not `Greenlock-express`. not sure how to pass the store, just set as `manager` key? Option 3: do you have some example e2e with `Greenlock-express`? https://git.rootprojects.org/root/greenlock-store-test.js seems to be a repo to test my manager/store. Ah.. so I need to implement that api and pass it to the `store` for the config? But not sure why there are so many configs https://git.rootprojects.org/root/greenlock-store-test.js#user-content-overview - I'd expect to give me a JSON and I give you back a JSON.
Owner

Wow! thanks for the quick response!

Usually I take about 3 weeks to respond :-/ but I've been trying to get better. :)

I happened to be checking my email right as you posted this I think.

not sure why there are so many configs

Because there's a many-to-many relationship between

  • keys <-> accounts
  • certs <-> accounts
  • certs <-> keys

do you have some example e2e with Greenlock-express

If you just modify the quick start to use the store implementation that you want, with the options that you want, that should do the trick:

npx greenlock defaults --store ./path/to/store.js --store-foo xxxx --store-bar yyyy

I think this would be the way to do that for the sequelize store:

# With PostgreSQL (mind the stutter of --store-store-...)
npx greenlock defaults --store greenlock-store-sequelize --store-store-database-url 'postgres://postgres@postgres:5432/postgres'

# With SQLite (not your use case, for sure)
npx greenlock defaults --store greenlock-store-sequelize --store-config-dir './greenlock.d/store-sequelize/'
> Wow! thanks for the quick response! Usually I take about 3 weeks to respond :-/ but I've been trying to get better. :) I happened to be checking my email right as you posted this I think. > not sure why there are so many configs Because there's a many-to-many relationship between - keys <-> accounts - certs <-> accounts - certs <-> keys > do you have some example e2e with Greenlock-express If you just modify the quick start to use the store implementation that you want, with the options that you want, that _should_ do the trick: ```bash npx greenlock defaults --store ./path/to/store.js --store-foo xxxx --store-bar yyyy ``` I think this would be the way to do that for the sequelize store: ```bash # With PostgreSQL (mind the stutter of --store-store-...) npx greenlock defaults --store greenlock-store-sequelize --store-store-database-url 'postgres://postgres@postgres:5432/postgres' # With SQLite (not your use case, for sure) npx greenlock defaults --store greenlock-store-sequelize --store-config-dir './greenlock.d/store-sequelize/' ```
Author

So I'd run CMD ["npx ", "greenlock defaults --store greenlock-store-sequelize --store-store-database-url 'postgres://postgres@postgres:5432/postgres'"] or similar on the docker image when it starts.

How do I get the certs back to node js? I assume it will save them to somewhere to the filesystem?

I normally prefer to have it as a script in node.js as things are simpler. I will investigate, but is not that easy to see how to use it in javascript and then pass the cert details as string to my express instance.

So I'd run `CMD ["npx ", "greenlock defaults --store greenlock-store-sequelize --store-store-database-url 'postgres://postgres@postgres:5432/postgres'"]` or similar on the docker image when it starts. How do I get the certs back to node js? I assume it will save them to somewhere to the filesystem? I normally prefer to have it as a script in node.js as things are simpler. I will investigate, but is not that easy to see how to use it in javascript and then pass the cert details as string to my express instance.
Owner

How do I get the certs back to node js? I assume it will save them to somewhere to the filesystem?

You don't. That's the purpose of the store - so that it would save them in the database or on the mounted volume.

pass the cert details as string to my express instance

You wouldn't do that either. You export your express instance to Greenlock Express, which will run it (or any other standard node http function) after https has been handled.

> How do I get the certs back to node js? I assume it will save them to somewhere to the filesystem? You don't. That's the purpose of the store - so that it would save them in the database or on the mounted volume. > pass the cert details as string to my express instance You wouldn't do that either. You export your express instance to Greenlock Express, which will run it (or any other standard node http function) _after_ https has been handled.
Sign in to join this conversation.
No Label
No Milestone
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: root/greenlock-express.js#58
No description provided.