[GH-ISSUE #9] Add secrets file support for docker #3

Closed
opened 2026-03-03 16:27:31 +03:00 by kerem · 2 comments
Owner

Originally created by @ChrisFromCnC on GitHub (Feb 19, 2024).
Original GitHub issue: https://github.com/natrontech/pbs-exporter/issues/9

I propose to add support to dockerfile secrets for PBS_USERNAME, PBS_API_TOKEN_NAME and PBS_API_TOKEN.

Idea is to move secrets outside of docker-compose file for instance for security purpose.

As example a docker-compose file can be created like this:
proxmoxbackup:
image: ghcr.io/natrontech/pbs-exporter:0.1.5
container_name: proxmoxbackup
restart: always
secrets:
- proxmoxbackup-username
- proxmoxbackup-api-token-name
- proxmoxbackup-api-token
environment:
PBS_USERNAME_FILE: /run/secrets/proxmoxbackup-username
PBS_API_TOKEN_NAME_FILE: /run/secrets/proxmoxbackup-api-token-name
PBS_API_TOKEN_FILE: /run/secrets/proxmoxbackup-api-token

secrets:
proxmoxbackup-username:
file: "./.secrets/proxmoxbackup_username.secret"
proxmoxbackup-api-token-name:
file: "./.secrets/proxmoxbackup_api_token_name.secret"
proxmoxbackup-api-token:
file: "./.secrets/proxmoxbackup_api_token.secret"

All secrets are now stored in a folder .secrets.

Convention naming for secrets in docker is to add _FILE to regular environnement variable.
In our case we need to manage PBS_USERNAME_FILE, PBS_API_TOKEN_NAME_FILE and PBS_API_TOKEN_FILE env variables.

I just adapt the main.go to read the new env variable for the secret file name and read the first line from the file.

Sorry I cannot add a file here so I post a diff of main

diff --git a/main.go b/main.go
index 1e6686d..cd8cd88 100644
--- a/main.go
+++ b/main.go
@@ -1,6 +1,7 @@
package main

import (

  • "bufio"
    "crypto/tls"
    "encoding/json"
    "flag"
    @@ -234,6 +235,24 @@ type Exporter struct {
    authorizationHeader string
    }

+func ReadSecretFile(secretfilename string) string {

  • file, err := os.Open(secretfilename)
  • // flag to check the file format
  • if err != nil {
  •   log.Fatal(err)
    
  • }
  • // Close the file
  • defer func() {
  •   if err = file.Close(); err != nil {
    
  •   	log.Fatal(err)
    
  •   }
    
  • }()
  • // Read the first line
  • line := bufio.NewScanner(file)
  • line.Scan()
  • return line.Text()
    +}

func NewExporter(endpoint string, username string, apitoken string, apitokenname string) *Exporter {
return &Exporter{
endpoint: endpoint,
@@ -660,12 +679,24 @@ func main() {
}
if os.Getenv("PBS_USERNAME") != "" {
*username = os.Getenv("PBS_USERNAME")

  • } else {
  •   if os.Getenv("PBS_USERNAME_FILE") != "" {
    
  •   	*username = ReadSecretFile(os.Getenv("PBS_USERNAME_FILE"))
    
  •   }
    
    }
    if os.Getenv("PBS_API_TOKEN_NAME") != "" {
    *apitokenname = os.Getenv("PBS_API_TOKEN_NAME")
  • } else {
  •   if os.Getenv("PBS_API_TOKEN_NAME_FILE") != "" {
    
  •   	*apitokenname = ReadSecretFile(os.Getenv("PBS_API_TOKEN_NAME_FILE"))
    
  •   }
    
    }
    if os.Getenv("PBS_API_TOKEN") != "" {
    *apitoken = os.Getenv("PBS_API_TOKEN")
  • } else {
  •   if os.Getenv("PBS_API_TOKEN_FILE") != "" {
    
  •   	*apitoken = ReadSecretFile(os.Getenv("PBS_API_TOKEN_FILE"))
    
  •   }
    
    }
    if os.Getenv("PBS_TIMEOUT") != "" {
    *timeout = os.Getenv("PBS_TIMEOUT")
Originally created by @ChrisFromCnC on GitHub (Feb 19, 2024). Original GitHub issue: https://github.com/natrontech/pbs-exporter/issues/9 I propose to add support to dockerfile secrets for PBS_USERNAME, PBS_API_TOKEN_NAME and PBS_API_TOKEN. Idea is to move secrets outside of docker-compose file for instance for security purpose. As example a docker-compose file can be created like this: proxmoxbackup: image: ghcr.io/natrontech/pbs-exporter:0.1.5 container_name: proxmoxbackup restart: always secrets: - proxmoxbackup-username - proxmoxbackup-api-token-name - proxmoxbackup-api-token environment: PBS_USERNAME_FILE: /run/secrets/proxmoxbackup-username PBS_API_TOKEN_NAME_FILE: /run/secrets/proxmoxbackup-api-token-name PBS_API_TOKEN_FILE: /run/secrets/proxmoxbackup-api-token secrets: proxmoxbackup-username: file: "./.secrets/proxmoxbackup_username.secret" proxmoxbackup-api-token-name: file: "./.secrets/proxmoxbackup_api_token_name.secret" proxmoxbackup-api-token: file: "./.secrets/proxmoxbackup_api_token.secret" All secrets are now stored in a folder .secrets. Convention naming for secrets in docker is to add _FILE to regular environnement variable. In our case we need to manage PBS_USERNAME_FILE, PBS_API_TOKEN_NAME_FILE and PBS_API_TOKEN_FILE env variables. I just adapt the main.go to read the new env variable for the secret file name and read the first line from the file. Sorry I cannot add a file here so I post a diff of main diff --git a/main.go b/main.go index 1e6686d..cd8cd88 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "bufio" "crypto/tls" "encoding/json" "flag" @@ -234,6 +235,24 @@ type Exporter struct { authorizationHeader string } +func ReadSecretFile(secretfilename string) string { + file, err := os.Open(secretfilename) + // flag to check the file format + if err != nil { + log.Fatal(err) + } + // Close the file + defer func() { + if err = file.Close(); err != nil { + log.Fatal(err) + } + }() + // Read the first line + line := bufio.NewScanner(file) + line.Scan() + return line.Text() +} + func NewExporter(endpoint string, username string, apitoken string, apitokenname string) *Exporter { return &Exporter{ endpoint: endpoint, @@ -660,12 +679,24 @@ func main() { } if os.Getenv("PBS_USERNAME") != "" { *username = os.Getenv("PBS_USERNAME") + } else { + if os.Getenv("PBS_USERNAME_FILE") != "" { + *username = ReadSecretFile(os.Getenv("PBS_USERNAME_FILE")) + } } if os.Getenv("PBS_API_TOKEN_NAME") != "" { *apitokenname = os.Getenv("PBS_API_TOKEN_NAME") + } else { + if os.Getenv("PBS_API_TOKEN_NAME_FILE") != "" { + *apitokenname = ReadSecretFile(os.Getenv("PBS_API_TOKEN_NAME_FILE")) + } } if os.Getenv("PBS_API_TOKEN") != "" { *apitoken = os.Getenv("PBS_API_TOKEN") + } else { + if os.Getenv("PBS_API_TOKEN_FILE") != "" { + *apitoken = ReadSecretFile(os.Getenv("PBS_API_TOKEN_FILE")) + } } if os.Getenv("PBS_TIMEOUT") != "" { *timeout = os.Getenv("PBS_TIMEOUT")
kerem 2026-03-03 16:27:31 +03:00
Author
Owner

@janfuhrer commented on GitHub (Apr 11, 2024):

Hi @ChrisFromCnC

Thanks for opening the issue.
It sounds reasonable to me to add this functionality as long as both methods work (with and without docker secrets).

Feel free to open a PR with your changes and we will test and verify your implementation.

<!-- gh-comment-id:2049820351 --> @janfuhrer commented on GitHub (Apr 11, 2024): Hi @ChrisFromCnC Thanks for opening the issue. It sounds reasonable to me to add this functionality as long as both methods work (with and without docker secrets). Feel free to open a PR with your changes and we will test and verify your implementation.
Author
Owner

@janfuhrer commented on GitHub (Apr 11, 2024):

implemented in #11
released in 0.3.0

Thanks again @ChrisFromCnC !

<!-- gh-comment-id:2050383921 --> @janfuhrer commented on GitHub (Apr 11, 2024): implemented in #11 released in [0.3.0](https://github.com/natrontech/pbs-exporter/releases/tag/0.3.0) Thanks again @ChrisFromCnC !
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
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
starred/pbs-exporter#3
No description provided.