InfrastructurelinuxubuntuDevOpssecurityplesk

Ubuntu 18.04 Server Initialization and Maintenance Guide

By Anthony Kung
Picture of the author
Published on
Domain
Infrastructure operations
Focus
Ubuntu server setup, hardening, and maintenance
Scope
SSH, Git, GPG, LVM, Plesk, and backup operations
System administrator preparing an Ubuntu server at a desk beside a server rack

Ubuntu 18.04 Server Initialization and Maintenance Guide

This is a practical baseline setup guide for a new Ubuntu 18.04 LTS server. It covers initial system updates, user creation, SSH key access, Git and GitHub configuration, GPG commit signing, LVM storage management, Plesk maintenance, and Acronis Backup Agent installation.

The goal is simple: get a server into a state that is secure enough to manage, predictable enough to maintain, and ready for web hosting or application deployment.

This article was first published on November 12, 2020 and last updated on November 6, 2022. It reflects an Ubuntu 18.04 and Plesk-era workflow. For new servers today, use a newer supported Ubuntu LTS release and confirm the current vendor documentation before applying the same steps blindly.

System administrator preparing an Ubuntu server at a desk beside a server rack
System administrator preparing an Ubuntu server at a desk beside a server rack

1. Update the server

After logging in to a newly provisioned server, update the package list and upgrade installed packages:

apt update
apt upgrade -y
apt autoremove -y

If a kernel update or another important system package changed, reboot the server:

reboot

After the reboot, log back in and continue the setup.

2. Change the root password

If the server was created with a temporary root password, change it immediately:

passwd

Use a strong password even if you plan to rely on SSH key authentication later. The root account may still be needed through the hosting provider's recovery console.

3. Create an administrator user

The root account should not be your normal daily login. Create a regular user and give it sudo access:

adduser anthony

Add the user to the sudo group:

usermod -aG sudo anthony

Then test the new user:

su - anthony
sudo whoami

Expected output:

root

If this works, the new user can handle administrative tasks through sudo.

4. Configure SSH key login

SSH keys are safer and more convenient than password-based SSH login.

On your local machine, generate a new SSH key:

ssh-keygen -t ed25519 -C "hi@anth.dev"

If Ed25519 is not supported by an older client or server, use a 4096-bit RSA key instead:

ssh-keygen -t rsa -b 4096 -C "hi@anth.dev"

Copy the SSH public key to the server:

ssh-copy-id -i ~/.ssh/id_ed25519.pub anthony@server.example.com

For RSA:

ssh-copy-id -i ~/.ssh/id_rsa.pub anthony@server.example.com

If ssh-copy-id is not available, add the key manually on the server:

mkdir -p ~/.ssh
chmod 700 ~/.ssh
nano ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

Paste the public key into authorized_keys.

Do not paste the private key. The private key should stay only on your local machine.

5. Harden SSH access

Once SSH key login works, disable root SSH login and password-based SSH login.

Edit the SSH server configuration:

sudo nano /etc/ssh/sshd_config

Recommended settings:

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes

Validate the SSH configuration before reloading the service:

sudo sshd -t

Reload SSH:

sudo systemctl reload sshd

Keep the current terminal open and test a second SSH session before closing anything:

ssh anthony@server.example.com

That extra test prevents accidental lockout.

6. Set the default editor

Set vim as the default editor for the current user:

nano ~/.bashrc

Add:

export VISUAL=vim
export EDITOR="$VISUAL"

Reload the shell configuration:

source ~/.bashrc

Set Git's editor too:

git config --global core.editor "vim"

7. Configure Git identity

Set the default Git name and email:

git config --global user.name "Anthony Kung"
git config --global user.email "hi@anth.dev"
git config --global core.editor "vim"
git config --global color.ui auto

Check the configuration:

git config --global --list

8. Configure GitHub authentication

Avoid relying on long-term cached GitHub passwords. SSH keys are usually the cleaner option for server-side Git access.

Set the repository remote to use SSH:

git remote set-url origin git@github.com:username/repository.git

Test GitHub SSH access:

ssh -T git@github.com

If HTTPS must be used, configure Git's credential cache with a reasonable timeout:

git config --global credential.helper 'cache --timeout=86400'

That caches credentials for one day.

Avoid extremely long cache durations. They are convenient, but they weaken the security boundary of the account.

9. Generate a GPG key for signed commits

Generate a GPG key:

gpg --full-generate-key

If the system uses an older GPG version:

gpg --gen-key

List secret keys:

gpg --list-secret-keys --keyid-format LONG

Example output:

sec   rsa4096/ABCDEF1234567890 2020-01-01 [SC]

The key ID is the long value after the slash:

