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​