Hi everyone! Glad to have you here. On this page, I want to document what I built and tested on a small Ubuntu 22.04 VPS before the VPS service reaches the end of its subscription. Instead of letting the environment disappear without documentation, I decided to capture the main components, Docker containers, exposed services, and the purpose of each tool.
This activity was conducted for learning, security testing, compliance management, and experimenting with AI-related security tools. The environment was intentionally built using Docker, allowing each application to run as an isolated container that could be started, stopped, recreated, or removed independently.
What Was Running on the VPS?
The VPS hosted several applications. The main stack consisted of Eramba for GRC and compliance management, Open WebUI for the AI interface, Nginx Proxy Manager for reverse proxy and HTTPS management, and the supporting MySQL and Redis services required by Eramba. I also installed NVIDIA Garak for LLM security testing, while NocoDB and Metabase were used as additional experimentation platforms.
• Ubuntu 22.04 LTS – the operating system for the VPS.
• Docker – the container runtime used to deploy and isolate applications.
• Eramba – GRC, compliance, risk, policy, and control management.
• MySQL 8.0 – database service used by Eramba.
• Redis 7 – caching service used by Eramba.
• Open WebUI – web-based interface for interacting with AI models and APIs.
• Nginx Proxy Manager – reverse proxy and HTTPS management.
• NVIDIA Garak – LLM vulnerability and security testing framework.
• NocoDB – database-oriented collaboration and experimentation platform.
• Metabase – business intelligence and data visualization platform.
The Docker Environment
The environment was managed through Docker containers rather than installing each application directly on the Ubuntu host. This approach kept application components isolated from the underlying operating system and made the environment easier to maintain, recreate, and remove when required.
The following table summarizes the Docker containers identified in the environment and their observed runtime status.
|
Component
|
Container
|
Image
|
Observed Port
|
Observed Status
|
|
AI Interface
|
open-webui
|
ghcr.io/open-webui/open-webui:main
|
3000
→ 8080
|
Up / healthy
|
|
Reverse Proxy
|
npm
|
jc21/nginx-proxy-manager:latest
|
80,
443, 81
|
Up
|
|
GRC Platform
|
eramba
|
ghcr.io/eramba/eramba:latest
|
8085
→ 80
|
Up
|
|
Eramba Cache
|
eramba-redis
|
redis:7
|
Internal
|
Up
|
|
Eramba Database
|
eramba-mysql
|
mysql:8.0
|
Internal
|
Up / healthy
|
|
LLM Security Testing
|
garak
|
garak:latest
|
N/A
|
Exited (127)
|
|
Database Platform
|
nocodb
|
nocodb/nocodb:latest
|
8080
| Exited (143)
|
|
BI Platform
|
metabase
|
metabase/metabase
|
3000
|
Exited (143)
|
The
observed status represents the state of the Docker environment at the time of
documentation. Up indicates that the
container was running, while Up / healthy indicates
that the container was running and its configured health check was passing. The
Exited
(127) status observed for Garak indicates that the container had
stopped with exit code 127, which generally indicates that the requested
command or executable could not be found or executed successfully.
1. Ubuntu 22.04 as the Base Operating System
Ubuntu 22.04 was used as the base operating
system for the lab. The host provided the underlying CPU, memory, storage,
networking, and Docker runtime required by the applications.
Typical commands used to inspect the host
environment included:
cat /etc/*release
uname -a
free -h
df -h
docker version
docker info
2. Docker as the Application Platform
Docker became the main application platform on
the VPS. Instead of installing Eramba, Open WebUI, Nginx Proxy Manager, and
other applications directly into Ubuntu, each application was deployed as a
container or as part of a containerized stack.
The most useful commands for documenting the
environment are:
docker ps -a
docker images
docker network ls
docker volume ls
docker inspect <container_name>
docker logs <container_name>
3. Eramba – GRC and Compliance Platform
One of the main applications installed on the
VPS was Eramba. I used it as a practical lab for GRC activities such as
managing policies, controls, compliance requirements, risks, and audit-related
information.
The Eramba deployment consisted of three main
application containers/services:
• eramba – the main Eramba application.
• eramba-mysql – MySQL 8.0 database backend.
• eramba-redis – Redis 7 caching service.
The Eramba application was exposed through the
host on port 8085 and forwarded to port 80 inside the container. MySQL and Redis
were used as supporting backend services and were not treated as public-facing
application endpoints.
The basic Docker verification command was:
docker ps
docker logs eramba
docker logs eramba-mysql
docker logs eramba-redis
4. DNS Records - Cloudflare
Cloudflare was used to manage the DNS records for the lab domain and to point the application subdomains to the VPS public IP address. Each application was assigned a dedicated subdomain, making the services easier to access and manage through separate hostnames.
The relevant DNS records were configured as A records with Cloudflare Proxy enabled. The www hostname was configured as a CNAME pointing to the main domain.
The configured hostnames included:
With Cloudflare Proxy enabled, incoming requests were routed through Cloudflare before reaching the VPS. Nginx Proxy Manager then handled the routing from each hostname to its corresponding Docker service.
The simplified request flow was:
Client → Cloudflare DNS/Proxy → VPS → Nginx Proxy Manager → Docker Service
This DNS configuration provided the foundation for the HTTPS and reverse proxy setup described in the next section.
5. Nginx Proxy Manager – Reverse Proxy and HTTPS
Nginx Proxy Manager (NPM) was installed to
provide a convenient reverse proxy layer in front of web applications. This
allowed multiple web applications to be hosted on the same VPS while using
different hostnames and HTTPS configurations.
• HTTP: port 80
• HTTPS: port 443
• Nginx Proxy Manager administration: port 81
The following proxy host mappings were observed in the NPM configuration.
This configuration allowed external requests to reach the corresponding Docker services through HTTPS-enabled public hostnames without directly exposing each application's internal Docker service to the Internet.
6. Open WebUI – AI Experimentation Platform
Open WebUI was another major component of the lab. It provided a browser-based interface for working with AI models and API-based AI services. The container was running from the ghcr.io/open-webui/open-webui:main image.
The Docker mapping observed in the environment was:
Host port 3000 → Container port 8080
The lab did not contain an Ollama, vLLM, LocalAI, LiteLLM, TGI, or llama.cpp model-server container. The AI interface was therefore used with an external/API-based model backend rather than a model server running as another Docker container on this VPS.
7. NVIDIA Garak – LLM Security Testing
I also installed NVIDIA Garak as an LLM vulnerability scanning and security testing tool. The purpose was to experiment with security testing techniques against AI systems, including testing an OpenAI-compatible model/API endpoint.
During the lab work, Garak was used together with an external DeepSeek API endpoint. This was useful for understanding how an LLM security scanner can be connected to an API-based model rather than requiring the model itself to run on the VPS.
The Docker container was named garak. In the final Docker snapshot, the container was stopped and showed exit code 127. This documentation records that state as observed; it should not be interpreted as proof that every previous Garak test failed.

One of the security tests I tried with NVIDIA Garak was Prompt Injection testing. The goal was to check how an AI model responds when it receives specially crafted prompts designed to influence or override its intended behavior.
For example, a Prompt Injection test can be performed with a command such as:
garak \
--model_type openai.OpenAIReasoningGenerator \
--target_name openai/gpt-4o-mini \
--probes promptinject
The main parameters can be understood as follows:
--model_type specifies the Garak generator that will be used to communicate with the target model.--target_name specifies the target model to be tested.--probes promptinject tells Garak to run the Prompt Injection probe set.
In this example, Garak sends a series of test prompts to the target model and evaluates how the model responds to them. The purpose is not simply to check whether the model produces an incorrect answer, but to identify whether carefully crafted instructions can manipulate the model into ignoring or deviating from its intended behavior.
The result can then be used as an initial indication of how the AI application handles Prompt Injection attacks and whether additional controls are required around the model, application, system prompt, or user input handling.
8. NocoDB and Metabase – Additional Lab ExperimentsNocoDB and Metabase were also deployed during the lifetime of the VPS. They were part of the experimentation environment.
• NocoDB – deployed using the nocodb/nocodb:latest image.
• Metabase – deployed using the metabase/metabase image.
9. High-Level Architecture
The overall environment can be understood as a small Docker-based lab with a reverse proxy in front of web applications and dedicated backend containers for Eramba.
Additional security/AI tooling:
Garak -> external/API-based LLM backend
Additional lab applications:
NocoDB, Metabase
10. What we Learned from This VPS Lab
• Docker makes it much easier to separate applications and their dependencies on a small server.
• A reverse proxy is useful when several web applications need to share one public IP address.
• Applications such as Eramba often depend on supporting services such as MySQL and Redis, so documenting the whole stack is more useful than documenting only the main container.
• AI interfaces and AI security testing tools do not necessarily require the model to run locally; they can also work with API-based model backends.
• A VPS can be used as a compact security lab for combining GRC, web infrastructure, AI experimentation, and security testing.
• Keeping a Docker inventory before terminating a server makes it much easier to rebuild the environment later.
11. Useful Commands for Capturing a VPS Before
Retirement
If you are going to terminate or rebuild a VPS, I recommend capturing the following information first. These commands help preserve the technical inventory without needing to remember everything manually.
# Operating system
cat /etc/os-release
uname -a
# CPU and memory
lscpu
free -h
# Storage
df -h
# Docker version and configuration
docker version
docker info
# Containers
docker ps -a
# Images
docker images
# Networks
docker network ls
# Volumes
docker volume ls
# Container configuration
docker inspect <container_name>
# Logs
docker logs <container_name> > <container_name>-logs.txt
2>&1
12. Final Docker Inventory
The final inventory captured from docker ps -a showed the following notable containers:
garak
open-webui
npm
eramba
eramba-redis
eramba-mysql
nocodb
metabase
There were also several stopped temporary containers associated with earlier Python/package installation activities. Because their final purpose could not be reliably determined from docker ps -a alone, they are intentionally not described as production services in this document.
Thank you for taking the time to read through this write-up.
This lab was mainly a personal learning and experimentation project, and this documentation reflects what I tried, configured, and learned along the way. It is by no means a perfect setup or a definitive guide, but I hope some parts of it may be useful to others who are exploring similar technologies.
If you notice anything that could be improved, corrected, or approached differently, I would really appreciate your feedback. I am still learning, and sharing this is also a way for me to learn from others.
Thanks again for reading, and I hope you found something useful here. See you in the next experiment!
Tidak ada komentar:
Posting Komentar