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

Environment variables ignored in docker-compose scenarios #1201

Closed
ctorgalson opened this issue Aug 17, 2020 · 6 comments
Closed

Environment variables ignored in docker-compose scenarios #1201

ctorgalson opened this issue Aug 17, 2020 · 6 comments
Labels

Comments

@ctorgalson
Copy link

ctorgalson commented Aug 17, 2020

The documentation explicitly states strongly implies that environment variables can be used to configure containers when using docker-compose. For example:

Make sure to pass in values for MYSQL_ROOT_PASSWORD and MYSQL_PASSWORD variables before you run this setup.

Also some of the docker-compose.yml examples apparently use env vars to set MYSQL* vars for the Nextcloud container:

  app:
    image: nextcloud:apache
    restart: always
    ports:
      - 8080:80
    volumes:
      - nextcloud:/var/www/html
    environment:
      - MYSQL_HOST=db
    env_file:
      - db.env
    depends_on:
      - db

But this doesn't work. AFAICT, the documentation is assuming that since passing env vars works with a Dockerfile, it will also work with docker-compose, but docker-compose doesn't run the docker-entrypoint.sh file that gets run by a Dockerfile.

The question for me is whether this is purely a documentation problem, or if this is a missing feature.

To reproduce

Reproduction script

Script
#!/usr/bin/env bash                                                                                                                                                                                                                                                                
#
# NOTE: you'll need to manually remove the containers, images, and volumes created by this script to re-run it.

mkdir nc-docker-compose-test

cd nc-docker-compose-test

echo ""
echo "Download sample docker compose file"
echo ""

curl -OL https://gist.githubusercontent.com/ctorgalson/0a05ef42acb931529c58c50b37b62dc6/raw/99e310b7ca1ab1ed1650ecfb1ed14e9365b1d3fd/docker-compose.yml

echo ""
echo "Build and start Nextcloud and Mariadb containers."
echo ""

docker-compose up --force-recreate --renew-anon-volumes --build --detach

echo ""
echo "NEXTCLOUD_ADMIN_* env vars."
echo ""

docker exec nc-docker-compose-test_db_1 env | grep NEXTCLOUD_ADMIN

echo ""
echo "MYSQL_* env vars."
echo ""

docker exec nc-docker-compose-test_db_1 env | grep MYSQL

echo ""
echo "Install Nextcloud--we should NOT need to pass login or mysql vars."
echo ""

echo "------------------------------------------------------------"

docker exec --user www-data nc-docker-compose-test_app_1 \
  php occ maintenance:install

echo "------------------------------------------------------------"

echo ""
echo "Install Nextcloud--this time, set an admin password."
echo ""

echo "------------------------------------------------------------"

docker exec --user www-data nc-docker-compose-test_app_1 \
  php occ maintenance:install --admin-pass="nc_admin_password_non_env"

echo "------------------------------------------------------------"

echo ""
echo "Check for database variables in Nextcloud config/config.php."
echo ""

echo "------------------------------------------------------------"

docker exec --user www-data nc-docker-compose-test_app_1 \
  cat config/config.php

echo "------------------------------------------------------------"

Output

The above script uses a very slightly modified version of the 'Base version - apache' sample from the README to:

  • Build and start nextcloud and db containers with the relevant env vars,
  • Greps the relevant env vars from the two containers to show they're present,
  • Tries running php occ maintenance:install with no admin password (this fails),
  • Tries running php occ maintenance:install with an admin password (this succeeds),
  • Dumps the contents of config/config.php.

The output demonstrates that:

  1. Env vars are correctly set in nextcloud container,
  2. Env vars are correctly set in db container,
  3. NEXTCLOUD_ADMIN_* vars are not used by the installer,
  4. MYSQL_* vars are not used by the installer.
Download sample docker compose file

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   634  100   634    0     0  21862      0 --:--:-- --:--:-- --:--:-- 21862

Build and start Nextcloud and Mariadb containers.

