Nextcloud behind Nginx reverse proxy

Create Nextcloud in Docker

Prepare directory tree

mkdir nextcloud
cd nextcloud
touch docker-compose.yml
touch .env

docker-compose.yml

Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. 

We gonna expose Nextcloud on 50020 host port and define external volumes.

version: '2'

volumes:
  nextcloud:
  db:

services:
  db:
    image: mariadb
    restart: always
    volumes:
      - ./data/db:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=$ENV_MYSQL_ROOT_PASSWORD
      - MYSQL_PASSWORD=$ENV_MYSQL_PASSWORD
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud

  app:
    image: nextcloud
    ports:
      - 50020:80
    links:
      - db
    volumes:
      - $ENV_APP_HTML:/var/www/html
      - $ENV_APP_DATA:/var/www/html/data
      - $ENV_APP_CONFIG:/var/www/html/config
      - $ENV_APP_APPS:/var/www/html/apps
    restart: always

.env file

Compose supports declaring default environment variables in an environment file named .env placed in the folder where the docker-compose command is executed (current working directory).

ENV_MYSQL_ROOT_PASSWORD=root_sql_pass
ENV_MYSQL_PASSWORD=nextcloud_sql_pass
ENV_APP_HTML=./data/app/html
ENV_APP_DATA=./data/app/data
ENV_APP_CONFIG=./data/app/config
ENV_APP_APPS=./data/app/apps

Start compose

To start our stack just call below commands:

docker-compose up -d
Creating network "nextcloud_default" with the default driver
Creating nextcloud_db_1 ... done
Creating nextcloud_app_1 ... done

docker-compose ps   
     Name                    Command               State           Ports        
--------------------------------------------------------------------------------
nextcloud_app_1   /entrypoint.sh apache2-for ...   Up      0.0.0.0:50020->80/tcp
nextcloud_db_1    docker-entrypoint.sh mysqld      Up      3306/tcp   

Everything is correct. MySQL service is encapsulated into the stack, only Nextcloud has access to it. On the other hand Nextcloud HTTP port 80 is exposed on 50020 host port. Let’s try go to http://HOST_IP:50020, you will be able to see Nextcloud wizard page. Set config and save.

It is not the end our case, because we want have access to our drive not via PORT but using the subfolder: http://DOMAIN_NAME/nc. To do this, we must use nginx reverse proxy.

Nginx configuration

Add insertion to your domain DOMAIN_NAME sites-enabled configuration file

# NextCloud
location ^~ /nc/ {
  rewrite ^/nc(.*) $1 break;
  # set your HOST_IP and Nextcloud PORT
  proxy_pass http://HOST_IP:50020/; 
  proxy_http_version 1.1;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $remote_addr;
  proxy_read_timeout 1d;
  proxy_set_header HTTP_X-Forwarded-For $proxy_add_x_forwarded_for;
}

Check config and restart service

nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

systemctl restart nginx.service
systemctl status nginx.service 

Try open http://DOMAIN_NAME/nc in your browser. Unfortunately, the login page does not look like we would expect. CSS/JS files has 404 Not found error because requested paths are malformed.

To fix this edit Nextcloud configuration file (availabled in compose volume) and overwrite lines as in the example below.

nano data/app/config/config.php
#  'overwrite.cli.url' => 'http://192.168.1.12:50020',

# www.example.com is our DOMAIN_NAME
# https is our external protocol, if you don't use ssl set http
# nc is subfolder defined in nginx config

  'overwrite.cli.url' => 'https://www.example.com/nc',
  'overwritehost' => 'www.example.com',
  'overwritewebroot' => '/nc',
  'overwriteprotocol' => 'https',

Leave a Reply

Your email address will not be published. Required fields are marked *