Moved all the setup of client files into a single use Docker image

This commit is contained in:
Jack Kawell 2021-12-08 00:50:15 -07:00
parent a38765d02d
commit f185c8b5db
7 changed files with 137 additions and 127 deletions

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
temp/ temp/
cmake-build-debug/ cmake-build-debug/
RelWithDebInfo/ RelWithDebInfo/
docker/configs
# Third party libraries # Third party libraries
thirdparty/mysql/ thirdparty/mysql/

View File

@ -1,22 +1,23 @@
# Run the Darkflame Server inside Docker # Run the Darkflame Server inside Docker
### What you need ## What you need
- Docker (Docker Desktop or on Linux normal Docker) - Docker (Docker Desktop or on Linux normal Docker)
- Docker-Compose (Included in Docker Desktop) - Docker-Compose (Included in Docker Desktop)
- LEGO® Universe Client - LEGO® Universe Client
### Run server inside Docker ## Run server inside Docker
1. Copy `.env.example` and save it as `.env` inside the root directory of this repository 1. Copy `.env.example` and save it as `.env` inside the root directory of this repository
2. Edit the `.env` file and add your path to your LEGO® Universe Client after `CLIENT_PATH=` 2. Edit the `.env` file and add your path to your LEGO® Universe Client after `CLIENT_PATH=`
3. Add some random long string after `ACCOUNT_MANAGER_SECRET=` in the `.env` file 3. Update other values in the `.env` file as need (be sure to update passwords!)
4. (Optional) You can decrease the build time if you change number behind `BUILD_THREADS=` in the `.env` file. You should change it to the number of threads your system have. 4. Run `docker-compose up setup --build`
5. Run `docker compose up -d --build` or `docker-compose up -d --build` and wait for it to complete 5. Run `docker-compose up -d database`
6. Now you can see the output of the server with `docker compose logs -f --tail 100` or `docker-compose logs -f --tail 100`. This can help you understand issues and there you can also see when the server finishes it's startup. 6. Run `docker-compose up -d account-manager brickbuildfix --build`
7. Run `docker-compose up -d darkflame`
8. Now you can see the output of the server with `docker compose logs -f --tail 100` or `docker-compose logs -f --tail 100`. This can help you understand issues and there you can also see when the server finishes it's startup.
## Disable brickbuildfix
### Disable brickbuildfix
If you don't need the http server running on port 80 do this: If you don't need the http server running on port 80 do this:
@ -30,4 +31,4 @@ services:
- donotstart - donotstart
``` ```
4. Now run `docker compose up -d --build` or `docker-compose up -d --build` 3. Now run `docker compose up -d --build` or `docker-compose up -d --build`

View File

@ -1,6 +1,21 @@
version: "3" version: "3"
services: services:
setup:
container_name: DarkflameSetup
build:
context: .
dockerfile: ./docker/setup.Dockerfile
environment:
- DATABASE=${MARIADB_DATABASE:-darkflame}
- DATABASE_HOST=database
- DATABASE_USER=${MARIADB_USER:-darkflame}
- DATABASE_PASSWORD=${MARIADB_PASSWORD:-darkflame}
- EXTERNAL_IP=${EXTERNAL_IP:-darkflame}
volumes:
- ${CLIENT_PATH:?err}:/client
- ./docker/:/docker/
database: database:
container_name: DarkflameDatabase container_name: DarkflameDatabase
image: mariadb:10.6 image: mariadb:10.6
@ -27,14 +42,9 @@ services:
args: args:
- BUILD_THREADS=${BUILD_THREADS:-1} - BUILD_THREADS=${BUILD_THREADS:-1}
- BUILD_VERSION=${BUILD_VERSION:-171022} - BUILD_VERSION=${BUILD_VERSION:-171022}
environment:
- DATABASE=${MARIADB_DATABASE:-darkflame}
- DATABASE_HOST=database
- DATABASE_USER=${MARIADB_USER:-darkflame}
- DATABASE_PASSWORD=${MARIADB_PASSWORD:-darkflame}
- EXTERNAL_IP=${EXTERNAL_IP:-darkflame}
volumes: volumes:
- ${CLIENT_PATH:?err}:/client - ${CLIENT_PATH:?err}:/client
- ./docker/configs/:/configs
depends_on: depends_on:
- database - database
ports: ports:

View File

