Comments

Latest Posts

Install NextCloud Docker and Integrate with Nginx and LetsEncrypt SSL Certificate

Previously, I had a couple of posts to present how to install NextCloud and how to configure it with some different storage options. This post is similar as one of them, but it will add two dockers to add SSL certificate for Nginx.

Here are all steps. For Dock Compose file, there are two options , one with MySQL DB, another without DB, which NextCloud will use built-in Sqlite for DB. 




    Install Docker and Docker Compose

    1  Update Package list and Upgrade Packages for Ubuntu 18.04

    Update and Upgrade Ubuntu to latest 

    $ sudo apt-get -y update && sudo apt-get -y upgrade

    2  Install Docker on Ubuntu

    sudo apt install docker.io -y
    sudo -i
    systemctl start docker
    systemctl enable docker
    docker version
    
    3  Install Docker Compose on Ubuntu


    [email protected]:~# curl -L "https://github.com/docker/compose/releases/download/1.19.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100   651  100   651    0     0   7076      0 --:--:-- --:--:-- --:--:--  7076
    100 8288k  100 8288k    0     0  4671k      0  0:00:01  0:00:01 --:--:-- 7520k
    [email protected]:~# chmod +x /usr/local/bin/docker-compose
    
    [email protected]:~# docker-compose version
    docker-compose version 1.19.0, build 9e633ef
    docker-py version: 2.7.0
    CPython version: 2.7.13
    OpenSSL version: OpenSSL 1.0.1t  3 May 2016
    [email protected]:~#
    
    

    Create NextCloud Project Folder and Nginx conf.d Folder

    Create a conf.d folder for nginx configure files

    mkdir -p /opt/nextcloud/conf.d

    Create a nextcloud.conf nginx configuration file 

    nano /opt/nextcloud/conf.d/nextcloud.conf


    Copy following information into nextcloud.conf file:

    upstream php-handler {
        server app:9000;
    }
    
    server {
        listen       80;
        listen       443 ssl http2;
        server_name  ${FQDN};
        # Max allowed upload file in web page
        client_max_body_size 20G;
        if ($server_port !~ 443){
            rewrite ^(/.*)$ https://$host$1 permanent;
        }
    
        # SSL and Support TLSv1.3
        ssl_certificate    /etc/letsencrypt/live/${FQDN}/fullchain.pem;
        ssl_certificate_key    /etc/letsencrypt/live/${FQDN}/privkey.pem;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_ciphers TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 10m;
        error_page 497  https://$host$request_uri;
    
        # add header information to fix Nextcloud console warning messages
        add_header X-Content-Type-Options nosniff;
        add_header X-XSS-Protection "1; mode=block";
        add_header X-Robots-Tag none;
        add_header X-Download-Options noopen;
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-Permitted-Cross-Domain-Policies none;
        add_header Referrer-Policy no-referrer;
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
        fastcgi_hide_header X-Powered-By;
    
        root /var/www/html;
    
        location = /robots.txt {
            allow all;
            log_not_found off;
            access_log off;
        }
    
        location = /.well-known/carddav {
          return 301 $scheme://$host/remote.php/dav;
        }
        location = /.well-known/caldav {
          return 301 $scheme://$host/remote.php/dav;
        }
    
        # Enable gzip compression
        gzip on;
        gzip_vary on;
        gzip_comp_level 4;
        gzip_min_length 256;
        gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
        gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
    
        # redirection and disable to access backend sensitive folders and resources
        location / {
            rewrite ^ /index.php$request_uri;
        }
    
        location ~ ^\/(?:build|tests|config|lib|3rdparty|templates|data)\/ {
            deny all;
        }
        location ~ ^\/(?:\.|autotest|occ|issue|indie|db_|console) {
            deny all;
        }
    
        # PHP configuration
        location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+)\.php(?:$|\/) {
            fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_path_info;
            fastcgi_param HTTPS on;
            #Avoid sending the security headers twice
            fastcgi_param modHeadersAvailable true;
            fastcgi_param front_controller_active true;
            fastcgi_pass php-handler;
            fastcgi_intercept_errors on;
            fastcgi_request_buffering off;
        }
    
        location ~ ^\/(?:updater|ocs-provider)(?:$|\/) {
            try_files $uri/ =404;
            index index.php;
        }
    
        location ~ \.(?:css|js|woff2?|svg|gif)$ {
            try_files $uri /index.php$request_uri;
            add_header Cache-Control "public, max-age=15778463";
            add_header X-Content-Type-Options nosniff;
            add_header X-XSS-Protection "1; mode=block";
            add_header X-Robots-Tag none;
            add_header X-Download-Options noopen;
            add_header X-Permitted-Cross-Domain-Policies none;
            add_header Referrer-Policy no-referrer;
            access_log off;
        }
    
        location ~ \.(?:png|html|ttf|ico|jpg|jpeg)$ {
            try_files $uri /index.php$request_uri;
            # Optional: Don't log access to other assets
            access_log off;
        }
    }



    Create a new nextcloud docker-compose file 


    nano /opt/nextcloud/docker-compose.yml

    1. Create a new nextcloud docker-compose file without DB

    Copy following information into compose file

    version: '3'
    
    volumes:
        letsencrypt:
        nextcloud:
    
    services: 
        proxy:
            image: staticfloat/nginx-certbot
            ports:
                - 80:80
                - 443:443
            environment: 
                CERTBOT_EMAIL: [email protected].com
                ENVSUBST_VARS: FQDN
                FQDN: nextcloud.51sec.org
            volumes:
                - ./conf.d:/etc/nginx/user.conf.d:ro
                - letsencrypt:/etc/letsencrypt
                - nextcloud:/var/www/html
            restart: unless-stopped
       
        app:
            image: nextcloud:fpm
            volumes:
                - nextcloud:/var/www/html
                - ./app/data:/var/www/html/data
                - ./app/config:/var/www/html/config
            restart: unless-stopped
    
        cron:
            image: rcdailey/nextcloud-cronjob
            environment:
                - NEXTCLOUD_CRON_MINUTE_INTERVAL=15
                - NEXTCLOUD_CONTAINER_NAME=app
                - NEXTCLOUD_PROJECT_NAME=nextcloud
            volumes:
                - /var/run/docker.sock:/var/run/docker.sock:ro
                - /etc/localtime:/etc/localtime:ro
            restart: always


    2. Create a new nextcloud docker-compose file with DB

    Copy following information into compose file

    version: '3'
    
    volumes:
        letsencrypt:
        nextcloud:
    
    services: 
        proxy:
            image: staticfloat/nginx-certbot
            ports:
                - 80:80
                - 443:443
            environment: 
                CERTBOT_EMAIL: [email protected].com
                ENVSUBST_VARS: FQDN
                FQDN: nextcloud.51sec.org
            volumes:
                - ./conf.d:/etc/nginx/user.conf.d:ro
                - letsencrypt:/etc/letsencrypt
                - nextcloud:/var/www/html
            restart: unless-stopped
    
        db:
            image: mariadb
            environment:
                - MYSQL_ROOT_PASSWORD[email protected]
                - MYSQL_PASSWORD[email protected]
                - MYSQL_DATABASE=nextcloud
                - MYSQL_USER=nextcloud
            volumes: 
                - ./mysql:/var/lib/mysql
            restart: unless-stopped
        
        app:
            image: nextcloud:fpm
            volumes:
                - nextcloud:/var/www/html
                - ./app/data:/var/www/html/data
                - ./app/config:/var/www/html/config
            restart: unless-stopped
    
        cron:
            image: rcdailey/nextcloud-cronjob
            environment:
                - NEXTCLOUD_CRON_MINUTE_INTERVAL=15
                - NEXTCLOUD_CONTAINER_NAME=app
                - NEXTCLOUD_PROJECT_NAME=nextcloud
            volumes:
                - /var/run/docker.sock:/var/run/docker.sock:ro
                - /etc/localtime:/etc/localtime:ro
            restart: always


    You might want to change following configuration using your own settings:

                CERTBOT_EMAIL: [email protected].com
                ENVSUBST_VARS: FQDN
                FQDN: nextcloud.51sec.org
               - MYSQL_ROOT_PASSWORD[email protected]
                - MYSQL_PASSWORD[email protected]
                - MYSQL_DATABASE=nextcloud
                - MYSQL_USER=nextcloud
    Please make sure your dns record has been created for nextcloud.51sec.org, which is pointing to this virtual machine's public ip.

    Please make sure your firewall ports 80 and 443 opened on your cloud security group and local virtual machine. By default, Ubuntu18.04 UFW status is inactive. 

    After confirmed all configuration has ben set correctly, you can start up your docker using docker-compose command:

    cd /opt/nextcloud
    docker-compose up -d


    Using your Browser to connect to the domain url, in my case, it is  https://nextcloud.51sec.org







    After installation


    After installation, There are a couple of things to clean up and to configure further. 

    1  Install Dockerwe will have to run following two commands to fix settings warnings:

    docker-compose exec -u www-data app php occ db:add-missing-indices
    docker-compose exec -u www-data app php occ db:convert-filecache-bigint
    2  Adding local file folder under your nextCloud user
    For example, if your nextcloud user is admin, you would like to add your local files under this user, you will need to copy all files to following folder.
    /opt/nextcloud/app/data/admin/files

    After copied all files into this folder, using following command to scan them:

    docker-compose exec -u www-data app php occ files:scan --all

    3  If you would like to install ffmpeg, following these commands:

    docker exec -it nextcloud_app_1 bash
    apt -y update
    apt -y install ffmpeg



    Backup & Restore

    Here are some steps to backup and restore your NextCloud system:

    1  Stop all dockers running using docker-compose command.
    cd /opt/nextcloud
    docker-compose stop
    2  Pack all files from /opt/nextcloud folder
    cd /opt
    tar -zcvf nextcloud.tar.gz nextcloud
    3  Transfer tar file to new machine
    scp nextcloud.tar.gz [email protected]:/opt
    4  Install Docker and Docker Compose on new machine
    cd /opt
    tar -xzvf nextcloud.tar.gz

    5  Bring dockers up, which should still keeps all of your files and configuration

    cd nextcloud
    docker-compose up -d



    YouTube:







    Another Way to Quickly Bring NextCloud Docker Up

    Go to NextCloud office image site at Docker Hub: https://hub.docker.com/_/nextcloud

    Go to "Base version - apache" section under "Running this image with docker-compose"

    Copy the whole code block into a new Portainer's stack's editor.

    Only change is to add "--innodb-read-only-compressed=OFF" into command line. 
    version: '2'
    
    volumes:
      nextcloud:
      db:
    
    services:
      db:
        image: mariadb
        restart: always
        command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW --innodb-read-only-compressed=OFF
        volumes:
          - db:/var/lib/mysql
        environment:
          - MYSQL_ROOT_PASSWORD=Password1!
          - MYSQL_PASSWORD=Password12!
          - MYSQL_DATABASE=nextcloud
          - MYSQL_USER=nextcloud
    
      app:
        image: nextcloud
        restart: always
        ports:
          - 8080:80
        links:
          - db
        volumes:
          - nextcloud:/var/www/html
        environment:
          - MYSQL_PASSWORD=Password12!
          - MYSQL_DATABASE=nextcloud
          - MYSQL_USER=nextcloud
          - MYSQL_HOST=db


    Click "Deploy the stack" button.

    You can now access Nextcloud by accessing the port 8080 on the server where Portainer is running.

    http://<your_vm_ip>:8080




    References









    5 comments:

    1. Thank you, I just managed to set this up on Raspberry Pi 4b. Advice: remove http2 from nginx config to enhance upload speed.

      ReplyDelete
      Replies
      1. What images did you go with for your Pi 4 install? I haven't had any luck so far with getting the proxy service going. My DB seems to be working. The Nextcloud image log is showing some errors, but I haven't been able to access the interface to test it out.

        Delete
    2. Would you please be so kind and let me know how can I configure nginx to load from mysite.com/nexcloud instead from mystic.com? Thanks a lot in advance!

      ReplyDelete
    3. Would you please be so kind and let me know how can I configure nginx to load from mysite.com/nexcloud instead from mystic.com? Thanks a lot in advance!

      ReplyDelete
    4. Would you please be so kind and let me know how can I configure nginx to load from mysite.com/nexcloud instead from mystic.com? Thanks a lot in advance!

      ReplyDelete