SENSE-O on Docker (WIP)
This document is a deployment template for the SENSE Orchestrator and remains WIP. It describes how to deploy (IPv4 and IPv6) StackV using Docker and how to verify connectivity. It also includes notes for troubleshooting Dockerâs IPv6 limitations.
Installing Docker
Section titled âInstalling Dockerâ-
sudo yum install -y docker(or use your distroâs package manager) -
sudo systemctl enable docker && sudo systemctl start docker
IPv4 Deployment
Section titled âIPv4 DeploymentâTODO
Credential Store Configuration
Section titled âCredential Store ConfigurationâConfigure the credential store before enabling a workflow that uses stored tokens.
-
Choose a current key source and prepare its versioned value as described in Configure the Credential Store. Retain existing keys if the database already contains credentials; use the rotation procedure when changing keys.
-
For inline configuration, set
SENSE_CRED_KEYindocker/.env. The basedocker-compose.local.ymlanddocker-compose.remote.ymlpass this value andSENSE_CRED_KEY_PREVIOUSto the application. Keep.envprotected and out of version control. -
For file configuration, add a Compose override, for example
docker/docker-compose.credential-files.yml:services:app:environment:SENSE_CRED_KEY: ""SENSE_CRED_KEY_FILE: /run/secrets/sense_cred_keyvolumes:- /path/to/current-credential-key:/run/secrets/sense_cred_key:roReplace the host path with an existing protected key file readable by the applicationâs container user. The empty inline value prevents a conflict with
SENSE_CRED_KEYfrom the base file. The base Compose files do not forward_FILEvariables or mount files: adding a path to.envalone is insufficient.If previous keys are needed, also clear
SENSE_CRED_KEY_PREVIOUS, setSENSE_CRED_KEY_PREVIOUS_FILEto its container path, and add a read-only mount for that file. Previous-key file contents use the format in the configuration guide. -
From the StackV
dockerdirectory, recreate the application after inline configuration changes:Terminal window docker compose -f docker-compose.local.yml up -d --force-recreate appFor file configuration, include the override on every recreation:
Terminal window docker compose -f docker-compose.local.yml -f docker-compose.credential-files.yml up -d --force-recreate appSubstitute
docker-compose.remote.ymlwhen using that deployment template, and retain any other Compose files used by the deployment.docker compose restartalone does not refresh the containerâs environment. -
As a SENSE System Admin, open Admin Settings â Credentials. Confirm Store Active, the expected Key Version, any needed previous keys marked LOADED, and no key or verification warnings. See credential-store diagnostics if these checks fail.
IPv6 Deployment
Section titled âIPv6 DeploymentâDocker Host Configuration for IPv6
Section titled âDocker Host Configuration for IPv6âFor Docker containers to communicate over IPv6, the Docker daemon must be configured to manage an IPv6 subnet.
-
Edit the Docker Daemon Configuration File:
Open or create the file /etc/docker/daemon.json. Add the following configuration to enable IPv6 and assign a default address pool for Docker networks.
{"ipv6": true,"fixed-cidr-v6": "2001:db8:21::/64"}Note: 2001:db8::/32 is a prefix reserved for documentation. For production, it is recommended to use a Unique Local Address (ULA) prefix from your organizationâs assigned block.
-
Apply the Configuration
Restart the Docker service for the changes to take effect.
sudo systemctl restart docker
Verifying Bidirectional IPv6 Connectivity
Section titled âVerifying Bidirectional IPv6 ConnectivityâVerification is a two-part process to confirm traffic can flow in both directions.
Part A: Outbound Verification (Client \u2192 StackV Server)
This tests if you can reach the containerized service from an external machine (e.g., your laptop).
-
Check Local Machineâs IPv6 Connectivity:
Get your public IPv6 address
curl -6 -s https://v6.ident.me
-
Resolve the Serverâs IPv6 Address:
Confirm the AAAA DNS record points to the hostâs IPv6
dig AAAA <YOUR_HOSTNAME_OR_DOMAIN> +short
-
Test Network and Port Reachability:
Ping the host machine
ping -6 <HOST_IPV6>
Check if the application port (8443) is open
nc -6vz <HOST_IPV6> <APP_PORT>
-
Test the Application Service:
Connect to the application using its hostname
curl -6 -v -k https://<YOUR_HOSTNAME_OR_DOMAIN>:<APP_PORT>/StackV-web/portal/
Or, connect directly using the hostâs IPv6 address (note the brackets)
curl -6 -v -k "https://[<HOST_IPV6>]:<APP_PORT>/yourapp/portal/"
Part B: Inbound Verification (StackV Server \u2192 Client)
This crucial test confirms the return path is clear by having the remote server connect back to a service running on your local machine.
-
Prepare Your Local Machine:
- Find your current global IPv6 address: curl -6 https://v6.ident.me/
- Ensure your local firewall is not blocking incoming traffic on test ports (e.g., 44444, 8080).
-
Set Up Test Listeners on Your Local Machine:
-
Option 1: Simple TCP Listener with ncat
On your local machine, listen on port 44444 for any IPv6 connection
sudo ncat -6 -l -p 44444 --keep-open
Verify with:
ss -lntp | grep 44444
-
Option 2: HTTP Server with Docker (nginx)
Run a temporary nginx container publishing port 8080 on IPv6
docker run -d --name test-nginx -p "[::]:8080:80" nginx:alpine
Verify it is listening on [::]:8080
ss -lntp | grep 8080
-
-
Execute the Test from the Remote Server:
- SSH into the remote server where StackV is running.
- Use your local machineâs IPv6 address (
LOCAL_IPV6) found in step 1.
Test the ncat listener
nc -6vz [<LOCAL_IPV6>] 44444
Test the nginx HTTP server
curl -6 -v http://[<LOCAL_IPV6>]:8080
Expected results: nc should report âConnection succeededâ, and curl should return the âWelcome to nginx!â HTML page. If these tests time out, proceed to troubleshooting.
Troubleshooting Common Issues
Section titled âTroubleshooting Common Issuesâ-
Issue: Inbound Tests Fail (Timeout)
-
Cause: This is often due to asymmetric routing, especially if your local machine is on a VPN. The serverâs connection request (SYN) arrives via your Wi-Fi/Ethernet, but your machineâs reply (SYN-ACK) is incorrectly routed out through the VPN, breaking the handshake.
-
Diagnosis: On your local machine, use tcpdump to watch for incoming packets: sudo tcpdump -i any -n âhost
REMOTE_HOST_IPV6and portTEST_PORTâ. If you see a SYN packet arrive but no reply is sent from your physical interface, asymmetric routing is the likely cause. -
Solution: Add a specific route on your local machine to force replies to the server to bypass the VPN. Find your default gateway (ip -6 route | grep default) and add the route:
sudo ip -6 route add <REMOTE_HOST_IPV6> via <your_gateway_link_local_address> dev <your_physical_interface
-
-
Issue: Service is Not Listening on IPv6
-
Cause: Docker did not bind the port to the hostâs IPv6 address.
-
Diagnosis: On the remote host, run ss -lntp | grep
APP_PORT. The output must show a listener on [::]:APP_PORTor :::APP_PORT. If it only shows 0.0.0.0:APP_PORT, it is only listening on IPv4. -
Solution: Ensure your docker-compose.yml uses the
[::]:<HOST_PORT>:<CONTAINER_PORT>syntax in the ports section. This explicitly tells Docker to create an IPv6 binding.
-
