Improving docker support
-
(a development post by a contributor, not a team member
)
NodeBB currently works with docker... technically.
I mean, the default image is fine if you set it up correctly - but that's a pretty big if and there wasn't any good documentation. The existing docker-compose file had some tiny pain points like:- not exposing any ports by default
- it recommends setting up a reverse proxy like traefik, which can be a good idea and avoids a small docker security footgun (ports exposed by containers can bypass some firewall configurations, e.g. ufw)
- but also means that running
docker compose up
just starts up a container you can't connect to by default! You'll need to modify the config, whether you want to expose a port or set up Traefik...
- not setting up volumes
- I hope you like redoing all your configuration when updating the image!
- also, hope you installed some plugin for storing uploads remotely, since even they'll be gone when you delete and recreate the container
- you can also, again, edit it to resolve that issue
- not creating any database in the mongodb container
- using
admin
works, but is really not intuitive!
- using
And when I said the image was fine, I mean that it's acceptable, not that it's great. It always builds NodeBB before startup, installing and activating plugins in a way that will persist properly requires using arcane configuration options that are not mentioned in the docs (and it results in not being able to install or remove any plugins at runtime), and - again - setting up volumes is entirely up to the user.
However, quite some time ago, @stevefan1999-personal made a pull request that addressed many of these issues, and over time came to address almost everything I mentioned here. And finally we're getting close to landing these changes, and some other small improvements, in NodeBB/NodeBB#12031
So what will change?
- Running
docker compose --profile mongo up
is now all you need to start a working instance of NodeBB in a container. Initially it'll launch the web installer, with already populated database configuration, leaving you just to set up the NodeBB URL and admin account. Then just waiting a bit for setup to finish and you're done - NodeBB is running under port4567
. You can now use some reverse proxy on host, modify the compose file to expose it under port 80 or add a containerized reverse proxy and remove the default port binding. - If you use the default compose file you'll notice that configuration and - more importantly - uploads are now mounted in
.docker
directory, so they'll persist when recreating the container - There are some additional env variables that can affect the image startup behavior - e.g. you can now choose if NodeBB will run a build before starting.
There's another nice change that you might've thought of if you saw the initial PR title - docker image size. And it's a fairly large difference. Some numbers:
- current image: 601MiB compressed/1.62GiB uncompressed
- original alpine PR: 315MiB compressed/986MiB uncompressed
- new PR (slim debian build): 211MiB compressed/674MiB uncompressed
For reference, now the official MongoDB image is actually larger than NodeBB, and combined (even with redis added to the mix) they're still e.g. almost 2x smaller than Discourse slim image (747MiB compressed/2.02GiB uncompressed).
And MongoDB is the largest of the supported databases - Postgres clocks at only 150MiB compressed and offers a 94MiB compressed alpine version, and Redis clocks in at 49MiB compressed for a debian image and just 15MiB for alpine.The result is that when running NodeBB with postgres the images will end up taking less than 1GB of disk space, basically half of what they do currently. All while offering much better user experience and configurability.
And finally, Docker is graduating to being mentioned in official docs with NodeBB/docs#78
- not exposing any ports by default
-
@oplik0 thank you so much for your work on this. I realize this post is a bit older at this point, but I'm hoping I can get some help. I'm a bit new to the docker world still and trying to figure out how I can use this to develop a few new plugins for NodeBB. It would seem like that would be a common use case but posts about that are a little few and far between. My goal is to have a folder where I put my new plugins, and spin up the docker-compose so I can attach to the nodebb container and view console logs, and have it auto-rebuild (if needed?) when I make changes to the plugin code. Really struggling to figure it out but I think I'm close. What is the point of the dev.Dockerfile? It does not seem to be used by Docker-compose or Dockerfile or Docker-compose-redis at all. Is it a manually invoked file? Is that what I should be using instead? What I'm struggling the most with is trying to mount my plugins into the container, and then npm link them which is what I think I'm supposed to do? Is there any chance you can share an example of how to achieve this? I would very much love to get to the point where I'm developing instead of struggling. LOL. One thing I'm just now starting to comprehend is that if I mount the plugins folder using compose it does not exist during the build process but will exist after the container spins up. I think I am getting somewhere hopefully. Much appreciated.
-
Argg
I am seemingly not allowed to use npm link inside the container because of permissions of the volume mount or of node_modules or something like that. I may need to throw in the towel and just do this on a linux VM or something. So frustrating.
-
okay guess I'm going to try like this... write my own development version of docker-compose and dockerfile to remove the nodebb user and do everything as root (because I can't npm link as user nodebb!). And this way I can also keep all the repositories separate and make commits to each individually. Yay this is fun * bang head on desk * lol
-
I got it working! github.com/SinisterSpatula/.docker-dev
I think we can definitely improve this, but I at least want to share my work in case there are others that want to use docker to develop a plugin, as it seems no one has really documented or shared their work when it comes to this, at least that I could find!