Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for using Docker Compose Secrets instead of older .env pattern #50

Open
andrewvaughan opened this issue Jun 20, 2024 · 2 comments
Labels
enhancement New feature or request

Comments

@andrewvaughan
Copy link

andrewvaughan commented Jun 20, 2024

Per the Docker's Docker Compose Secrets documentation, most Docker containers are starting to support the recommended _FILE suffix for sensitive information, allowing Docker Compose to use the more-secure secrets top-level element.

For example from the MySQL Docker image documentation:

Docker Secrets

As an alternative to passing sensitive information via environment variables, _FILE may be appended to the previously listed environment variables, causing the initialization script to load the values for those variables from files present in the container. In particular, this can be used to load passwords from Docker secrets stored in /run/secrets/<secret_name> files. For example:

$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD_FILE=/run/secrets/mysql-root -d mysql:tag

Currently, this is only supported for MYSQL_ROOT_PASSWORD, MYSQL_ROOT_HOST, MYSQL_DATABASE, MYSQL_USER, and MYSQL_PASSWORD.

By simply adding additional _FILE environment parameters, this change is entirely backwards compatible and will not disrupt any users that make use of the older .env pattern.

Motivation

This pattern is significantly more secure, as .env files have singular user access control. This also removes sensitive information from existing in the container's environment variables, which is a significant security improvement.

Especially for EspoCRM, there may be a realistic case where a development operations manager may want to give users the ability to manage their ESPOCRM_ADMIN_*** credentials, but not have access to the MySQL database credentials. With the existing .env pattern, that access is "all or nothing."

Following Docker's official recommendation in the link above, I recommend making seven (7) additional ***_FILE environment variables in the Dockerfile to match each of the following, existing variables:

  • ESPOCRM_DATABASE_HOST (often DevOps managing remote databases do not wish to expose their hosts to developers)
  • ESPOCRM_DATABASE_PORT
  • ESPOCRM_DATABASE_NAME
  • ESPOCRM_DATABASE_USER
  • ESPOCRM_DATABASE_PASSWORD
  • ESPOCRM_ADMIN_USERNAME
  • ESPOCRM_ADMIN_PASSWORD

Example Docker Compose File

As an example of what the improved Docker Compose file may look like for your documentation:

name: espocrm

# Note, the `version` top-level element is deprecated. See:
# https://docs.docker.com/compose/compose-file/04-version-and-name/

services:

  mysql:
    image: mysql:8
    container_name: mysql
    secrets:
      - mysql_root_password
      - mysql_database
      - mysql_user
      - mysql_password
    environment:
      MYSQL_ROOT_PASSWORD_FILE: "/run/secrets/mysql_root_password"
      MYSQL_DATABASE_FILE: "/run/secrets/mysql_database"
      MYSQL_USER_FILE: "/run/secrets/mysql_user"
      MYSQL_PASSWORD_FILE: "/run/secrets/mysql_password"
    volumes:
      - mysql:/var/lib/mysql
    restart: always

  espocrm:
    image: espocrm/espocrm
    container_name: espocrm
    secrets:
      - mysql_host
      - mysql_port
      - mysql_database
      - mysql_user
      - mysql_password
      - espocrm_admin_user
      - espocrm_admin_password
    environment:
      ESPOCRM_DATABASE_PLATFORM: Mysql
      ESPOCRM_DATABASE_HOST_FILE: "/run/secrets/mysql_host"
      ESPOCRM_DATABASE_PORT_FILE: "/run/secrets/mysql_port"
      ESPOCRM_DATABASE_NAME_FILE: "/run/secrets/mysql_database"
      ESPOCRM_DATABASE_USER_FILE: "/run/secrets/mysql_user"
      ESPOCRM_DATABASE_PASSWORD_FILE: "/run/secrets/mysql_password"
      ESPOCRM_ADMIN_USERNAME_FILE: "/run/secrets/espocrm_admin_user"
      ESPOCRM_ADMIN_PASSWORD_FILE: "/run/secrets/espocrm_admin_password"
      ESPOCRM_SITE_URL: "http://localhost:8080"
    volumes:
      - espocrm:/var/www/html
    restart: always
    ports:
      - 8080:80

  espocrm-daemon:
    image: espocrm/espocrm
    container_name: espocrm-daemon
    volumes:
      - espocrm:/var/www/html
    restart: always
    entrypoint: docker-daemon.sh

  espocrm-websocket:
    image: espocrm/espocrm
    container_name: espocrm-websocket
    environment:
      ESPOCRM_CONFIG_USE_WEB_SOCKET: "true"
      ESPOCRM_CONFIG_WEB_SOCKET_URL: "ws://localhost:8081"
      ESPOCRM_CONFIG_WEB_SOCKET_ZERO_M_Q_SUBSCRIBER_DSN: "tcp://*:7777"
      ESPOCRM_CONFIG_WEB_SOCKET_ZERO_M_Q_SUBMISSION_DSN: "tcp://espocrm-websocket:7777"
    volumes:
      - espocrm:/var/www/html
    restart: always
    entrypoint: docker-websocket.sh
    ports:
      - 8081:8080

volumes:
  mysql:
  espocrm:

# The `secrets` directory should have `770` permissions and be owned by the
# user/group running the Docker daemon (usually `root`).
secrets:
  mysql_host:
    file: "./secrets/mysql/host"
  mysql_port:
    file: "./secrets/mysql/port"
  mysql_database:
    file: "./secrets/mysql/database_name"
  mysql_root_password:
    file: "./secrets/mysql/root_password"
  mysql_database:
    file: "./secrets/mysql/database"
  mysql_user:
    file: "./secrets/mysql/user"
  mysql_password:
    file: "./secrets/mysql/password"
  espocrm_admin_user:
    file: "./secrets/espocrm/admin_username"
  espocrm_admin_password:
    file: "./secrets/espocrm/admin_password"

As an example for implementation of this change, here is how MySQL manages this:

https://github.com/docker-library/mysql/blob/1a703318803fa85bf69cb5d2e5b3f1c4087627b5/docker-entrypoint.sh#L24-L43

And WordPress, as a more dynamic alternative:

https://github.com/docker-library/wordpress/blob/8c2ded17022e67c6accacfae637c5a577ce169af/wp-config-docker.php#L26-L40

@tmachyshyn
Copy link
Collaborator

Thanks for your feature request. We will review it.

@tmachyshyn tmachyshyn added the enhancement New feature or request label Jun 24, 2024
@alexfacciorusso
Copy link

Agreed, this should be the default in docker by now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants