Docker-Compose Method - Recommended

Install Docker

Update the repo to get latest versions

sudo apt update

Install the latest version

sudo apt install docker.io

Set Docker to start on startup

sudo systemctl enable --now docker

Give your user permissions to docker, replacing user with your username

sudo usermod -aG docker user

Once you have run this command close and reopen your session if you accessing remotely. This is to apply the permissions in the above step

Test it has installed correctly by getting the docker version

docker --version

Docker Compose

I also install docker-compose as some dockers need you to compose from a yml file. This downloads v2.16.0, just change this if the version updates to a later version

sudo curl -L "https://github.com/docker/compose/releases/download/v2.16.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

Give permissions to this

sudo chmod +x /usr/local/bin/docker-compose

Test it has installed correctly by getting the docker-compose version

docker-compose --version

Install Vaultwarden

I keep all my dockers in a dockers folder in my home directory. If it doesn’t exist already, create this folder:-

mkdir ~/dockers

Now create a folder for Vaultwarden to live in.

mkdir ~/dockers/vaultwarden

Create a folder for the data

mkdir ~/dockers/vaultwarden/vw-data  

Change directory to this folder

cd ~/dockers/vaultwarden

Create a docker-compose.yml file

nano docker-compose.yml

Paste the following. Change the 8088 part of 8088:80 if you want it to listen on an alternative port to port 8088.

---
version: "2.1"
services:
   vaultwarden:
    image: vaultwarden/server
    container_name: vaultwarden
    volumes:
      - ./vw-data/:/data/
    ports:
      - 8088:80
      - 3012:3012
    restart: unless-stopped

Save the file with ctl + x, then y to save.

Run the docker-compose file with the following:-

docker-compose up -d
  1. Browse to the server ip and the port mentioned in the compose file, eg http://1.1.1.1:8088 and you should get the default dashboard.

Adding HTTPS using Nginx Proxy Manager

Install Nginx Proxy Manager

I keep all my dockers in a dockers folder in my home directory. If it doesn’t exist already, create this folder:-

mkdir ~/dockers

Now create a folder for Nginx Proxy Manager to live in.

mkdir ~/dockers/nginxproxymanager

Change directory to this folder

cd ~/dockers/nginxproxymanager

Create 2 directories, data and letsencrypt, for nginxproxymanager to save to:-

mkdir data letsencrypt

Create a docker-compose.yml file

nano docker-compose.yml

Paste the following. If you want to save the data to another directory change the volumes to point to the directories you want to.

version: '3'
services:
  app:
     image: 'jc21/nginx-proxy-manager:latest'
     restart: unless-stopped
     ports:
       - '80:80'
       - '81:81'
       - '443:443'
     environment:
       DB_MYSQL_HOST: "db"
       DB_MYSQL_PORT: 3306
       DB_MYSQL_USER: "npm"
       DB_MYSQL_PASSWORD: "npm"
       DB_MYSQL_NAME: "npm"
     volumes:
       - ./data:/data
       - ./letsencrypt:/etc/letsencrypt
  db:
     image: 'jc21/mariadb-aria:latest'
     restart: unless-stopped
     environment:
       MYSQL_ROOT_PASSWORD: 'npm'
       MYSQL_DATABASE: 'npm'
       MYSQL_USER: 'npm'
       MYSQL_PASSWORD: 'npm'
     volumes:
       - ./data/mysql:/var/lib/mysql

Save the file with ctl + x, then y to save.

Run the docker-compose file with the following:-

docker-compose up -d

First run Nginx Proxy Manger

Browse to http://serverip:81 and you will get the login screen. Default login is [email protected] password changeme. You will then get the edit user screen. Update the user email and press Save. You will then be prompted to change the password. Save this and you will get the main login screen.

Creating a wildcard certificate with DNS Challenge

Go to SSL Certificates, select “Add SSL Certificate”.

In the domain name type *.domainname, so *.llewellynhughes.co.uk for example. Edit the email if you need to. Tick “Use DNS Challenge”. Select your DNS provider. If your current DNS provider isn’t there, sign up for a free Cloudflare account and use their DNS, pointing your existing DNS Name Servers (ns) to Cloudflare. Agree to the terms and conditions and Save.

