A Step-by-Step Guide to Building Your Private Cloud with Nextcloud (2023)
Tags: opensource, cloud, docker, ngrok
Published: 2023-07-15 10:50:13

This guide will walk you through the process of setting up your personal Nextcloud instance. In the first section, you will be setting up a Nextcloud Docker container and running it in your local network. Then, you will learn how to access your Nextcloud instance over the internet using Ngrok.

## Setting Up a Nextcloud Docker Container
First, ensure you have [Docker Desktop](https://www.docker.com/products/docker-desktop/) installed on your machine. Since we will be writing some configuration files, it would also be helpful to have a code editor like [Visual Studio Code](https://code.visualstudio.com/) installed.

To keep this project organised, create a folder called `Nextcloud` in a directory of your choice.

In the `Nextcloud` folder, create a file called `docker-compose.yml` and another folder called `data`.

Your folder structure should now look like this
```
Nextcloud/
├ docker-compose.yml
├ data/
```

In `docker-compose.yml`, add the following configuration for your Nextcloud instance
```
version: '3'

volumes:
  db:
  nextcloud:

services:
  db:
    image: mariadb:10.6
    restart: always
    command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW
    volumes:
      - db:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=nextcloud
      - MYSQL_PASSWORD=nextcloud
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud

  app:
    image: nextcloud
    restart: always
    ports:
      - 8080:80
    depends_on:
      - db
    volumes:
      - nextcloud:/var/www/html
      - ./data:/var/www/html/data
    environment:
      - MYSQL_PASSWORD=nextcloud
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_HOST=db
```

Save the file and run the following command in a terminal
```
docker-compose up
```

In the browser, go to http://localhost:8080 (you may have to refresh the browser before the Nextcloud login page loads). You should see a prompt to create an admin account. Provide a username and secure password, then select 'Install'. Installation takes a few minutes.
![Admin Setup](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wagq3ciw1szn6vtc8z7g.png)

Once done, you will be brought to an app installation page. Skip the installation for now.
![App installation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/25nxpfyyfemej0s8q2o0.png)

Finally, you will see the welcome page, meaning you have successfully set up your private Nextcloud instance!
![Nextcloud welcome page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c6e9xz0s0gb9ewyyjyux.png)


If you would like to "shutdown" your Nextcloud instance, head back to your terminal and run
```
docker-compose down
```

If you look at the `Nextcloud` directory created earlier, it should like this now
```
Nextcloud/
├ docker-compose.yml
├ data/
  ├ files_external/
  ├ admin/
  ├ .htaccess
  ├ .ocdata
  ├ index.html
  ├ nextcloud.log
```

The `data` folder created earlier is where you can find files uploaded to Nextcloud. The `admin` folder contains the files that were uploaded by the admin user.

## Accessing Nextcloud Over The Internet With Ngrok
[Ngrok](https://ngrok.com) is a service that provides a secure URL which can be used to access the Nextcloud instance created in the previous section. Creating a free account is sufficient for this guide.

Once you have created your Ngrok account, go to your account dashboard and navigate to the "Getting Started" tab and select "Your Authtoken". You will be using this authtoken later on.

Navigate to the "Domains" tab and select "Claim your free static subdomain". Take note of your generated URL.
![Claim a free static sub-domain](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8nni83qyam9k8gdvus6u.jpg)

Now, go to "Edges" and select "Create Edge"
![Create edge](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4bmfpzgyw089pij5ifqy.jpg)

Select "Create HTTPS edge"
![Create HTTPS edge](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lb32ktalfavt0rj848nh.jpg)

You should now see the following dashboard. Take note of your tunnel label, `edge=XXXXXX`
![Edge dashboard](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l0ii7vwwt2k5wp1kjhr4.jpg)

Go back to your `docker-compose.yml` file created earlier and add the following entry which contains your Ngrok tunnel label and authtoken.
```
ngrok:
    image: ngrok/ngrok:latest
    restart: always
    command: tunnel --label edge=<YOUR-NGROK-TUNNEL-LABEL> app:80
    ports:
      - 4040:4040
    environment:
      - NGROK_AUTHTOKEN=<YOUR-NGROK-TOKEN>
```

The `docker-compose.yml` file should now look like this
```
version: '3'

volumes:
  db:
  nextcloud:

services:
  db:
    image: mariadb:10.6
    restart: always
    command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW
    volumes:
      - db:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=nextcloud
      - MYSQL_PASSWORD=nextcloud
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud

  app:
    image: nextcloud
    restart: always
    ports:
      - 8080:80
    depends_on:
      - db
    volumes:
      - nextcloud:/var/www/html
      - ./data:/var/www/html/data
    environment:
      - MYSQL_PASSWORD=nextcloud
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_HOST=db

  ngrok:
    image: ngrok/ngrok:latest
    restart: always
    command: tunnel --label edge=<YOUR-NGROK-TUNNEL-LABEL> app:80
    ports:
      - 4040:4040
    environment:
      - NGROK_AUTHTOKEN=<YOUR-NGROK-TOKEN>
```

Now, run `docker-compose up` again, and head to the Ngrok URL created earlier. You should see an error message.
![Error message](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jzja8k7sbe3w10qvt5bz.jpg)

This is not a problem, as the Nextcloud instance simply has to whitelist your Ngrok subdomain. Run the following command in the terminal
```
docker exec -u 33 -it nextcloud-app-1 php occ config:system:set trusted_domains 1 --value=<YOUR-NGROK-SUBDOMAIN>
```

The success message looks like this
```
System config value trusted domains => 1 set to string <YOUR-NGROK-SUBDOMAIN>
```

Restart the Nextcloud instance by running `docker restart nextcloud-app-1`. Then go to your Ngrok URL again. Now, you should be able to access Nextcloud.
![Accessed via ngrok](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/38b7n5jvta2o13lz336v.jpg)

You might have noticed that Ngrok's free subdomains are pretty random.

For personal use, using the free subdomain would be sufficient. Another way I have tried is redirecting a custom domain to the free subdomain.

However, you would need to get a paid Ngrok plan to to use a custom domain name without the aforementioned workarounds.

## Conclusion
Congratulations, you have a private cloud that is accessible from anywhere! 

When starting out using Nextcloud, I sourced for information from many different places, was quite confused and had to experiment quite a bit. I hope that this guide helps someone who was in my position.

While this guide has covered a basic set up process of Nextcloud, I hope to cover more security and feature configurations in the future.