<?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>DEV Community: R. Quazi</title>
    <description>The latest articles on DEV Community by R. Quazi (@r-quazi).</description>
    <link>https://dev.to/r-quazi</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%2F2074957%2Fa838fbf4-b1b6-47a1-8073-702919988808.png</url>
      <title>DEV Community: R. Quazi</title>
      <link>https://dev.to/r-quazi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/r-quazi"/>
    <language>en</language>
    <item>
      <title>Purelymail – The Most Cost-Effective Email Provider for Custom Domains</title>
      <dc:creator>R. Quazi</dc:creator>
      <pubDate>Sun, 31 Aug 2025 08:44:39 +0000</pubDate>
      <link>https://dev.to/r-quazi/purelymail-the-most-cost-effective-email-provider-for-custom-domains-2j56</link>
      <guid>https://dev.to/r-quazi/purelymail-the-most-cost-effective-email-provider-for-custom-domains-2j56</guid>
      <description>&lt;p&gt;When I was searching for a cost-effective email provider, I noticed that most providers bundle &lt;strong&gt;a single mailbox with strict storage limits&lt;/strong&gt;. As someone starting a new venture, I didn’t want to mix personal emails with business ones, and I wanted the flexibility to create separate mailboxes for different apps and domains right from the beginning.&lt;/p&gt;

&lt;h3&gt;
  
  
  My Journey Before Purelymail
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Self-hosted email:&lt;/strong&gt; I tried this route, but most ISPs block outbound ports to fight spam. AWS also requires opening a support ticket, providing justifications, and waiting for approval. In short—too much hassle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zoho Mail:&lt;/strong&gt; They once offered 5 free mailboxes, but that plan is gone for new users. Even then, the 5 GB storage and mailbox cap quickly felt restrictive.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mainstream providers (Google Workspace, GoDaddy, Hostinger, etc.):&lt;/strong&gt; All are &lt;em&gt;overpriced and inflexible&lt;/em&gt; for startups. Paying per mailbox gets ridiculous when you want multiple admin addresses.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why Multiple Emails Matter
&lt;/h3&gt;

&lt;p&gt;I prefer compartmentalization. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="//mailto:bizops@domain.com"&gt;bizops@domain.com&lt;/a&gt;&lt;/strong&gt; for operations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="//mailto:clouds@domain.com"&gt;clouds@domain.com&lt;/a&gt;&lt;/strong&gt; for infrastructure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="//mailto:vault@domain.com"&gt;vault@domain.com&lt;/a&gt;&lt;/strong&gt; for sensitive data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="//mailto:finance@domain.com"&gt;finance@domain.com&lt;/a&gt;&lt;/strong&gt; for bookkeeping&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="//mailto:marketing@domain.com"&gt;marketing@domain.com&lt;/a&gt;&lt;/strong&gt; for campaigns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="//mailto:social@domain.com"&gt;social@domain.com&lt;/a&gt;&lt;/strong&gt; for social platforms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This way, if one account gets compromised, the rest of my business isn’t automatically exposed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enter Purelymail
&lt;/h3&gt;

&lt;p&gt;Purelymail offers a &lt;strong&gt;simple, transparent pricing model&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;\$10/year&lt;/strong&gt; for infinite mailboxes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&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%2Fkh817v2csr7bxiwijwr8.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%2Fkh817v2csr7bxiwijwr8.png" alt=" " width="636" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pay-as-you-go billing once you cross certain thresholds (storage, sending/receiving limits).&lt;/li&gt;
&lt;li&gt;Full support for &lt;strong&gt;IMAP, POP3, and SMTP&lt;/strong&gt;, meaning you can configure it in Gmail, Outlook, Thunderbird, etc.&lt;/li&gt;
&lt;li&gt;You can also use their own webmail client (though, honestly, the UI is quite outdated).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s a snapshot from my monthly usage report:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cost this month: &lt;strong&gt;\$0.65&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Under advanced pricing, it could have been even lower.&lt;/li&gt;
&lt;li&gt;Storage: practically free unless you hoard huge attachments.&lt;/li&gt;
&lt;li&gt;Sending &amp;amp; receiving costs: negligible.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The best part? &lt;strong&gt;Unlimited domains and unlimited users.&lt;/strong&gt; This is a dream for startups that want flexibility without breaking the bank.&lt;/p&gt;

&lt;h3&gt;
  
  
  Downsides (the reality check)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Single-person operation:&lt;/strong&gt; From what I’ve read on Reddit, Purelymail is largely run by one individual. That’s impressive, but also risky if the bus factor = 1.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI/UX is barebones:&lt;/strong&gt; Don’t expect the polish of Gmail or Outlook. It’s functional, not pretty.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not mainstream:&lt;/strong&gt; No huge brand recognition or corporate backing. If reliability and long-term continuity are a concern, always keep &lt;strong&gt;backups of your emails&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No big ecosystem:&lt;/strong&gt; Unlike Google or Microsoft, you don’t get extras like calendar, storage, or docs. This is &lt;em&gt;just email&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Verdict
&lt;/h3&gt;

&lt;p&gt;If you’re a &lt;strong&gt;startup, indie hacker, or small business&lt;/strong&gt; that just needs cheap, reliable, custom-domain email with multiple mailboxes, &lt;strong&gt;Purelymail is unbeatable&lt;/strong&gt; in terms of cost.&lt;/p&gt;

&lt;p&gt;If you need enterprise-grade support, integrations, or guaranteed longevity, you might still prefer Google Workspace or Microsoft 365.&lt;/p&gt;

&lt;p&gt;For me, Purelymail has been a hidden gem. It’s not flashy, but it just works—and for \$10/year, that’s hard to beat.&lt;/p&gt;

&lt;p&gt;👉 Check it out here: &lt;a href="https://purelymail.com" rel="noopener noreferrer"&gt;https://purelymail.com&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;About me: I’m Quazi, with 5 years of experience in AWS Cloud, IT &amp;amp; Infrastructure, DevOps, and DevSecOps. I enjoy exploring cost-effective tools and sharing honest reviews to help startups, solo founders, and small teams make better tech decisions. Feel free to connect with me on LinkedIn : &lt;a href="https://www.linkedin.com/in/r-quazi/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/r-quazi/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>startup</category>
      <category>mailserver</category>
      <category>development</category>
      <category>mail</category>
    </item>
    <item>
      <title>Take Control of Your Data- Self-host NextCloud.</title>
      <dc:creator>R. Quazi</dc:creator>
      <pubDate>Fri, 20 Sep 2024 14:30:14 +0000</pubDate>
      <link>https://dev.to/r-quazi/take-control-of-your-data-self-hosting-nextcloud-4enf</link>
      <guid>https://dev.to/r-quazi/take-control-of-your-data-self-hosting-nextcloud-4enf</guid>
      <description>&lt;h1&gt;
  
  
  Take Control of Your Data- Self-Hosting NextCloud with MariaDB, Redis, with Let's Encrypt SSL and Securely Access via TailScale VPN
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;[! Table of Contents]&lt;/p&gt;

&lt;blockquote&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
1.1. Preface&lt;br&gt;&lt;br&gt;
1.2. Architecture&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Initial Setup&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
2.1. Get a Domain Name&lt;br&gt;&lt;br&gt;
2.2. Tailscale VPN Setup&lt;br&gt;&lt;br&gt;
2.3. Installing Docker&lt;br&gt;&lt;br&gt;
2.4. Pointing DNS to the Server's Private IP Address&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;NextCloud Deployment&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
3.1. SSL Request with Let's Encrypt&lt;br&gt;&lt;br&gt;
3.2. Using a &lt;code&gt;.env&lt;/code&gt; File to Manage Configuration Variables&lt;br&gt;&lt;br&gt;
3.3. NextCloud Configuration in &lt;code&gt;config.php&lt;/code&gt;&lt;br&gt;&lt;br&gt;
3.4. Creating the Apache Configuration File&lt;br&gt;&lt;br&gt;
3.5. Setting Request Limits in Apache&lt;br&gt;&lt;br&gt;
3.6. Script to Enable SSL and Headers Module in NextCloud Container&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Docker Compose&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
4.1. Creating a Docker Compose File&lt;br&gt;&lt;br&gt;
4.2. Running Docker Services&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Accessing NextCloud on a Private IP&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
5.1. Accessing via Private IP&lt;br&gt;&lt;br&gt;
5.2. Resolving Untrusted Domain Error &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  1 Introduction :
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1.1  Preface
&lt;/h2&gt;