Your SSL Certificate should now be created and renewed automatically.

Proxying to an existing site

This presumes you have set your DNS record for your domain name. I use Adguard as my DNS server, so added a DNS Rewrite here to point back to my Nginx Proxy Manager. I have a DNS record for vault.llewellynhughes.co.uk, with a DNS rewrite for that URL to go to my server ip.

Go to Hosts, Proxy Hosts, Add Proxy Host.

Domain names, fill in the url you have setup. In my example it’s vault.llewellynhughes.co.uk.

Scheme is http Forward Hostname/IP is my server ip Port is my vault install port, so 8088.

Tick Block Known Exploits and WebSocket Support.

Leave custom locations blank. For other projects you might need to use this for subfolders.

SSL, select your SSL Certificate created. I tick Force SSL, HTTP/2 Support, HSTS Enabled.

Nothing in advanced. These are for advanced Nginx configs.

Once done, Click Save.

After this, test going to your https url and it should work

Docker run Method

Install Docker

Update the repo to get latest versions

sudo apt update

Install the latest version

sudo apt install docker.io

Set Docker to start on startup

sudo systemctl enable --now docker

Give your user permissions to docker, replacing user with your username

sudo usermod -aG docker user

Test it has installed correctly by getting the docker version

docker --version

Installing Vaultwarden

Download the latest Vaultwarden docker

docker pull vaultwarden/server:latest

Running Vaultwarden

Default port for Vaultwarden is port 80. I have something running on this so I want to map a different port to Vaultwarden. I chose 8088, so you can just change the below whatever port you need.

docker run -d --name vaultwarden -v /vw-data/:/data/ -p 8088:80 -p 3012:3012 vaultwarden/server:latest

Securing the server over dns

Add latest certbot repository

sudo apt-add-repository ppa:certbot/certbot

Install certbot

sudo apt install certbot

First get the certbot file

wget https://github.com/joohoi/acme-dns-certbot-joohoi/raw/master/acme-dns-auth.py

Change permissions on file

chmod +x acme-dns-auth.py

Edit file

sudo nano acme-dns-auth.py

Change first line to python3

#!/usr/bin/env python3

Move to the lets encrypt folder

sudo mv acme-dns-auth.py /etc/letsencrypt/

Create request (change vault.example.com for your url)

sudo certbot certonly --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth.py --preferred-challenges dns --debug-challenges -d \*.vault.example.com -d vault.example.com

It will then prompt you to add a cname to your dns host. Log into your dns, and create a cname. Press enter once complete. If it fails due to dns replication timings, just run the above command again.

sudo certbot certonly --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth.py --preferred-challenges dns --debug-challenges -d \*.vault.example.com -d vault.example.com

Once complete it will tell you where the certificate and chain have been saved. Change vault.example.com to the domain used above and it will probably be in there.

   Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/vault.example.com/fullchain.pem
   Your key file has been saved at
   /etc/letsencrypt/live/vault.example.com/privkey.pem

Creating nginx forward

Installing nginx if it’s not installed

  1. First, update the repo to get latest versions

    sudo apt update
    
  2. Install nginx

    sudo apt install nginx
    
  3. Enable the service to start on boot

    sudo systemctl enable nginx
    

Create the config file

sudo nano /etc/nginx/conf.d/vaultwarden.conf

Paste the below. Changing 8088 for the port you used in the docker above, changing server_name for your website url, and changing ssl_certificate and ssl_certificate_key to the paths certbox saved to above name

server {
  listen 443 ssl http2;
  server_name vault.example.com;

  ssl_certificate /etc/letsencrypt/live/vault.example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/vault.example.com/privkey.pem;

  # Specify SSL config if using a shared one.
  #include conf.d/ssl/ssl.conf;

  # Allow large attachments
  client_max_body_size 128M;

  location / {
    proxy_pass http://127.0.0.1:8088;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }

  location /notifications/hub {
    proxy_pass http://127.0.0.1:3012;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
   }

  location /notifications/hub/negotiate {
    proxy_pass http://127.0.0.1:8088;
  }

}

Open browser and run to https://vault.example.com (changing this for your website url) and you should get your login screen, and be able to create an account.