Interesting, I’m already building the binaries using goreleaser, so adding the docker images should be fairly easy. If you have an example I can copy paste, that would be perfect ![]()
Its not mine (i have ko running without goreleaser on gitlab with private registries only) but after taking a peek this should be a good source to copy from https://goreleaser.com/blog/goreleaser-ko/
decide where the images should be hosted and set KO_DOCKER_REPO, add the kos: block to your .goreleaser.yaml
And to make startup easy set an entrypoint like
ko_data:
# Run PocketBase directly with args
entrypoint:
- /ko-app/opensoho
args:
- serve
- "--http=0.0.0.0:8090"
- "--dir=/pb_data"
to run the container mount a volume to pb_data and hand in the OPENSOHO_SHARED_SECRET
I know, but since someone posted iperf3 results with and without NSS on wireless performance there’s a small voice in the back of my head that would prefer that result in favor of running a default but fully stock and supported OpenWRT release. But I realize all to well that community effort for NSS hacks will cease at some point. I plan on trying a Cudy WR3000H in a few months and expand on that. Managing those with a tool like OpenSOHO would make managing those devices a lot easier.
For those interested in running OpenSOHO in a container, I present to you the first container image:
ghcr.io/opensoho/opensoho-da212a3daf23f854555a4afaf75d4a02:v0.6.0
Somehow goreleaser or ko added a hash behind the name, I’ll fix that in a later release.
Pushing to multiple registries without the automated ko generated name+hash was the fiddly part. "bare" pushes to the repository without added name components.
bare: true
The documentation suggests that goreleaser handles that detail nicely
# Repositories to push to.
#
# First one will be used on Ko build, the other ones will be copied from the
# first one using crane.
pc@pc-Client:~/opensoho$ ssh root@10.20.20.5
root@10.20.20.5's password:
BusyBox v1.36.1 (2025-07-08 07:41:44 UTC) built-in shell (ash)
_______ ________ __
| |.-----.-----.-----.| | | |.----.| |_
| - || _ | -__| || | | || _|| _|
|_______|| __|_____|__|__||________||__| |____|
|__| W I R E L E S S F R E E D O M
-----------------------------------------------------
OpenWrt 24.10.2, r28739-d9340319c6
-----------------------------------------------------
root@OpenWrt_Access_Point_1:~# uci delete openwisp.http.uuid
uci: Entry not found
root@OpenWrt_Access_Point_1:~# uci delete openwisp.http.key
uci: Entry not found
root@OpenWrt_Access_Point_1:~# cat /etc/config/openwisp
config controller 'http'
option enabled 'monitoring'
option url 'http://0.0.0.0.0:8090'
option shared_secret 'randompassphrase'
option mac_interface 'eth0'
option interval '30'
root@OpenWrt_Access_Point_1:~# cat /etc/config/openwisp-monitoring
config monitoring 'monitoring'
option monitored_interfaces '*'
option interval '300'
option verbose_mode '0'
option required_memory '0.05'
option max_retries '5'
#option bootup_delay '10'
root@OpenWrt_Access_Point_1:~#
I have this dump access point behind a pfsense firewall. I did all the steps to install OpenSOHO but the dump access point does not appear as a device on OpenSOHO. I tried to reregister the device but OpenWrt responded "uci entry not found"
I'm not sure about the other options. (shared_secret looks good)
But this should point to the IP where you run the opensoho controller.
I made the changes but nothing appears on devices.
Then it's time for debugging why it is not appearing.
You started OpenSOHO like this?
OPENSOHO_SHARED_SECRET=randompassphrase ./opensoho serve --http 0.0.0.0:8090
Can you access the opensoho web interface from a different device then the one its running on?
Do you see access Logs on the console where opensoho runs? Requests from your browser? And requests from the dumb AP?
Is there anything in the logs of the dumb AP related to openwisp?
Thanks a lot.
I run OpenSOHO on a Linux Mint, firewall was blocking 8090. Now I can see the OpenWRT DumpAccessPoint.
How do I start opensoho in a docker container with docker-compose?
How do I expose the Shared Secret to the container with docker-compose? Via an environment variable in docker-compose? Or in the command in docker-compose? I currently have guessed how to do that with the following config in docker-compose:
opensoho:
image: ghcr.io/opensoho/opensoho-da212a3daf23f854555a4afaf75d4a02:v0.6.0
container_name: opensoho
mem_swappiness: 0
command:
- "./opensoho serve --http 0.0.0.0:8090"
environment:
- OPENSOHO_SHARED_SECRET=${OPENSOHO_SHARED_SECRET}
volumes:
- "${CONFIG_DIRECTORY}/opensoho:/tmp"
ports:
- 8090:8090
restart: unless-stopped
But that results in:
Error: unknown command "./opensoho serve --http 0.0.0.0:8090" for "opensoho"
Run 'opensoho --help' for usage.
Can you try with:
command:
- "serve --http 0.0.0.0:8090"
Opensoho is set as entrypoint, so only the arguments need to be passed as command.
command:
- "serve --http 0.0.0.0:8090"
results in:
Error: unknown command "serve --http 0.0.0.0:8090" for "opensoho"
Run 'opensoho --help' for usage.
I’ve tried an extra space before serve:
command:
- " serve --http 0.0.0.0:8090"
That results in:
Error: unknown command " serve --http 0.0.0.0:8090" for "opensoho"
Run 'opensoho --help' for usage.
I’ve also tried to remove serve :
command:
- "--http 0.0.0.0:8090"
That results in:
Summary
opensoho CLI
Usage:
opensoho [command]
Available Commands:
migrate Executes app DB migration scripts
serve Starts the web server (default to 127.0.0.1:8090 if no domain is specified)
superuser Manage superusers
Flags:
--automigrate enable/disable auto migrations (default true)
--dev enable dev mode, aka. printing logs and sql statements to the console
--developerMode Turns off admin protections, only for development
--dir string the PocketBase data directory (default "/ko-app/pb_data")
--doEmbeddedFileExtraction Extracts the embedded migrations and frontend files (default true)
--enableNewDevices Enable newly discovered devices, set to false for "monitoring mode" (default true)
--encryptionEnv string the env variable whose value of 32 characters will be used
as encryption key for the app settings (default none)
-h, --help help for opensoho
--queryTimeout int the default SELECT queries timeout in seconds (default 30)
-v, --version version for opensoho
Use "opensoho [command] --help" for more information about a command.
Aha, we’re getting closer! Try without the quotes in the command. Docker compose sends the whole command as one single argument when you add quotes.
I’ve now set it without quotes:
opensoho:
image: ghcr.io/opensoho/opensoho-da212a3daf23f854555a4afaf75d4a02:v0.6.0
container_name: opensoho
mem_swappiness: 0
command:
- serve --http 0.0.0.0:8090
environment:
- OPENSOHO_SHARED_SECRET=${OPENSOHO_SHARED_SECRET}
volumes:
- "${CONFIG_DIRECTORY}/opensoho:/tmp"
ports:
- 8090:8090
restart: unless-stopped
This results in:
Error: unknown command "serve --http 0.0.0.0:8090" for "opensoho"
Run 'opensoho --help' for usage.
I’ve been trying to get the same error message on executing the opensoho binary on the router itself to guess what is passed on to the opensoho binary in the docker container, but I can’t replicate the error message when executing the binary on the router itself (without docker). I can’t exec into the container itself with a shell because it is continuously restarting with either the usage or error message.
You use podman instead of docker? There isn’t so much difference is there in running a container with either?
–EDIT–
This works:
opensoho:
image: ghcr.io/opensoho/opensoho-da212a3daf23f854555a4afaf75d4a02:v0.6.0
container_name: opensoho
mem_swappiness: 0
command: serve --http 0.0.0.0:8090
environment:
- OPENSOHO_SHARED_SECRET=${OPENSOHO_SHARED_SECRET}
volumes:
- "${CONFIG_DIRECTORY}/opensoho:/tmp"
ports:
- 8090:8090
restart: unless-stopped
Result:
2025/09/10 19:11:23 Server started at http://0.0.0.0:8090
├─ REST API: http://0.0.0.0:8090/api/
└─ Dashboard: http://0.0.0.0:8090/_/
(!) Launch the URL below in the browser if it hasn't been open already to create your first superuser account:
–EDIT 2–
Now that I’ve been able to exec a shell inside the opensoho container, I was able to map a volume to the correct location so I could migrate the superuser account and existing configuration from the router to this container on my NAS. The OpenSOHO stanza in docker-compose now is:
opensoho:
image: ghcr.io/opensoho/opensoho-da212a3daf23f854555a4afaf75d4a02:v0.6.0
container_name: opensoho
mem_swappiness: 0
command: serve --http 0.0.0.0:8090
environment:
- OPENSOHO_SHARED_SECRET=${OPENSOHO_SHARED_SECRET}
volumes:
- "${CONFIG_DIRECTORY}/opensoho/pb_data:/ko-app/pb_data"
- "${CONFIG_DIRECTORY}/opensoho/pb_migrations:/ko-app/pb_migrations"
ports:
- 8090:8090
restart: unless-stopped
But do I need to map pb_migrations? Or is that something from pocketbase internal and is the pb_data the only directory I need? Because in the container, I see a newer pb_migrations directory in the root (/) of the container.
No real need to map pb_migrations, OpenSOHO contains them and extracts them on each startup. They could help you revert to older versions, but that hasn't been implemented yet.
@D43m0n if you want, you can make a pull request to add the instructions in the opensoho repo, thanks!
If not, I’ll add it myself, but I want to give the opportunity to be credited for your R&D first ![]()
I’ve created a pull request, nothing fancy.
For those running a container: with the new release, I managed to fix the naming into something clean ![]()
ghcr.io/opensoho/opensoho:v0.7.1
And there are also a small number of new features in 0.7.0 ![]()
Great!
could you also…
:
Pulling opensoho (ghcr.io/opensoho/opensoho:latest)...
ERROR: Head "https://ghcr.io/v2/opensoho/opensoho/manifests/latest": unauthorized