AkkStack is a simple Docker Compose environment that is augmented with developer and operator focused tooling for running EverQuest Emulator servers
You can have an entire server running within minutes, configured and ready to go for development or production use
This is what I've used in production, battle-tested, for almost 2 years. I've worked through a lot of issues to give you the final stable product. It's what I've also used for development for around the same time frame and you will see why shortly
- AkkStack | Containerized EverQuest Emulator Server Environment
- Requirements
- What's Included
- Features
- Installation
- Install
- Post-Install
- Feature Requests
- Contributing
- Pay it Forward
Linux Host or VM with Docker Installed along with Docker Compose
Service | Description |
---|---|
eqemu-server | Runs the Emulator server and all services |
mariadb | MySQL service |
phpmyadmin | (Optional) PhpMyAdmin which is automatically configured behind a password proxy |
peq-editor | (Optional) PEQ Editor which is automatically configured |
ftp-quests | (Optional) An FTP instance fully ready to be used to remotely edit quests |
backup-cron | (Optional) A container built to automatically backup (Dropbox API) the entire deployment and perform database and quest snapshots for with different retention schedules defined in .env |
Embedded server management CLI (What is used a majority of the time)
A make
menu to manage the in-container environment
A make
menu to manage the host-level container environment
Automatically configured SSH to the eqemu-server
with automatically generated 30+ character password, persistent keys through reboot; default port is 2222
Cronjob support has been added into the eqemu-server
service; you can add / edit crons and they persist through reboots. Simply start by editing the crontab.cron file
eqemu@12a1e5add2b9:~$ cat ~/assets/cron/crontab.cron
# * * * * * echo "example" >> /home/eqemu/server/example.txt
# This extra line makes it a valid cron - Don't remove
If you want your eqemu-server
service to fire any particular scripts on container bootup; such as a Discord relay server or any other type of service, you can put the script in the ~/server/startup/*
folder and they will all be ran. Do not try to run EQEmu services here as they are managed by Occulus
Configurable INNODB_BUFFER_POOL_MEMORY (Default: 256MB) (Must set before make install or rebuild mariadb)
If you are running a production server with a decent amount of players, consider setting this to 512MB or 1GB to avoid page thrashing
If you already ran make install
simply adjust this value in your .env
(Uncomment) and rebuild the mariadb container via docker-compose build mariadb
and restarting the container docker-compose restart mariadb
You can validate your buffer pool value what you set in the
An eqemu
user is created for the eqemu-server
server service and only has permissions over the peq
default database, the root user is also not able to be accessed externally. If you want to restrict the eqemu
user from external access then you will need to lock that down
root@host:/opt/eqemu-servers/peq-test-server# make mysql-list-users
docker-compose exec mariadb bash -c "mysql -uroot -pxxx -h localhost -e 'select user, password, host from mysql.user;'"
WARNING: The DROPBOX_OAUTH_ACCESS_TOKEN variable is not set. Defaulting to a blank string.
+-------------+-------------------------------------------+-----------+
| User | Password | Host |
+-------------+-------------------------------------------+-----------+
| mariadb.sys | | localhost |
| root | *F6CFC46CF35E6BCE3E85D621B308A7940CF8F242 | localhost |
| eqemu | *A1824B8E01E5C97385C3D93754C444DC23DB3583 | % |
+-------------+-------------------------------------------+-----------+
To create new users; simply log in via the root user using the host-level make mc
which will give you a direct root shell to create new full or limited users to your hearts content
Automatically configured with pre-set admin password; listens on port 8081 by default
Automatically configured PhpMyAdmin instance with pre-set admin password (Behind a password protected proxy); listens on port 8082 by default
Automatically installed server admin panel Occulus repository; listens on port 3000 by default
- Server binaries - Never need to copy binaries after a compile
- Patch files
- Quests
- Plugins
- LUA Modules
Automated cron-based backups that upload to Dropbox using Dropbox API
Follow instructions below to get an API key to enter into the .env
This is the first time you run this script, please follow the instructions:
1) Open the following URL in your Browser, and log in using your account: https://www.dropbox.com/developers/apps
2) Click on "Create App", then select "Dropbox API app"
3) Now go on with the configuration, choosing the app permissions and access restrictions to your DropBox folder
4) Enter the "App Name" that you prefer (e.g. MyUploader984915521299)
Now, click on the "Create App" button.
Backup retention configurable in .env
# DEPLOYMENT_NAME=peq-production (used in backup names)
# DROPBOX_OAUTH_ACCESS_TOKEN=
# BACKUP_RETENTION_DAYS_DB_SNAPSHOTS=10
# BACKUP_RETENTION_DAYS_DEPLOYMENT=35
# BACKUP_RETENTION_DAYS_QUEST_SNAPSHOTS=7
Crons defined in backup/crontab.cron
Crons are configured to run on a variance so that not all deployments fire backups at the same time
Backup Type | Description | Schedule |
---|---|---|
Deployment | Deployment consists of the entire akk-stack folder (server, database etc.). If you ever experienced catastrophic failure or needed to restore the entire setup, simply restoring the deployment folder will get you back up and running | Once a week at 1AM on a random variance of 1800 seconds |
Quests | A simple snapshot of the quests folder | Once a day at 1M on a random variance of 1800 seconds |
Database | A simple snapshot of the database | Once a day at 1M on a random variance of 1800 seconds |
Bash into the backup-cron
service; assuming your OAUTH token is valid and everything works
root@host:/opt/eqemu-servers/peq-production# docker-compose exec backup-cron bash
backup-cron@backup-cron:~$ dropbox_uploader.sh list peq-production
> Listing "/peq-production"... DONE
[D] database-snapshots
[D] deployment-backups
[D] quest-snapshots
Database Snapshots
backup-cron@backup-cron:~$ dropbox_uploader.sh list peq-production/database-snapshots
> Listing "/peq-production/database-snapshots"... DONE
[F] 182189205 peq-07-02-2020.tar.gz
[F] 182222834 peq-07-03-2020.tar.gz
[F] 182263995 peq-07-04-2020.tar.gz
[F] 182300144 peq-07-05-2020.tar.gz
[F] 182394017 peq-07-06-2020.tar.gz
[F] 182464528 peq-07-07-2020.tar.gz
[F] 182465093 peq-07-08-2020.tar.gz
[F] 182527952 peq-07-09-2020.tar.gz
[F] 182574977 peq-07-10-2020.tar.gz
[F] 182566469 peq-07-11-2020.tar.gz
[F] 182661537 peq-07-12-2020.tar.gz
...
Deployment Snapshots
(Includes entire deployment folder)
backup-cron@backup-cron:~$ dropbox_uploader.sh list peq-production/deployment-backups
> Listing "/peq-production/deployment-backups"... DONE
[F] 3309179293 deployment-07-02-2020.tar.gz
[F] 2357754207 deployment-07-05-2020.tar.gz
[F] 2364156848 deployment-07-12-2020.tar.gz
...
Quest Snapshots
backup-cron@backup-cron:~$ dropbox_uploader.sh list peq-production/quest-snapshots
> Listing "/peq-production/quest-snapshots"... DONE
[F] 29464443 quests-07-07-2020.tar.gz
[F] 29464443 quests-07-08-2020.tar.gz
[F] 29464443 quests-07-09-2020.tar.gz
[F] 29464443 quests-07-10-2020.tar.gz
[F] 29464443 quests-07-11-2020.tar.gz
[F] 29464443 quests-07-12-2020.tar.gz
...
If a zone process goes into an infinite loop; the watchdog will kill the process and log it in the home directory
eqemu@f8905f80723c:~$ cat process-kill.log
Sat Jul 11 20:52:47 CDT 2020 [process-watcher] Killed process [21143] [./bin/zone] for taking too much CPU time [43.50]
To protect the host and the rest of the services running on the box, in the event that someone may be compiling source or trying to maximize all CPU resources, the container is limited
root@host:/opt/eqemu-servers/peq-test-server# cat docker-compose.yml | grep shares
cpu_shares: 900
https://docs.docker.com/compose/compose-file/compose-file-v2/#cpu-and-other-resources
https://docs.docker.com/config/containers/resource_constraints/#configure-the-default-cfs-scheduler
First clone the repository somewhere on your server, in this case I'm going to clone it to an /opt/eqemu-servers
folder in a Debian Linux host with Docker installed
root@host:/opt/eqemu-servers# git clone https://github.com/Akkadius/akk-stack.git peq-test-server
Cloning into 'peq-test-server'...
remote: Enumerating objects: 57, done.
remote: Counting objects: 100% (57/57), done.
remote: Compressing objects: 100% (42/42), done.
remote: Total 782 (delta 14), reused 52 (delta 11), pack-reused 725
Receiving objects: 100% (782/782), 101.94 KiB | 7.28 MiB/s, done.
Resolving deltas: 100% (437/437), done.
Change into the new directory that represents your server
root@host:/opt/eqemu-servers# cd peq-test-server/
There are a ton of configuration variables available in the .env
file that is produced from running the next command, we will get into that later. The key thing here is that it creates the base .env
and scrambles all of the password fields in the environment
root@host:/opt/eqemu-servers# make init-reset-env
make env-transplant
Wrote updated config to [.env]
make env-scramble-secrets
Wrote updated config to [.env]
The next command is going to initialize two large key things in our setup
- The ip address we're going to use
- The zone port range we're going to use
Make sure that you only open as many ports as you need on the zone end, because docker-proxy
will NAT all ports individually in its own docker userland which does take some time when starting and shutting off containers. The more ports you nail up, the longer it takes to start / stop. Since this is a test server, I'm only going to use 30 ports. This make
command also drives the eqemu_config.json
port and address parameters as well automatically for you
root@host:/opt/eqemu-servers# make set-vars port-range-high=7030 ip-address=66.70.153.122
Wrote [IP_ADDRESS] = [66.70.153.122] to [.env]
Wrote [PORT_RANGE_HIGH] = [7030] to [.env]
From this point you're ready to run the fully automated install with a simple make install
An example of what this output looks like below (Sped up)
Now that you're installed we need to look at how we interact with the environment
To gain a bash into the emulator server we have two options, we can come through a docker exec entry or we can SSH into the container
You can hop into MySQL shell from either docker exec make mc
or from the eqemu-server
embeded shell alias mc
To print a handy list of passwords and access URL's, simply use make info
at the host level of the deployment
root@host:/opt/eqemu-servers/peq-test-server# make info
##################################
# Server Info
##################################
# Akkas Docker PEQ Installer
##################################
# Passwords
##################################
MARIADB_PASSWORD=1jo5XUzpY7lYOf5FmJKRBhUfGmnVzBN
MARIADB_ROOT_PASSWORD=mDI8gefiVEGjeiMCUMrZhMmKMWI101B
SERVER_PASSWORD=uVNjjlucE5H9UzUlziZfP16GQvsWJhe
PHPMYADMIN_PASSWORD=tD02XcNGoaIaV82wnnEnenp0V7p58V9
PEQ_EDITOR_PASSWORD=5X5o1E84SXQzjmxN86fLzuBFJyGEjN9
FTP_QUESTS_PASSWORD=Jqx3KxCZFkRA1aPqBJqMTSA1vA8uK4Y
##################################
# IP
##################################
IP_ADDRESS=66.70.153.122
##################################
# Quests FTP | 66.70.153.122:21 | quests / Jqx3KxCZFkRA1aPqBJqMTSA1vA8uK4Y
##################################
# Web Interfaces
##################################
# PEQ Editor | http://66.70.153.122:8081 | admin / 5X5o1E84SXQzjmxN86fLzuBFJyGEjN9
# PhpMyAdmin | http://66.70.153.122:8082 | admin / tD02XcNGoaIaV82wnnEnenp0V7p58V9
# EQEmu Admin | http://66.70.153.122:3000 | admin / 82a71144a51c521283834f99daff5a
##################################
By default each container / service in the docker-compose.yml
is configured to restart unless stopped, meaning if the server restarts the Docker daemon will boot the services you had started initially which is the default behavior of this stack
Occulus and the eqemu-server entrypoint bootup script is designed to start the emulator server services when the server first comes up, so if you need to bring the whole host down, everything will come back up on reboot automatically
By default the whole deployment is booted post install, but for production setups maybe you only want the emulator server and the database server only. Simply bring everything down with either make down
or docker-compose down
make up
will by default only bring up eqemu-server and mariadb
root@host:/opt/eqemu-servers/peq-test-server# make up --dry-run
docker-compose up -d eqemu-server mariadb
If you want to single boot another service, such as the peq-editor
simply docker-compose up -d peq-editor
and you'll have the 2 main services as well as the editor booted
By default, Occulus runs within the eqemu-server
service container and is available on port 3000
To access your admin panel bash or ssh into your server and run config to see your web admin password (Or view it in make info mentioned before)
eqemu@97b8129b90b4:~$ config | jq '.["web-admin"]'
{
"application": {
"key": "dadbeb31-3073-43dc-a359-569737bb2746",
"admin": {
"password": "82a71144a51c521283834f99daff5a"
}
},
"launcher": {
"runLoginserver": false,
"runQueryServ": false,
"isRunning": true,
"minZoneProcesses": 3
}
}
Updating server binaries is as simple as running update
in the server shell, it will change directory to the source directory, git pull and run a build which will be immediately available the next time you boot a process
While developing its easy to jump back and forth between compiling changes and running single processes
If you have camped to character select, you can run kzone
which will kill all zones and simply typing z
will boot a zone process in the background but will still display in the foreground of the shell
world
ucs
shared
are all shorthands that also work anywhere in any folder in the shell (See below in compiling and developing)
Compiling is as simple as typing m
anywhere in the embedded shell
If you want to compile using Ninja instead of traditional make for development; there is support in the container ready to go to compile with Ninja, you just need to configure your build repository to use it
eqemu@e5311a8e9505:~$ b
eqemu@e5311a8e9505:~/code/build$ cmake -GNinja -DEQEMU_BUILD_LOGIN=OFF -DEQEMU_BUILD_LUA=ON -DEQEMU_BUILD_PERL=ON -DEQEMU_BUILD_LOGGING=ON ..
-- Boost version: 1.67.0
-- **************************************************
-- * Library Detection *
-- **************************************************
-- * MySQL: FOUND *
-- * MariaDB: FOUND *
-- * ZLIB: FOUND *
-- * Lua: FOUND *
...truncated
To compile, simply use the n
keyword anywhere
eqemu@e5311a8e9505:~/code/build$ n
ninja: no work to do
Want a feature that isn't already available? Open an issue with the title "[Feature Request]" and we will see about getting it added
If you want to contribute to the repo, please submit Pull Requests
If you use this repository; you're taking advantage of a ton of work that I've done to make the experience incredibly simple for you to use for free - please pay it forward to the community by contributing back