&lt;p&gt;In today's digital age, data is the new currency. But with popular collaboration tools like Slack and Microsoft Teams, there's a growing concern about data privacy and security. These platforms may collect user data, potentially using it to train AI models or fix bugs, leaving organizations vulnerable.&lt;/p&gt;

&lt;p&gt;That's why self-hosting has become an attractive option for businesses seeking control over their data. In this article, we'll guide you through setting up NextCloud, a powerful collaboration platform, using MariaDB as our database and Redis for caching. We'll also use Let's Encrypt SSL certificates using Certbot and accessing it securely via TailScale VPN. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Best Part?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Flexibility&lt;/strong&gt;: This setup will run entirely in Docker containers, making it easy to deploy on any platform with Docker installed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security&lt;/strong&gt;: We'll use TailScale to establish secure, encrypted connections from client devices, ensuring NextCloud is only accessible via private IP.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  1.2  Architecture :
&lt;/h2&gt;

&lt;p&gt;This self-hosted NextCloud setup is designed with security, privacy, and performance in mind. The architecture ensures that services remains private and secure ( Considering you have enabled RBAC , followed Zero Trust Principles and  best practices for shared security model  if you have Virtual Machine/Server in public cloud . )&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fslnmpphgyjz0a0y1ri5y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fslnmpphgyjz0a0y1ri5y.png" alt="Architecture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The NextCloud server is accessible only through Tailscale VPN, which establishes secure, encrypted communication between employee devices and the server. Access control (ACLs) is strictly enforced, allowing only approved employees (e.g., Employee 1 and Employee 2) to connect, while denying access to others (e.g., Employee 3..even if he connected to VPN and external users trying to connect to  nextcloud without VPN).&lt;/p&gt;

&lt;p&gt;The NextCloud service itself is containerized and runs within a Docker container. The key services include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Let's Encrypt&lt;/strong&gt;: Ensuring secure communication between clients and the server using Let's Encrypt SSL/TLS certificates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;NextCloud&lt;/strong&gt;: The core collaboration platform, running alongside Apache2 as the web server (Apache2 running in same nextcloud container. If you are using &lt;code&gt;nextcloud:fpm&lt;/code&gt; docker image you may need to setup &lt;code&gt;apache&lt;/code&gt; or &lt;code&gt;traefik&lt;/code&gt; container. In this article have used &lt;code&gt;nextcloud:apache-stable&lt;/code&gt; docker image).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Redis&lt;/strong&gt;: Handling caching duties to improve performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;MariaDB&lt;/strong&gt;: Serving as the primary database for storing sensitive data.    &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This containerized approach offers modularity, ease of management, and scalability, all while maintaining a high level of security and performance.&lt;/p&gt;




&lt;h1&gt;
  
  
  2 Initial Setup  :
&lt;/h1&gt;

&lt;h2&gt;
  
  
  2.1  Get a Domain name:
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;[!NOTE]&lt;br&gt;
If you already have a domain name, you can skip this step.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For those who need to purchase a domain, there are several providers to choose from, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Namecheap&lt;/li&gt;
&lt;li&gt;GoDaddy&lt;/li&gt;
&lt;li&gt;Hostinger&lt;/li&gt;
&lt;li&gt;Google Domains&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please note, I am not promoting any specific platform, and these links are not affiliate links. You are free to select any domain provider that suits your needs.&lt;/p&gt;




&lt;h2&gt;
  
  
  2.2  Tailscale  :
&lt;/h2&gt;

&lt;p&gt;Tailscale is a modern VPN service that simplifies connecting devices and applications over a secure network. It leverages the WireGuard protocol to create a peer-to-peer mesh network, known as TailNet, which allows devices within the same private network to communicate directly. This is different from traditional VPNs, which route all traffic through a central gateway.&lt;/p&gt;

&lt;p&gt;Tailscale can be used for various purposes, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SSH Access&lt;/strong&gt;: Securely connect to remote machines.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File Access and Sharing&lt;/strong&gt;: Access and share files across devices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private Website Access&lt;/strong&gt;: Reach privately hosted websites.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database and Kubernetes Clusters&lt;/strong&gt;: Connect to databases and Kubernetes clusters securely.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.2.1   Key Differences from Traditional VPNs
&lt;/h3&gt;

&lt;p&gt;Traditional VPNs create a central tunnel for all network traffic, routing it through a single gateway. In contrast, Tailscale establishes a peer-to-peer or point-to-point mesh network, which they refer to as TailNet, enabling direct communication between devices.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.2.2    Setting Up Tailscale
&lt;/h3&gt;

&lt;h3&gt;
  
  
  2.2.3    Sign Up and Access the Admin Dashboard
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Sign Up&lt;/strong&gt;: Create an account at &lt;a href="https://tailscale.com/" rel="noopener noreferrer"&gt;Tailscale&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Admin Dashboard&lt;/strong&gt;: After signing up, you will be directed to the Tailscale Admin Dashboard.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fbjuxx15t2t5xaxuqen7o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fbjuxx15t2t5xaxuqen7o.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2.2.4    Install Tailscale on Linux
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Open your Linux terminal and run:&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://tailscale.com/install.sh | sh
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Check the status of the Tailscale service:&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status tailscaled
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Enable and start the Tailscale service:&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;tailscaled
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start tailscaled
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  2.2.5    Install Tailscale on Windows
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Download the Tailscale installer for Windows from &lt;a href="https://pkgs.tailscale.com/stable/tailscale-setup-latest.exe" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Once Installed login to tailscale.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  2.2.6   Configure Tailscale
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Generate an Auth Key&lt;/strong&gt;:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Return to the Tailscale Admin Dashboard.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Navigate to &lt;strong&gt;Settings&lt;/strong&gt; to generate an authentication key. (I have used Ubuntu 24.04 Linux as WSL. )&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2F5kl53j2hfrlpkl868wwe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F5kl53j2hfrlpkl868wwe.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Authenticate and Connect&lt;/strong&gt;:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Return to your Linux terminal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run the following command to authenticate and connect:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;tailscale up &lt;span class="nt"&gt;--auth-key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;YOUR_AUTH_KEY &lt;span class="nt"&gt;--ssh&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Replace &lt;code&gt;YOUR_AUTH_KEY&lt;/code&gt; with the key you generated.&lt;/p&gt;

&lt;p&gt;Congratulations! Your Linux is now configured for remote SSH access over a private IP. Both your Windows machine and the Linux instance should be connected to Tailscale to access resources or applications and to perform SSH.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.2.7   SSH Using Tailscale Browser-Based Access
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Access Tailscale Admin Portal&lt;/strong&gt;:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Go to the Tailscale Admin Portal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select the machine you want to SSH into and choose the option to SSH into the machine.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fzbpb7b57h6m7u00203r4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fzbpb7b57h6m7u00203r4.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Select User&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Choose the user you want to log in as.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fp44po6tmxg3uyh8w8j0p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fp44po6tmxg3uyh8w8j0p.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Confirm Identity&lt;/strong&gt;:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Confirm your identity by logging in to Tailscale.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You are now connected to WSL / Linux through your browser.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fi8nixtnzflh8zql5kgvz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fi8nixtnzflh8zql5kgvz.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2.2.8   Get Private IP :
&lt;/h3&gt;

&lt;p&gt;To obtain the private IP address of your machine, you can use the following command in the terminal:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;tailscale ip &lt;span class="nt"&gt;-4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Alternatively, you can also find the private IP address through the Tailscale admin portal. Be sure to note this IP, as we will need it for subsequent configuration steps.&lt;/p&gt;




&lt;h2&gt;
  
  
  2.3  Installing Docker :
&lt;/h2&gt;

&lt;p&gt;-- Steps For ubuntu 24 : &lt;/p&gt;

&lt;h3&gt;
  
  
  2.3.1   &lt;a href="https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository" rel="noopener noreferrer"&gt;Install using the &lt;code&gt;apt&lt;/code&gt; repository&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Before you install Docker Engine for the first time on a new host machine, you need to set up the Docker repository. Afterward, you can install and update Docker from the repository.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set up Docker's &lt;code&gt;apt&lt;/code&gt; repository.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Add Docker's official GPG key:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;ca-certificates curl
&lt;span class="nb"&gt;sudo install&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; 0755 &lt;span class="nt"&gt;-d&lt;/span&gt; /etc/apt/keyrings
&lt;span class="nb"&gt;sudo &lt;/span&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://download.docker.com/linux/ubuntu/gpg &lt;span class="nt"&gt;-o&lt;/span&gt; /etc/apt/keyrings/docker.asc
&lt;span class="nb"&gt;sudo chmod &lt;/span&gt;a+r /etc/apt/keyrings/docker.asc