ABCDEF1234567890

Export the public key:

gpg --armor --export ABCDEF1234567890

Add the public key to GitHub.

Configure Git to use the signing key:

git config --global user.signingkey ABCDEF1234567890
git config --global commit.gpgsign true
git config --global user.email "hi@anth.dev"

Test GPG signing:

echo "test" | gpg --clearsign

10. Configure GPG agent

Edit the GPG configuration file:

nano ~/.gnupg/gpg.conf

Add:

use-agent

Edit the GPG agent configuration:

nano ~/.gnupg/gpg-agent.conf

Recommended cache settings:

default-cache-ttl 28800
max-cache-ttl 86400
default-cache-ttl-ssh 28800
max-cache-ttl-ssh 86400

That lets the passphrase stay cached for a work session, but not indefinitely.

Restart the GPG agent:

gpgconf --kill gpg-agent
gpgconf --launch gpg-agent

Add the GPG terminal setting to ~/.bashrc:

nano ~/.bashrc

Add:

GPG_TTY=$(tty)
export GPG_TTY

Reload:

source ~/.bashrc

Test signing again:

echo "test" | gpg --clearsign

If needed, test file signing:

echo "test" > test.txt
gpg -s test.txt

11. Set a Git commit template

Create a global commit message template:

nano ~/.gitmessage

Example:

Short summary under 50 characters

Why:
- 

What changed:
- 

Testing:
- 

Enable the template:

git config --global commit.template ~/.gitmessage

12. Prepare Git for large files

For large binary files, use Git LFS instead of committing those files directly into the repository.

Install Git LFS:

sudo apt update
sudo apt install git-lfs -y

Enable Git LFS:

git lfs install

Inside the repository, track large file types:

cd /path/to/repository
git lfs track "*.zip"
git lfs track "*.psd"
git lfs track "*.bin"
git add .gitattributes
git commit -m "Configure Git LFS"

This setting sometimes appears as a temporary workaround for large HTTP pushes:

git config --global http.postbuffer 524288000

It should not be the default solution for large files. Git LFS is the better approach for binary assets and large project files.

13. Check current storage layout

Before making LVM changes, inspect the current disk and volume layout:

lsblk -f
sudo pvs
sudo vgs
sudo lvs
df -h

That makes it less likely you modify the wrong disk or logical volume.

14. Create a new logical volume

Create a logical volume:

sudo lvcreate -n data -L 100G hdd

Create an ext4 filesystem:

sudo mkfs.ext4 /dev/hdd/data -L data

Create a mount point:

sudo mkdir -p /data

Mount the logical volume:

sudo mount /dev/hdd/data /data

Verify it:

df -h
lsblk -f

15. Configure automatic mounting

Edit /etc/fstab:

sudo nano /etc/fstab

A direct device path works:

/dev/hdd/data  /data  ext4  noatime,errors=remount-ro  0  2

A UUID-based entry is safer because device names can change.

Find the UUID:

sudo blkid /dev/hdd/data

Example /etc/fstab entry:

UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx  /data  ext4  noatime,errors=remount-ro  0  2

Test before rebooting:

sudo mount -a

Check mounted filesystems:

findmnt

16. Migrate data between logical volumes

Create temporary mount points:

mkdir ~/oldLV
mkdir ~/newLV

Mount both logical volumes:

sudo mount /dev/oldvg/oldlv ~/oldLV
sudo mount /dev/newvg/newlv ~/newLV

Use rsync instead of cp for server data migration:

sudo rsync -aAXH --numeric-ids --info=progress2 ~/oldLV/ ~/newLV/

Unmount both volumes:

sudo umount ~/oldLV
sudo umount ~/newLV

For application data, databases, mailboxes, or web hosting directories, stop the related services before the final sync.

17. Extend a logical volume

To increase the size of a logical volume and resize the filesystem at the same time:

sudo lvresize --resizefs --size +50G /dev/hdd/data

To use all free space in the volume group:

sudo lvresize --resizefs --extents +100%FREE /dev/hdd/data

Verify the result:

df -h
lsblk -f
sudo lvs

18. Reduce a logical volume

Reducing a logical volume is dangerous. Back up the data first.

Unmount the filesystem:

sudo umount /dev/hdd/data

Check the filesystem:

sudo e2fsck -f /dev/hdd/data

Shrink the filesystem first:

sudo resize2fs /dev/hdd/data 80G

Then shrink the logical volume:

sudo lvreduce -L 80G /dev/hdd/data

Check the filesystem again:

sudo e2fsck -f /dev/hdd/data

Mount it again:

sudo mount /dev/hdd/data /data

A combined command may also be used:

sudo lvreduce --resizefs -L 80G /dev/hdd/data

