<?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: Portabase</title>
    <description>The latest articles on DEV Community by Portabase (@portabase_io).</description>
    <link>https://dev.to/portabase_io</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3712488%2F29d3504e-62bd-4f4b-9a35-1123c9f3384b.png</url>
      <title>DEV Community: Portabase</title>
      <link>https://dev.to/portabase_io</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/portabase_io"/>
    <language>en</language>
    <item>
      <title>How to Back Up Nextcloud with Portabase</title>
      <dc:creator>Portabase</dc:creator>
      <pubDate>Thu, 24 Sep 2026 14:30:04 +0000</pubDate>
      <link>https://dev.to/portabase_io/how-to-back-up-nextcloud-with-portabase-m5</link>
      <guid>https://dev.to/portabase_io/how-to-back-up-nextcloud-with-portabase-m5</guid>
      <description>&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fln4eg0vgwl6qwz194jxx.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fln4eg0vgwl6qwz194jxx.png" alt=" " width="800" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hosting your own &lt;a href="https://nextcloud.com" rel="noopener noreferrer"&gt;Nextcloud&lt;/a&gt; instance lets you keep full control over your files, calendars, contacts, and other data. In return, self-hosting also means you are responsible for protecting that data.&lt;/p&gt;

&lt;p&gt;When Nextcloud is deployed with &lt;a href="https://www.docker.com" rel="noopener noreferrer"&gt;Docker&lt;/a&gt;, the containers themselves are disposable: they can be recreated at any time from their images. The part that really matters in the deployment is the persistent data stored in the Docker volumes - in particular the application data, the configuration, the databases, and the user files.&lt;/p&gt;

&lt;p&gt;Backing up these persistent volumes is therefore essential to be able to restore your Nextcloud instance after a server failure, an accidental deletion, a migration, or a configuration problem. Docker volumes are, in practice, where the state of a containerized application is kept.&lt;/p&gt;

&lt;p&gt;In this tutorial, we will deploy a Nextcloud instance with Docker, then configure Portabase to back up and restore its Docker volumes.&lt;/p&gt;

&lt;p&gt;By the end of this tutorial, the architecture will include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a Nextcloud deployment;&lt;/li&gt;
&lt;li&gt;a Portabase server providing the web interface and backup management;&lt;/li&gt;
&lt;li&gt;a Portabase agent connected to the Docker host running Nextcloud;&lt;/li&gt;
&lt;li&gt;a storage destination for the backups;&lt;/li&gt;
&lt;li&gt;scheduled backups of the Nextcloud Docker volumes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is Nextcloud?
&lt;/h2&gt;

&lt;p&gt;Nextcloud is an open-source, self-hosted collaboration platform designed as an alternative to proprietary cloud services.&lt;/p&gt;

&lt;p&gt;Originally, Nextcloud provides file storage and synchronization features, but its ecosystem goes far beyond simple file hosting. Depending on the installed apps, a Nextcloud instance can also offer calendars, contacts, collaborative document editing, communication tools, task management, and many other services.&lt;/p&gt;

&lt;p&gt;One of the main advantages of Nextcloud is that it lets organizations and individuals keep control over where their data lives and how their infrastructure is operated.&lt;/p&gt;

&lt;p&gt;Although Docker makes the application easy to deploy and maintain, the containers themselves must not be considered backups. The persistent state of the Nextcloud deployment is stored in the Docker volumes. Protecting those volumes is therefore an essential part of any backup strategy.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Portabase?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://portabase.io" rel="noopener noreferrer"&gt;Portabase&lt;/a&gt; is an open-source, self-hosted backup and restore platform, designed to centrally manage the backups of multiple servers.&lt;/p&gt;

&lt;p&gt;It supports nine database technologies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PostgreSQL&lt;/li&gt;
&lt;li&gt;MySQL&lt;/li&gt;
&lt;li&gt;MariaDB&lt;/li&gt;
&lt;li&gt;Microsoft SQL Server&lt;/li&gt;
&lt;li&gt;Firebird SQL&lt;/li&gt;
&lt;li&gt;SQLite&lt;/li&gt;
&lt;li&gt;MongoDB&lt;/li&gt;
&lt;li&gt;Redis&lt;/li&gt;
&lt;li&gt;Valkey&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Portabase also supports backing up and restoring Docker volumes, which allows it to protect the persistent data used by containerized applications.&lt;/p&gt;