Recreating nc-docker-compose-test_db_1 ... done
Recreating nc-docker-compose-test_app_1 ... done

NEXTCLOUD_ADMIN_* env vars.


MYSQL_* env vars.

MYSQL_ROOT_PASSWORD=nextcloud_mysql_root_pass
MYSQL_PASSWORD=nextcloud_mysql_pass
MYSQL_DATABASE=nextcloud
MYSQL_USER=nextcloud

Install Nextcloud--we should NOT need to pass login or mysql vars.

------------------------------------------------------------
Set an admin password.
------------------------------------------------------------

Install Nextcloud--this time, set an admin password.

------------------------------------------------------------
Nextcloud was successfully installed
------------------------------------------------------------

Check for database variables in Nextcloud config/config.php.

------------------------------------------------------------
<?php
$CONFIG = array (
  'htaccess.RewriteBase' => '/',
  'memcache.local' => '\\OC\\Memcache\\APCu',
  'apps_paths' => 
  array (
    0 => 
    array (
      'path' => '/var/www/html/apps',
      'url' => '/apps',
      'writable' => false,
    ),
    1 => 
    array (
      'path' => '/var/www/html/custom_apps',
      'url' => '/custom_apps',
      'writable' => true,
    ),
  ),
  'passwordsalt' => 'oUH/PIrsL7xTajHk/9Xm8Pyr0Bt/Ej',
  'secret' => '1pF7ClUXmaIGOmODkJYOGTlEqNZOZAlZUJ6Jmsa1P22rShb3',
  'trusted_domains' => 
  array (
    0 => 'localhost',
  ),
  'datadirectory' => '/var/www/html/data',
  'dbtype' => 'sqlite3',
  'version' => '19.0.1.1',
  'overwrite.cli.url' => 'http://localhost',
  'installed' => true,
);
------------------------------------------------------------
@cacack
Copy link

cacack commented Sep 15, 2020

I believe I've found my way here from the reverse proxy problems, and the TRUSTED_PROXIES environment variables not being honored. Dumping my config I can see those values are missing...

@ptoulouse
Copy link

ptoulouse commented Sep 25, 2020

Running it with docker-compose still runs the entrypoint.sh file.

I just had the same issue and the problem is that the way the entrypoint is written is an "all or nothing at all" approach.

To set the DB, you need to specify the 4 variables (MYSQL_HOST, MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD). But even if you set these, you cannot set the DB or Trusted Domains if you don't define NEXTCLOUD_ADMIN_USER and NEXTCLOUD_ADMIN_PASSWORD. There is a big if clause that will skip treating the SQL and trusted domains env vars if the admin vars are not set.

The documentation does not mention this. In fact, the documentation is misleading as it says that the env vars are used to prepopulate values. I was expecting to get to the start page and have the DB variables populated,even if I had not specified an admin user.

@iFreilicht
Copy link

@ptoulouse I cannot reproduce this. I struggled initially because I forgot to add the MYSQL_HOST variable, but after that, the prepopulation worked perfectly, as implied by the documentation.

@ptoulouse
Copy link

What I am saying is that the MYSQL_* and NEXTCLOUD_TRUSTED_DOMAINS are ignored if the NEXTCLOUD_ADMIN_* variables are not set. See entrypoint.sh at line 121 and down. Also the 4 MYSQL_* vars need to be set to initialize the DB.

The Readme implies that the MYSQL_* vars will be populated even without NEXTCLOUD_ADMIN_* being set.

@iFreilicht
Copy link

@ptoulouse I understood. What I'm saying is that despite what the entrypoint.sh looks like, I was able to install nextcloud with mariadb following the README using docker-compose:

