<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Nat</title>
    <description>The latest articles on Forem by Nat (@natanielchng).</description>
    <link>https://forem.com/natanielchng</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1066254%2F1d2277e7-852f-40ad-9bca-07157836714f.jpg</url>
      <title>Forem: Nat</title>
      <link>https://forem.com/natanielchng</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/natanielchng"/>
    <language>en</language>
    <item>
      <title>How to Set Up a Clean Development Environment with Docker and Alpine Linux</title>
      <dc:creator>Nat</dc:creator>
      <pubDate>Tue, 24 Sep 2024 14:45:04 +0000</pubDate>
      <link>https://forem.com/natanielchng/how-to-set-up-a-clean-development-environment-with-docker-and-alpine-linux-4ff</link>
      <guid>https://forem.com/natanielchng/how-to-set-up-a-clean-development-environment-with-docker-and-alpine-linux-4ff</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;In this tutorial, you will set up a lightweight development environment using Docker and Alpine Linux. Docker works on containers, providing a lightweight and isolated space for running different programming languages and tools without affecting your main computer. Alpine Linux, known for its small footprint, is ideal for this setup.&lt;/p&gt;

&lt;p&gt;By following this guide, you'll create a Docker-based environment where you can experiment with Python, Node.js, and other tools without installing them directly on your machine. You'll also set up a shared folder, allowing you to transfer files between your host machine and the Docker container.&lt;/p&gt;

&lt;p&gt;By the end of this tutorial, you will have a fully functioning, isolated development environment. You'll be able to install and test different programming languages and tools quickly, keeping your main system clean and organized, which is perfect for coders who like to experiment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To follow this tutorial, you'll need: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker installed on your machine. Follow the instructions for your system on the &lt;a href="https://docs.docker.com/engine/install/" rel="noopener noreferrer"&gt;Docker Official Website&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Familiarity with Linux commands like &lt;code&gt;cd&lt;/code&gt; (change directory), &lt;code&gt;mkdir&lt;/code&gt; (create a directory), &lt;code&gt;ls&lt;/code&gt; (list directory contents), and &lt;code&gt;nano&lt;/code&gt; (text editor) will be helpful for navigating and editing files in the terminal.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1 -- Create a Project Directory
&lt;/h2&gt;

&lt;p&gt;We'll start by setting up a project folder to hold our files.&lt;/p&gt;

&lt;p&gt;Create the directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;docker-dev-env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Navigate to the directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;docker-dev-env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will serve as the workspace for your Docker setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2 -- Create a Dockerfile
&lt;/h2&gt;