&lt;p&gt;Its architecture relies on two main components:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Portabase server&lt;/strong&gt; provides the web interface used to configure projects, storage destinations, backup schedules, retention policies, and restore operations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Portabase agents&lt;/strong&gt; are installed on the infrastructure where the databases or Docker volumes live. They run the backup and restore operations and communicate with the central Portabase server.&lt;/p&gt;

&lt;p&gt;This architecture makes it possible to manage backups of multiple Docker hosts from a single interface.&lt;/p&gt;

&lt;p&gt;For our Nextcloud deployment, the Portabase agent will run on the Docker host where Nextcloud is installed. It will have access to the Nextcloud Docker volumes and will be responsible for backing them up to the storage destination configured in Portabase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tutorial architecture
&lt;/h2&gt;

&lt;p&gt;The environment used in this tutorial consists of two main elements:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Nextcloud&lt;/strong&gt;, deployed with Docker and using persistent Docker volumes;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Portabase&lt;/strong&gt;, made up of the central dashboard and an agent connected to the Docker host.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The backup flow will be as follows:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nextcloud Docker volumes → Portabase Agent → Backup Storage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Portabase dashboard will be used to configure and monitor the backup process, while the agent runs the operations directly on the Docker host.&lt;/p&gt;

&lt;p&gt;In the following sections, we will first deploy Nextcloud, then install Portabase, connect the agent to the Docker host, and finally configure our first backup and restore operation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing Nextcloud
&lt;/h2&gt;

&lt;p&gt;Create a dedicated directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;nextcloud
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Move into that directory:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Create a &lt;code&gt;docker-compose.yml&lt;/code&gt; file and paste the following code into it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

  &lt;span class="na"&gt;postgres&lt;/span&gt;&lt;span class="pi"&gt;:&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;nextcloud-db&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_POSTGRES_IMAGE_TAG}&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-postgres:/var/lib/postgresql/data&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${NEXTCLOUD_DB_NAME}&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${NEXTCLOUD_DB_USER}&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${NEXTCLOUD_DB_PASSWORD}&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;default&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="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CMD"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pg_isready"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-q"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-d"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;${NEXTCLOUD_DB_NAME}"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-U"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;${NEXTCLOUD_DB_USER}"&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;10s&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;5s&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;start_period&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;60s&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;redis&lt;/span&gt;&lt;span class="pi"&gt;:&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;nextcloud-redis&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_REDIS_IMAGE_TAG}&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;redis-server"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--requirepass"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;$NEXTCLOUD_REDIS_PASSWORD"&lt;/span&gt;&lt;span class="pi"&gt;]&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;redis-data:/data&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;default&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="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CMD"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;redis-cli"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;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;10s&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;5s&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;start_period&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;60s&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;nextcloud&lt;/span&gt;&lt;span class="pi"&gt;:&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;nextcloud-app&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_IMAGE_TAG}&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-data:${DATA_PATH}&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="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;7689:80"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;TZ&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${NEXTCLOUD_TIMEZONE}&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_HOST&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nextcloud-db&lt;/span&gt;
      &lt;span class="na"&gt;DB_PORT&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5432&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${NEXTCLOUD_DB_NAME}&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${NEXTCLOUD_DB_USER}&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${NEXTCLOUD_DB_PASSWORD}&lt;/span&gt;
      &lt;span class="na"&gt;REDIS_HOST&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nextcloud-redis&lt;/span&gt;
      &lt;span class="na"&gt;REDIS_HOST_PORT&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;6379&lt;/span&gt;
      &lt;span class="na"&gt;REDIS_HOST_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${NEXTCLOUD_REDIS_PASSWORD}&lt;/span&gt;
      &lt;span class="na"&gt;NEXTCLOUD_ADMIN_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${NEXTCLOUD_ADMIN_USERNAME}&lt;/span&gt;
      &lt;span class="na"&gt;NEXTCLOUD_ADMIN_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${NEXTCLOUD_ADMIN_PASSWORD}&lt;/span&gt;
      &lt;span class="na"&gt;NEXTCLOUD_TRUSTED_DOMAINS&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${NEXTCLOUD_HOSTNAME}&lt;/span&gt;
      &lt;span class="na"&gt;OVERWRITECLIURL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${NEXTCLOUD_URL}&lt;/span&gt;
      &lt;span class="na"&gt;OVERWRITEHOST&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${NEXTCLOUD_HOSTNAME}&lt;/span&gt;
      &lt;span class="na"&gt;TRUSTED_PROXIES&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;172.16.0.0/12 192.168.0.0/16 10.0.0.0/8 fc00::/7 fe80::/10 2001:db8::/32&lt;/span&gt;
      &lt;span class="na"&gt;PHP_UPLOAD_LIMIT&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;8G&lt;/span&gt;
      &lt;span class="na"&gt;PHP_MEMORY_LIMIT&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;8G&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;default&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="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CMD"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;curl"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-f"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:80/"&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;10s&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;5s&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;start_period&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;90s&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;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;postgres&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;service_healthy&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;condition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;service_healthy&lt;/span&gt;

  &lt;span class="na"&gt;nextcloud-cron&lt;/span&gt;&lt;span class="pi"&gt;:&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;nextcloud-cron&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_IMAGE_TAG}&lt;/span&gt;
    &lt;span class="na"&gt;entrypoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/cron.sh&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-data:${DATA_PATH}&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;default&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;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;nextcloud-data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;redis-data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;nextcloud-postgres&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create the &lt;code&gt;.env&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch&lt;/span&gt; .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then add the following variables to that file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="py"&gt;NEXTCLOUD_POSTGRES_IMAGE_TAG&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;postgres:16&lt;/span&gt;
