Skip to main content

Install HashiCorp Vault on Ubuntu

This guide explains how to install and configure HashiCorp Vault on an Ubuntu 24.04 LTS server. Vault centralizes the management of secrets (API keys, passwords, TLS certificates) securely.

Modern applications rely on secrets: API keys, database passwords, TLS certificates, encryption keys. Storing them in code or in plain text is a risk. Vault provides secure storage, dynamic credential generation, encryption as a service, and fine-grained access control.

Order a Server

To host your Vault instance, HostMyServers offers several suitable options:

Prerequisites

  • SSH access as root or user with sudo
  • Ubuntu 24.04 LTS 64-bit system
  • A DNS A record pointing to the server IP (for Let's Encrypt)
  • Ports 8200 (Vault HTTPS) and 80 (Certbot, temporary) accessible

Required Configuration

ComponentMinimumRecommended
RAM512 MB1-2 GB
CPU1 core2 cores
Storage5 GB10 GB
Network100 Mbps1 Gbps
Default port

Vault listens on port 8200 over HTTPS. The web UI and API use this port.

Connect to the Server

Connect via SSH to your Ubuntu server (default port 22, or custom port / PEM key depending on your setup):

ssh user@server_ip_address

System Update

Update the package list before installing Vault:

sudo apt update
sudo apt upgrade -y

Install Vault from HashiCorp Repository

HashiCorp provides an official APT repository to install the latest stable version of Vault.

Install required packages

sudo apt install -y gnupg curl lsb-release

Add HashiCorp GPG key

This key verifies that packages actually come from HashiCorp:

curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg

Add HashiCorp repository

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list

Install Vault

sudo apt update
sudo apt install -y vault

Verify installation

vault --version

You should see a line like: Vault v1.20.x (...).

Enable autocompletion (optional)

vault -autocomplete-install
exec $SHELL

Firewall Configuration

Open the ports needed for Vault and for Let's Encrypt certificate issuance:

sudo ufw allow 8200/tcp
sudo ufw allow 80/tcp
sudo ufw reload
Port 80

Port 80 is used temporarily by Certbot for HTTP validation. You can close it after obtaining certificates if you don't need it otherwise.

TLS Certificates with Let's Encrypt

For production, Vault must be served over HTTPS. We use Certbot to obtain free Let's Encrypt certificates.

Install Certbot

sudo apt install -y certbot

Obtain a certificate for your domain

Replace vault.yourdomain.com with your subdomain and your-email@example.com with your email:

sudo certbot certonly --standalone -d vault.yourdomain.com --non-interactive --agree-tos --email your-email@example.com

Certificates are created in /etc/letsencrypt/live/vault.yourdomain.com/.

Prepare TLS directory for Vault

The Vault package usually creates a system user vault. If needed, create it: sudo adduser --system --group vault. Then create the certificate directory and copy the files:

sudo mkdir -p /opt/vault/tls
sudo mkdir -p /opt/vault/data

sudo cp /etc/letsencrypt/live/vault.yourdomain.com/fullchain.pem /opt/vault/tls/cert.pem
sudo cp /etc/letsencrypt/live/vault.yourdomain.com/privkey.pem /opt/vault/tls/key.pem

sudo chown -R vault:vault /opt/vault
sudo chmod 600 /opt/vault/tls/cert.pem /opt/vault/tls/key.pem
Replace the domain

Adapt vault.yourdomain.com to your actual domain in all commands and files below.

Certificate renewal script

So that Vault always uses up-to-date certificates after a Let's Encrypt renewal:

sudo tee /etc/letsencrypt/renewal-hooks/deploy/vault.sh << 'EOF'
#!/bin/bash
cp /etc/letsencrypt/live/vault.yourdomain.com/fullchain.pem /opt/vault/tls/cert.pem
cp /etc/letsencrypt/live/vault.yourdomain.com/privkey.pem /opt/vault/tls/key.pem
chown -R vault:vault /opt/vault/tls
chmod 600 /opt/vault/tls/*
systemctl reload vault
EOF
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/vault.sh

Remember to replace vault.yourdomain.com in this script with your domain.

Close port 80 after obtaining certificates (optional)

If you no longer need port 80:

sudo ufw delete allow 80/tcp
sudo ufw reload

Configure Vault for Production

The configuration file controls storage, network listeners, and security settings.

Backup default configuration

sudo cp /etc/vault.d/vault.hcl /etc/vault.d/vault.hcl.backup

Create production configuration

Replace vault.yourdomain.com with your domain:

sudo tee /etc/vault.d/vault.hcl << 'EOF'
# Vault production configuration
ui = true

disable_mlock = true

storage "file" {
path = "/opt/vault/data"
}

listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/opt/vault/tls/cert.pem"
tls_key_file = "/opt/vault/tls/key.pem"
tls_min_version = "tls12"
tls_cipher_suites = "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
tls_require_and_verify_client_cert = "false"
tls_disable_client_certs = "true"
}

api_addr = "https://vault.yourdomain.com:8200"
cluster_addr = "https://vault.yourdomain.com:8201"
EOF
ParameterDescription
uiEnable web UI
storage "file"Local storage backend (encrypted data)
listener "tcp"HTTPS listener on port 8200
api_addrPublic API URL (for clients)

Start Vault

sudo systemctl enable vault
sudo systemctl restart vault
sudo systemctl status vault

Status should show active (running).

Environment Variables for CLI

So the Vault client knows where to connect:

echo 'export VAULT_ADDR="https://vault.yourdomain.com:8200"' >> ~/.bashrc
source ~/.bashrc

Verify:

echo $VAULT_ADDR
vault status

Before initialization you should see e.g.: Initialized: false, Sealed: true.

Initialize and Unseal

Vault starts in a sealed state: data is present but cannot be decrypted. Initialization creates unseal keys and the root token.

Understanding the process

When you initialize, Vault creates:

  • Master key: encrypts all secrets
  • Unseal keys: 5 keys from Shamir's algorithm; 3 of 5 are required to unseal Vault
  • Root token: initial admin token
Save the keys

Unseal keys and root token are shown only once. Store them in separate, secure locations. Without them, data remains inaccessible.

Initialize Vault

vault operator init

Note the 5 unseal keys and the Initial Root Token. Do not share them or commit them to a repository.

Unseal Vault

You must provide 3 different keys (one per run):

vault operator unseal

Paste the first key when prompted. Then run twice more with two other keys:

vault operator unseal
vault operator unseal

When unsealing succeeds, vault status shows: Sealed: false.

Log in with root token

vault login

Enter the Initial Root Token when prompted.

Access the Web UI

  1. Open a browser and go to: https://vault.yourdomain.com:8200
  2. Choose Token as the method
  3. Enter your root token and submit

You reach the Vault dashboard: status, secrets engines (KV, etc.) and access policies.

HTTPS

Vault only listens over HTTPS on port 8200. Use https:// in the URL and accept the certificate if needed (Let's Encrypt is recognized by browsers).

Useful Commands

CommandDescription
vault statusVault status (initialized, sealed, etc.)
vault operator unsealProvide an unseal key
vault loginLog in with a token
sudo systemctl status vaultsystemd service status
sudo systemctl restart vaultRestart Vault

File Structure

PathDescription
/etc/vault.d/vault.hclConfiguration file
/opt/vault/data/Vault data (encrypted)
/opt/vault/tls/TLS certificate and key

Troubleshooting

Service won't start

  • Check logs: sudo journalctl -u vault.service -n 50
  • Ensure paths in vault.hcl exist and user vault has rights on /opt/vault
  • Check syntax: vault server -config=/etc/vault.d/vault.hcl (debug mode, then stop)

TLS or certificate error

  • Ensure cert.pem and key.pem are in /opt/vault/tls/ and readable by user vault
  • Test renewal: sudo certbot renew --dry-run

Vault stays sealed after reboot

After each server reboot, Vault is sealed again. You must provide 3 keys again with vault operator unseal. To automate unsealing (less secure), you can use auto-unseal (e.g. with a cloud KMS); see Vault documentation.

References