mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2025-11-29 17:38:24 +08:00
fix(Docker): windows improvements and permissions fix (#5444)
This commit is contained in:
@@ -5,11 +5,12 @@
|
||||
#
|
||||
#=================================================================
|
||||
|
||||
FROM ubuntu:20.04 as dev
|
||||
FROM ubuntu:20.04 as base
|
||||
ARG USER_ID=1000
|
||||
ARG GROUP_ID=1000
|
||||
ARG DOCKER_USER=acore
|
||||
|
||||
LABEL description="AC Worldserver Debug Container for use with Visual Studio"
|
||||
LABEL description="AC base image for dev containers"
|
||||
|
||||
# List of timezones: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||
|
||||
@@ -21,15 +22,14 @@ ENV TZ=Etc/UTC
|
||||
# set noninteractive mode so tzdata doesn't ask to set timezone on install
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# install essentials
|
||||
RUN apt-get update && apt-get install -y gdb gdbserver git dos2unix lsb-core sudo curl unzip
|
||||
|
||||
# copy everything so we can work directly within the container
|
||||
# using tools such as vscode dev-container
|
||||
COPY . /azerothcore
|
||||
|
||||
# install the required dependencies to run the worldserver
|
||||
RUN /azerothcore/acore.sh install-deps
|
||||
# Do not use acore dashboard to install
|
||||
# since it's not cacheable by docker
|
||||
RUN apt-get update && apt-get install -y gdb gdbserver git dos2unix lsb-core sudo curl unzip \
|
||||
make cmake clang libmysqlclient-dev libace-dev \
|
||||
build-essential libtool cmake-data openssl libgoogle-perftools-dev \
|
||||
libssl-dev libmysql++-dev libreadline6-dev zlib1g-dev libbz2-dev mysql-client \
|
||||
libncurses5-dev ccache \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# change timezone in container
|
||||
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && dpkg-reconfigure --frontend noninteractive tzdata
|
||||
@@ -40,27 +40,36 @@ RUN addgroup --gid $GROUP_ID acore && \
|
||||
passwd -d acore && \
|
||||
echo 'acore ALL=(ALL:ALL) NOPASSWD: ALL' >> /etc/sudoers
|
||||
|
||||
RUN mkdir -p /azerothcore
|
||||
# must be created to set the correct permissions on them
|
||||
RUN mkdir -p /azerothcore/env/dist/data
|
||||
RUN mkdir -p /azerothcore/env/dist/logs
|
||||
RUN mkdir -p /azerothcore/env/dist/etc
|
||||
RUN mkdir -p /azerothcore/var/build
|
||||
|
||||
# Correct permissions for non-root operations
|
||||
RUN chown -R acore:acore \
|
||||
/run \
|
||||
/home/acore \
|
||||
/opt/ \
|
||||
/azerothcore
|
||||
RUN chown -R $DOCKER_USER:$DOCKER_USER /home/acore
|
||||
RUN chown -R $DOCKER_USER:$DOCKER_USER /run
|
||||
RUN chown -R $DOCKER_USER:$DOCKER_USER /opt
|
||||
RUN chown -R $DOCKER_USER:$DOCKER_USER /azerothcore
|
||||
|
||||
USER acore
|
||||
USER $DOCKER_USER
|
||||
|
||||
# copy everything so we can work directly within the container
|
||||
# using tools such as vscode dev-container
|
||||
# NOTE: this folder is different by the /azerothcore (which is binded instead)
|
||||
COPY --chown=$DOCKER_USER:$DOCKER_USER . /azerothcore
|
||||
|
||||
WORKDIR /azerothcore
|
||||
|
||||
#================================================================
|
||||
#
|
||||
# BUILD STAGE: to prepare binaries for the production services
|
||||
# Dev: create dev server image
|
||||
#
|
||||
#=================================================================
|
||||
FROM dev as build
|
||||
|
||||
RUN bash acore.sh compiler build
|
||||
FROM base as dev
|
||||
|
||||
LABEL description="AC dev image for dev containers"
|
||||
|
||||
#================================================================
|
||||
#
|
||||
@@ -70,6 +79,12 @@ RUN bash acore.sh compiler build
|
||||
|
||||
FROM ubuntu:20.04 as servicebase
|
||||
|
||||
ARG USER_ID=1000
|
||||
ARG GROUP_ID=1000
|
||||
ARG DOCKER_USER=acore
|
||||
|
||||
LABEL description="AC service image for server applications"
|
||||
|
||||
# List of timezones: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||
|
||||
# set timezone environment variable
|
||||
@@ -78,51 +93,105 @@ ENV TZ=Etc/UTC
|
||||
# set noninteractive mode so tzdata doesn't ask to set timezone on install
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
COPY --from=build /azerothcore/env /azerothcore/env
|
||||
# Create a non-root user
|
||||
RUN addgroup --gid $GROUP_ID acore && \
|
||||
adduser --disabled-password --gecos '' --uid $USER_ID --gid $GROUP_ID acore && \
|
||||
passwd -d acore && \
|
||||
echo 'acore ALL=(ALL:ALL) NOPASSWD: ALL' >> /etc/sudoers
|
||||
|
||||
# copy the sources from the host machine
|
||||
COPY apps /azerothcore/apps
|
||||
COPY bin /azerothcore/bin
|
||||
COPY conf /azerothcore/conf
|
||||
COPY data /azerothcore/data
|
||||
COPY deps /azerothcore/deps
|
||||
COPY acore.json /azerothcore/acore.json
|
||||
COPY acore.sh /azerothcore/acore.sh
|
||||
|
||||
# install the required dependencies to run the authserver
|
||||
RUN apt-get update && apt-get install -y gdb gdbserver net-tools tzdata libmysqlclient-dev libace-dev mysql-client curl unzip;
|
||||
# install the required dependencies to run the server
|
||||
RUN apt-get update && apt-get install -y dos2unix gdb gdbserver net-tools tzdata libmysqlclient-dev libace-dev mysql-client curl unzip && rm -rf /var/lib/apt/lists/* ;
|
||||
|
||||
# change timezone in container
|
||||
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && dpkg-reconfigure --frontend noninteractive tzdata
|
||||
|
||||
# copy the sources from the host machine
|
||||
COPY --chown=$DOCKER_USER:$DOCKER_USER apps /azerothcore/apps
|
||||
COPY --chown=$DOCKER_USER:$DOCKER_USER bin /azerothcore/bin
|
||||
COPY --chown=$DOCKER_USER:$DOCKER_USER conf /azerothcore/conf
|
||||
COPY --chown=$DOCKER_USER:$DOCKER_USER data /azerothcore/data
|
||||
COPY --chown=$DOCKER_USER:$DOCKER_USER deps /azerothcore/deps
|
||||
COPY --chown=$DOCKER_USER:$DOCKER_USER acore.json /azerothcore/acore.json
|
||||
COPY --chown=$DOCKER_USER:$DOCKER_USER acore.sh /azerothcore/acore.sh
|
||||
|
||||
# Correct permissions for non-root operations
|
||||
RUN chown -R $DOCKER_USER:$DOCKER_USER /home/acore
|
||||
RUN chown -R $DOCKER_USER:$DOCKER_USER /run
|
||||
RUN chown -R $DOCKER_USER:$DOCKER_USER /opt
|
||||
|
||||
RUN chown $DOCKER_USER:$DOCKER_USER /azerothcore
|
||||
|
||||
USER $DOCKER_USER
|
||||
|
||||
# must be created to avoid permissions errors
|
||||
RUN mkdir -p /azerothcore/env/dist/data
|
||||
RUN mkdir -p /azerothcore/env/dist/logs
|
||||
RUN mkdir -p /azerothcore/env/dist/etc
|
||||
RUN mkdir -p /azerothcore/env/dist/bin
|
||||
|
||||
WORKDIR /azerothcore/
|
||||
|
||||
RUN cp -n "/azerothcore/env/docker/etc/worldserver.conf.dockerdist" "/azerothcore/env/dist/etc/worldserver.conf"
|
||||
RUN cp -n "/azerothcore/env/docker/etc/authserver.conf.dockerdist" "/azerothcore/env/dist/etc/authserver.conf"
|
||||
#================================================================
|
||||
#
|
||||
# AUTH & WORLD local: images used for local services
|
||||
# These images don't include binaries by default
|
||||
#
|
||||
#=================================================================
|
||||
|
||||
FROM servicebase as authserver-local
|
||||
|
||||
LABEL description="AC authserver image for local environment"
|
||||
|
||||
CMD ./acore.sh run-authserver
|
||||
|
||||
FROM servicebase as worldserver-local
|
||||
|
||||
LABEL description="AC worldserver image for local environment"
|
||||
|
||||
CMD ./acore.sh run-worldserver
|
||||
|
||||
#================================================================
|
||||
#
|
||||
# BUILD: compile sources
|
||||
#
|
||||
#=================================================================
|
||||
FROM base as build
|
||||
|
||||
LABEL description="AC Image used by the build stage to generate production images"
|
||||
|
||||
RUN bash bin/acore-docker-build
|
||||
|
||||
#================================================================
|
||||
#
|
||||
# AUTH SERVICE: create a ready-to-use authserver image
|
||||
# with binaries included
|
||||
#
|
||||
#=================================================================
|
||||
FROM authserver-local as authserver
|
||||
|
||||
FROM servicebase as authserver
|
||||
LABEL description="AC Production ready authserver"
|
||||
|
||||
CMD ./acore.sh run-authserver
|
||||
ARG DOCKER_USER=acore
|
||||
|
||||
COPY --chown=$DOCKER_USER:$DOCKER_USER --from=build /azerothcore/env/dist/etc /azerothcore/env/dist/etc
|
||||
COPY --chown=$DOCKER_USER:$DOCKER_USER --from=build /azerothcore/env/dist/bin/authserver /azerothcore/env/dist/bin/authserver
|
||||
|
||||
#================================================================
|
||||
#
|
||||
# WORLD SERVICE: create a ready-to-use worldserver image
|
||||
# with binaries and data included
|
||||
#
|
||||
#=================================================================
|
||||
FROM authserver-local as worldserver
|
||||
|
||||
FROM servicebase as worldserver
|
||||
LABEL description="AC Production ready worldserver"
|
||||
|
||||
ARG DOCKER_USER=acore
|
||||
|
||||
COPY --chown=$DOCKER_USER:$DOCKER_USER --from=build /azerothcore/env/dist/etc /azerothcore/env/dist/etc
|
||||
COPY --chown=$DOCKER_USER:$DOCKER_USER --from=build /azerothcore/env/dist/bin/worldserver /azerothcore/env/dist/bin/worldserver
|
||||
|
||||
ENV DATAPATH=/azerothcore/env/dist/data
|
||||
|
||||
RUN /azerothcore/acore.sh client-data
|
||||
|
||||
CMD ./acore.sh run-worldserver
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -7,59 +7,98 @@ import {
|
||||
|
||||
const program = new Command();
|
||||
|
||||
program.name("acore.sh docker")
|
||||
program
|
||||
.name("acore.sh docker")
|
||||
.description("Shell scripts for docker")
|
||||
.version("1.0.0");
|
||||
|
||||
shellCommandFactory(
|
||||
"start:app",
|
||||
"Startup the authserver and worldserver apps",
|
||||
"docker-compose --profile app up",
|
||||
["docker-compose --profile app up"],
|
||||
);
|
||||
|
||||
shellCommandFactory(
|
||||
"start:app:d",
|
||||
"Startup the authserver and worldserver apps in detached mode",
|
||||
"docker-compose --profile app up -d",
|
||||
["docker-compose --profile app up -d"],
|
||||
);
|
||||
|
||||
shellCommandFactory(
|
||||
"start:dev",
|
||||
"Startup the dev server",
|
||||
"docker-compose --profile dev up",
|
||||
);
|
||||
|
||||
shellCommandFactory(
|
||||
"build",
|
||||
"Build the authserver and worldserver",
|
||||
`docker-compose run --rm ac-dev-server bash bin/acore-docker-build`,
|
||||
);
|
||||
shellCommandFactory("build", "Build the authserver and worldserver", [
|
||||
"docker-compose --profile all build",
|
||||
"docker image prune -f",
|
||||
"docker-compose run --rm ac-build bash bin/acore-docker-update",
|
||||
]);
|
||||
|
||||
shellCommandFactory(
|
||||
"build:clean",
|
||||
"Clean build data",
|
||||
`docker-compose run --rm ac-dev-server bash rm -rf var/build`,
|
||||
"Clean and run build",
|
||||
[
|
||||
"docker-compose --profile all build",
|
||||
"docker image prune -f",
|
||||
`docker-compose run --rm ac-build bash acore.sh compiler clean`,
|
||||
"docker-compose run --rm ac-build bash bin/acore-docker-update",
|
||||
],
|
||||
);
|
||||
|
||||
shellCommandFactory(
|
||||
"build:nocache",
|
||||
"Build the authserver and worldserver without docker cache",
|
||||
[
|
||||
"docker-compose --profile all build --no-cache",
|
||||
"docker image prune -f",
|
||||
"docker-compose run --rm ac-build bash bin/acore-docker-update",
|
||||
],
|
||||
);
|
||||
|
||||
shellCommandFactory(
|
||||
"build:compile",
|
||||
"Run the compilation process only, without rebuilding all docker images and importing db",
|
||||
[
|
||||
"docker-compose build ac-build",
|
||||
"docker image prune -f",
|
||||
"docker-compose run --rm ac-build bash acore.sh compiler build",
|
||||
],
|
||||
);
|
||||
|
||||
shellCommandFactory(
|
||||
"client-data",
|
||||
"Download client data inside the ac-data volume",
|
||||
"docker-compose run --rm ac-dev-server bash acore.sh client-data",
|
||||
["docker-compose run --rm ac-worldserver bash acore.sh client-data"],
|
||||
);
|
||||
|
||||
shellCommandFactory(
|
||||
"db-import",
|
||||
"Create and upgrade the database with latest updates",
|
||||
"docker-compose run --rm ac-dev-server bash acore.sh db-assembler import-all",
|
||||
["docker-compose run --rm ac-build bash acore.sh db-assembler import-all"],
|
||||
);
|
||||
|
||||
shellCommandFactory(
|
||||
"dashboard [args...]",
|
||||
"Execute acore dashboard within a running ac-dev-server",
|
||||
"docker-compose exec ac-dev-server bash acore.sh",
|
||||
"dev:up",
|
||||
"Start the dev server container",
|
||||
["docker-compose up ac-dev-server"],
|
||||
);
|
||||
|
||||
program.command("attach [service]")
|
||||
shellCommandFactory(
|
||||
"dev:build",
|
||||
"Build using the dev server, it uses volumes to compile which can be faster on linux & WSL",
|
||||
["docker-compose run --rm ac-dev-server bash acore.sh compiler build"],
|
||||
);
|
||||
|
||||
shellCommandFactory(
|
||||
"dev:dash [args...]",
|
||||
"Execute acore dashboard within a running ac-dev-server",
|
||||
["docker-compose run --rm ac-dev-server bash acore.sh"],
|
||||
);
|
||||
|
||||
shellCommandFactory(
|
||||
"dev:shell [args...]",
|
||||
"Open an interactive shell within the dev server",
|
||||
["docker-compose run --rm ac-dev-server bash"],
|
||||
);
|
||||
|
||||
program
|
||||
.command("attach [service]")
|
||||
.description("attach to a service")
|
||||
.action(async (service: string | undefined) => {
|
||||
const { run } = Deno;
|
||||
@@ -84,6 +123,11 @@ program.command("attach [service]")
|
||||
|
||||
let services = new TextDecoder().decode(output).split("\n");
|
||||
|
||||
if (!services) {
|
||||
console.error("No services available!");
|
||||
return
|
||||
}
|
||||
|
||||
services.pop();
|
||||
services = services.slice(2);
|
||||
|
||||
@@ -99,6 +143,11 @@ program.command("attach [service]")
|
||||
selService = services[0];
|
||||
}
|
||||
|
||||
if (!selService) {
|
||||
console.log(`Service ${service} is not available`)
|
||||
return;
|
||||
}
|
||||
|
||||
command = `docker attach ${selService.split(" ")[0]}`;
|
||||
|
||||
console.log(ink.colorize(`<green>>>>>> Running: ${command}</green>`));
|
||||
@@ -121,9 +170,12 @@ program.command("attach [service]")
|
||||
shellCmd.close();
|
||||
});
|
||||
|
||||
program.command("quit").description("Close docker command").action(()=> {
|
||||
process.exit(0)
|
||||
})
|
||||
program
|
||||
.command("quit")
|
||||
.description("Close docker command")
|
||||
.action(() => {
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
// Handle it however you like
|
||||
// e.g. display usage
|
||||
@@ -133,42 +185,63 @@ while (true) {
|
||||
const command = await Input.prompt({
|
||||
message: "Enter the command:",
|
||||
});
|
||||
console.log(command)
|
||||
await program.parseAsync(command.split(" "));
|
||||
} else {
|
||||
await program.parseAsync(Deno.args);
|
||||
process.exit(0)
|
||||
process.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param name
|
||||
* @param description
|
||||
* @param commands you can pass one or more commands, they will be executed sequentially
|
||||
* @returns
|
||||
*/
|
||||
function shellCommandFactory(
|
||||
name: string,
|
||||
description: string,
|
||||
command: string,
|
||||
commands: string[],
|
||||
): Command {
|
||||
return program.command(name)
|
||||
return program
|
||||
.command(name)
|
||||
.description(
|
||||
`${description}. Command: \n"${ink.colorize(`<green>${command}</green>`)}"\n`,
|
||||
`${description}. Command: \n"${
|
||||
ink.colorize(
|
||||
`<green>${commands.join(" && ")}</green>`,
|
||||
)
|
||||
}"\n`,
|
||||
)
|
||||
.action(async (args: any[] | undefined) => {
|
||||
const { run } = Deno;
|
||||
|
||||
console.log(ink.colorize(`<green>>>>>> Running: ${command}</green>`));
|
||||
for (const command of commands) {
|
||||
console.log(
|
||||
ink.colorize(`<green>>>>>> Running: ${command}</green>`),
|
||||
);
|
||||
|
||||
const cmd = command.split(" ");
|
||||
const cmd = command.split(" ");
|
||||
|
||||
if (Array.isArray(args)) {
|
||||
cmd.push(...args);
|
||||
if (Array.isArray(args)) {
|
||||
cmd.push(...args);
|
||||
}
|
||||
|
||||
const shellCmd = run({
|
||||
cmd,
|
||||
cwd: process.cwd(),
|
||||
});
|
||||
|
||||
const status = await shellCmd.status();
|
||||
|
||||
if (!status.success) {
|
||||
throw new Error(`Failed with error: ${status.code}, however,
|
||||
it's not related to this Deno script directly. An error occurred within
|
||||
the script called by the command itself`);
|
||||
}
|
||||
|
||||
shellCmd.close();
|
||||
}
|
||||
|
||||
const shellCmd = run({
|
||||
cmd,
|
||||
cwd: process.cwd(),
|
||||
});
|
||||
|
||||
await shellCmd.status();
|
||||
|
||||
shellCmd.close();
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user