&lt;span class="py"&gt;NEXTCLOUD_REDIS_IMAGE_TAG&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;redis:7.2&lt;/span&gt;
&lt;span class="py"&gt;NEXTCLOUD_IMAGE_TAG&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;nextcloud:34&lt;/span&gt;

&lt;span class="py"&gt;NEXTCLOUD_REDIS_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;your-redis-password&amp;gt;&lt;/span&gt;

&lt;span class="py"&gt;NEXTCLOUD_DB_NAME&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;nextclouddb&lt;/span&gt;
&lt;span class="py"&gt;NEXTCLOUD_DB_USER&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;nextclouddbuser&lt;/span&gt;
&lt;span class="py"&gt;NEXTCLOUD_DB_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;your-database-password&amp;gt;&lt;/span&gt;

&lt;span class="py"&gt;NEXTCLOUD_ADMIN_USERNAME&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;admin&lt;/span&gt;
&lt;span class="py"&gt;NEXTCLOUD_ADMIN_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;your-admin-password&amp;gt;&lt;/span&gt;

&lt;span class="py"&gt;NEXTCLOUD_URL&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;http://localhost:7689&lt;/span&gt;
&lt;span class="py"&gt;NEXTCLOUD_HOSTNAME&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;localhost:7689&lt;/span&gt;
&lt;span class="py"&gt;NEXTCLOUD_TIMEZONE&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Europe/Paris&lt;/span&gt;

&lt;span class="py"&gt;DATA_PATH&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/var/www/html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once this step is complete, you can start your instance by running the following command:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbsumbuvv5wht63b71gp1.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbsumbuvv5wht63b71gp1.png" alt="Output of the docker compose up command for Nextcloud" width="800" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then go to &lt;code&gt;http://localhost:7689&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You should then see:&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe0g2rshna5spunwonjk9.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe0g2rshna5spunwonjk9.png" alt="Nextcloud login screen" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Log in using the Nextcloud username and password set in the &lt;code&gt;.env&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Everything is now up and running: your Nextcloud instance is ready to use.&lt;/p&gt;

&lt;p&gt;You can move on to the next section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing Portabase
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Portabase dashboard
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;portabase
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Move into that directory:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Create a &lt;code&gt;docker-compose.yml&lt;/code&gt; file and paste the following code into it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;portabase&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;portabase&lt;/span&gt;&lt;span class="pi"&gt;:&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;portabase-app&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;portabase/portabase:latest&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;env_file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;.env&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="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;${HOST_PORT}:80"&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;TZ=${TZ}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;LOG_LEVEL=${LOG_LEVEL}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PROJECT_SECRET=${PROJECT_SECRET}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PROJECT_URL=${PROJECT_URL}&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;portabase-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="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CMD-SHELL"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;curl&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-f&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;http://localhost/api/health"&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;30s&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;5s&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;start_period&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;60s&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;portabase-data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to use an external PostgreSQL database to store Portabase's internal metadata, you can refer to the following documentation: &lt;a href="https://portabase.io/docs/dashboard/configuration/environment" rel="noopener noreferrer"&gt;https://portabase.io/docs/dashboard/configuration/environment&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create the &lt;code&gt;.env&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch&lt;/span&gt; .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then add the following variables to that file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="py"&gt;HOST_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"8887"&lt;/span&gt;
&lt;span class="py"&gt;PROJECT_SECRET&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;your-secret&amp;gt;"&lt;/span&gt; &lt;span class="c"&gt;# openssl rand -hex 32
&lt;/span&gt;&lt;span class="s"&gt;PROJECT_URL="http://localhost:8887"&lt;/span&gt;
&lt;span class="py"&gt;TZ&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Europe/Paris"&lt;/span&gt;
&lt;span class="py"&gt;LOG_LEVEL&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"info"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once this step is complete, you can start your instance by running the following command:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Then go to &lt;code&gt;http://localhost:8887&lt;/code&gt;.&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcryloomr12y829ev23o1.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcryloomr12y829ev23o1.png" alt="Start of the Portabase configuration wizard" width="800" height="667"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Start of the Portabase configuration wizard to install and customize the solution.&lt;/em&gt;&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8yo9vqd797bm7czfe2bp.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8yo9vqd797bm7czfe2bp.png" alt="Completion of the Portabase configuration wizard" width="800" height="667"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Completing the Portabase configuration wizard during installation.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding "agents" to Portabase
&lt;/h2&gt;