@ -43,7 +43,7 @@ FROM gcc:11 as runtime
RUN --mount=type=cache,id=runtime-apt-cache,target=/var/cache/apt \ RUN --mount=type=cache,id=runtime-apt-cache,target=/var/cache/apt \
apt update && \ apt update && \
apt install mariadb-client python3 sudo sqlite3 -yqq --no-install-recommends && \ apt install sudo -yqq --no-install-recommends && \
apt remove -y libmysqlcppconn7v5 libmysqlcppconn-dev && \ apt remove -y libmysqlcppconn7v5 libmysqlcppconn-dev && \
rm -rf /var/lib/apt/lists/* rm -rf /var/lib/apt/lists/*
@ -51,16 +51,9 @@ WORKDIR /app
COPY --from=build /build/build /app COPY --from=build /build/build /app
COPY --from=build /build/migrations /app/migrations RUN mkdir /app/logs
RUN mkdir -p /build/build && ln -s /app/_deps /build/build/_deps RUN mkdir -p /build/build && ln -s /app/_deps /build/build/_deps
ADD docker/*.py /app/utils/
COPY docker/start_server.sh /start_server.sh COPY docker/start_server.sh /start_server.sh
RUN chmod +x /start_server.sh
RUN mkdir /app/logs
CMD [ "/start_server.sh" ] CMD [ "/start_server.sh" ]

14
docker/setup.Dockerfile Normal file
View File

@ -0,0 +1,14 @@
FROM python:3.10.0-slim-buster as prep
RUN apt update && apt install unzip sqlite3
WORKDIR /setup
# copy needed files from repo
COPY resources/ resources/
COPY migrations/cdserver/ migrations/cdserver
ADD docker/*.py utils/
COPY docker/setup.sh /setup.sh
CMD [ "/setup.sh" ]

82
docker/setup.sh Executable file
View File

@ -0,0 +1,82 @@
#!/bin/bash
function update_ini() {
FILE="/docker/configs/$1"
KEY=$2
NEW_VALUE=$3
sed -i "/^$KEY=/s/=.*/=$NEW_VALUE/" $FILE
}
function update_database_ini_values_for() {
INI_FILE=$1
update_ini $INI_FILE mysql_host $DATABASE_HOST
update_ini $INI_FILE mysql_database $DATABASE
update_ini $INI_FILE mysql_username $DATABASE_USER
update_ini $INI_FILE mysql_password $DATABASE_PASSWORD
if [[ "$INI_FILE" != "worldconfig.ini" ]]; then
update_ini $INI_FILE external_ip $EXTERNAL_IP
fi
}
function update_ini_values() {
echo "Copying and updating config files"
mkdir -p /docker/configs
cp resources/masterconfig.ini /docker/configs/
cp resources/authconfig.ini /docker/configs/
cp resources/chatconfig.ini /docker/configs/
cp resources/worldconfig.ini /docker/configs/
update_ini worldconfig.ini chat_server_port $CHAT_SERVER_PORT
update_ini worldconfig.ini max_clients $MAX_CLIENTS
update_database_ini_values_for masterconfig.ini
update_database_ini_values_for authconfig.ini
update_database_ini_values_for chatconfig.ini
update_database_ini_values_for worldconfig.ini
}
function fdb_to_sqlite() {
echo "Run fdb_to_sqlite"
python3 utils/fdb_to_sqlite.py /client/client/res/cdclient.fdb --sqlite_path /client/client/res/CDServer.sqlite
(
cd migrations/cdserver
readarray -d '' entries < <(printf '%s\0' *.sql | sort -zV)
for entry in "${entries[@]}"; do
echo "Execute $entry"
sqlite3 /client/client/res/CDServer.sqlite < $entry
done
)
}
update_ini_values
if [[ ! -d "/client" ]]; then
echo "Client not found."
echo "Did you forgot to mount the client into the \"/client\" directory?"
exit 1
fi
if [[ ! -f "/client/extracted" ]]; then
echo "Start client resource extraction"
python3 utils/pkextractor.py /client/ /client/
touch /client/extracted
else
echo "Client already extracted. Skip this step"
echo "If you want to force re-extract, just delete the file called \"extracted\" in the client directory"
fi
if [[ ! -f "/client/migrated" ]]; then
echo "Start client db migration"
fdb_to_sqlite
touch /client/migrated
else
echo "Client db already migrated. Skip this step"
echo "If you want to force re-migrate, just delete the file called \"migrated\" in the client directory"
fi

115
docker/start_server.sh Normal file → Executable file
View File