&lt;p&gt;The Dockerfile is a text file where we define the instructions or commands for building our development environment within a container. This file is also conventionally named &lt;code&gt;Dockerfile&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Create the Dockerfile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano Dockerfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; alpine:latest&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apk add bash
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["bash"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;FROM alpine:latest&lt;/code&gt;: Specifies Alpine Linux as the base image. Alpine is lightweight, making it ideal for development.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;RUN apk add bash&lt;/code&gt;: Installs Bash in the container.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CMD ["bash"]&lt;/code&gt;: Launches Bash when the container starts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 3 -- Build the Docker Image
&lt;/h2&gt;

&lt;p&gt;Now we'll build the Docker image from the Dockerfile. The Docker image acts as a snapshot of everything you want in your container. It will be used to create and run your container.&lt;/p&gt;

&lt;p&gt;Run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; docker-dev-env &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;docker build -t docker-dev-env&lt;/code&gt;: Builds the image and tags (names) it as &lt;code&gt;docker-dev-env&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.&lt;/code&gt;: Indicates the current directory, where the Dockerfile is located.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 4 -- Set Up a Shared Folder
&lt;/h2&gt;

&lt;p&gt;To exchange files between your host machine and the container, we'll create a shared folder and use a feature called bind mount&lt;/p&gt;

&lt;p&gt;First, create a folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;shared-folder
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This folder will be accessible inside the container, allowing easy file transfer between the host and container.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5 -- Run the Container
&lt;/h2&gt;

&lt;p&gt;Now, we'll run the container using the image we built.&lt;/p&gt;

&lt;p&gt;Run the container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--name&lt;/span&gt; dev-env-01 &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;/shared-folder:/app"&lt;/span&gt; docker-dev-env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--name dev-env-01&lt;/code&gt;: Assigns a name to the container.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-it&lt;/code&gt;: Runs the container in &lt;em&gt;interactive&lt;/em&gt; mode with a terminal. Interactive mode allows you to use the terminal inside the container just like you would on a regular computer.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-v "$(pwd)/shared-folder:/app"&lt;/code&gt;: Mounts the &lt;code&gt;shared-folder&lt;/code&gt; directory on the host to the &lt;code&gt;app&lt;/code&gt; directory inside the container.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the container is running, the terminal will switch to the container's environment (the container ID will differ):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;902f3cefc126:/#
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 6 -- Create a File in the Container
&lt;/h2&gt;

&lt;p&gt;Let's create a file inside the container and check if it appears in the shared folder on the host.&lt;/p&gt;

&lt;p&gt;List the contents of the current directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see the app directory (declared from the bind mount):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;app    bin    dev    etc    home   ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Navigate to the app directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;someFile.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This file will now appear in the &lt;code&gt;shared-folder&lt;/code&gt; on your host machine, showing that the bind mount works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7 -- Install Programming Languages
&lt;/h2&gt;

&lt;p&gt;Next, we'll install Python and Node.js in the container.&lt;/p&gt;

&lt;p&gt;Run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apk add python3 nodejs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the installation, confirm Python is installed by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Python 3.12.6 (main, Sep 24 2024, ...) on linux
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exit Python by typing &lt;code&gt;quit()&lt;/code&gt;. Then, try running the Node.js interpreter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see the Node.js prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Welcome to Node.js v20.15.1.
Type ".help" for more information.
&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Press &lt;code&gt;Ctrl+C&lt;/code&gt; to exit. &lt;/p&gt;

&lt;p&gt;Using the container like this helps you experiment with different languages without cluttering your host machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 8 -- Stopping and Restarting the Container
&lt;/h2&gt;

&lt;p&gt;Once you're done working in the container, you can stop it without losing any data or configurations.&lt;/p&gt;

&lt;p&gt;To stop the container, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker stop dev-env-01
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command gracefully stops the container named &lt;code&gt;dev-env-01&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To restart the container and pick up where you left off, use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker start &lt;span class="nt"&gt;-i&lt;/span&gt; dev-env-01
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;-i&lt;/code&gt; flag opens the container in interactive mode again, allowing you to continue working inside the environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;You've successfully set up a lightweight development environment using Docker, created a shared folder between the host and container, and installed Python and Node.js. This isolated development setup ensures that your main system remains clean and uncluttered, making Docker a great tool for testing and experimenting.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>linux</category>
      <category>softwaredevelopment</category>
      <category>tooling</category>
    </item>
    <item>
      <title>A Step-by-Step Guide to Building Your Private Cloud with Nextcloud (2023)</title>
      <dc:creator>Nat</dc:creator>
      <pubDate>Sat, 15 Jul 2023 10:50:13 +0000</pubDate>
      <link>https://forem.com/natanielchng/a-step-by-step-guide-to-building-your-private-cloud-with-nextcloud-2023-em5</link>
      <guid>https://forem.com/natanielchng/a-step-by-step-guide-to-building-your-private-cloud-with-nextcloud-2023-em5</guid>
      <description>&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up a Nextcloud Docker Container
&lt;/h2&gt;

&lt;p&gt;First, ensure you have &lt;a href="https://www.docker.com/products/docker-desktop/" rel="noopener noreferrer"&gt;Docker Desktop&lt;/a&gt; installed on your machine. Since we will be writing some configuration files, it would also be helpful to have a code editor like &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;Visual Studio Code&lt;/a&gt; installed.&lt;/p&gt;

&lt;p&gt;To keep this project organised, create a folder called &lt;code&gt;Nextcloud&lt;/code&gt; in a directory of your choice.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;Nextcloud&lt;/code&gt; folder, create a file called &lt;code&gt;docker-compose.yml&lt;/code&gt; and another folder called &lt;code&gt;data&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Your folder structure should now look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Nextcloud/
├ docker-compose.yml
├ data/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In &lt;code&gt;docker-compose.yml&lt;/code&gt;, add the following configuration for your Nextcloud instance&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save the file and run the following command in a terminal&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the browser, go to &lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt; (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.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwagq3ciw1szn6vtc8z7g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwagq3ciw1szn6vtc8z7g.png" alt="Admin Setup" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once done, you will be brought to an app installation page. Skip the installation for now.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F25nxpfyyfemej0s8q2o0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F25nxpfyyfemej0s8q2o0.png" alt="App installation" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, you will see the welcome page, meaning you have successfully set up your private Nextcloud instance!&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc6e9xz0s0gb9ewyyjyux.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc6e9xz0s0gb9ewyyjyux.png" alt="Nextcloud welcome page" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you would like to "shutdown" your Nextcloud instance, head back to your terminal and run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose down
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you look at the &lt;code&gt;Nextcloud&lt;/code&gt; directory created earlier, it should like this now&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Nextcloud/
├ docker-compose.yml
├ data/
  ├ files_external/
  ├ admin/
  ├ .htaccess
  ├ .ocdata
  ├ index.html
  ├ nextcloud.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;data&lt;/code&gt; folder created earlier is where you can find files uploaded to Nextcloud. The &lt;code&gt;admin&lt;/code&gt; folder contains the files that were uploaded by the admin user.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accessing Nextcloud Over The Internet With Ngrok
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://ngrok.com" rel="noopener noreferrer"&gt;Ngrok&lt;/a&gt; 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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Navigate to the "Domains" tab and select "Claim your free static subdomain". Take note of your generated URL.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8nni83qyam9k8gdvus6u.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8nni83qyam9k8gdvus6u.jpg" alt="Claim a free static sub-domain" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, go to "Edges" and select "Create Edge"&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4bmfpzgyw089pij5ifqy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4bmfpzgyw089pij5ifqy.jpg" alt="Create edge" width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select "Create HTTPS edge"&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flb32ktalfavt0rj848nh.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flb32ktalfavt0rj848nh.jpg" alt="Create HTTPS edge" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should now see the following dashboard. Take note of your tunnel label, &lt;code&gt;edge=XXXXXX&lt;/code&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl0ii7vwwt2k5wp1kjhr4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl0ii7vwwt2k5wp1kjhr4.jpg" alt="Edge dashboard" width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go back to your &lt;code&gt;docker-compose.yml&lt;/code&gt; file created earlier and add the following entry which contains your Ngrok tunnel label and authtoken.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ngrok:
    image: ngrok/ngrok:latest
    restart: always
    command: tunnel --label edge=&amp;lt;YOUR-NGROK-TUNNEL-LABEL&amp;gt; app:80
    ports:
      - 4040:4040
    environment:
      - NGROK_AUTHTOKEN=&amp;lt;YOUR-NGROK-TOKEN&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;docker-compose.yml&lt;/code&gt; file should now look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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=&amp;lt;YOUR-NGROK-TUNNEL-LABEL&amp;gt; app:80
    ports:
      - 4040:4040
    environment:
      - NGROK_AUTHTOKEN=&amp;lt;YOUR-NGROK-TOKEN&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, run &lt;code&gt;docker-compose up&lt;/code&gt; again, and head to the Ngrok URL created earlier. You should see an error message.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjzja8k7sbe3w10qvt5bz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjzja8k7sbe3w10qvt5bz.jpg" alt="Error message" width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is not a problem, as the Nextcloud instance simply has to whitelist your Ngrok subdomain. Run the following command in the terminal&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker exec -u 33 -it nextcloud-app-1 php occ config:system:set trusted_domains 1 --value=&amp;lt;YOUR-NGROK-SUBDOMAIN&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The success message looks like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;System config value trusted domains =&amp;gt; 1 set to string &amp;lt;YOUR-NGROK-SUBDOMAIN&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart the Nextcloud instance by running &lt;code&gt;docker restart nextcloud-app-1&lt;/code&gt;. Then go to your Ngrok URL again. Now, you should be able to access Nextcloud.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F38b7n5jvta2o13lz336v.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F38b7n5jvta2o13lz336v.jpg" alt="Accessed via ngrok" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You might have noticed that Ngrok's free subdomains are pretty random.&lt;/p&gt;

&lt;p&gt;For personal use, using the free subdomain would be sufficient. Another way I have tried is redirecting a custom domain to the free subdomain.&lt;/p&gt;

&lt;p&gt;However, you would need to get a paid Ngrok plan to to use a custom domain name without the aforementioned workarounds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Congratulations, you have a private cloud that is accessible from anywhere! &lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

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

</description>
      <category>opensource</category>
      <category>cloud</category>
      <category>docker</category>
      <category>ngrok</category>
    </item>
  </channel>
</rss>
