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',

Playing Glances 3.0 with Grafana

Library stack

  • Grafana v5.3.2
  • Glances v3.0.2
  • InfluxDb v1.0.2

Install & conf Glances 3.0

Install Glances from PIP:

sudo apt-get install python python-pip python-dev influxdb-client
sudo pip install glances influxdb

If you need additional support for your services you have to install optional dependencies. In my case I also installed docker, hddtemp 

sudo pip install docker hddtemp

Login into InfluxDB and create database:

influx -username LOGIN -password PASS
CREATE DATABASE glances
CREATE RETENTION POLICY "one_year_only" ON "glances" DURATION 365d REPLICATION 1 DEFAULT

Create configuration file for glances:

nano /usr/src/glances.conf
[influxdb]
host=127.0.0.1
port=8086
user=USER
password=PASSWORD
db=glances
prefix=localhost

Create systemd service

Add glances to Systemd as new service. Create new file and copy/past example (source):

sudo nano /etc/systemd/system/glances.service
[Unit]
Description=Glances
After=network.target

[Service]
ExecStart=/usr/local/bin/glances --quiet -t 15 --export influxdb -C /usr/src/glances.conf
Restart=on-failure
RestartSec=30s
TimeoutSec=30s

[Install]
WantedBy=multi-user.target

Parameter -t says how often data will be refreshed. Default is 3s. I changed it, because 3s resolution is useless.

sudo systemctl enable glances.service
sudo systemctl start glances.service

After few second we can see new data stored in InfluxDB 

> use glances
Using database glances
> show series
key
localhost.cpu
localhost.diskio
localhost.docker
localhost.fs
localhost.ip
localhost.load
localhost.mem
localhost.memswap
localhost.network
localhost.percpu
localhost.processcount
localhost.sensors
localhost.system
localhost.uptime

Grafana config

Create data source

Grafana

Source configuration

Import dashboard

You can import predefined dashboard from community or prepare yours own.

Grafana

Dashboard