> For the complete documentation index, see [llms.txt](https://docs.devolutions.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.devolutions.net/server/knowledge-base/how-to-articles/install-devolutions-server-for-linux.md).

# Install Devolutions Server for Linux

Install Devolutions Server for Linux with Bash and PowerShell on a SQL Server or PostgreSQL database, with TLS setup, updates, and removal via systemd.

Devolutions Server is available for Linux with Microsoft Kestrel as the built-in web server and Microsoft PowerShell 7 for command-line installation. The database can be Microsoft SQL Server or PostgreSQL. The present topic shows how to manually install Devolutions Server for Linux using Bash prompts and PowerShell scripts, as well as how to access, update, and remove it.

Alternatively, Devolutions Server can be installed automatically using the scripts found on the [Devolutions GitHub ScriptLibrary repository](https://github.com/Devolutions/ScriptLibrary/tree/main/DVLSForLinux).

### Installing prerequisites <a href="#installing-prerequisites" id="installing-prerequisites"></a>

Devolutions Server needs a database server. Install the database engine to use with the SQL Server or the PostgreSQL procedure, or go directly to the PowerShell installation if the database server already exists.

#### SQL Server

1. If Microsoft SQL Server is not already installed, run the following Bash prompt with the `MSSQL_SA_PASSWORD` variable changed to a strong password:

   ```bash
   source /etc/os-release
   curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | sudo gpg --dearmor --batch --yes -o /usr/share/keyrings/microsoft-prod.gpg
   curl -fsSL https://packages.microsoft.com/config/ubuntu/$VERSION_ID/mssql-server-2022.list | sudo tee /etc/apt/sources.list.d/mssql-server-2022.list
   sudo apt-get update
   sudo apt-get install -y mssql-server
   sudo MSSQL_PID="evaluation" MSSQL_SA_PASSWORD="mystrongpassword" /opt/mssql/bin/mssql-conf -n setup accept-eula
   sudo /opt/mssql/bin/mssql-conf set sqlagent.enabled true
   sudo systemctl restart mssql-server
   ```

   `MSSQL_PID` is set to ***evaluation*** in this example, but a product key can be entered here instead.

{% hint style="warning" %}
Microsoft only supports [certain SQL versions](/server/overview-of-devolutions-server/system-requirements.md#software-dependencies). Refer to Microsoft's documentation to make sure your version of SQL is officially supported for your distribution.
{% endhint %}

#### PostgreSQL

Devolutions Server supports PostgreSQL 14 or later, installed on a server or provided by a managed PostgreSQL service. Devolutions Server connects with a single role, using a username and a password: integrated authentication is not available with PostgreSQL.

1. If PostgreSQL is not already available, install it on the database server with this Bash prompt:

   ```bash
   sudo apt-get update
   sudo apt-get install -y postgresql
   psql --version
   ```

   The PostgreSQL version provided by the distribution depends on its release. Make sure the installed version is PostgreSQL 14 or later.
2. Create a dedicated role that owns the Devolutions Server database, instead of using the `postgres` superuser. Change `YOURSTRONGPASSWORD` to a strong password:

   ```bash
   sudo -u postgres psql -c "CREATE ROLE dvls_owner LOGIN PASSWORD 'YOURSTRONGPASSWORD';"
   sudo -u postgres psql -c "CREATE DATABASE dvls OWNER dvls_owner;"
   ```

   With a managed PostgreSQL service, create the role and the database with the administrator account of the service. When the database does not exist, the installation creates it from the `postgres` maintenance database, which requires a role with the `CREATEDB` attribute and the `CONNECT` privilege on `postgres`.
3. On the machine that runs Devolutions Server, install the PostgreSQL client tools. The built-in database backup job of Devolutions Server runs `pg_dump` and `pg_restore`, and the update and removal procedures on this page use them:

   ```bash
   sudo apt-get install -y postgresql-client
   pg_dump --version
   ```

   The major version of `pg_dump` must be equal to or newer than the major version of the PostgreSQL server, otherwise the backup fails. When the distribution package is older than the server, install the matching `postgresql-client-<major version>` package from the PostgreSQL APT repository.

#### PowerShell and the Devolutions.PowerShell module

1. Run this Bash prompt to install PowerShell 7:

   ```bash
   sudo apt-get update
   sudo apt-get install -y wget apt-transport-https software-properties-common
   source /etc/os-release
   wget -q https://packages.microsoft.com/config/ubuntu/$VERSION_ID/packages-microsoft-prod.deb
   sudo dpkg -i packages-microsoft-prod.deb
   rm packages-microsoft-prod.deb
   sudo apt-get update
   sudo apt-get install -y powershell
   ```

   Run this prompt from a directory where the current user can write, since `wget` downloads the `.deb` package to the current directory.
2. Install the [Devolutions.PowerShell module](https://www.powershellgallery.com/packages/Devolutions.PowerShell/) for all users (location: `/opt/microsoft/powershell/7/Modules`). The installation and update procedures on this page run PowerShell as root, which only finds modules installed for all users:

   ```powershell
   & sudo pwsh -Command { Install-Module -Name 'Devolutions.PowerShell' -Confirm:$False -Scope 'AllUsers' -Force }
   ```

   A warning is likely to appear stating that the installation comes from an untrusted repository. The module is hosted on PowerShell Gallery, the official location for hosting PowerShell modules managed by Microsoft. To avoid seeing this warning in the future, run `Set-PSRepository -Name PSGallery -InstallationPolicy Trusted`.
3. Create a user and a group for Devolutions Server. A separate user and group are optional and isolate Devolutions Server from other services. This Bash prompt creates a user and a group both named ***dvls***, with the installation directory set to `/opt/devolutions/dvls`:

   ```bash
   sudo useradd -N dvls
   sudo groupadd dvls
   sudo usermod -a -G dvls dvls
   # optional, add current user to dvls group
   sudo usermod -a -G dvls $(id -un)
   sudo mkdir -p /opt/devolutions/dvls
   sudo chown -R dvls:dvls /opt/devolutions/dvls
   sudo chmod 550 /opt/devolutions/dvls
   ```

### Downloading and installing Devolutions Server for Linux <a href="#downloading-and-installing-dvls-for-linux" id="downloading-and-installing-dvls-for-linux"></a>

The installation directory is owned by `dvls:dvls` in mode 550, so the installation runs as root. Start PowerShell with `sudo pwsh` and run all the PowerShell scripts of this section in that session.

1. Download the latest version of Devolutions Server for Linux and extract the `.tar.gz` file into `/opt/devolutions/dvls`:

   ```powershell
   Import-Module -Name 'Devolutions.PowerShell'

   $DVLSPath = '/opt/devolutions/dvls'
   $DVLSDownloadPath = '/tmp/dvls-linux-x64.tar.gz'

   Get-DPSProduct -Name 'DPSLinuxX64bin' -Destination $DVLSDownloadPath
   & tar -xzf $DVLSDownloadPath -C $DVLSPath --strip-components=1
   Remove-Item -Path $DVLSDownloadPath

   & chown -R dvls:dvls $DVLSPath
   & chmod -R o-rwx $DVLSPath
   & chmod 660 (Join-Path -Path $DVLSPath -ChildPath 'appsettings.json')
   & chmod 770 (Join-Path -Path $DVLSPath -ChildPath 'App_Data')

   Set-Location -Path $DVLSPath
   ```
2. Generate a certificate if Devolutions Server must respond over TLS and no certificate exists yet. Replace `MYHOST` with the host name of the server:

   ```powershell
   & openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes -keyout cert.key -out cert.crt -subj "/CN=MYHOST" -addext "subjectAltName=DNS:MYHOST"
   & openssl pkcs12 -export -out cert.pfx -inkey cert.key -in cert.crt -passout pass:
   ```

   The `subjectAltName` uses `DNS:` in this example. To respond on an IP address only, use `IP:` instead. The generated `.pfx` certificate does not have a password.

#### Installation parameters for SQL Server

Define the installation parameters in the same PowerShell session. Replace `MYHOST`, `MYEMAIL`, `MSSQLHOST`, `DBUSERNAME`, and `YOURSTRONGPASSWORD` with the values of the environment. `MSSQLHOST` is the SQL Server host, `localhost` when SQL Server runs on the same machine. To respond over TLS, use `https` in `$DVLSURI`.

```powershell
$DVLSPath = '/opt/devolutions/dvls'
$DVLSURI  = 'http://MYHOST:5000/'

$DVLSAdminUsername = 'dvls-admin'
$DVLSAdminPassword = 'dvls-admin'
$DVLSAdminEmail    = 'MYEMAIL'

$Params = @{
    'DatabaseHost'           = 'MSSQLHOST'
    'DatabaseName'           = 'DSERVER'
    'DatabaseUserName'       = 'DBUSERNAME'
    'DatabasePassword'       = 'YOURSTRONGPASSWORD'
    'ServerName'             = 'DSERVER'
    'AccessUri'              = $DVLSURI
    'HttpListenerUri'        = $DVLSURI
    'DPSPath'                = $DVLSPath
    'UseEncryptedConnection' = $False # Modify as needed
    'TrustServerCertificate' = $False # Modify as needed
    'EnableTelemetry'        = $True  # Modify as needed
    'DisableEncryptConfig'   = $True
}
```

#### Installation parameters for PostgreSQL

Define the installation parameters in the same PowerShell session. Replace `MYHOST`, `MYEMAIL`, `PGHOST`, and `YOURSTRONGPASSWORD` with the values of the environment. `PGHOST` is the PostgreSQL host, `localhost` when PostgreSQL runs on the same machine. To respond over TLS, use `https` in `$DVLSURI`.

```powershell
$DVLSPath = '/opt/devolutions/dvls'
$DVLSURI  = 'http://MYHOST:5000/'

$DVLSAdminUsername = 'dvls-admin'
$DVLSAdminPassword = 'dvls-admin'
$DVLSAdminEmail    = 'MYEMAIL'

$Params = @{
    'DatabaseType'         = 'PostgreSql'
    'DatabaseHost'         = 'PGHOST'
    'DatabasePort'         = 5432
    'DatabaseName'         = 'dvls'
    'DatabaseUserName'     = 'dvls_owner'
    'DatabasePassword'     = 'YOURSTRONGPASSWORD'
    'ServerName'           = 'DSERVER'
    'AccessUri'            = $DVLSURI
    'HttpListenerUri'      = $DVLSURI
    'DPSPath'              = $DVLSPath
    'EnableTelemetry'      = $True # Modify as needed
    'DisableEncryptConfig' = $True
}
```

`DatabasePort` defaults to 5432 when omitted. Use a lowercase database name: the installation creates the database with its name quoted, so the name is case-sensitive in PostgreSQL commands.

With `DatabaseType` set to `PostgreSql`, `New-DPSInstallConfiguration` ignores the SQL Server parameters `-IntegratedSecurity`, `-FailoverPartner`, `-RetryCount`, and `-RetryInterval` and displays a warning when they are specified. `-UseEncryptedConnection` and `-TrustServerCertificate` do not apply either: the connection string uses `SSL Mode=Prefer`, which encrypts the connection only when the PostgreSQL server offers TLS. To require encryption, change `SSL Mode` to `Require` or `VerifyFull` in the connection strings of `appsettings.json` after the installation, then restart Devolutions Server.

The connection string keeps the PostgreSQL keywords (`Host=`, `Port=`, `Database=`, `Username=`, `Password=`), which is how Devolutions Server detects the PostgreSQL engine. It is stored under `ConnectionStrings.LocalSqlServer` in `appsettings.json`, the same key as with SQL Server. Devolutions Server adds `Search Path=dbo,public` and `Keep Alive=30` when they are not specified. When setting `Search Path` manually, keep `dbo` in it, since all the Devolutions Server tables are in the `dbo` schema.

#### Running the installation

1. Run the installation of Devolutions Server with the Devolutions.PowerShell module, in the same PowerShell session:

   ```powershell
   $Configuration = New-DPSInstallConfiguration @Params
   New-DPSAppSettings -Configuration $Configuration

   $Settings = Get-DPSAppSettings -ApplicationPath $DVLSPath
   $ConnectionString = $Settings.ConnectionStrings.LocalSqlServer

   New-DPSDatabase -ConnectionString $ConnectionString
   Update-DPSDatabase -ConnectionString $ConnectionString -InstallationPath $DVLSPath
   New-DPSWorkspaceSettings -ConnectionString $ConnectionString

   New-DPSEncryptConfiguration -ApplicationPath $DVLSPath
   New-DPSDatabaseAppSettings -Configuration $Configuration

   New-DPSAdministrator -ConnectionString $ConnectionString -Name $DVLSAdminUsername -Password $DVLSAdminPassword -Email $DVLSAdminEmail
   ```

   `New-DPSDatabase` displays a warning and continues when the database already exists, which is the case when the database was created beforehand. `Update-DPSDatabase` then creates the schema.
2. If a certificate was generated, modify the `appsettings.json` file to allow Kestrel to respond over TLS:

   ```powershell
   $JSON = Get-Content -Path (Join-Path -Path $DVLSPath -ChildPath 'appsettings.json') | ConvertFrom-JSON -Depth 100

   $JSON.Kestrel.Endpoints.Http | Add-Member -MemberType NoteProperty -Name 'Certificate' -Value @{
       'Path'     = (Join-Path -Path $DVLSPath -ChildPath 'cert.pfx')
       'Password' = ''
   }

   $JSON | ConvertTo-JSON -Depth 100 | Set-Content -Path (Join-Path -Path $DVLSPath -ChildPath 'appsettings.json')

   $AccessUri = (Get-DPSAccessUri -ConnectionString $ConnectionString).AccessUri
   Set-DPSAccessUri -ApplicationPath $DVLSPath -ConnectionString $ConnectionString -AccessURI ($AccessUri -Replace '^http:', 'https:')
   ```
3. Re-apply the ownership and permissions of the files created by the installation, then close the root PowerShell session:

   ```powershell
   & chown -R dvls:dvls $DVLSPath
   & chmod -R o-rwx $DVLSPath
   & chmod 550 $DVLSPath
   & chmod 660 (Join-Path -Path $DVLSPath -ChildPath 'appsettings.json')
   & chmod 770 (Join-Path -Path $DVLSPath -ChildPath 'App_Data')
   exit
   ```
4. Create a systemd unit file to run Devolutions Server for Linux in the background, and enable it at startup, with this Bash prompt:

   ```bash
   sudo tee /etc/systemd/system/dvls.service > /dev/null <<EOT
   [Unit]
   Description=Devolutions Server

   [Service]
   Type=simple
   Restart=always
   RestartSec=10
   User=dvls
   ExecStart=/opt/devolutions/dvls/Devolutions.Server
   WorkingDirectory=/opt/devolutions/dvls
   KillSignal=SIGINT
   SyslogIdentifier=dvls
   Environment="SCHEDULER_EMBEDDED=true"

   [Install]
   WantedBy=multi-user.target
   EOT

   sudo systemctl daemon-reload
   sudo systemctl enable dvls
   ```

   `SCHEDULER_EMBEDDED=true` runs the Devolutions Server scheduler inside the service. With PostgreSQL, the built-in backup job looks for `pg_dump` and `pg_restore` in the `PATH` of the service. If they are installed elsewhere, add `Environment="DVLS_PG_DUMP_PATH=/path/to/pg_dump"` and `Environment="DVLS_PG_RESTORE_PATH=/path/to/pg_restore"` to the `[Service]` section.
5. Start Devolutions Server and view its status:

   ```bash
   sudo systemctl start dvls
   sudo systemctl status dvls
   ```

### Accessing Devolutions Server for Linux <a href="#accessing-dvls-linux" id="accessing-dvls-linux"></a>

Devolutions Server for Linux listens on the port of the `HttpListenerUri` set during the installation, on the IP address or host name of the installation system, for example `http://MYHOST:5000`. OAuth errors may occur upon first launch when accessing Devolutions Server from a URL that is not configured. If this is the case, add additional URIs to listen on, or modify the primary one, by running the following script in PowerShell:

```powershell
Import-Module -Name 'Devolutions.PowerShell'

$DVLSPath = '/opt/devolutions/dvls'

$Settings = Get-DPSAppSettings -ApplicationPath $DVLSPath
$ConnectionString = $Settings.ConnectionStrings.LocalSqlServer

Get-DPSAccessUri -ConnectionString $ConnectionString

Set-DPSAccessUri -ConnectionString $ConnectionString -ApplicationPath $DVLSPath -AccessURI 'http://10.10.0.20:5000/' -AdditionalAccessURIs @('http://ubuntu-2204:5000/')
```

If Devolutions Server remains inaccessible outside of the installed system, make sure the firewall allows the port, for example with Uncomplicated Firewall: `sudo ufw allow 5000`.

### Importing Devolutions Server encryption key <a href="#importing-devolutions-server-encryption-key" id="importing-devolutions-server-encryption-key"></a>

When the Linux installation uses the database of an existing Windows installation, it needs the encryption keys of that installation.

**Export from an existing Windows installation**

```powershell
Import-Module -Name 'Devolutions.PowerShell'
$existingDVLSInstance = 'C:\my\path\dvlsInstance\'
$destination = 'C:\other\path\encryption.config'
Export-DPSEncryptionKeys -ApplicationPath $existingDVLSInstance -Destination $destination
```

**Import to the new Linux installation**

```powershell
Import-Module -Name 'Devolutions.PowerShell'
$DVLSPath = '/opt/devolutions/dvls'
$keysToImport = '/path/to/encryption.config'
Import-DPSEncryptionKeys -ApplicationPath $DVLSPath -Filename $keysToImport
```

When the keys were exported with `-Password`, add the same `-Password` to `Import-DPSEncryptionKeys`.

### Updating Devolutions Server for Linux <a href="#updating-devolutions-server-for-linux" id="updating-devolutions-server-for-linux"></a>

Do not extract the new `.tar.gz` archive directly over `/opt/devolutions/dvls`. Doing so replaces `appsettings.json`, which contains the connection strings and the Kestrel settings, and leaves the files of the previous version in place, which leaves the service unable to start. Always follow the update method detailed on this page.

#### Backing up the database

Back up the database before updating.

With SQL Server, run `sqlcmd` from the `mssql-tools18` package, on Linux or against a remote SQL Server:

```bash
/opt/mssql-tools18/bin/sqlcmd -S <MSSQLHOST> -U <DBUSERNAME> -P '<PASSWORD>' -C \
  -Q "BACKUP DATABASE [DSERVER] TO DISK = N'/var/opt/mssql/data/DSERVER-$(date +%F-%H%M).bak' WITH INIT, COMPRESSION;"
```

The full path to `sqlcmd` avoids the "command not found" error in non-login shells where `/etc/profile.d/mssql-tools.sh` has not been sourced. `-C` trusts the server certificate, which is required for local SQL Server installations that use a self-signed certificate. The backup directory must be writable by the `mssql` user: `/var/opt/mssql/data/` works out of the box. Make sure the `.bak` file exists and is not empty before continuing.

With PostgreSQL, run `pg_dump` with the database role, then validate the archive with `pg_restore --list`:

```bash
sudo mkdir -p /var/backups/dvls
sudo chown $(id -un) /var/backups/dvls
BACKUP_FILE=/var/backups/dvls/dvls-$(date +%F-%H%M).backup
pg_dump --format=custom --host=<PGHOST> --port=5432 --username=dvls_owner --dbname=dvls --file=$BACKUP_FILE
pg_restore --list $BACKUP_FILE > /dev/null && echo "Backup is valid: $BACKUP_FILE"
```

`pg_dump` prompts for the password of the role. The archive contains the database only: back up the encryption keys separately, since a database backup cannot be used without them.

#### Updating the installation

1. Stop the Devolutions Server service:

   ```bash
   sudo systemctl stop dvls.service
   sudo systemctl status dvls.service   # confirm inactive (dead)
   ```
2. Back up the installation and configuration files. `/opt/devolutions/dvls` is in mode 550 and owned by `dvls:dvls`, so the backup cmdlets must run as root. Start PowerShell with `sudo pwsh`, run this script, and keep the session open for the rest of the update:

   ```powershell
   Import-Module -Name 'Devolutions.PowerShell'
   $DVLSPath      = '/opt/devolutions/dvls'
   $BackupBase    = "/var/backups/dvls/$(Get-Date -Format 'yyyy-MM-dd-HHmm')"
   $BackupConfig  = Join-Path -Path $BackupBase -ChildPath 'config'
   $BackupInstall = Join-Path -Path $BackupBase -ChildPath 'installation'
   New-Item -ItemType Directory -Path $BackupConfig, $BackupInstall -Force | Out-Null
   Backup-DPSConfigurationFiles -ApplicationPath $DVLSPath -BackupConfigurationPath $BackupConfig
   Backup-DPSInstallationFiles  -ApplicationPath $DVLSPath -BackupPath $BackupInstall
   ```

   `Backup-DPSConfigurationFiles` copies `App_Data/encryption.config`, `appsettings.json`, and `web.config` when it exists, and fails if `encryption.config` is missing. `Backup-DPSInstallationFiles` copies the whole installation directory and requires an empty destination directory.
3. Download the new version, empty the installation directory except for `App_Data`, which contains `encryption.config` and the runtime state, then extract the new version:

   ```powershell
   $DVLSDownloadPath = '/tmp/dvls-linux-x64.tar.gz'
   Get-DPSProduct -Name 'DPSLinuxX64bin' -Destination $DVLSDownloadPath
   Get-ChildItem -Path $DVLSPath -Force | Where-Object { $_.Name -ne 'App_Data' } | Remove-Item -Recurse -Force
   & tar -xzf $DVLSDownloadPath -C $DVLSPath --strip-components=1
   Remove-Item -Path $DVLSDownloadPath
   ```
4. Restore the custom folders and the configuration:

   ```powershell
   Restore-DPSCustomFolders          -BackupPath $BackupInstall -ApplicationPath $DVLSPath
   Restore-DPSAnomalyDetectionFolder -BackupPath $BackupInstall -ApplicationPath $DVLSPath
   Restore-DPSConfigurationFiles     -BackupConfigurationPath $BackupConfig -ApplicationPath $DVLSPath
   ```

   `Restore-DPSConfigurationFiles` merges the saved `appsettings.json`, including the connection strings, into the `appsettings.json` of the new version, and copies the saved `encryption.config` to `App_Data`.
5. Update the database schema with the connection string of the restored `appsettings.json`:

   ```powershell
   $ConnectionString = (Get-DPSAppSettings -ApplicationPath $DVLSPath).ConnectionStrings.LocalSqlServer
   Update-DPSDatabase -ConnectionString $ConnectionString -InstallationPath $DVLSPath
   ```

   `Update-DPSDatabase` works with both SQL Server and PostgreSQL connection strings. It prints no output on success and displays the warning `Update failed.` on failure.
6. Re-apply ownership and permissions:

   ```powershell
   & chown -R dvls:dvls $DVLSPath
   & chmod -R o-rwx $DVLSPath
   & chmod 550 $DVLSPath
   & chmod 660 (Join-Path -Path $DVLSPath -ChildPath 'appsettings.json')
   & chmod 770 (Join-Path -Path $DVLSPath -ChildPath 'App_Data')
   # If a certs directory is in use:
   if (Test-Path -Path (Join-Path -Path $DVLSPath -ChildPath 'certs')) { & chmod 750 (Join-Path -Path $DVLSPath -ChildPath 'certs') }
   ```
7. Start the service and make sure it works correctly:

   ```powershell
   & systemctl start dvls.service
   & systemctl status dvls.service --no-pager
   & journalctl -u dvls.service -n 100 --no-pager
   ```

   The journal shows ***Migration done with status Done*** entries and no `[ERR]` lines when the update succeeded.

#### Troubleshooting <a href="#troubleshooting" id="troubleshooting"></a>

* **Service does not start, `appsettings.json` missing or empty:** copy `$BackupConfig/appsettings.json` to `/opt/devolutions/dvls`, re-apply ownership and permissions, then start the service.
* **Login works but entries fail to decrypt:** `encryption.config` was not restored. Copy `$BackupConfig/encryption.config` into `/opt/devolutions/dvls/App_Data/`, set its owner and mode with `chown dvls:dvls` and `chmod 660`, then restart the service.
* **Database schema errors at runtime:** `Update-DPSDatabase` was skipped or failed. Run `Update-DPSDatabase` again with the connection string of `appsettings.json`.
* **Full rollback:** stop the service, empty `/opt/devolutions/dvls` except `App_Data`, copy the contents of `$BackupInstall` back into `/opt/devolutions/dvls`, re-apply ownership and permissions, restore the database from the backup taken before the update, then start the service. With SQL Server, restore the `.bak` file with `sqlcmd` and `RESTORE DATABASE [DSERVER] FROM DISK = N'<backup file>' WITH REPLACE;`. With PostgreSQL, restore the archive with `pg_restore --clean --if-exists --single-transaction --host=<PGHOST> --username=dvls_owner --dbname=dvls <backup file>`. If the roles of the destination server differ from the source, add `--no-owner --role=dvls_owner`.

### PostgreSQL database maintenance <a href="#postgresql-database-maintenance" id="postgresql-database-maintenance"></a>

A PostgreSQL database used by Devolutions Server needs the following maintenance:

* **Autovacuum:** keep autovacuum enabled, which is the PostgreSQL default.
* **Statistics:** run `ANALYZE;` in the Devolutions Server database once after the installation and after large imports, for example `psql --host=<PGHOST> --username=dvls_owner --dbname=dvls -c "ANALYZE;"`.
* **Indexes:** PostgreSQL does not need the index rebuild and reorganize jobs used with SQL Server. If index bloat accumulates over time, run `REINDEX CONCURRENTLY` on the affected index.
* **Scheduling:** PostgreSQL has no equivalent of SQL Server Agent. Schedule custom maintenance tasks with cron.
* **Queries:** the identifiers of the Devolutions Server schema are lowercase in PostgreSQL. In `psql`, query `dbo.connections`, not `dbo.Connections`.

### Removing Devolutions Server <a href="#removing-dvls" id="removing-dvls"></a>

Stop and remove the service, the installation directory, and the ***dvls*** user and group by running this script in PowerShell, customized for the system:

```powershell
& sudo systemctl stop dvls.service
& sudo systemctl disable dvls.service
& sudo rm /etc/systemd/system/dvls.service
& sudo systemctl daemon-reload
& sudo rm -rf /opt/devolutions/dvls
& sudo userdel -r dvls
& sudo groupdel dvls
```

Then delete the Devolutions Server database.

#### Deleting the SQL Server database

This PowerShell script relies on the [DbaTools PowerShell module](https://dbatools.io/) to delete the database. It assumes `localhost` is the SQL Server installation and `DSERVER` the database name:

```powershell
Import-Module dbatools
$Credential = Get-Credential

Set-DbaToolsInsecureConnection

Remove-DbaDatabase -SqlInstance localhost -SqlCredential $Credential -Database 'DSERVER' -Confirm:$False
```

#### Deleting the PostgreSQL database

Run `dropdb` with the role that owns the database, or with an administrator role:

```bash
dropdb --host=<PGHOST> --port=5432 --username=dvls_owner dvls
```

`DROP DATABASE dvls;` in `psql` gives the same result, from a connection to another database such as `postgres`. To also delete the role, run `DROP ROLE dvls_owner;` with an administrator role.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.devolutions.net/server/knowledge-base/how-to-articles/install-devolutions-server-for-linux.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
