I’m currently trying to create an one-click catalog deployment of an nginx container with letsencrypt based on “github.com/JrCs/docker-letsencrypt-nginx-proxy-companion” and “github.com/jwilder/docker-gen” with the official nginx docker container.
For now the catalog template work as expected and i can bring up an stack with nginx and 2 sidekicks (letsencrypt/docker-gen) who is proxying the virtual hosts to my containers.
My problem is that i have a few problems i currently don’t know how to get rid off:
The letsencrypt companion has an env-var (NGINX_DOCKER_GEN_CONTAINER) to be able to trigger the creation of the nginx configuration + reloading nginx. The value of this env-var should be the name of the docker-gen container but rancher creates his own name based on the stack name and so on. Is it possible to lets say use an other variable to pass the name of the docker-gen container to the letsencrypt container?
The docker-gen container needs an template file to work so i have to curl this before the creation of the containers. Is there a way to run a curl command inside the docker-compose file or is it better to create an “app” which bootstraps something like that? I also want to generate an webGUI for changing nginx configs so there will be an custom created app for this.
PS: Sry for the bad language, i hope everyone understands what i want to do.
PPS: aahhh as a new user i can only put two links in an post -.-
Thanks for your help,
Hi, We’ve done this using rancher-metadata service. In your example it would require to setup
export NGINX_DOCKER_GEN_CONTAINER=`curl -s rancher-metadata/latest/self/container/name`
This will always result with current container name.
Thank you for your fast reply unfortunately these are my first/second steps with docker and I need a little bit more information on what you want me to do ^^
The NGINX_DOCKER_GEN_CONTAINER hast to be set for the letsencrypt container and it needs as value the name of the docker-gen container so “rancher-metadata/latest/self/container/name” appears to me to reference to the letsencrypt not docker-gen.
The second thing is it possible to use “export” in the composer.yml? Or where should I put that?
Thanks in advance,
So you need to get other containers in your current stack? You can do it also via rancher-metadata but it will be a bit trickier.
Unfortunately you cannot use comands as result in ENV in docker-compse to user result of another command you need to have some kinf of bootstrap.sh file which will load all missing data before running you application.
So if you wold like to get hostnames(not service name) for other container in stack it would be sth like
curl -s rancher-metadata/latest/self/stack/services/<Service_Name>/containers
Then you need to pares result(you can receive them as json response also if you pass accepted parameters) and export as env variable. In this schema you can provide <Service_Name> as parameter. Of course you can also check other stack and do same thing with other stack
“rancher-metadata/latest/self/container/name” Will always return your container, if
Oh yeah thanks for that explanation now i know what i have to do.
We have this working with a combination of the following containers:
- our own version of jwilder/nginx-proxy which is basically an extension of the base image with our standard template files included - so new containers have a default nginx.tmpl file to use
- A data container (always use data containers where possible to persist relevant data durin gupgrades) with the files being used / created by the pother containers.
This works without having to do anything but spin up a stack - and make sure ports 80 and 443 are accessible on the host (otherwise letsencrypt fails)
i know about the jwilder/nginx-proxy container but jrcs and also jwilder are recommending the 3 container way with the official nginx container and the docker-gen container in case of security cause the nginx-proxy container is using the docker.socket and is accessible from outside (80/443).
About the data-container i’m using volumes for all shared paths i think that is the best i can do.
I found out that the letsencrypt container does not need the “NGINX_DOCKER_GEN_CONTAINER” if you are using the volumes from the nginx container cause the app itself gets the id of this container over the linked volumes.
The only thing i have to fix is the “command” for the docker-gen container cause there is also the “nginx” container name in there which is not present.
I had some issues with the container name and managed to sort this out by turning things on it’s head a little in my catalog entry so that the letsencrypt-companion container is the main container and this then has the nginx container as a sidekick:
This means that I can do :
and the nginx-proxy container has :
nginx-proxy-data is the data container that we store all the data from the setup in - not on the host but in a separate container. This means we don’t have any dependency on files or dirs on the host.
I think the reference to the nginx container also works if you set the docker-compose “hostname” property for the nginx container.
Any chance you could share your YAML files? I’ve been tinkering with this recipe for a while, and some of the Rancher-specific stuff has been tripping me up.
Sure you can find my catalog repository under: https://github.com/Munsio/rancher-cattle-nginx-letsencrypt
(You can add it under Admin->Settings->Add Catalog)
I had to fork the letsencrypt container to download the nginx.tmpl and create an docker-gen config file - i try to contact jrcs to make is container configureable via an config file cause there are some things that could be done better imho.
For the catalog template:
Everything is running in an volume if you want to add custom locations or something else you can do it in the specific volume (proxyPasswd/proxyVhost) just create an file named the same as the domain you want it for.
For more information about the vhost files just read this section of nginx-proxy:
I’m unfamiliar with how to use the catalog – all my stuff is orchestrated from the command line with rancher-compose. Adding the catalog was pretty easy, and spinning up a new stack was even easier!
I have some questions, though:
- How does it know what domain for which it must request a certificate? https://github.com/fatk/docker-letsencrypt-nginx-proxy-companion-examples has a “simple-site” example which has worked very well for orchestrating my Rancher server itself but I can’t see where to put my own “simple-site” in your example.
- Similarly, where do you put the services which will use those certs? Must they be in the same stack so they can share the volumes, or do you have your web/mail/whatever-needs-a-cert containers in a separate stack and then cross-link to this one to access the certs?
- Finally, can more than one of these stacks run on a single host?
Thank you in advance for your help. This has been a blocker for me for a long, long time.
Great to hear that you got it up and running
- Lets say you want to host an “ghost blog” website with its docker container. So you creating an Service adding the image and the only thing left is the environment-vars. You need 3 of them:
- VIRTUAL_HOST: example.com - The virtual_host var defines which domain nginx should listen. Also thanks to docker-gen it adds the internal ip address to an upstream directive so you dont have to do anything else to get your blog running under example.com
- LETSENCRYPT_HOST: example.com - the same as virtual host except if you want an SAN cert but for that please read the documentation from jrcs repository.
- LETSENCRYPT_EMAIL: Your email address where the cert is pointing to.
- VIRTUAL_PORT: This one is optional but if you have multiple ports in one container you had to specify which one should be used.
Just leave the “Proxy” Service allone and create new one for your apps - the only restriction is that you need an proxy service for each environment
I don’t know if this is possible or better if you need that - afaik there is only one webserver needed one an machine even if there are multiple ip-addresses pointing to it cause nginx is using the incoming domain name to determine where to route the request.
My first use case is indeed a simple blog in its own Docker container.
Everything worked exactly as you described. I am so excited!
Hey there! Still very happy with your catalog entry, but I have a feature request.
Somewhere in your configuration you enable HSTS. This is great, but I’d really really appreciate it if you could make includeSubDomains optional. Having that in there breaks stuff for me, and it took me two or three days to figure out where and why. Any chance you could help me out here? I’d make an issue on one of your repositories, but I don’t know where.
Thank you so much!
@mathuin you should file your enhancement/feature requests here: https://github.com/rancher/rancher/issues
Glad things are working for you!