&lt;p&gt;The "agents" are essentially the component installed on the Docker host. They run the core operations related to backing up your Docker volumes.&lt;/p&gt;

&lt;p&gt;The configuration requires a few steps on both sides: on your Portabase server and on the Docker host whose volumes you want to back up.&lt;/p&gt;

&lt;p&gt;On the Portabase server side, go to the &lt;strong&gt;Agents&lt;/strong&gt; menu, then click &lt;strong&gt;Add an agent&lt;/strong&gt;.&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjg6unj6zfulnlx36ipmi.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjg6unj6zfulnlx36ipmi.png" alt="Agents menu in the Portabase dashboard" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will open the &lt;strong&gt;Create a new agent&lt;/strong&gt; dialog.&lt;/p&gt;

&lt;p&gt;Give the agent a name. You can also add a description.&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frg6iyked0921l999j22q.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frg6iyked0921l999j22q.png" alt="Create a new agent dialog" width="503" height="324"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Name the agent and optionally add a description.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The agent is now added on the Portabase side.&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdjhcs1xzpufzx60t77aa.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdjhcs1xzpufzx60t77aa.png" alt="Agent added in Portabase" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flhayav4adfg6p99pl82r.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flhayav4adfg6p99pl82r.png" alt="Portabase agent configuration screen" width="799" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring the Portabase CLI
&lt;/h2&gt;

&lt;p&gt;Now that the agent is configured on the Portabase side, we need to configure the "client" part - that is, the Docker host.&lt;/p&gt;

&lt;p&gt;To do this, we will install the Portabase CLI. Its installation is simple using the command below, following the Portabase documentation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sL&lt;/span&gt; https://portabase.io/install | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzbmnwgglmnofwzojtsib.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzbmnwgglmnofwzojtsib.png" alt="Portabase CLI installation" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The agent screen displays the &lt;strong&gt;Registration&lt;/strong&gt; and &lt;strong&gt;Setup&lt;/strong&gt; sections, where you can copy the CLI command containing the authentication token that lets the remote agent connect to Portabase.&lt;/p&gt;

&lt;p&gt;Before continuing, check the Nextcloud volumes as well as the container names:&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fygbfdxb3ypahcgw2evmt.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fygbfdxb3ypahcgw2evmt.png" alt="Verifying the Nextcloud Docker volumes" width="799" height="401"&gt;&lt;/a&gt;&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fphd518m2rkjt0i84zzf1.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fphd518m2rkjt0i84zzf1.png" alt="Verifying the Nextcloud Docker volumes" width="800" height="85"&gt;&lt;/a&gt;&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7mqqiw6vdpgp83ajaxn7.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7mqqiw6vdpgp83ajaxn7.png" alt="Verifying the Nextcloud Docker volumes" width="601" height="822"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then go back to the Portabase dashboard.&lt;/p&gt;

&lt;p&gt;As you can see below, the agent is now connected and the &lt;strong&gt;Managed Databases&lt;/strong&gt; section shows the Docker volume we configured to be protected.&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvxwdn6wq9ipjqurf52zy.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvxwdn6wq9ipjqurf52zy.png" alt="Connected agent showing the managed database" width="799" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Agent added to Portabase and communicating correctly with the registered Docker volume.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Linking the agent to an organization
&lt;/h3&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F52ycbjc8y1wi1o0r8bnv.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F52ycbjc8y1wi1o0r8bnv.png" alt="Linking the agent to an organization in Portabase" width="799" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a new project and select the Docker volume to protect
&lt;/h3&gt;