&lt;span class="c"&gt;# Add the repository to Apt sources:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"deb [arch=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;dpkg &lt;span class="nt"&gt;--print-architecture&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
  &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; /etc/os-release &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VERSION_CODENAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; stable"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/docker.list &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;To install the latest version, run:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Verify that the Docker Engine installation is successful by running :&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;docker ps
&lt;span class="nb"&gt;sudo &lt;/span&gt;docker info
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;-- For Other Machines : &lt;br&gt;
Docker Installation Guide  for : &lt;/p&gt;

&lt;p&gt;Windows : &lt;a href="https://docs.docker.com/desktop/install/windows-install/" rel="noopener noreferrer"&gt;https://docs.docker.com/desktop/install/windows-install/&lt;/a&gt;&lt;br&gt;
Mac : &lt;a href="https://docs.docker.com/desktop/install/mac-install/" rel="noopener noreferrer"&gt;https://docs.docker.com/desktop/install/mac-install/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ubuntu : &lt;a href="https://docs.docker.com/engine/install/ubuntu/" rel="noopener noreferrer"&gt;https://docs.docker.com/engine/install/ubuntu/&lt;/a&gt;&lt;br&gt;
Debian :  &lt;a href="https://docs.docker.com/engine/install/debian/" rel="noopener noreferrer"&gt;https://docs.docker.com/engine/install/debian/&lt;/a&gt;&lt;br&gt;
RHEL : &lt;a href="https://docs.docker.com/engine/install/rhel/" rel="noopener noreferrer"&gt;https://docs.docker.com/engine/install/rhel/&lt;/a&gt;&lt;br&gt;
Fedora : &lt;a href="https://docs.docker.com/engine/install/fedora/" rel="noopener noreferrer"&gt;https://docs.docker.com/engine/install/fedora/&lt;/a&gt;&lt;br&gt;
Raspberry Pi : &lt;a href="https://docs.docker.com/engine/install/raspberry-pi-os/" rel="noopener noreferrer"&gt;https://docs.docker.com/engine/install/raspberry-pi-os/&lt;/a&gt;&lt;br&gt;
CentOS : &lt;a href="https://docs.docker.com/engine/install/centos/" rel="noopener noreferrer"&gt;https://docs.docker.com/engine/install/centos/&lt;/a&gt;&lt;br&gt;
SLES : &lt;a href="https://docs.docker.com/engine/install/centos/" rel="noopener noreferrer"&gt;https://docs.docker.com/engine/install/centos/&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2.4 Pointing DNS to the Server's Private IP Address :
&lt;/h2&gt;

&lt;p&gt;To configure your DNS to point to the private IP of your server, follow these steps. In this example, I have used  Cloudflare as the domain provider:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Log in to your domain provider's dashboard. &lt;/li&gt;
&lt;li&gt;Navigate to the &lt;strong&gt;Website&lt;/strong&gt; section and select &lt;strong&gt;your domain&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.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%2F8za0g8n62p30s3nu12bk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F8za0g8n62p30s3nu12bk.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now click &lt;strong&gt;DNS&lt;/strong&gt; --&amp;gt; &lt;strong&gt;Records&lt;/strong&gt; --&amp;gt; &lt;strong&gt;Add record&lt;/strong&gt; : &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fel75zquqbaean5si3pa5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fel75zquqbaean5si3pa5.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To set up access to your Nextcloud instance via a custom subdomain, you need to create an &lt;strong&gt;A record&lt;/strong&gt; with your domain provider. &lt;/p&gt;

&lt;p&gt;Choose a subdomain name, such as &lt;code&gt;nextcloud-server&lt;/code&gt;, so your Nextcloud instance will be accessible at &lt;code&gt;nextcloud-server.domain.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the DNS settings, point this subdomain to the Tailscale IP address you copied earlier in step 2.2.8  .&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F6afvk7ly19z6qo5p30k4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F6afvk7ly19z6qo5p30k4.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;keep this tab open we may need to add &lt;code&gt;TXT record&lt;/code&gt; for  Let's Encrypt SSL .&lt;/p&gt;




&lt;h1&gt;
  
  
  3 Nextcloud Deployment :
&lt;/h1&gt;

&lt;h2&gt;
  
  
  3.1 SSL request :
&lt;/h2&gt;

&lt;p&gt;In this section, we’ll walk through how to request a free SSL certificate from Let's Encrypt using Certbot. This SSL certificate will secure your domain, and the process is simple with Docker.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 1: Running Certbot to Generate an SSL Certificate
&lt;/h4&gt;

&lt;p&gt;To begin, open your terminal and run the following Docker command. This will start the Certbot client, which will guide you through the process of generating a free SSL certificate:&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;-it&lt;/span&gt; &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="se"&gt;\ &lt;/span&gt;&lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"/etc/letsencrypt:/etc/letsencrypt"&lt;/span&gt; &lt;span class="se"&gt;\ &lt;/span&gt;&lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"/var/lib/letsencrypt:/var/lib/letsencrypt"&lt;/span&gt; &lt;span class="se"&gt;\ &lt;/span&gt;certbot/certbot certonly &lt;span class="nt"&gt;--manual&lt;/span&gt; &lt;span class="nt"&gt;--preferred-challenges&lt;/span&gt; dns
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This command will initiate Certbot in interactive mode, prompting you for details like your domain name and email address.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 2: Input Required Information
&lt;/h4&gt;

&lt;p&gt;After running the command, Certbot will ask for several pieces of information. Follow the prompts as shown below:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address &lt;span class="o"&gt;(&lt;/span&gt;used &lt;span class="k"&gt;for &lt;/span&gt;urgent renewal and security notices&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;Enter &lt;span class="s1"&gt;'c'&lt;/span&gt; to cancel&lt;span class="o"&gt;)&lt;/span&gt;: email@example.com

Please &lt;span class="nb"&gt;read &lt;/span&gt;the Terms of Service at:
https://letsencrypt.org/documents/LE-SA-v1.4-April-3-2024.pdf. You must agree to &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;Y&lt;span class="o"&gt;)&lt;/span&gt;es/&lt;span class="o"&gt;(&lt;/span&gt;N&lt;span class="o"&gt;)&lt;/span&gt;o: Y

Would you like to receive email updates from Let&lt;span class="s1"&gt;'s Encrypt and the EFF?
(Y)es/(N)o: Y

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Next, you will be prompted to enter the domain name for which you want the SSL certificate:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Please enter the domain name&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)&lt;/span&gt; you would like on your certificate &lt;span class="o"&gt;(&lt;/span&gt;comma and/or space separated&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;Enter &lt;span class="s1"&gt;'c'&lt;/span&gt; to cancel&lt;span class="o"&gt;)&lt;/span&gt;:

nextcloud-server.domain.com


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  Step 3: Deploying DNS TXT Record
&lt;/h4&gt;

&lt;p&gt;Certbot will now ask you to deploy a DNS TXT record for domain validation. You need to add a specific TXT record to your domain's DNS configuration:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
Please deploy a DNS TXT record under the name:
_acme-challenge.nextcloud-server.domain.com.

With the following value:
D1eW0MaeV4L61WsvJJHniuUBAuj3aoggwF2-mXad21KaF-x


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Go to your domain provider's DNS management interface and add a new TXT record:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Type&lt;/strong&gt;: TXT&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Name&lt;/strong&gt;: _acme-challenge.nextcloud-server.domain.com&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Value&lt;/strong&gt;: D1eW0MaeV4L61WsvJJHniuUBAuj3aoggwF2-mXad21KaF-x&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2F4iz62wksmpki7kean42g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F4iz62wksmpki7kean42g.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 4: Verifying the DNS Record
&lt;/h4&gt;

&lt;p&gt;Before continuing, ensure the DNS record has been successfully deployed. You can verify this using online tools like the &lt;a href="https://toolbox.googleapps.com/apps/dig/#TXT/" rel="noopener noreferrer"&gt;Google Admin Toolbox&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once the record is visible, return to your terminal and press &lt;code&gt;Enter&lt;/code&gt; to proceed.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 5: SSL Certificate Issuance
&lt;/h4&gt;

