How I can use a variable name in file path ?

ssl_certificate /home/ec2-user/.certificados/$server_name.crt;
ssl_certificate_key /home/ec2-user/.certificados/$server_name.key;

3 Answers 3


You cannot use variables in every directive. ssl_certificate is treated as a literal string and is one of the many directives where variables are unsupported.

To specify different certificates for hosts, you have to explicitly write it in a server block:

server {
    server_name example.com;
    ssl_certificate /home/ec2-user/.certificados/example.com.crt;
    ssl_certificate_key /home/ec2-user/.certificados/example.com.key;
    # ...
server {
    server_name example.net;
    ssl_certificate /home/ec2-user/.certificados/example.net.crt;
    ssl_certificate_key /home/ec2-user/.certificados/example.net.key;
    # ...
# ...

If you feel uncomfortable duplicating the configuration, create templates and generate the nginx configuration using those templates. See also http://nginx.org/en/docs/faq/variables_in_config.html.


You can use variables since nginx 1.15.9 (26 Feb 2019)

Note that using variables implies that a certificate will be loaded for each SSL handshake, and this may have a negative impact on performance

But be aware of Changes with nginx 1.15.12 (16 Apr 2019):

Bugfix: a segmentation fault might occur in a worker process if variables were used in the "ssl_certificate" or "ssl_certificate_key" directives and OCSP stapling was enabled.

  • 3
    Something to keep in mind here is when the certificate has a static path, it is loaded at init time which runs as root. When using a variable, it is loaded at runtime which generally runs as www or nginx so it is likely not going to have the permissions. Jul 4, 2020 at 23:24

Simple Starting Point

Here is a complete, basic, dynamic SSL cert configuration. The regex used pulls the TLDN, for instance, seacoast.com even if the request is www.seacoast.com. If you want the full domain name, just use $ssl_server_name variable anywhere in your block.

map $ssl_server_name $domain {
 default $ssl_server_name;
 ~(([^\.]+)\.([^\.]+))$ $1;

server {
 listen 443 ssl http2 default_server;
 listen [::]:443 ssl http2 default_server;
 server_name _;

 add_header Content-Type text/html;
 return 200 "domain: $domain, document_root: $document_root, request_uri: $request_uri";

 ssl_certificate /etc/letsencrypt/live/$domain/fullchain.pem; 
 ssl_certificate_key /etc/letsencrypt/live/$domain/privkey.pem; 

I found that SSL enabled blocks are unable to pull variables out of server_name and would leave me with a blank variable, whereas http blocks worked as expected. I am running Nginx 1-Alpine Docker, and automatically generating letsencrypt certs for dozens of domains.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.