@ -1,72 +1,12 @@
#!/bin/bash #!/bin/bash
function set_defaults() {
DATABASE_PORT=${DATABASE_PORT:-3306}
DATABASE=${DATABASE:-darkflame}
if [[ -z $DATABASE_PASSWORD ]]; then
USE_DATABASE_PASSWORD="No"
else
USE_DATABASE_PASSWORD="Yes"
fi
CHAT_SERVER_PORT=${CHAT_SERVER_PORT:-2005}
MAX_CLIENTS=${MAX_CLIENTS:-999}
EXTERNAL_IP=${EXTERNAL_IP:-localhost}
echo "Start server with configuration:"
echo "===== Database Config ========="
echo "Database: $DATABASE"
echo "Database host: $DATABASE_HOST"
echo "Database port: $DATABASE_PORT"
echo "Database user: $DATABASE_USER"
echo "Database password set: $USE_DATABASE_PASSWORD"
echo "===== Other settings =========="
echo "Chat server port: $CHAT_SERVER_PORT"
echo "Max clients: $MAX_CLIENTS"
echo "External IP: $EXTERNAL_IP"
}
function check_sql_connection() {
until echo '\q' | mysql -h"$DATABASE_HOST" -P"$DATABASE_PORT" -u"$DATABASE_USER" -p"$DATABASE_PASSWORD" $DATABASE; do
>&2 echo "MySQL/MariaDB is unavailable - sleeping"
sleep 1
done
}
function update_ini() {
INI_FILE=$1
KEY=$2
NEW_VALUE=$3
sed -i "/^$KEY=/s/=.*/=$NEW_VALUE/" $INI_FILE
}
function update_database_ini_values_for() {
INI_FILE=$1
update_ini $INI_FILE mysql_host $DATABASE_HOST
update_ini $INI_FILE mysql_database $DATABASE
update_ini $INI_FILE mysql_username $DATABASE_USER
update_ini $INI_FILE mysql_password $DATABASE_PASSWORD
if [[ "$INI_FILE" != "worldconfig.ini" ]]; then
update_ini $INI_FILE external_ip $EXTERNAL_IP
fi
}
function update_ini_values() {
update_ini worldconfig.ini chat_server_port $CHAT_SERVER_PORT
update_ini worldconfig.ini max_clients $MAX_CLIENTS
update_database_ini_values_for masterconfig.ini
update_database_ini_values_for authconfig.ini
update_database_ini_values_for chatconfig.ini
update_database_ini_values_for worldconfig.ini
}
function symlink_client_files() { function symlink_client_files() {
echo "Creating symlinks for client files"
ln -s /client/client/res/macros/ /app/res/macros ln -s /client/client/res/macros/ /app/res/macros
ln -s /client/client/res/BrickModels/ /app/res/BrickModels ln -s /client/client/res/BrickModels/ /app/res/BrickModels
ln -s /client/client/res/chatplus_en_us.txt /app/res/chatplus_en_us.txt ln -s /client/client/res/chatplus_en_us.txt /app/res/chatplus_en_us.txt
ln -s /client/client/res/names/ /app/res/names ln -s /client/client/res/names/ /app/res/names
ln -s /client/client/res/CDServer.sqlite /app/res/CDServer.sqlite
ln -s /client/client/locale/locale.xml /app/locale/locale.xml ln -s /client/client/locale/locale.xml /app/locale/locale.xml
# need to iterate over entries in maps due to maps already being a directory with navmeshes/ in it # need to iterate over entries in maps due to maps already being a directory with navmeshes/ in it
( (
@ -78,51 +18,20 @@ function symlink_client_files() {
) )
} }
function fdb_to_sqlite() { function symlink_config_files() {
echo "Run fdb_to_sqlite" echo "Creating symlinks for config files"
python3 /app/utils/fdb_to_sqlite.py /client/client/res/cdclient.fdb --sqlite_path /client/client/res/CDServer.sqlite rm /app/*.ini
ln -s /configs/authconfig.ini /app/authconfig.ini
( ln -s /configs/chatconfig.ini /app/chatconfig.ini
cd /app/migrations/cdserver ln -s /configs/masterconfig.ini /app/masterconfig.ini
readarray -d '' entries < <(printf '%s\0' *.sql | sort -zV) ln -s /configs/worldconfig.ini /app/worldconfig.ini
for entry in "${entries[@]}"; do
echo "Execute $entry"
sqlite3 /client/client/res/CDServer.sqlite < $entry
done
)
ln -s /client/client/res/CDServer.sqlite /app/res/CDServer.sqlite
} }
set_defaults # setup symlinks for volume files
check_sql_connection
update_ini_values
if [[ ! -d "/client" ]]; then
echo "Client not found."
echo "Did you forgot to mount the client into the \"/client\" directory?"
exit 1
fi
if [[ ! -f "/client/extracted" ]]; then
echo "Start client resource extraction"
python3 /app/utils/pkextractor.py /client/ /client/
touch /client/extracted
else
echo "Client already extracted. Skip this step"
echo "If you want to force re-extract, just delete the file called \"extracted\" in the client directory"
fi
symlink_client_files symlink_client_files
symlink_config_files
fdb_to_sqlite # start the server
echo "Start MasterServer" echo "Start MasterServer"
./MasterServer ./MasterServer
tail -f /dev/null tail -f /dev/null