&lt;p&gt;Once the DNS record is verified, Certbot will complete the certificate generation. You will see a message like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/nextcloud-server.domain.com/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/nextcloud-server.domain.com/privkey.pem
This certificate expires on 2024-12-15.


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Important Notes:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;This certificate is valid for 90 days, and you will need to renew it before it expires.&lt;/li&gt;
&lt;li&gt;For manual DNS-based certificates, renewal requires repeating this process unless you configure automated renewal using Certbot hooks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;( I will cover SSL Autorenewal in next article. )&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We have successfully obtained an SSL certificate for your domain. Now, your connection will be secured with HTTPS!&lt;/p&gt;


&lt;h2&gt;
  
  
  3.2 Utilizing a .env File to Manage Configuration Variables
&lt;/h2&gt;

&lt;p&gt;When deploying applications using Docker, it’s important to manage the configuration effectively. One of the best practices is to use a &lt;code&gt;.env&lt;/code&gt; file to store environment variables instead of hardcoding values directly in your &lt;code&gt;docker-compose.yml&lt;/code&gt; file. This approach not only keeps your configuration organized but also simplifies the process of making changes in the future.&lt;/p&gt;

&lt;p&gt;To create a &lt;code&gt;.env&lt;/code&gt; file, open your terminal and use the following command:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the &lt;code&gt;.env&lt;/code&gt; file, you can define your environment variables like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NEXTCLOUD_ADMIN_USER=email@example.com
NEXTCLOUD_ADMIN_PASSWORD=YOUR_SECURE_PASSWORD
NEXTCLOUD_PORT=80
NEXTCLOUD_PORT_HTTPS=443
PRIVATE_IP=YOUR_TAILSCALE_IP_HERE
REDIS_HOST=redis
REDIS_HOST_PORT=6379
REDIS_HOST_PASSWORD=YOUR_SECURE_PASSWORD
MYSQL_HOST=db
MYSQL_DATABASE=nextcloud
MYSQL_USER=nextclouddb
MYSQL_PASSWORD=YOUR_SECURE_PASSWORD
MYSQL_ROOT_PASSWORD=YOUR_SECURE_ROOT_PASSWORD
MYSQL_HOST_PORT=3379
NEXTCLOUD_SSL_KEY_PATH=/etc/letsencrypt/live/nextcloud-server.domain.com/privkey.pem
NEXTCLOUD_SSL_CERT_PATH=/etc/letsencrypt/live/nextcloud-server.domain.com/fullchain.pem
NEXTCLOUD_APACHE_CONFIG_PATH=./000-default.conf
NEXTCLOUD_APACHE_LIMIT_PATH=./apache-limits.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h3&gt;
  
  
  3.3 Nextcloud Configuration in config.php
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;[!NOTE]&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;!! SKIP this step if you are deploying  nextcloud first time.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;

&lt;p&gt;Next, you'll need to configure Nextcloud itself. The configuration settings for Nextcloud are typically stored in the &lt;code&gt;/var/www/html/config/config.php&lt;/code&gt;  file in nextcloud docker container. Below is a sample configuration that you can adapt to your setup:&lt;/p&gt;

&lt;p&gt;To create a &lt;code&gt;config.php&lt;/code&gt; file, open your terminal and use the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano config.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the &lt;code&gt;config.php&lt;/code&gt; file, you can add configurations like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="nv"&gt;$CONFIG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="s1"&gt;'htaccess.RewriteBase'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'memcache.local'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'\\OC\\Memcache\\APCu'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'apps_paths'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
  &lt;span class="k"&gt;array&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
    &lt;span class="k"&gt;array&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="s1"&gt;'path'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'/var/www/html/apps'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s1"&gt;'url'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'/apps'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s1"&gt;'writable'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
    &lt;span class="k"&gt;array&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="s1"&gt;'path'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'/var/www/html/custom_apps'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s1"&gt;'url'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'/custom_apps'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s1"&gt;'writable'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="s1"&gt;'memcache.distributed'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'\\OC\\Memcache\\Redis'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'memcache.locking'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'\\OC\\Memcache\\Redis'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'redis'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
  &lt;span class="k"&gt;array&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s1"&gt;'host'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'redis'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'password'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'port'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;6379&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="s1"&gt;'upgrade.disable-web'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'passwordsalt'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'NSOLqCOL3s+8JyIaFtz6Xw0guUC7Vf'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'secret'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'nLg9bkVKY4HV4fOkop6vmJ5/DyqdOUo21545JQTpmzWQSGe3'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'trusted_domains'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
  &lt;span class="k"&gt;array&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'nextcloud-server.domain.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="s1"&gt;'datadirectory'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'/var/www/html/data'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'dbtype'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'mysql'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'version'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'29.0.6.1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'overwrite.cli.url'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'http://localhost'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'dbname'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'nextcloud'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'dbhost'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'db'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'dbport'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'dbtableprefix'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'oc_'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'mysql.utf8mb4'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'dbuser'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'nextclouddb'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'dbpassword'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'YOUR_SECURE_PASSWORD'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'installed'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'instanceid'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'ocuijn9xg681'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Mounting an Existing config.php File
&lt;/h3&gt;

&lt;p&gt;If you already have a &lt;code&gt;config.php&lt;/code&gt; file and want to mount it to your Nextcloud Docker container, make sure to uncomment the following line in your &lt;code&gt;docker-compose.yml&lt;/code&gt; file:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 3 - ./config.php:/var/www/html/config/config.php&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;By doing so, you can easily manage your Nextcloud configuration without modifying the Docker image itself.&lt;/p&gt;




&lt;h2&gt;
  
  
  3.4 Creating the Apache Configuration File
&lt;/h2&gt;

&lt;p&gt;To set up your Apache web server, you’ll need to create a configuration file. Start by opening your terminal and running the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano 000-default.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In this &lt;code&gt;apache.conf&lt;/code&gt; file, you will define your server settings. Below is a sample configuration for a Nextcloud server, which includes both HTTP and HTTPS settings:&lt;/p&gt;

&lt;h3&gt;
  
  
  Sample Apache2 Configuration File
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apache"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nl"&gt;VirtualHost&lt;/span&gt;&lt;span class="sr"&gt; *:80&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="nc"&gt;ServerName&lt;/span&gt; nextcloud-server.domain.com
    &lt;span class="nc"&gt;Redirect&lt;/span&gt; &lt;span class="ss"&gt;permanent&lt;/span&gt; / https://nextcloud-server.domain.com/
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nl"&gt;VirtualHost&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nl"&gt;VirtualHost&lt;/span&gt;&lt;span class="sr"&gt; *:443&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="nc"&gt;ServerName&lt;/span&gt; nextcloud-server.domain.com

    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nl"&gt;IfModule&lt;/span&gt;&lt;span class="sr"&gt; mod_headers.c&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="nc"&gt;Header&lt;/span&gt; &lt;span class="ss"&gt;always&lt;/span&gt; &lt;span class="ss"&gt;set&lt;/span&gt; Strict-Transport-Security "max-age=15552000; includeSubDomains"
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nl"&gt;IfModule&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;
&lt;/span&gt;
    &lt;span class="nc"&gt;ServerAdmin&lt;/span&gt; webmaster@localhost
    &lt;span class="nc"&gt;DocumentRoot&lt;/span&gt; /var/www/html

    &lt;span class="c"&gt;# Enable SSL&lt;/span&gt;
    &lt;span class="nc"&gt;SSLEngine&lt;/span&gt; &lt;span class="ss"&gt;on&lt;/span&gt;
    &lt;span class="nc"&gt;SSLProtocol&lt;/span&gt; TLSv1.2 TLSv1.3

    &lt;span class="c"&gt;# Specify the certificate files&lt;/span&gt;
    &lt;span class="nc"&gt;SSLCertificateFile&lt;/span&gt; /etc/ssl/certs/fullchain.pem
    &lt;span class="nc"&gt;SSLCertificateKeyFile&lt;/span&gt; /etc/ssl/private/privkey.pem

    &lt;span class="nc"&gt;ErrorLog&lt;/span&gt; ${APACHE_LOG_DIR}/error.log
    &lt;span class="nc"&gt;CustomLog&lt;/span&gt; ${APACHE_LOG_DIR}/access.log combined
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nl"&gt;VirtualHost&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h2&gt;
  
  
  3.5 Setting Request Limits in Apache
&lt;/h2&gt;