&lt;p&gt;Below, I create a new project. Creating a project is required, because this is where backup operations can be configured and run.&lt;/p&gt;

&lt;p&gt;Here, I give the project a name and select the Docker volume to protect.&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv68ipoq2m5ilc0tnnnhd.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv68ipoq2m5ilc0tnnnhd.png" alt="Creating a new project in Portabase" width="799" height="401"&gt;&lt;/a&gt;&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0zczj9x3o6r5tfqkkc0b.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0zczj9x3o6r5tfqkkc0b.png" alt="Selecting the Docker volume to protect" width="799" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Run a backup with Portabase
&lt;/h3&gt;

&lt;p&gt;Open the Nextcloud project in Portabase.&lt;/p&gt;

&lt;p&gt;You should now see the Docker volumes that were added to the project.&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fll1v7kv8hfl0pjpzkacw.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fll1v7kv8hfl0pjpzkacw.png" alt="Nextcloud project Docker volumes in Portabase" width="799" height="401"&gt;&lt;/a&gt;&lt;/p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6l0h7oe87a6qln9j1jlz.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6l0h7oe87a6qln9j1jlz.png" alt="Nextcloud project Docker volumes protected by Portabase" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your Nextcloud Docker volumes are now protected with Portabase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Going further
&lt;/h2&gt;

&lt;p&gt;A manual backup is a first step, but a real backup strategy must be automated.&lt;/p&gt;

&lt;p&gt;From the Portabase dashboard, you can configure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;scheduled backup policies to run backups automatically;&lt;/li&gt;
&lt;li&gt;retention policies to define how long backups are kept;&lt;/li&gt;
&lt;li&gt;storage providers to keep backups off the Docker host;&lt;/li&gt;
&lt;li&gt;restore operations to recover a volume when needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For production environments, it is strongly recommended to store your backups on infrastructure separate from the Nextcloud server. That way, a failure affecting the original host cannot also destroy your backups.&lt;/p&gt;

&lt;p&gt;A reliable backup strategy must also include regular restore tests. A backup is only truly useful if it can be restored when an incident occurs.&lt;/p&gt;

&lt;p&gt;Thanks to Portabase, which centralizes the backup process, and an agent running directly on the Docker host, you can manage and monitor the protection of your Nextcloud deployment from a single interface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Useful links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://portabase.io" rel="noopener noreferrer"&gt;https://portabase.io&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Documentation: &lt;a href="https://portabase.io/docs" rel="noopener noreferrer"&gt;https://portabase.io/docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/portabase/portabase?utm_source=portabase.io" rel="noopener noreferrer"&gt;https://github.com/portabase/portabase&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>nextcloud</category>
      <category>backup</category>
      <category>docker</category>
    </item>
    <item>
      <title>Portabase: A self-hosted tool for database backup &amp; restore</title>
      <dc:creator>Portabase</dc:creator>
      <pubDate>Tue, 24 Feb 2026 13:43:10 +0000</pubDate>
      <link>https://dev.to/portabase/portabase-a-self-hosted-tool-for-database-backup-restore-21ki</link>
      <guid>https://dev.to/portabase/portabase-a-self-hosted-tool-for-database-backup-restore-21ki</guid>
      <description>&lt;p&gt;Backups are one of those things everyone knows they should have, but few enjoy setting up. Between security concerns, network complexity, and tools that assume way too much expertise, database backups often end up ignored until something breaks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Portabase/portabase?ref=dev.to"&gt;Portabase&lt;/a&gt; is a backup and restore tool for databases, currently supporting PostgreSQL, MySQL, MariaDB and MongoDB with Redis coming soon.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Portabase features a secure-by-design architecture&lt;/strong&gt;, using a central server and lightweight agents that enable deployment at the edge and operation across multiple networks. Don’t worry—you never need to expose your database to the internet!&lt;/p&gt;

&lt;p&gt;These agents handle everything: they back up your data and send it encrypted to your preferred storage locations, all without requiring any technical skills. You can manage everything from the web interface.&lt;/p&gt;

&lt;p&gt;In a hurry? Use the CLI or the ready-to-go Docker Compose setup provided in the &lt;a href="https://portabase.io/docs/dashboard/setup?utm_source=dev.to&amp;amp;utm_medium=referral&amp;amp;utm_campaign=presentation"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/nSTzT27GgAg"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  How does Portabase Work?
&lt;/h2&gt;

