Database+permissions errors using docker-compose and PHP-FPM

I started out with the docker-compose example hosted on GitHub. Now, docker-compose on Ubuntu server must be run under root. When I run it for the first time, all the files NC creates on install are therefore owned by root. This results in an internal server error on the web interface (on a formatted NC page) and a “client denied by server” error in the Apache logs.

On the other hand, if I chown everything to www-data, I can reach the setup form but get this when submitting the installation form (admin user, database): Error while trying to create admin user: Failed to connect to the database: An exception occurred in driver: SQLSTATE[HY000] [2002] No such file or directory ; and in the logs: An exception occurred in the driver: could not find driver.

So, my problems, currently, are:

  • Should I be connecting to MariaDB under localhost on that form? Or is there another configuration?
  • I’m concerned about having to manually chown the NC files. This will likely lead to problems for any files modified or created by NC in the future.

nope. you made a mistake. nevertheless i don’t know which on. because even if you run docker-compose as root you shouldn’t see what you describe here.

which files? where? the docker setup started by this docker-compose file will create a docker volume somewhere in /var/lib/docker. inside the container the files belong to www-data. did you check with something like docker exec app ls -l /var/www/html`

no. that would be the localhost of the nextcloud container. you want to connect to another container which is an another “server”. it’s address is the name of the container “db”. docker has a buildin dns fot this.

since you made something wrong we have to figure what to solve this.

did you look at this:

Thank you for the response. I looked at the Awesome Docker-compose Collection—it is very good indeed, but my use case is different. I am running Apache on the host machine, not Docker; Nextcloud/redis/cron/MariaDB are in the docker-compose.

According to the official Docker documentation, running the docker daemon in rootless mode is experimental and lacking in features, though I should give it a try. At first I deleted the nextcloud installation and followed this tutorial to add my user to the docker group, and the processes now run under user 82 (no username). I still get the internal server error message anyway. Here is my docker-compose.yml:

version: '3'

services:
  db:
    image: mariadb
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
    restart: always
    volumes:
      - db:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=##########
    env_file:
      - db.env
  redis:
    image: redis:alpine
    restart: always
  app:
    image: nextcloud:18-fpm-alpine
    restart: always
    volumes:
      - nextcloud:/var/www/html
    environment:
      - MYSQL_HOST=db
      - REDIS_HOST=redis
    env_file:
      - db.env
    depends_on:
      - db
      - redis
  web:
    build: ./web
    restart: always
    ports:
      - 8080:80
    volumes:
      - nextcloud:/var/www/html:ro
    depends_on:
      - app
  cron:
    image: nextcloud:18-fpm-alpine
    restart: always
    volumes:
      - nextcloud:/var/www/html
    entrypoint: /cron.sh
    depends_on:
      - db
      - redis

volumes:
  db:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /opt/nextcloud/var/lib/mysql
  nextcloud:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /var/www/nextcloud

And my Apache conf:

<IfModule mod_ssl.c>
<VirtualHost *:443>
	ServerName intranet.#######
	DocumentRoot /var/www/nextcloud
	<Directory /var/www/nextcloud/>
		Require all granted
		AllowOverride All
		Options +FollowSymlinks +ExecCGI +MultiViews
		Satisfy Any
		<IfModule mod_dav.c>
			Dav off
		</IfModule>
	</Directory>
	#<IfModule mod_proxy_fcgi.c>
		#<FilesMatch \.php$>
			#SetHandler "proxy:fcgi://127.0.0.1:8080"
		#</FilesMatch>
	#</IfModule>
        LogLevel info ssl:warn
	ErrorLog ${APACHE_LOG_DIR}/intranet-error.log
	CustomLog ${APACHE_LOG_DIR}/intranet-access.log combined

	Include /etc/letsencrypt/options-ssl-apache.conf
	SSLCertificateFile /etc/letsencrypt/live/intranet.#######/fullchain.pem
	SSLCertificateKeyFile /etc/letsencrypt/live/intranet.######/privkey.pem
	RewriteEngine On
	RewriteCond %{HTTPS} off
	RewriteRule (.*) https://%{SERVER_NAME}/$1 [R,L]
	RewriteRule ^/\.well-known/carddav https://%{SERVER_NAME}/remote.php/dav/ [R=301,L]
	RewriteRule ^/\.well-known/caldav https://%{SERVER_NAME}/remote.php/dav/ [R=301,L]
	RewriteRule ^/ - [QSA,L]
</VirtualHost>
</IfModule>

Note that if I uncomment the mod_proxy_fcgi part, I get a 503: service unavailable error.

“do not try this at home.”

why? your own server? you are alone? against which attack you want to defend your container?

don’t mix host and container. of course the user with the id 82 has a name. inside the container. docker exec -u www-data nextcloud id will show you. if you want to beautify the output of ps -ef on your host just add a user www-data with id 82. (probably a bad idea because the apache user is already www-data but with a different id.)

did you try to access your nextcloudthrough port 8080? firewall shouldn’t block this port. otherwise try curl -v http://127.0.0.1:8080 on the same machine.

1 Like

Thank you so much for the hint. It turns out the web container was taking a long time to spin up, so I was getting the NginX splash screen for a while and thought it wasn’t working. After waiting a while, I was able to access the Nextcloud install through port 8080 and finish configuration. I then fixed the “trusted domains” in the config.php and enabled the reverse proxy in the Apache conf. Now it seems everything’s up and running! Thanks again!

did you close port 8080 on your firewall again? otherwise the apache reverse proxy has no effect.

or use:

  web:
    build: ./web
    restart: always
    ports:
      - 127.0.0.1:8080:80

I accessed port 8080 through a private VPN between my office and the server that I only use for such maintenance cases now.