&lt;p&gt;To enhance the performance and security of your Apache server, you can set limits on the size of the request body. This helps prevent abuse by limiting the maximum size of uploaded files. To do this, create or modify the &lt;code&gt;apache-limits.conf&lt;/code&gt; file. Open your terminal and enter the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano apache-limits.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the &lt;code&gt;apache-limits.conf&lt;/code&gt; file, add the following line:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apache"&gt;&lt;code&gt;&lt;span class="nc"&gt;LimitRequestBody&lt;/span&gt; 104857600
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This configuration sets the maximum allowed size of the request body to &lt;strong&gt;100 MB&lt;/strong&gt; (104,857,600 bytes). &lt;/p&gt;




&lt;h2&gt;
  
  
  3.6 Script to Enable SSL and Headers Module in Nextcloud Container :
&lt;/h2&gt;

&lt;p&gt;The official Nextcloud Docker image (&lt;code&gt;nextcloud:apache-stable&lt;/code&gt;) does not come with SSL enabled by default. To enable SSL support and necessary headers in your Nextcloud container, you can use the following script. This script ensures that the SSL module and headers are properly configured.&lt;/p&gt;

&lt;p&gt;Create a new script file, for example &lt;code&gt;enable_ssl.sh&lt;/code&gt;, and add the following content:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# 4 Enable SSL module and configure Apache SSL&lt;/span&gt;
docker &lt;span class="nb"&gt;exec &lt;/span&gt;ncapp-nextcloud-server /bin/bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"a2enmod ssl"&lt;/span&gt;
docker &lt;span class="nb"&gt;exec &lt;/span&gt;ncapp-nextcloud-server /bin/bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"a2ensite 000-default"&lt;/span&gt;
docker &lt;span class="nb"&gt;exec &lt;/span&gt;ncapp-nextcloud-server /bin/bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"a2enmod headers"&lt;/span&gt;

&lt;span class="c"&gt;# 5 Restart Apache to apply changes&lt;/span&gt;
docker &lt;span class="nb"&gt;exec &lt;/span&gt;ncapp-nextcloud-server /bin/bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"service apache2 reload"&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Make sure to give the script execution permissions before running it:&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;chmod&lt;/span&gt; +x enable_ssl.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h1&gt;
  
  
  4 Docker Compose :
&lt;/h1&gt;

&lt;p&gt;At this stage, we have gathered the essential files required for our setup, including the SSL certificates, &lt;code&gt;config.php&lt;/code&gt;, &lt;code&gt;000-default.conf&lt;/code&gt;, &lt;code&gt;apache-limits.conf&lt;/code&gt;, and the necessary &lt;code&gt;script&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Now, let's move forward by creating a Docker Compose file. This file will serve as the backbone of our deployment, orchestrating the various services and configurations we've prepared.&lt;/p&gt;

&lt;p&gt;To create our Docker Compose file, open a terminal and enter the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano docker-compose.yml

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This command will open the Nano text editor, where we can define our services and configurations. Below is a sample configuration to get you started:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;#   Docker compose file for Nextcloud setup with Redis and Mariadb&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;nc&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nextcloud:stable-apache&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ncapp-nextcloud-server&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;${PRIVATE_IP}:${NEXTCLOUD_PORT}:80&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;${PRIVATE_IP}:${NEXTCLOUD_PORT_HTTPS}:443&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;${NEXTCLOUD_SSL_KEY_PATH}:/etc/ssl/private/privkey.pem&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;${NEXTCLOUD_SSL_CERT_PATH}:/etc/ssl/certs/fullchain.pem&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;${NEXTCLOUD_APACHE_CONFIG_PATH}:/etc/apache2/sites-enabled/000-default.conf&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;${NEXTCLOUD_APACHE_LIMIT_PATH}:/etc/apache2/conf-enabled/apache-limits.conf&lt;/span&gt;
      &lt;span class="c1"&gt;# - ./config.php:/var/www/html/config/config.php&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;nc_data:/var/www/html&lt;/span&gt;      
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;nc_apache2:/etc/apache2/&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;redis&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;db&lt;/span&gt;
    &lt;span class="na"&gt;links&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;db&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;redis&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;redisnet&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;dbnet&lt;/span&gt;
    &lt;span class="na"&gt;healthcheck&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;CMD-SHELL&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;curl -f http&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;//localhost&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1m&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;10s&lt;/span&gt;
      &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
    &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;cpus&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2'&lt;/span&gt;
          &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2048M&lt;/span&gt;      
    &lt;span class="c1"&gt;# labels:&lt;/span&gt;
    &lt;span class="c1"&gt;#   maintainer: "Your Name &amp;lt;your@email.com&amp;gt;"&lt;/span&gt;
    &lt;span class="c1"&gt;#   org.label-schema.version: "latest"&lt;/span&gt;
    &lt;span class="c1"&gt;#   org.label-schema.name: "Nextcloud-NC-APP"&lt;/span&gt;
    &lt;span class="c1"&gt;#   org.label-schema.description: "Self-hosted file sharing and collaboration platform"&lt;/span&gt;
    &lt;span class="c1"&gt;#   org.label-schema.url: "https://nextcloud.com"&lt;/span&gt;
    &lt;span class="c1"&gt;#   org.label-schema.documentation: "https://docs.nextcloud.com"&lt;/span&gt;
    &lt;span class="c1"&gt;#   org.label-schema.source: "https://github.com/nextcloud/docker"&lt;/span&gt;
    &lt;span class="c1"&gt;#   org.label-schema.issues: "https://github.com/nextcloud/docker/issues"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER}&lt;/span&gt;  
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD}&lt;/span&gt;    
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;REDIS_HOST=${REDIS_HOST}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;REDIS_HOST_PORT=${REDIS_HOST_PORT}&lt;/span&gt;
      &lt;span class="c1"&gt;# - REDIS_HOST_PASSWORD=${REDIS_HOST_PASSWORD}  # Cant login to nexcloud if enabled&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MYSQL_HOST=${MYSQL_HOST}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MYSQL_DATABASE=${MYSQL_DATABASE}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MYSQL_USER=${MYSQL_USER}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MYSQL_PASSWORD=${MYSQL_PASSWORD}&lt;/span&gt;


  &lt;span class="na"&gt;redis&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;redis@sha256:6a5130174e14177c3777ea34f4989a91bb5a7d7562dd48578cbfa3ad8cd53743&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ncapp-redis-server&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;redisnet&lt;/span&gt;
    &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;cpus&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1'&lt;/span&gt;
          &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1024M&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
       &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;rd_data:/data&lt;/span&gt;
    &lt;span class="na"&gt;healthcheck&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;CMD-SHELL&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;redis-cli PING&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1m&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;10s&lt;/span&gt;
      &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;3&lt;/span&gt;  
    &lt;span class="c1"&gt;# labels:&lt;/span&gt;
    &lt;span class="c1"&gt;#   maintainer: "Your Name &amp;lt;your@email.com&amp;gt;"&lt;/span&gt;
    &lt;span class="c1"&gt;#   org.label-schema.version: "latest"&lt;/span&gt;
    &lt;span class="c1"&gt;#   org.label-schema.name: "Nextcloud-REDIS"&lt;/span&gt;
    &lt;span class="c1"&gt;#   org.label-schema.description: "Self-hosted file sharing and collaboration platform"&lt;/span&gt;
    &lt;span class="c1"&gt;#   org.label-schema.url: "https://nextcloud.com"&lt;/span&gt;
    &lt;span class="c1"&gt;#   org.label-schema.documentation: "https://docs.nextcloud.com"&lt;/span&gt;
    &lt;span class="c1"&gt;#   org.label-schema.source: "https://github.com/nextcloud/docker"&lt;/span&gt;
    &lt;span class="c1"&gt;#   org.label-schema.issues: "https://github.com/nextcloud/docker/issues"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;REDIS_HOST=${REDIS_HOST}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;REDIS_HOST_PORT=${REDIS_HOST_PORT}&lt;/span&gt;
      &lt;span class="c1"&gt;# - REDIS_PASSWORD=${REDIS_HOST_PASSWORD}&lt;/span&gt;
    &lt;span class="na"&gt;expose&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;${REDIS_HOST_PORT}&lt;/span&gt;

  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mariadb:10.5&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;--transaction-isolation=READ-COMMITTED --binlog-format=ROW&lt;/span&gt;
    &lt;span class="c1"&gt;# if getting this error : 4047 InnoDB refuses to write tables with ROW_FORMAT=COMPRESSED or KEY_BLOCK_SIZE.&lt;/span&gt;
    &lt;span class="c1"&gt;# More details here : https://techoverflow.net/2021/08/17/how-to-fix-nextcloud-4047-innodb-refuses-to-write-tables-with-row_formatcompressed-or-key_block_size/&lt;/span&gt;
    &lt;span class="c1"&gt;# Comment the above command and use the below :&lt;/span&gt;
    &lt;span class="c1"&gt;# command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW --innodb-file-per-table=1 --skip-innodb-read-only-compressed&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ncapp-db-server&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;db_data:/var/lib/mysql&lt;/span&gt;
    &lt;span class="na"&gt;healthcheck&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;CMD-SHELL&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;mysqladmin ping -h localhost&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1m&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;10s&lt;/span&gt;
      &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;dbnet&lt;/span&gt;
    &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;cpus&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2'&lt;/span&gt;
          &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;4096M&lt;/span&gt;

    &lt;span class="c1"&gt;# labels:&lt;/span&gt;
    &lt;span class="c1"&gt;#   maintainer: "Your Name &amp;lt;your@email.com&amp;gt;"&lt;/span&gt;
    &lt;span class="c1"&gt;#   org.label-schema.version: "latest"&lt;/span&gt;
    &lt;span class="c1"&gt;#   org.label-schema.name: "Nextcloud-MARIADB"&lt;/span&gt;
    &lt;span class="c1"&gt;#   org.label-schema.description: "Self-hosted file sharing and collaboration platform"&lt;/span&gt;
    &lt;span class="c1"&gt;#   org.label-schema.url: "https://nextcloud.com"&lt;/span&gt;
    &lt;span class="c1"&gt;#   org.label-schema.documentation: "https://docs.nextcloud.com"&lt;/span&gt;
    &lt;span class="c1"&gt;#   org.label-schema.source: "https://github.com/nextcloud/docker"&lt;/span&gt;
    &lt;span class="c1"&gt;#   org.label-schema.issues: "https://github.com/nextcloud/docker/issues"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MYSQL_DATABASE=${MYSQL_DATABASE}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MYSQL_USER=${MYSQL_USER}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MYSQL_PASSWORD=${MYSQL_PASSWORD}&lt;/span&gt;
    &lt;span class="na"&gt;expose&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;${MYSQL_HOST_PORT}&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;db_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;nc_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;rd_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;nc_apache2&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;dbnet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bridge&lt;/span&gt;
  &lt;span class="na"&gt;redisnet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bridge&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;p&gt;Once you have saved your &lt;code&gt;docker-compose.yml&lt;/code&gt; file, you can start your services in detached mode using the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This command will pull the necessary images (if not already available) and start the containers in the background, allowing you to continue using your terminal for other tasks.&lt;/p&gt;