version: '2'
services:
  nextcloud:
    image: nextcloud
    container_name: nextcloud
    restart: always
    environment:
      - MYSQL_HOST=nextcloud-database
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud_database_user
      - MYSQL_PASSWORD=nextcloud_database_password
      - VIRTUAL_HOST=nextcloud.example.com
      - LETSENCRYPT_HOST=nextcloud.example.com
      - LETSENCRYPT_EMAIL=admin@example.com
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - /mnt/vol1/nextcloud:/var/www/html
    ports:
      - "8080:80"
    links:
      - nextcloud-database

  nextcloud-database:
    image: mariadb:10.3.22 # See https://github.com/nextcloud/docker/issues/1038
    container_name: nextcloud-database
    restart: always
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
    environment:
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud_database_user
      - MYSQL_PASSWORD=nextcloud_database_password
      - MYSQL_ROOT_PASSWORD=nextcloud_database_root_password
    volumes:
      - /mnt/vol1/database:/var/lib/mysql

I did try this two more times after completely wiping vol1 and it works perfectly. The database connection is initialized, I could enter a username and password in the web-interface, config.php was properly populated and the installation ran through fully:

<?php
$CONFIG = array (
  'htaccess.RewriteBase' => '/',
  'memcache.local' => '\\OC\\Memcache\\APCu',
  'apps_paths' => 
  array (
    0 => 
    array (
      'path' => '/var/www/html/apps',
      'url' => '/apps',
      'writable' => false,
    ),
    1 => 
    array (
      'path' => '/var/www/html/custom_apps',
      'url' => '/custom_apps',
      'writable' => true,
    ),
  ),
  'instanceid' => 'ocaykbzzgr4w',
  'passwordsalt' => 'rt2LI5mPfLZ69i9B0WwFSefzjlOgJI',
  'secret' => 'M0v1wTgTKTOcVcb1HEVJrZAAEDO/5sKWML7NmOobIgckPQJU',
  'trusted_domains' => 
  array (
    0 => 'nextcloud.example.com',
  ),
  'datadirectory' => '/var/www/html/data',
  'dbtype' => 'mysql',
  'version' => '21.0.1.1',
  'overwrite.cli.url' => 'http://nextcloud.example.com',
  'dbname' => 'nextcloud',
  'dbhost' => 'nextcloud-database',
  'dbport' => '',
  'dbtableprefix' => 'oc_',
  'mysql.utf8mb4' => true,
  'dbuser' => 'nextcloud_database_user',
  'dbpassword' => 'nextcloud_database_password',
  'installed' => true,
);

However, this doesn't work when using the _FILE suffixes for some reason. What I did now instead was to use a .env-file and set the variables via substitution.

@joshtrichards
Copy link
Member

But this doesn't work. AFAICT, the documentation is assuming that since passing env vars works with a Dockerfile, it will also work with docker-compose, but docker-compose doesn't run the docker-entrypoint.sh file that gets run by a Dockerfile.

This is incorrect:

The ENTRYPOINT definition in the Dockerfile specifies what a container should run as the entrypoint at start time. The entrypoint is absolutely invoked when you start a container.

Tries running php occ maintenance:install with an admin password (this succeeds),
[...]
NEXTCLOUD_ADMIN_* vars are not used by the installer,

Well, they're not used when you manually run the Nextcloud installer as you did in your test cases. But that's not surprising. You're overriding how this image works. :-) Those variables are injected through the entrypoint when a container starts for the first time. Those particular ones are passed to the installer within the entrypoint.

What I am saying is that the MYSQL_* and NEXTCLOUD_TRUSTED_DOMAINS are ignored if the NEXTCLOUD_ADMIN_* variables are not set. See entrypoint.sh at line 121 and down. Also the 4 MYSQL_* vars need to be set to initialize the DB.

The Readme implies that the MYSQL_* vars will be populated even without NEXTCLOUD_ADMIN_* being set.

Because they do. There are multiple ways of injecting them internally. What you don't see in the entrypoint, is that the MYSQL_* variables still get picked up by the installer via Nextcloud's autoconfig.php support located in the image here. It doesn't matter if that part of the entrypoint is skipped. Those are different code paths.

I'm going to close this for the following reasons:

@joshtrichards joshtrichards closed this as not planned Won't fix, can't repro, duplicate, stale Jun 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants