[Feature] Read database password from Docker secret file #4870

Closed
opened 2025-11-02 06:05:30 -06:00 by GiteaMirror · 15 comments
Owner

Originally created by @camo-f on GitHub (Feb 17, 2020).

Hi there,

I plan to use Gitea in a production environment on a Docker Swarm cluster. I want to avoid having clear-text passwords in my docker-compose file.

An easy way to protect credentials with Docker Swarm is to use secrets. See https://docs.docker.com/engine/swarm/secrets/

Docker secrets are mounted as files in the container, so I can't use the environment variable DB_PASSWD.

A workaround used by images like MySQL or Postgres is to provide an environment variable storing the path of the secret, e.g. DB_PASSWD_FILE, then read that file. See section "Docker Secrets" on https://hub.docker.com/_/mysql for an example.

It would be nice to have the same for Gitea. This would only require an additional step during Gitea s6 setup, before setting default configuration variables.

if [ -n "$DB_PASSWD_FILE" ] && [ -r "$DB_PASSWD_FILE" ]; then
    DB_PASSWD=$(cat $DB_PASSWD_FILE)
fi

Here is a minimal docker-compose example where I used a custom image to add the above step.

version: '3.7'

services:
  git:
    image: custom-gitea
    environment:
      DB_TYPE: mysql
      DB_HOST: db:3306
      DB_NAME: gitea
      DB_USER: root
      DB_PASSWD_FILE: /run/secrets/db-password
      ROOT_URL: git:3000
      SSH_DOMAIN: git
      SSH_PORT: 22
    ports:
      - 3003:3000
    networks:
      - default
    secrets:
      - source: db-password
        target: /run/secrets/db-password
        mode: 0400

  db:
    image: mysql:5.7
    environment: 
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db-password
      MYSQL_DATABASE: gitea
    networks:
      - default
    secrets:
      - source: db-password
        target: /run/secrets/db-password
        mode: 0400

networks:
  default:
    driver: overlay

secrets:
  db-password:
    file: './db-password'

Steps :

# On a Docker Swarm cluster
echo 'mydatabasepassword' > db-password
docker stack deploy -c docker-compose.yml gitea-test
  • Gitea version (or commit ref): 1.10
  • Operating system: Docker
  • Database (use [x]):
    • PostgreSQL
    • MySQL
    • MSSQL
Originally created by @camo-f on GitHub (Feb 17, 2020). Hi there, I plan to use Gitea in a production environment on a Docker Swarm cluster. I want to avoid having clear-text passwords in my docker-compose file. An easy way to protect credentials with Docker Swarm is to use secrets. See https://docs.docker.com/engine/swarm/secrets/ Docker secrets are mounted as files in the container, so I can't use the environment variable `DB_PASSWD`. A workaround used by images like MySQL or Postgres is to provide an environment variable storing the path of the secret, e.g. `DB_PASSWD_FILE`, then read that file. See section "Docker Secrets" on https://hub.docker.com/_/mysql for an example. It would be nice to have the same for Gitea. This would only require an additional step during Gitea s6 `setup`, before setting default configuration variables. ``` if [ -n "$DB_PASSWD_FILE" ] && [ -r "$DB_PASSWD_FILE" ]; then DB_PASSWD=$(cat $DB_PASSWD_FILE) fi ``` Here is a minimal docker-compose example where I used a custom image to add the above step. ``` version: '3.7' services: git: image: custom-gitea environment: DB_TYPE: mysql DB_HOST: db:3306 DB_NAME: gitea DB_USER: root DB_PASSWD_FILE: /run/secrets/db-password ROOT_URL: git:3000 SSH_DOMAIN: git SSH_PORT: 22 ports: - 3003:3000 networks: - default secrets: - source: db-password target: /run/secrets/db-password mode: 0400 db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db-password MYSQL_DATABASE: gitea networks: - default secrets: - source: db-password target: /run/secrets/db-password mode: 0400 networks: default: driver: overlay secrets: db-password: file: './db-password' ``` Steps : ``` # On a Docker Swarm cluster echo 'mydatabasepassword' > db-password docker stack deploy -c docker-compose.yml gitea-test ``` - Gitea version (or commit ref): 1.10 - Operating system: Docker - Database (use `[x]`): - [x] PostgreSQL - [x] MySQL - [x] MSSQL
GiteaMirror added the type/proposal label 2025-11-02 06:05:30 -06:00
Author
Owner

@lunny commented on GitHub (Feb 18, 2020):

Another way is to store password on envs.

@lunny commented on GitHub (Feb 18, 2020): Another way is to store password on envs.
Author
Owner

@camo-f commented on GitHub (Feb 18, 2020):

Is there a way to have them hashed as environment variables ? I can't find anything about this in the documentation.
With Docker secrets, I avoid writing them in clear-text, which is a security concern.

@camo-f commented on GitHub (Feb 18, 2020): Is there a way to have them hashed as environment variables ? I can't find anything about this in the documentation. With Docker secrets, I avoid writing them in clear-text, which is a security concern.
Author
Owner

@lafriks commented on GitHub (Feb 22, 2020):

If you create separate network for db and add only db and Gitea to it noone else will be able to connect to it so this way password complexity does not matter anymore

@lafriks commented on GitHub (Feb 22, 2020): If you create separate network for db and add only db and Gitea to it noone else will be able to connect to it so this way password complexity does not matter anymore
Author
Owner

@camo-f commented on GitHub (Feb 24, 2020):

From the outside, Gitea being on an overlay network (which I'm already using) doesn't change a thing. It is easier to read an environment variable than a file. My point is also not to have sensitive values such as passwords in docker-compose.yml, especially if it is versioned.

@camo-f commented on GitHub (Feb 24, 2020): From the outside, Gitea being on an overlay network (which I'm already using) doesn't change a thing. It is easier to read an environment variable than a file. My point is also not to have sensitive values such as passwords in `docker-compose.yml`, especially if it is versioned.
Author
Owner

@anicolaides commented on GitHub (Aug 16, 2020):

Considering that most major databases support password file handling through docker secrets, I would like to see this feature implemented as well.

@anicolaides commented on GitHub (Aug 16, 2020): Considering that most major databases support password file handling through docker secrets, I would like to see this feature implemented as well.
Author
Owner

@laxmanpradhan commented on GitHub (Dec 8, 2020):

I too would like to see this, it is very important for easy infrastructure as code deployments. Databases like mariadb and postgres already support this (when setting the env variables, you just append _FILE to the end like DB_PASSWORD_FILE) and many other applications are adding in support as well (see the docker secrets section here).

It is now pretty standard practice to not include plain text passwords in the docker compose file or to inject them at runtime so this would be a great addition.

@laxmanpradhan commented on GitHub (Dec 8, 2020): I too would like to see this, it is very important for easy infrastructure as code deployments. Databases like mariadb and postgres already support this (when setting the env variables, you just append _FILE to the end like DB_PASSWORD_FILE) and many other applications are adding in support as well ([see the docker secrets section here](https://hub.docker.com/_/nextcloud)). It is now pretty standard practice to not include plain text passwords in the docker compose file or to inject them at runtime so this would be a great addition.
Author
Owner

@achaiah commented on GitHub (Jan 18, 2021):

I agree that this is an important feature that is currently sorely missing!

@achaiah commented on GitHub (Jan 18, 2021): I agree that this is an important feature that is currently sorely missing!
Author
Owner

@DennisGaida commented on GitHub (Jan 22, 2022):

I solved this using a custom entrypoint script.

  1. Copy the original entrypoint script with following adjustments (diff):
1c1
< #!/bin/sh
---
> #!/bin/bash
26a27,40
> ## Set environment variables by their respective secrets
> supportedSecrets=( "GITEA__database__PASSWD" 
>                    "GITEA__mailer__PASSWD" 
>                  )
> for secret in ${supportedSecrets[@]}; do
>     envFile="${secret}_FILE"
>     if [ $(printenv ${envFile}) ]; then envFileName=`printenv ${envFile}`; fi
>     if [[ ${!envFile} && -f "$envFileName" ]]; then
>         val=`cat $envFileName`
>         export "${secret}"="$val"
>         echo "${secret} environment variable was set by secret ${envFile}"
>     fi
> done
> 
  1. Mount that entrypoint in your docker-compose
volumes:
    ...
      - ./gitea/entrypoint:/usr/bin/entrypoint

You're done. Gitea now supports secrets for GITEA__database__PASSWD_FILE & GITEA__mailer__PASSWD_FILE. You can use them like this:

# docker-compose
secrets:
  gitea_db_password:
    file: $SECRETSDIR/gitea_db_password

services:
  gitea:
    image: gitea/gitea
    ...
    environment:
      GITEA__database__PASSWD_FILE: /run/secrets/gitea_db_password
    secrets:
      - gitea_db_password
@DennisGaida commented on GitHub (Jan 22, 2022): I solved this using a custom `entrypoint` script. 1. Copy the original `entrypoint` script with following adjustments (diff): ```diff 1c1 < #!/bin/sh --- > #!/bin/bash 26a27,40 > ## Set environment variables by their respective secrets > supportedSecrets=( "GITEA__database__PASSWD" > "GITEA__mailer__PASSWD" > ) > for secret in ${supportedSecrets[@]}; do > envFile="${secret}_FILE" > if [ $(printenv ${envFile}) ]; then envFileName=`printenv ${envFile}`; fi > if [[ ${!envFile} && -f "$envFileName" ]]; then > val=`cat $envFileName` > export "${secret}"="$val" > echo "${secret} environment variable was set by secret ${envFile}" > fi > done > ``` 2. Mount that entrypoint in your docker-compose ```yaml volumes: ... - ./gitea/entrypoint:/usr/bin/entrypoint ``` You're done. Gitea now supports secrets for `GITEA__database__PASSWD_FILE` & `GITEA__mailer__PASSWD_FILE`. You can use them like this: ```yaml # docker-compose secrets: gitea_db_password: file: $SECRETSDIR/gitea_db_password services: gitea: image: gitea/gitea ... environment: GITEA__database__PASSWD_FILE: /run/secrets/gitea_db_password secrets: - gitea_db_password
Author
Owner

@alanmv01 commented on GitHub (Feb 15, 2022):

@DennisGaida Thanks for the code, it works great.

One problem with adding secrets now is that the variable is added as a parameter in gitea's app.ini file:

PASSWD_FILE = /run/secrets/gitea_mariadb_password

This seems to be expected according to the documentation:

In addition to the environment variables above, any settings in app.ini can be set or overridden with an environment variable of the form: GITEA__SECTION_NAME__KEY_NAME.

Don't know if this will cause any issue in the future. Just a heads up for those who are trying to implement secrets in gitea.

@alanmv01 commented on GitHub (Feb 15, 2022): @DennisGaida Thanks for the code, it works great. One problem with adding secrets now is that the variable is added as a parameter in gitea's app.ini file: `PASSWD_FILE = /run/secrets/gitea_mariadb_password` This seems to be expected according to the [documentation](https://docs.gitea.io/en-us/install-with-docker/#managing-deployments-with-environment-variables): ``` In addition to the environment variables above, any settings in app.ini can be set or overridden with an environment variable of the form: GITEA__SECTION_NAME__KEY_NAME. ``` Don't know if this will cause any issue in the future. Just a heads up for those who are trying to implement secrets in gitea.
Author
Owner

@mugartec commented on GitHub (Feb 27, 2022):

Another way is to store password on envs.

This is the classic (read old) way of doing it, but passing sensitive data via environment variables is not a good idea (also read here).

I also believe @DennisGaida's workaround can lead to problems: passing sensitive data via secrets and then exporting them to env vars gives other processes the ability to read them. We should use secrets as they are intended to.

That's why several images out there are being updated to support the _FILE version of sensitive env vars, +1 for the feature.

Edit: suggestion -> workaround as mentioned in the comment below.

@mugartec commented on GitHub (Feb 27, 2022): > Another way is to store password on envs. This is the *classic* (read *old*) way of doing it, but passing sensitive data via environment variables is [not a good idea](https://earthly.dev/blog/docker-secrets/) (also read [here](https://techbeacon.com/app-dev-testing/how-keep-your-container-secrets-secure)). I also believe @DennisGaida's workaround can lead to problems: passing sensitive data via secrets and then exporting them to env vars gives other processes the ability to read them. We should use secrets as they are intended to. That's why several images out there are being updated to support the `_FILE` version of sensitive env vars, +1 for the feature. Edit: suggestion -> workaround as mentioned in the comment below.
Author
Owner

@DennisGaida commented on GitHub (Feb 27, 2022):

I also believe @DennisGaida's suggestion can lead to problems

Please don’t take my workaround as a suggestion - I would have created a PR if I thought it were a solution. I‘m working with what we have: secrets in environment variables.

secrets should be natively supported so this feature request is totally valid.

@DennisGaida commented on GitHub (Feb 27, 2022): > I also believe @DennisGaida's suggestion can lead to problems Please don’t take my workaround as a suggestion - I would have created a PR if I thought it were a solution. I‘m working with what we have: secrets in environment variables. secrets should be natively supported so this feature request is totally valid.
Author
Owner

@Beanow commented on GitHub (Apr 30, 2022):

Here's one idea to add this feature. How about expanding environment-to-ini, such that it can read a configurable env (or ini) file. This could be a docker secret and won't need to be exposed as environment variables to any other process.

This is already a docker-specific utility intended to rewrite the app.ini, it would just add one more source of inputs, plus it doesn't require specifically supporting _FILE for what the devs consider sensitive. You'd be able to move any variable into the secret as you see fit.

@Beanow commented on GitHub (Apr 30, 2022): Here's one idea to add this feature. How about expanding [environment-to-ini](https://github.com/go-gitea/gitea/tree/main/contrib/environment-to-ini), such that it can read a configurable env (or ini) file. This could be a docker secret and won't need to be exposed as environment variables to any other process. This is already a docker-specific utility intended to rewrite the app.ini, it would just add one more source of inputs, plus it doesn't require specifically supporting `_FILE` for what the devs consider sensitive. You'd be able to move any variable into the secret as you see fit.
Author
Owner

@vladisalv commented on GitHub (May 20, 2022):

Guys, this is important feature for prod using. How can we upvote it?

@vladisalv commented on GitHub (May 20, 2022): Guys, this is important feature for prod using. How can we upvote it?
Author
Owner

@pleshevskiy commented on GitHub (May 30, 2022):

this is important not only for database. I want to use secret and for smtp too.

@pleshevskiy commented on GitHub (May 30, 2022): this is important not only for database. I want to use secret and for smtp too.
Author
Owner

@KarolNi commented on GitHub (Jul 2, 2022):

Duplicate of https://github.com/go-gitea/gitea/issues/19856
There is promising pull request https://github.com/go-gitea/gitea/pull/19857

@KarolNi commented on GitHub (Jul 2, 2022): Duplicate of https://github.com/go-gitea/gitea/issues/19856 There is promising pull request https://github.com/go-gitea/gitea/pull/19857
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/gitea#4870