&lt;p&gt;After running above command , wait for about 5 to 10 seconds to ensure that all services are properly initialized. Once the waiting period is over, you can enable SSH by running the script:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./enable-ssh.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This script will configure SSH access, allowing you to manage your services remotely and securely.&lt;/p&gt;

&lt;p&gt;If you are getting output similar to this , then please wait for 5 more seconds and rerun the script :&lt;br&gt;
ERROR :&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Considering dependency setenvif &lt;span class="k"&gt;for &lt;/span&gt;ssl:
Module setenvif already enabled
Considering dependency mime &lt;span class="k"&gt;for &lt;/span&gt;ssl:
Module mime already enabled
Considering dependency socache_shmcb &lt;span class="k"&gt;for &lt;/span&gt;ssl:
Enabling module socache_shmcb.
Enabling module ssl.
See /usr/share/doc/apache2/README.Debian.gz on how to configure SSL and create self-signed certificates.
To activate the new configuration, you need to run:
  service apache2 restart
Site 000-default already enabled
Module headers already enabled
Reloading Apache httpd web server: apache2 failed!
Apache2 is not running ... &lt;span class="o"&gt;(&lt;/span&gt;warning&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;EXPECTED OUTPUT :&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;./enable-ssl.sh
Considering dependency setenvif &lt;span class="k"&gt;for &lt;/span&gt;ssl:
Module setenvif already enabled
Considering dependency mime &lt;span class="k"&gt;for &lt;/span&gt;ssl:
Module mime already enabled
Considering dependency socache_shmcb &lt;span class="k"&gt;for &lt;/span&gt;ssl:
Module socache_shmcb already enabled
Module ssl already enabled
Site 000-default already enabled
Module headers already enabled
Reloading Apache httpd web server: apache2.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h2&gt;
  
  
  5 Accessing Nextcloud on a Private IP
&lt;/h2&gt;

&lt;p&gt;To successfully access your Nextcloud instance running on a private IP, ensure that Tailscale is active on both the server hosting Nextcloud and the machine you are using for access.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Open Your Browser&lt;/strong&gt;: Navigate to the private IP address of your Nextcloud server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Login Credentials&lt;/strong&gt;: Enter your administrator username and password. Upon logging in, you may encounter the following error:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   ## Access through untrusted domain

   Please contact your administrator. If you are an administrator, edit the "trusted_domains" setting in config/config.php like the example in config.sample.php.

   Further information on how to configure this can be found in the [documentation](https://docs.nextcloud.com/server/29/go.php?to=admin-trusted-domains).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.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%2F2abrnw5t9mg5sg3wyiev.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F2abrnw5t9mg5sg3wyiev.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Resolving the Untrusted Domain Error
&lt;/h3&gt;

&lt;p&gt;To resolve the untrusted domain issue, you need to update the trusted domains in your Nextcloud configuration:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Access the Docker Container&lt;/strong&gt;: Execute the following command to enter your Nextcloud Docker container:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; ncapp-nextcloud-server /bin/bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install a Text Editor&lt;/strong&gt;: If not already installed, you can install &lt;code&gt;nano&lt;/code&gt; by running:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt &lt;span class="nb"&gt;install &lt;/span&gt;nano
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Edit the Configuration File&lt;/strong&gt;: Open the configuration file using:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   nano /var/www/html/config/config.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Locate the Trusted Domains Section&lt;/strong&gt;: Use &lt;code&gt;Ctrl + W&lt;/code&gt; to initiate a search and type &lt;code&gt;trusted_domains&lt;/code&gt;, then hit Enter.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fa6q0izyn4baor015kn3i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fa6q0izyn4baor015kn3i.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Modify the Trusted Domains&lt;/strong&gt;: You can either edit the existing &lt;code&gt;localhost&lt;/code&gt; entry or add your domain. Your configuration block should look like this:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;   &lt;span class="k"&gt;array&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'localhost'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'nextcloud-server.domain.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Save and Exit&lt;/strong&gt;: Save your changes in &lt;code&gt;nano&lt;/code&gt; by pressing &lt;code&gt;Ctrl + X&lt;/code&gt;, then confirm with &lt;code&gt;Y&lt;/code&gt; and press Enter.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, you should be able to access your Nextcloud instance at &lt;code&gt;https://nextcloud-server.domain.com&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Congratulations! You've successfully configured your Nextcloud server to recognize your domain.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fxm73ozi5w7b8peezrify.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fxm73ozi5w7b8peezrify.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;As we come to the end of this guide, we hope you've gained valuable insights and practical steps to take control of your data by self-hosting NextCloud with MariaDB, Redis, and secure access via Tailscale VPN. By following these steps, you've not only set up a powerful collaboration platform but also enhanced your data security and privacy. &lt;/p&gt;

&lt;p&gt;Remember, self-hosting isn't just about functionality—it's about owning your infrastructure and safeguarding sensitive information. Whether you're managing it for personal use or for a team, always prioritize regular backups, updates, and monitoring to maintain the integrity of your setup.&lt;/p&gt;

&lt;p&gt;If you found this guide helpful and have any questions or feedback, feel free to reach out. For more insights on technology and to stay updated with my latest content, connect with me on &lt;a href="https://linkedin.com/in/r-quazi" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; and you can support open source community by buying a coffee &lt;a href="https://buymeacoffee.com/rquazi" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Email  *&lt;/em&gt;: &lt;a href="//mailto:hi@plexio.cloud"&gt;hi@plexio.cloud&lt;/a&gt;&lt;br&gt;
*&lt;em&gt;Linkedin *&lt;/em&gt;:   &lt;a href="https://linkedin.com/in/r-quazi" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you for following along, and best of luck with your self-hosting journey!&lt;/p&gt;

</description>
      <category>selfhosted</category>
      <category>nextcloud</category>
      <category>docker</category>
      <category>database</category>
    </item>
    <item>
      <title>Install Ubuntu 24.04 or Any Linux Flavor on Windows 11 and Access It via SSH Using Tailscale Private IP</title>
      <dc:creator>R. Quazi</dc:creator>
      <pubDate>Sun, 15 Sep 2024 08:06:58 +0000</pubDate>
      <link>https://dev.to/r-quazi/install-ubuntu-2404-or-any-linux-flavor-on-windows-11-and-access-it-via-ssh-using-tailscale-private-ip-2788</link>
      <guid>https://dev.to/r-quazi/install-ubuntu-2404-or-any-linux-flavor-on-windows-11-and-access-it-via-ssh-using-tailscale-private-ip-2788</guid>
      <description>&lt;h1&gt;
  
  
  1  Introduction
&lt;/h1&gt;

&lt;p&gt;In today's tech-driven world, many professionals and hobbyists need to work across both Windows and Linux environments. Whether you're a developer or a small business owner relying on Windows for daily tasks but needing Linux-based applications, the challenge is to efficiently run Linux applications without disrupting your primary Windows setup.&lt;/p&gt;

&lt;p&gt;Linux environments are often preferred for running applications like Nginx, Apache, Jenkins, Docker, Kubernetes, and MongoDB, as many software tools are optimized for Linux. However, since most computers come with Windows pre-installed, finding an efficient way to run Linux applications is important.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fvo4nfqlkwnzfven211xc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fvo4nfqlkwnzfven211xc.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image Credit : Ubuntu&lt;/em&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  1.1  Common Methods to Run Linux on Windows:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dual Boot&lt;/strong&gt;: Windows + Linux. This method requires rebooting to switch between operating systems, which can be inconvenient and consumes more resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cloud VM/VPS&lt;/strong&gt;: Effective but potentially costly. Even when not in active use, you might incur charges for storage and uptime/IP etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.virtualbox.org/" rel="noopener noreferrer"&gt;VirtualBox&lt;/a&gt;&lt;/strong&gt;: Provides a portable solution without altering the host system directly. But, it requires allocating CPU cores  RAM and storage, which can impact system performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://linuxcontainers.org/lxc/" rel="noopener noreferrer"&gt;LXC&lt;/a&gt;/&lt;a href="https://documentation.ubuntu.com/lxd/en/latest/" rel="noopener noreferrer"&gt;LXD&lt;/a&gt; Containers&lt;/strong&gt;: Containers share the host’s kernel but have their own filesystem, processes, and network stack. They may not always integrate seamlessly with host applications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; Containers&lt;/strong&gt;: Similar to LXC containers, Docker containers share the host’s kernel and might be restrictive in GUI support and file system access.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each of these methods has its trade-offs. Dual booting requires frequent reboots, virtual machines can consume significant resources, and containers may be limiting in terms of file access and GUI support. &lt;/p&gt;

&lt;p&gt;To find a balance between efficiency, convenience, and functionality, you need a solution that bridges the gap between Windows and Linux environments. &lt;/p&gt;




&lt;h1&gt;
  
  
  2 WSL (Windows Subsystem for Linux)
&lt;/h1&gt;

&lt;p&gt;WSL is a compatibility layer that allows you to run a Linux distribution directly on Windows. It provides a Linux-like environment within Windows, making it ideal for developers who need Linux tools and utilities. WSL supports various development, scripting, and testing tasks and can even run DevOps tools like Kubernetes , docker and jenkins etc.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"To master technology, we must learn to integrate it, not just use it in isolation."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  2.1  WSL Advantages
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Direct Integration&lt;/strong&gt;: Seamlessly interacts with the Windows filesystem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Software Compatibility&lt;/strong&gt;: Works well with Windows software (e.g., Docker Desktop , VS code).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full Linux Kernel&lt;/strong&gt;: Utilizes a complete Linux kernel in WSL 2.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interoperability&lt;/strong&gt;: Facilitates interaction between Windows and Linux applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Convenience&lt;/strong&gt;: Easier setup and use compared to dual boot or traditional VMs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developer-Friendly&lt;/strong&gt;: Streamlined for development tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easier Maintenance&lt;/strong&gt;: Simpler to manage than dual boot systems or VMs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2.2  WSL Limitations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt;: Not as performant as a native Linux installation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GUI Support&lt;/strong&gt;: Limited support for graphical applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kernel Limitations&lt;/strong&gt;: Not suitable for all use cases, especially those requiring specific kernel modules or low-level hardware access.&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  3 Installation
&lt;/h1&gt;

&lt;h2&gt;
  
  
  3.1  System Requirements
&lt;/h2&gt;

&lt;p&gt;Before installing WSL, ensure your system meets the following requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Enable Virtualization&lt;/strong&gt; in your BIOS settings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Windows 10&lt;/strong&gt; version 2004 or higher (Build 19041 or higher)

&lt;ul&gt;
&lt;li&gt;For &lt;strong&gt;x64 systems&lt;/strong&gt;: Version 1903 or later, Build 18362.1049 or later.&lt;/li&gt;
&lt;li&gt;For &lt;strong&gt;ARM64 systems&lt;/strong&gt;: Version 2004 or later, Build 19041 or later.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Windows 11&lt;/strong&gt; is fully compatible.&lt;/li&gt;

&lt;li&gt;Minimum &lt;strong&gt;4 GB RAM&lt;/strong&gt;.&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  3.2  Opening PowerShell as Administrator
&lt;/h2&gt;

&lt;p&gt;To install WSL, you need to open PowerShell with administrative privileges. Follow one of these methods:&lt;/p&gt;

&lt;h3&gt;
  
  
  3.2.1    Option 1: Using the Start Menu
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Press the &lt;strong&gt;Windows&lt;/strong&gt; key or click the &lt;strong&gt;Start menu&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Type &lt;strong&gt;PowerShell&lt;/strong&gt; in the search bar.&lt;/li&gt;
&lt;li&gt;Right-click &lt;strong&gt;Windows PowerShell&lt;/strong&gt; from the search results.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Run as administrator&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fn6c8071tuaw6c22iy50c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fn6c8071tuaw6c22iy50c.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3.2.2   Option 2: Using the Run Dialog
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Press &lt;strong&gt;Windows Key + R&lt;/strong&gt; to open the &lt;strong&gt;Run&lt;/strong&gt; dialog.&lt;/li&gt;
&lt;li&gt;Type &lt;strong&gt;powershell&lt;/strong&gt; in the text box.&lt;/li&gt;
&lt;li&gt;Press &lt;strong&gt;Ctrl + Shift + Enter&lt;/strong&gt; to run PowerShell as an administrator. Avoid pressing Enter alone, as this will open PowerShell in normal user mode.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fm7iqrm4en2ljbxckc0f9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fm7iqrm4en2ljbxckc0f9.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3.3  Enabling WSL and Installing a Linux Distribution
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.3.1   Enable the Required Features
&lt;/h3&gt;

&lt;p&gt;First, enable the "Windows Subsystem for Linux" feature and the &lt;strong&gt;Virtual Machine Platform&lt;/strong&gt; feature:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enable "Windows Subsystem for Linux"&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;dism.exe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/online&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/enable-feature&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/featurename:Microsoft-Windows-Subsystem-Linux&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/all&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/norestart&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Output:&lt;/p&gt;

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

Deployment Image Servicing and Management tool
Version: 10.0.22621.2792

Image Version: 10.0.22631.3880

Enabling feature(s)
[==========================100.0%==========================]
The operation completed successfully.


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Enable "Virtual Machine Platform"&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;dism.exe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/online&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/enable-feature&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/featurename:VirtualMachinePlatform&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/all&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/norestart&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Output:&lt;/p&gt;

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

Deployment Image Servicing and Management tool
Version: 10.0.22621.2792

Image Version: 10.0.22631.3880

Enabling feature(s)
[==========================100.0%==========================]
The operation completed successfully.


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After running these commands, restart your computer to apply the changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.3.2    Install the Linux Kernel Update Package
&lt;/h3&gt;

&lt;p&gt;To download and install the latest Linux kernel update package:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For x64: 
```PowerShell
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;wsl.exe --install&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
- For ARM 64 :
Download the package : https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_arm64.msi

Double click to install the WSL.

&amp;gt; [!NOTE]
&amp;gt; &amp;gt; If you dont know the type of system you are using you can run this command : ``systeminfo | find "System Type"``
&amp;gt; &amp;gt; Output : `System Type:               x64-based PC`
&amp;gt; 
&amp;gt; 


Output:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...&lt;br&gt;
...&lt;br&gt;
...&lt;br&gt;
Launching Ubuntu...&lt;br&gt;
Installing, this may take a few minutes...&lt;br&gt;
Please create a default UNIX user account. The username does not need to match your Windows username.&lt;br&gt;
For more information visit: &lt;a href="https://aka.ms/wslusers" rel="noopener noreferrer"&gt;https://aka.ms/wslusers&lt;/a&gt;&lt;br&gt;
Enter new UNIX username:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
### 3.3.3    Set WSL Version 2 as the Default

Ensure that WSL version 2 is set as the default version:
```PowerShell


wsl --set-default-version 2


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Output:&lt;/p&gt;

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

For information on key differences with WSL 2 please visit https://aka.ms/wsl2
The operation completed successfully.


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  3.3.4    Install Your Preferred Linux Distribution
&lt;/h3&gt;

&lt;p&gt;Install your favorite Linux distribution. For example, to install Ubuntu 24.04:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;wsl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Ubuntu-24.04&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Or you can install any distro of your choice : &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Linux Distribution&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;WSL Installation Command&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ubuntu 18.04 LTS&lt;/td&gt;
&lt;td&gt;&lt;code&gt;wsl --install -d Ubuntu-18.04&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ubuntu 20.04 LTS&lt;/td&gt;
&lt;td&gt;&lt;code&gt;wsl --install -d Ubuntu-20.04&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ubuntu 22.04 LTS&lt;/td&gt;
&lt;td&gt;&lt;code&gt;wsl --install -d Ubuntu-22.04&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;openSUSE Leap 15.1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;wsl --install -d openSUSE-Leap-15.1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SUSE Linux Enterprise Server 12 SP5&lt;/td&gt;
&lt;td&gt;&lt;code&gt;wsl --install -d SLES-12-SP5&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SUSE Linux Enterprise Server 15 SP1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;wsl --install -d SLES-15-SP1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kali Linux&lt;/td&gt;
&lt;td&gt;&lt;code&gt;wsl --install -d Kali-Linux&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Debian GNU/Linux&lt;/td&gt;
&lt;td&gt;&lt;code&gt;wsl --install -d Debian&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fedora Remix for WSL&lt;/td&gt;
&lt;td&gt;&lt;code&gt;wsl --install -d Fedora-Remix-for-WSL&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pengwin&lt;/td&gt;
&lt;td&gt;&lt;code&gt;wsl --install -d Pengwin&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pengwin Enterprise&lt;/td&gt;
&lt;td&gt;&lt;code&gt;wsl --install -d WLinux-Enterprise&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alpine WSL&lt;/td&gt;
&lt;td&gt;&lt;code&gt;wsl --install -d Alpine&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Raft (Free Trial)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;wsl --install -d Raft&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AlmaLinux&lt;/td&gt;
&lt;td&gt;&lt;code&gt;wsl --install -d AlmaLinux&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  3.3.5   Set Up Your Linux Distribution
&lt;/h3&gt;

&lt;p&gt;Once the installation is complete, open your Linux distribution (e.g., Ubuntu 24.04) and create a username and password when prompted.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.3.6   Verify Installation and Check WSL Version
&lt;/h3&gt;

&lt;p&gt;To check the installed distributions and their WSL versions, use:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;wsl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-v&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Output:&lt;/p&gt;

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

  NAME            STATE           VERSION
* Ubuntu-24.04    Stopped         2
  Ubuntu          Stopped         2


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  3.3.7   Launch Your Linux Distribution
&lt;/h3&gt;

&lt;p&gt;You can launch Ubuntu (or any installed Linux distribution) using either of the following commands:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using the distribution executable&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;ubuntu2404.exe&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Using WSL command&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;wsl&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h1&gt;
  
  
  4  Tailscale
&lt;/h1&gt;

&lt;p&gt;Tailscale is a modern VPN service that simplifies connecting devices and applications over a secure network. It leverages the WireGuard protocol to create a peer-to-peer mesh network, known as TailNet, which allows devices within the same private network to communicate directly. This is different from traditional VPNs, which route all traffic through a central gateway.&lt;/p&gt;

&lt;p&gt;Tailscale can be used for various purposes, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SSH Access&lt;/strong&gt;: Securely connect to remote machines.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File Access and Sharing&lt;/strong&gt;: Access and share files across devices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private Website Access&lt;/strong&gt;: Reach privately hosted websites.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database and Kubernetes Clusters&lt;/strong&gt;: Connect to databases and Kubernetes clusters securely.
## 4.1  Key Differences from Traditional VPNs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Traditional VPNs create a central tunnel for all network traffic, routing it through a single gateway. In contrast, Tailscale establishes a peer-to-peer or point-to-point mesh network, which they refer to as TailNet, enabling direct communication between devices.&lt;/p&gt;

&lt;h2&gt;
  
  
  4.2  Setting Up Tailscale
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.2.1   Sign Up and Access the Admin Dashboard
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Sign Up&lt;/strong&gt;: Create an account at &lt;a href="https://tailscale.com" rel="noopener noreferrer"&gt;Tailscale&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Admin Dashboard&lt;/strong&gt;: After signing up, you will be directed to the Tailscale Admin Dashboard.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.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%2Ffh3vip7wpqiz42qfjs8c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Ffh3vip7wpqiz42qfjs8c.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4.2.2    Install Tailscale on WSL
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Open your WSL terminal and run:
```bash
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;curl -fsSL &lt;a href="https://tailscale.com/install.sh" rel="noopener noreferrer"&gt;https://tailscale.com/install.sh&lt;/a&gt; | sh&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2. Check the status of the Tailscale service:
   ```bash


   sudo systemctl status tailscaled


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Enable and start the Tailscale service:
```bash
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;sudo systemctl enable tailscaled&lt;br&gt;
   sudo systemctl start tailscaled&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
### 4.2.3    Install Tailscale on Windows
1. Download the Tailscale installer for Windows from [here](https://pkgs.tailscale.com/stable/tailscale-setup-latest.exe).
2. Once Installed login to tailscale.

### 4.2.4    Configure Tailscale
1. **Generate an Auth Key**:
   - Return to the Tailscale Admin Dashboard.
   - Navigate to **Settings** to generate an authentication key.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ywgb6cwtwbog9p15dbk.png)






2. **Authenticate and Connect**:
   - Return to your WSL terminal.
   - Run the following command to authenticate and connect:
     ```bash


     sudo tailscale up --auth-key=YOUR_AUTH_KEY --ssh


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Replace &lt;code&gt;YOUR_AUTH_KEY&lt;/code&gt; with the key you generated.&lt;/p&gt;

&lt;p&gt;Congratulations! Your WSL is now configured for remote SSH access over a private IP. Both your Windows machine and the WSL instance should be connected to Tailscale to access resources or applications and to perform SSH.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.2.5    SSH Using Tailscale Browser-Based Access
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Access Tailscale Admin Portal&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Go to the Tailscale Admin Portal.&lt;/li&gt;
&lt;li&gt;Select the machine you want to SSH into and choose the option to SSH into the machine.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fvxzfdviuzollxs7g3ivw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fvxzfdviuzollxs7g3ivw.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Select User&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Choose the user you want to log in as.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.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%2F91u22dvc7eyxz1ixlhw8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F91u22dvc7eyxz1ixlhw8.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Confirm Identity&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Confirm your identity by logging in to Tailscale.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You are now connected to WSL through your browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fr10vbsqvcycsdlwy2f2t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fr10vbsqvcycsdlwy2f2t.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! You have successfully set up Ubuntu 24.04 on Windows 11 using WSL and configured it for secure SSH access via Tailscale. This setup allows you to leverage the power of Linux applications seamlessly within your Windows environment while ensuring secure, private connectivity from anywhere and using any device.&lt;/p&gt;




&lt;p&gt;If you found this guide helpful and have any questions or feedback, feel free to reach out. For more insights on technology and to stay updated with my latest content, connect with me on &lt;a href="https://linkedin.com/in/r-quazi" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; and you can support open source community by buying a coffee &lt;a href="https://buymeacoffee.com/rquazi" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Connect with me :  &lt;a href="mailto:hi@plexio.cloud"&gt;hi@plexio.cloud&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you for reading!&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;References:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ubuntu.com/desktop/wsl.exe" rel="noopener noreferrer"&gt;Ubuntu on WSL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/windows/wsl/install-manual" rel="noopener noreferrer"&gt;Manual Installation of WSL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tailscale.com/kb/1017/install" rel="noopener noreferrer"&gt;Tailscale Installation Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>linux</category>
      <category>vpn</category>
      <category>microsoft</category>
      <category>ssh</category>
    </item>
  </channel>
</rss>
