Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/AZhur771/pivpn-web/llms.txt

Use this file to discover all available pages before exploring further.

Updating PiVPN Web is a straightforward process: stop and remove the running container, pull the latest image from Docker Hub, and start a new container with the same configuration. Because the application is fully stateless at the image level (all runtime state lives in the SQLite database), no application data is lost during an update as long as the database file is persisted on the host.

Updating with docker run

Run the following commands in order to update a container that was started with docker run:
docker stop pivpn-web
docker rm pivpn-web
docker pull andrew771/pivpn-web
docker run -d -p 3001:3001 --name pivpn-web --restart=unless-stopped \
  -e SSH_HOST=<host> \
  -e SSH_USER=<user> \
  -e SSH_PASSWORD=<password> \
  -e ADMIN_USER=<admin> \
  -e ADMIN_PASSWORD=<password> \
  andrew771/pivpn-web
By default the SQLite database is stored inside the container at /app/pivpn.sqlite. When you run docker rm pivpn-web, that data is deleted along with the container. This means your user accounts, active sessions, and banned-client records will be lost.To persist the database across updates, mount a host file as a volume:
# Create the file on the host first so Docker doesn't create a directory
touch /path/to/pivpn.sqlite

docker run -d -p 3001:3001 --name pivpn-web --restart=unless-stopped \
  -v /path/to/pivpn.sqlite:/app/pivpn.sqlite \
  -e SSH_HOST=<host> \
  -e SSH_USER=<user> \
  -e SSH_PASSWORD=<password> \
  -e ADMIN_USER=<admin> \
  -e ADMIN_PASSWORD=<password> \
  andrew771/pivpn-web
With the volume in place, docker rm only removes the container — the database file on the host is untouched and automatically picked up when you start the new container.

Updating with Docker Compose

If you are using Docker Compose, updating is a two-command operation:
docker compose pull
docker compose up -d
docker compose pull fetches the latest image for every service defined in your docker-compose.yml. docker compose up -d recreates any containers whose image has changed, leaving containers with unchanged images untouched. To persist the database when using Compose, create the database file on the host first, then add a volume mount to your docker-compose.yml:
touch ./pivpn.sqlite
services:
  pivpn-web:
    image: andrew771/pivpn-web
    container_name: pivpn-web
    ports:
      - "51821:51821"
    restart: unless-stopped
    volumes:
      - ./pivpn.sqlite:/app/pivpn.sqlite
    environment:
      - SSH_HOST=192.168.1.2
      - SSH_USER=pi
      - SSH_PASSWORD=raspberry
      - ADMIN_USER=admin
      - ADMIN_PASSWORD=yourpassword

Image tags and version pinning

Docker Hub images for PiVPN Web are published with semver tags (e.g. andrew771/pivpn-web:1.1.2) automatically by the GitHub Actions workflow whenever a new version tag is pushed. The latest tag always points to the most recent release.
TagBehaviour
andrew771/pivpn-web / andrew771/pivpn-web:latestAlways pulls the most recent release. Easiest to keep up to date.
andrew771/pivpn-web:1.1.2Pinned to a specific release. Update by changing the tag explicitly.
Pinning to a specific version tag is recommended in production environments where unplanned changes to behaviour could cause issues.

Checking the currently running version

To see the image metadata for the running container, including the version label applied by the build pipeline:
docker inspect pivpn-web --format '{{json .Config.Labels}}'
This prints the OCI image labels in JSON format, which include the version and Git revision stamped into the image at build time by the docker/metadata-action step in the CI workflow.

Build docs developers (and LLMs) love