Do not shrink XFS filesystems. XFS supports growing, but not shrinking.

19. Add a new drive to LVM

Identify the new disk:

lsblk

Partition the disk:

sudo fdisk /dev/sdb

Inside fdisk:

n
p
ENTER
ENTER
ENTER
t
8e
p
w

Create the physical volume:

sudo pvcreate /dev/sdb1

Extend the existing volume group:

sudo vgextend hdd /dev/sdb1

Extend a logical volume to use the new free space:

sudo lvresize --resizefs --extents +100%FREE /dev/hdd/data

Verify the result:

lsblk -f
df -h
sudo pvs
sudo vgs
sudo lvs

20. Remove a logical volume

Unmount the logical volume:

sudo umount /dev/hdd/data

Remove it:

sudo lvremove /dev/hdd/data

This permanently removes the logical volume. Confirm backups before running it.

21. Update Plesk

Before major Plesk updates, take a backup or server snapshot.

Update Plesk:

sudo plesk installer --select-release-latest --upgrade-installed-components

If the update is locked:

BUSY: Update operation was locked by another update process.
exit status 1

Stop the existing installer process:

sudo plesk installer stop

Then retry the update:

sudo plesk installer --select-release-latest --upgrade-installed-components

If the package manager is in a broken state, repair it first:

sudo dpkg --configure -a
sudo apt -f install
sudo apt update

22. Install Node.js on a Plesk server

For Plesk-managed hosting, prefer using Plesk's Node.js support when available. That keeps the application runtime easier to manage from the Plesk interface.

If system packages are required, install Node.js carefully and avoid mixing multiple unmanaged Node.js installations.

The following dependency-based install may be needed for older package setups:

sudo apt-get install libssl1.0-dev
sudo apt-get install nodejs-dev
sudo apt-get install node-gyp
sudo apt-get install npm

After installation, verify versions:

node -v
npm -v

For production applications, make sure the Node.js version used by the application matches the one configured in Plesk or the process manager.

23. Upgrade MariaDB on a Plesk server

MariaDB upgrades on Plesk servers should be handled carefully because Plesk and hosted websites depend on the database service.

Before upgrading, create database backups:

sudo plesk db dump psa > ~/psa-backup.sql
sudo mysqldump --all-databases --single-transaction --routines --events > ~/all-databases-backup.sql

Also take a full server snapshot if available.

Then follow the Plesk-supported upgrade path for the installed Plesk version, Ubuntu version, and MariaDB version.

Do not blindly follow a generic MariaDB upgrade guide on a Plesk server. Plesk-managed environments may have additional repositories, packages, and service dependencies.

24. Install Acronis Backup Agent

If the installer is provided as a shell script:

sudo bash ./path/to/installer.sh

If the installer is provided as an executable:

chmod +x ./path/to/installer
sudo ./path/to/installer

If prompted for an activation token, provide the token from the Acronis management portal.

After installation, confirm that the server appears in the Acronis console and run a test backup.

25. Uninstall Acronis Backup Agent

Run the Acronis uninstaller:

sudo /usr/lib/Acronis/BackupAndRecovery/uninstall/uninstall

If full removal is supported:

sudo /usr/lib/Acronis/BackupAndRecovery/uninstall/uninstall -a

After uninstalling, verify that the related services are gone:

systemctl list-units | grep -i acronis

26. Final server checklist

Check system information:

hostnamectl
lsb_release -a
whoami
groups
sudo whoami

Check updates:

sudo apt update
sudo apt upgrade

Check SSH:

sudo sshd -t
sudo systemctl status ssh

Check disk and LVM status:

lsblk -f
df -h
sudo pvs
sudo vgs
sudo lvs

Check Git:

git --version
git config --global --list

Check GPG:

gpg --version
echo "test" | gpg --clearsign

Check Plesk:

plesk version

27. Notes and cautions

Use a normal sudo user instead of logging in as root for daily work.

Confirm SSH key login before disabling password login or root login.

Do not cache GitHub credentials for extremely long periods. SSH keys or short credential cache durations are safer.

Do not cache GPG passphrases indefinitely. A daily cache is usually enough.

Use Git LFS for large binary files instead of pushing large assets directly into Git.

Use rsync instead of cp -rp for serious server data migration.

Be careful when shrinking LVM volumes. Extending is usually simple, but reducing can destroy data if the filesystem and logical volume sizes are not handled correctly.

For Plesk servers, prefer Plesk-supported workflows for updates, Node.js, MariaDB, and service management. Generic Linux tutorials can break Plesk-managed environments.

Stay Tuned

Want to stay up to date with the latest posts?
The best articles, links and news delivered once a week to your inbox.