certificates and not intermediate CAs.
```ini
[root_ca]
basicConstraints = critical,CA:TRUE,pathlen:1
keyUsage = critical, nonRepudiation, cRLSign, keyCertSign
subjectKeyIdentifier=hash
```
4. Sign the certificate.
```console
$ openssl x509 -req -days 3650 -in "root-ca.csr" \
-signkey "root-ca.key" -sha256 -out "root-ca.crt" \
-extfile "root-ca.cnf" -extensions \
root_ca
```
5. Generate the site key.
```console
$ openssl genrsa -out "site.key" 4096
```
6. Generate the site certificate and sign it with the site key.
```console
$ openssl req -new -key "site.key" -out "site.csr" -sha256 \
-subj '/C=US/ST=CA/L=San Francisco/O=Docker/CN=localhost'
```
7. Configure the site certificate. Edit a new file called `site.cnf` and
paste the following contents into it. This constrains the site
certificate so that it can only be used to authenticate a server and
can't be used to sign certificates.
```ini
[server]
authorityKeyIdentifier=keyid,issuer
basicConstraints = critical,CA:FALSE
extendedKeyUsage=serverAuth
keyUsage = critical, digitalSignature, keyEncipherment
subjectAltName = DNS:localhost, IP:127.0.0.1
subjectKeyIdentifier=hash
```
8. Sign the site certificate.
```console
$ openssl x509 -req -days 750 -in "site.csr" -sha256 \
-CA "root-ca.crt" -CAkey "root-ca.key" -CAcreateserial \
-out "site.crt" -extfile "site.cnf" -extensions server
```
9. The `site.csr` and `site.cnf` files are not needed by the Nginx service, but
you need them if you want to generate a new site certificate. Protect
the `root-ca.key` file.
#### Configure the Nginx container
1. Produce a very basic Nginx configuration that serves static files over HTTPS.
The TLS certificate and key are stored as Docker secrets so that they
can be rotated easily.
In the current directory, create a new file called `site.conf` with the
following contents:
```nginx
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /run/secrets/site.crt;
ssl_certificate_key /run/secrets/site.key;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
```
2. Create three secrets, representing the key, the certificate, and the
`site.conf`. You can store any file as a secret as long as it is smaller
than 500 KB. This allows you to decouple the key, certificate, and
configuration from the services that use them. In each of these
commands, the last argument represents the path to the file to read the
secret from on the host machine's filesystem. In these examples, the secret
name and the file name are the same.
```console
$ docker secret create site.key site.key
$ docker secret create site.crt site.crt
$ docker secret create site.conf site.conf
```
```console
$ docker secret ls
ID NAME CREATED UPDATED
2hvoi9mnnaof7olr3z5g3g7fp site.key 58 seconds ago 58 seconds ago
aya1dh363719pkiuoldpter4b site.crt 24 seconds ago 24 seconds ago
zoa5df26f7vpcoz42qf2csth8 site.conf 11 seconds ago 11 seconds ago
```
3. Create a service that runs Nginx and has access to the three secrets. The
last part of the `docker service create` command creates a symbolic link
from the location of the `site.conf` secret to `/etc/nginx.conf.d/`, where
Nginx looks for extra configuration files. This step happens before Nginx
actually starts, so you don't need to rebuild your image if you change the
Nginx configuration.
> [!NOTE]
>
> Normally you would create a Dockerfile which copies the `site.conf`
> into place, build the image, and run a container using your custom image.