This image is based on the fantastic base image built & maintained by LinuxServer.io. LinuxServer.io distributes dozens of software packages following repeatable patterns. Thank you so much LinuxServer.io for making a base image available that anybody, including our project, can use.
macOS and Linux work well. Development of this image is done on my macOS laptop. I run MBBSEmu on a Linux server.
Windows should work in principle but I have not personally tried it. I also include a build.sh
helper script to build the image. It's a bourne shell script, so it certainly won't work out of the box on Windows. But it woudldn't be too hard to do its work manually.
- Docker
- I've personally run on Docker Desktop macOS and Docker on Linux.
- An unzipped MBBSEmu package
- Grab your preferred build from the MBBSEmu website.
- Since development is so rapid right now, I generally use the latest build from GitHub Actions.
- You can also use the
download-latest-mbbsemu.sh
shell script to grab the latest build. (I do suggest you review this file before running it.)
- Unzipped MajorBBS modules
- MBBSEmu-ready modules can be found on the MBBSEmu website Modules section.
Broadly speaking we will be going three steps to build, setup, and run this image.
- Build the image from source.
- Prepare the runtime and configuration directory.
- Create a
compose.yml
file and run a container.
- Clone and cd into the repository.
- Download and unzip MBBSEmu into the a subdirectory of the
pkg
directory- Get the Linux x86 build
- The directory needs to be named like
mbbs-linux-x64-*
- It should already be in this format if you unzipped a package from the website
- This directory will not be committed to source control.
- Run
./build.sh
- This assumes Linux or macOS.
- This script wraps a
docker build
command. On Windows, you can refer to the script and rundocker build
by hand. - The image is now built and we can get it running.
Now we need to prepare a directory for running our container and storing configuration. Where we are headed is a directory structure like this:
mbbsemu-runtime
├── config
│ ├── appsettings.json
│ ├── mbbsemu.db
│ ├── modules
│ │ ├── HVSXROAD
│ │ ├── pkg
│ │ ├── TSGARN
│ │ └── WCCMMUD
│ └── modules.json
└── docker-compose.yml
As seen above, unzipped modules are kept in in config/modules
. Here I've got the HVSXROAD
(Crossroads), TSGARN
(Tele-Arena), and WCCMMUD
(MajorMUD) modules.
I also chose to archive the zip file packages from MBBSEmu in the config/modules/pkg
directory but this is not required.
Next up is the required config/modules.json
file, which specifies the modules to load and their path. In this example, modules.json
looks like this:
{
"Modules": [
{
"Identifier": "HVSXROAD",
"Path": "/config/modules/HVSXROAD"
},
{
"Identifier": "TSGARN",
"Path": "/config/modules/TSGARN"
},
{
"Identifier": "WCCMMUD",
"Path": "/config/modules/WCCMMUD"
}
]
}
Note the leading slash in the paths -- this is because, inside of the container, this config
directory will be mounted at /config
.
Next we need to create the mbbsemu.db
file. This is the main database for MBBSEmu (duh)
Setting up the database will also set the Sysop account password.
To do this, we'll use docker run
to run the MBBSEmu command to set the Sysop password.
Here is an example of what that looks like:
docker run \
-e "PUID=1000" \
-e "PGID=999" \
-e "TZ=America/Detroit" \
-v /host/path/to/config:/config -it \
--entrypoint /app/MBBSEmu mbbsemu -DBRESET <FILL IN PASSWORD HERE>
The first two environment variables set the user and group ids you want this to run as. This is following LinuxServer.io's pattern. Set these values to the same user and group ids as the user you want to run this as.
The third environment variable sets the timezone.
The -v
volume mapping the /config
directory in the container to the local ./config
directory relative to this script. The left side of the colon should be the config path on your host system. You need to include this kind of bind volume so that the new database file is persisted.
Finally, the --entrypoint
and remaining syntax runs the emulator with the -DBRESET
parameter.
Fill you preferred sysop password in at the end.
Lastly we need to prep the config/appsettings.json
file. The MBBSEmu zip package from the website should come with a sample file. Copy it in here.
We'll for sure need to change the Database.File
key in that file. Given our directory structure above, we want that line to read as:
"Database.File": "/config/mbbsemu.db",
Take note of the telnet port and rlogin ports specified in this file. We'll need to map those ports when running the container.
At this point our runtime and configuration directory should be all setup. Now we can actually run a container.
Inside of our directory, create a docker-compose.yml
that looks like the following.
services:
mbbsemu:
image: mbbsemu # this is the name of the image built by build.sh
environment:
- PUID=ABC # fill in with uid of the user running the container
- PGID=XYZ # fill in with gid of the user running the container
- TZ=America/Detroit # fill in with your preferred timezone
ports:
- "2323:23" # set your preferred port mapping for telnet. The syntax is host:container port numbers.
volumes:
- ./config:/config
Follow the comments above on which values need to be filled in where.
The PUID
and PGID
will likely match the values you used while creating the database and setting the sysop password.
At last we can run a conatiner. docker-compose up
Note the output from running the container. The majority of it is the LinuxServer.io base setting up the environment and running our command.
- [] Build and push images to Github container registry - avoids people needing to build this themselves.
- [] Update
svc-mbbsemu
to be oftype
longrun
instead ofoneshot
. This way s6 will restart the daemon if it crashes.- Note: leaving it as
oneshot
for now until the stability of the application is pretty solid and we can assume restarting the daemon is ok. - Also note: when switching to
longrun
we can delete theup
file insvn-mbbsemu
.
- Note: leaving it as
- Update to use newer LinuxServer.io base images, including the new version of s6 they use.
- Test whether the :delegated flag on the modules volume mapping makes a difference on a linux host.
- Finish authoring te section about creating the database file.
- Put all config, database, module files into /config , not read only
- Figure out if there is a way to map /config, and also have /config/modules be :delegated in docker-compose.yml
- Figure out how to get the VERSION arg passed in / configured in the Dockerfile - maybe download directly from mbbsemu?
- Go through files changed on the linuxserver.io branch; remove commented out reference code from the old implementation
- Update this README to account for linuxserver changeover
- Remove
modules.json
from source control. Instead, provide an example and have the end user configure it for their own needs. - Volume map the modules directory -- modules are simply too messy to be copied in with one of two data files mapped. They drop stuff all over the place :(
- Do MBBS modules that save data dump all their data files in the same directory as the bbs exectuables themselves? I believe so. Test if there is a way to dump the static bbs files during build time, but volume map the data files at runtime into the same directory. Need one or two modules to test this with first.
- Identify a slimmer base image to build from. (I chose this one because I know the app is being developed on .net, but I suspect something smaller can be used for runtime only)
- See if a generic
docker-compose.yml
can be created to ease running this beast.