&lt;p&gt;Portabase’s ecosystem is built around three primary components:&lt;/p&gt;

&lt;h3&gt;
  
  
  Central server (management plane)
&lt;/h3&gt;

&lt;p&gt;It provides a &lt;strong&gt;user-friendly interface&lt;/strong&gt; that serves as the central control plane for all backup and restoration operations. From here, users can &lt;strong&gt;register and manage agents&lt;/strong&gt;, configure backup policies and review historical backups. The dashboard also provides visibility into storage usage and retention compliance, making it easy for teams to manage multiple databases and agents from a single location.&lt;/p&gt;

&lt;h3&gt;
  
  
  Agents (execution plane)
&lt;/h3&gt;

&lt;p&gt;Lightweight connectors deployed on database hosts that perform the actual backup and restore operations. Agents operate in outbound pull mode, eliminating the need to open inbound ports on protected infrastructure while maintaining secure communication with the central server.&lt;/p&gt;

&lt;h3&gt;
  
  
  CLI (assistant)
&lt;/h3&gt;

&lt;p&gt;A command‑line utility that streamlines installation and configuration of both the dashboard and agents. The CLI automates environment setup, configuration generation, and operational commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Core Features &amp;amp; Capabilities
&lt;/h2&gt;

&lt;p&gt;It’s cron-based and supports three different retention strategies which works well for logical backups :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Fixed number of backups retained&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Time‑based retention (n days)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GFS rotation (Grandfather‑Father‑Son)&lt;/strong&gt;&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%2F5okusmt6pcuybzquvo0m.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%2F5okusmt6pcuybzquvo0m.png" alt="Retention policies" width="781" height="791"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These policies apply to logical backup artifacts and help enforce organizational data retention standards.&lt;/p&gt;

&lt;p&gt;For organizational usage, Portabase implements workspace structures that let you manage access and segmentation of resources (databases, storage locations and notifiers). This helps enforce permission boundaries for teams and projects within the same instance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Highly modular with many integrations
&lt;/h2&gt;

&lt;p&gt;The platform supports multiple storage backends, including local file systems and any S3-compatible storage (whether from cloud providers like AWS S3 or CloudFlare R2, or on-premise solutions such as MinIO or RustFS), and Google Drive.&lt;/p&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%2Fguu5hl2lwaiy7vy3gsig.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%2Fguu5hl2lwaiy7vy3gsig.png" alt="Add storage channel" width="506" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Portabase is designed for flexibility and scalability. You can link each database to multiple storage targets, enabling redundancy and resilience to keep backups safe even if one storage location fails.&lt;/p&gt;

&lt;p&gt;Portabase integrates with popular notification and alerting platforms such as &lt;strong&gt;Slack, Discord, or Telegram&lt;/strong&gt;, allowing teams to stay informed about backup status in real time. Alerts can notify you of successful backups or failures, enabling proactive monitoring and faster response times. These integrations help ensure that critical backup operations are never overlooked and make it easy to embed Portabase into existing team workflows and communication channels.&lt;/p&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%2F049rrvzoimhpibp6k1hb.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%2F049rrvzoimhpibp6k1hb.png" alt="Add notification channel" width="506" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Under the Hood
&lt;/h2&gt;

&lt;p&gt;The central server is built with Next.js 16, leveraging server-side rendering (SSR) and optimized client-side hydration to deliver low-latency interfaces. The backend uses PostgreSQL for reliable data storage with Drizzle ORM managing database interactions, ensuring type-safe queries, transactional integrity, and efficient schema migrations.&lt;/p&gt;

&lt;p&gt;The agent, originally written in Python, has been fully refactored in Rust 🦀, taking advantage of Tokio’s asynchronous runtime for high-throughput, non-blocking operations. This rewrite reduces the Docker image size by 4x, minimizes runtime errors, and ensures reliable, concurrent backup and restore operations across multiple databases. Rust’s memory safety and performance guarantees make the agent well-suited for production environments with high I/O demands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you find Portabase useful, don’t forget to give it a star on &lt;a href="https://github.com/Portabase/portabase?ref=dev.to"&gt;GitHub&lt;/a&gt;!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>database</category>
      <category>postgres</category>
      <category>mysql</category>
      <category>mongodb</category>
    </item>
  </channel>
</rss>
