Securing the AtSea App with Docker Secrets

Jul 11 2017

Passing application configuration information as environmental variables was once considered best practice in 12 factor applications. However, this practice can expose information in logs, can be difficult to track how and when information is exposed, third party applications can access this information. Instead of environmental variables, Docker implements secrets to manage configuration and confidential information.

Secrets are a way to keep information such as passwords and credentials secure in a Docker CE or EE with swarm mode. Docker manages secrets and securely transmits it to only those nodes in the swarm that need access to it. Secrets are encrypted during transit and at rest in a Docker swarm. A secret is only accessible to those services which have been granted explicit access to it, and only while those service tasks are running.

The AtSea Shop is an example storefront application that can be deployed on different operating systems and can be customized to both your enterprise development and operational environments. The previous post showed how to use multi-stage builds to create small and efficient images. In this post, I’ll demonstrate how secrets are implemented in the application.

Creating Secrets

Secrets can be created using the command line or with a Compose file. The AtSea application uses nginx as a reverse proxy secured with HTTPS. To accomplish this, I created a self-signed x509 certificate.

mkdir certs
openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key -x509 -days 365 -out certs/domain.crt

I then created secrets using the domain key and certificate for nginx.

docker secret create revprox_cert certs/domain.crt
docker secret create revprox_key certs/domain.key

I also used secrets to hold the PostgreSQL database password and a token for the payment gateway by making files that contained the password and token. For example, the postgres_password file contains the password ‘gordonpass’. In the compose file, I added the secrets:

 file: ./devsecrets/postgres_password
 file: ./devsecrets/payment_token

 I then set the database password secret,

       context: ./database
    image: atsea_db
      POSTGRES_USER: gordonuser
      POSTGRES_DB_PASSWORD_FILE: /run/secrets/postgres_password
      POSTGRES_DB: atsea
      - "5432:5432" 
      - back-tier
      - postgres_password

and I make the postgres_password secret available to the application server.

       context: .
       dockerfile: app/Dockerfile
    image: atsea_app
      - "8080:8080" 
      - "5005:5005"
      - front-tier
      - back-tier
      - postgres_password

As you can see, you can set secrets at the command line and programmatically in the a compose file.

Docker Enterprise Edition (formerly known as Docker Datacenter) fully incorporates secrets management through creation, update and removal of secrets. In addition Docker EE supports authorization, rotation and auditing of secrets. Creating a secret in Docker Enterprise Edition is accomplished by clicking on the Resources tab and then the Secrets menu item.

Docker secrets

Create the secret by entering the name and the value and clicking Create. In this example, I’m using the secret for the PostgreSQL password in the AtSea application.

 Docker secrets

Docker secrets

Using Secrets

In order to use the Secret containing the certificate for nginx, I configured the nginx.conf file to point at the secret in the nginx container.

server {
        listen 443;
        ssl on;
        ssl_certificate /run/secrets/revprox_cert;
        ssl_certificate_key /run/secrets/revprox_key;
        access_log /dev/stdout;
        error_log /dev/stderr;

        location / {
            proxy_pass http://appserver:8080;

The AtSea application uses the postgres_password secret to connect to the database. This is done by reading the secret from the container and setting it to Spring-Boot’s DataSourceProperties class in the file.

// Set password to connect to postgres using Docker secrets.
try(BufferedReader br = new BufferedReader(new  FileReader("/run/secrets/postgres_password"))) 
      StringBuilder sb = new StringBuilder();
      String line = br.readLine();

      while (line != null) {
           line = br.readLine();
      } catch (IOException e) {
         System.err.println("Could not successfully load DB password file");
return dataSourceProperties;

Learn more about Docker secrets:


2 thoughts on "Securing the AtSea App with Docker Secrets"

DockerCon 2022

Registration is now open for DockerCon 2022! Join us for this free, immersive online experience complete with product demos, breakout learning tracks, panel discussions, hacks & tips, deep dive technical sessions, and much more.

Register Now