mirror of
https://github.com/itzg/docker-minecraft-server.git
synced 2026-10-10 06:07:11 +00:00
Compare commits
18
Commits
2026.4.2
...
cdc2c7977e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cdc2c7977e | ||
|
|
14d0be9430 | ||
|
|
ffbd905ec4 | ||
|
|
b35db38cd3 | ||
|
|
32696ae457 | ||
|
|
50155230bd | ||
|
|
14c8509bee | ||
|
|
a44c717041 | ||
|
|
60ab277060 | ||
|
|
3393e65d6f | ||
|
|
4caed18ead | ||
|
|
de5e99cfa1 | ||
|
|
ff280ecf48 | ||
|
|
d34111c3e3 | ||
|
|
c660ac5e8f | ||
|
|
a383184e92 | ||
|
|
eb63433d35 | ||
|
|
5e1d166ba6 |
No files matched your search
@@ -13,6 +13,9 @@ updates:
|
||||
- minor
|
||||
- package-ecosystem: pip
|
||||
directory: "/docs"
|
||||
labels:
|
||||
- dependencies
|
||||
- documentation
|
||||
schedule:
|
||||
interval: weekly
|
||||
groups:
|
||||
|
||||
@@ -86,13 +86,13 @@ jobs:
|
||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
||||
mcVersion: 1.12.2
|
||||
# Pin version for Java 8
|
||||
mcHelperVersion: 1.51.1
|
||||
mcHelperVersion: 1.51.2
|
||||
- variant: java8-jdk
|
||||
baseImage: eclipse-temurin:8u312-b07-jdk-focal
|
||||
platforms: linux/amd64,linux/arm64
|
||||
mcVersion: 1.12.2
|
||||
# Pin version for Java 8
|
||||
mcHelperVersion: 1.51.1
|
||||
mcHelperVersion: 1.51.2
|
||||
env:
|
||||
IMAGE_TO_TEST: "${{ github.repository_owner }}/minecraft-server:test-${{ matrix.variant }}-${{ github.run_id }}"
|
||||
HAS_IMAGE_REPO_ACCESS: ${{ secrets.DOCKER_USER != '' && secrets.DOCKER_PASSWORD != '' }}
|
||||
|
||||
+5
-5
@@ -26,12 +26,12 @@ ARG APPS_REV=1
|
||||
ARG GITHUB_BASEURL=https://github.com
|
||||
|
||||
# renovate: datasource=github-releases packageName=itzg/easy-add
|
||||
ARG EASY_ADD_VERSION=0.8.11
|
||||
ARG EASY_ADD_VERSION=0.8.12
|
||||
ADD ${GITHUB_BASEURL}/itzg/easy-add/releases/download/${EASY_ADD_VERSION}/easy-add_${TARGETOS}_${TARGETARCH}${TARGETVARIANT} /usr/bin/easy-add
|
||||
RUN chmod +x /usr/bin/easy-add
|
||||
|
||||
# renovate: datasource=github-releases packageName=itzg/restify
|
||||
ARG RESTIFY_VERSION=1.7.12
|
||||
ARG RESTIFY_VERSION=1.7.13
|
||||
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
|
||||
--var version=${RESTIFY_VERSION} --var app=restify --file {{.app}} \
|
||||
--from ${GITHUB_BASEURL}/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
|
||||
@@ -43,19 +43,19 @@ RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
|
||||
--from ${GITHUB_BASEURL}/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
|
||||
|
||||
# renovate: datasource=github-releases packageName=itzg/mc-monitor
|
||||
ARG MC_MONITOR_VERSION=0.16.1
|
||||
ARG MC_MONITOR_VERSION=0.16.2
|
||||
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
|
||||
--var version=${MC_MONITOR_VERSION} --var app=mc-monitor --file {{.app}} \
|
||||
--from ${GITHUB_BASEURL}/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
|
||||
|
||||
# renovate: datasource=github-releases packageName=itzg/mc-server-runner
|
||||
ARG MC_SERVER_RUNNER_VERSION=1.14.5
|
||||
ARG MC_SERVER_RUNNER_VERSION=1.14.6
|
||||
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
|
||||
--var version=${MC_SERVER_RUNNER_VERSION} --var app=mc-server-runner --file {{.app}} \
|
||||
--from ${GITHUB_BASEURL}/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
|
||||
|
||||
# renovate: datasource=github-releases packageName=itzg/mc-image-helper versioning=loose
|
||||
ARG MC_HELPER_VERSION=1.56.3
|
||||
ARG MC_HELPER_VERSION=1.57.4
|
||||
ARG MC_HELPER_BASE_URL=${GITHUB_BASEURL}/itzg/mc-image-helper/releases/download/${MC_HELPER_VERSION}
|
||||
# used for cache busting local copy of mc-image-helper
|
||||
ARG MC_HELPER_REV=1
|
||||
|
||||
@@ -18,6 +18,7 @@ apk add --no-cache -U \
|
||||
curl \
|
||||
iputils \
|
||||
git \
|
||||
git-lfs \
|
||||
jq \
|
||||
mysql-client \
|
||||
tzdata \
|
||||
@@ -45,4 +46,5 @@ cat <<EOF >> /etc/gitconfig
|
||||
[user]
|
||||
name = Minecraft Server on Docker
|
||||
email = server@example.com
|
||||
EOF
|
||||
EOF
|
||||
git lfs install
|
||||
@@ -46,6 +46,7 @@ dnf install -y \
|
||||
zstd \
|
||||
$([ "$os_major_version" -ge 10 ] && echo 'bzip2' || echo 'lbzip2') \
|
||||
libpcap \
|
||||
libcap \
|
||||
libwebp \
|
||||
findutils \
|
||||
which \
|
||||
@@ -81,3 +82,4 @@ cat <<EOF >> /etc/gitconfig
|
||||
name = Minecraft Server on Docker
|
||||
email = server@example.com
|
||||
EOF
|
||||
git lfs install
|
||||
@@ -16,6 +16,7 @@ apt-get install -y \
|
||||
iputils-ping \
|
||||
curl \
|
||||
git \
|
||||
git-lfs \
|
||||
jq \
|
||||
dos2unix \
|
||||
mysql-client \
|
||||
@@ -28,13 +29,9 @@ apt-get install -y \
|
||||
nfs-common \
|
||||
libpcap0.8 \
|
||||
libnuma1 \
|
||||
libcap2-bin \
|
||||
${EXTRA_DEB_PACKAGES}
|
||||
|
||||
# Install Git LFS
|
||||
curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
|
||||
apt-get update
|
||||
apt-get install -y git-lfs
|
||||
|
||||
# Clean up APT when done
|
||||
apt-get clean
|
||||
|
||||
@@ -51,3 +48,4 @@ cat <<EOF >> /etc/gitconfig
|
||||
name = Minecraft Server on Docker
|
||||
email = server@example.com
|
||||
EOF
|
||||
git lfs install
|
||||
@@ -81,7 +81,13 @@ These paths work well if you want to have a common set of modules in a separate
|
||||
|
||||
You can download/copy additional configuration files or other resources before the server starts by using the `APPLY_EXTRA_FILES` environment variable. This is useful for downloading configs that you want to patch or modify during the startup process.
|
||||
|
||||
The format uses a `<` separator between the destination path and the source URL/path. The destination path is relative to the `/data` directory. If specifying a source path, it needs to be path mounted within the container.
|
||||
The format uses a `<` separator between the destination path and the source URL/path.
|
||||
|
||||
The destination path is relative to the `/data` directory.
|
||||
|
||||
If specifying a source path, rather than URL, it needs to reference a path mounted into the container as a volume.
|
||||
|
||||
A source path can refer to a directory, in which case the files within that directory will be copied into the destination directory. At startup, it will take care of synchronizing the removal of files it copied when they are removed from the source.
|
||||
|
||||
!!! example
|
||||
|
||||
@@ -150,6 +156,54 @@ Disabling mods within docker compose files:
|
||||
mod2.jar
|
||||
```
|
||||
|
||||
### Loading container configuration from a pack
|
||||
|
||||
A pack can ship its own container configuration so that the server type, version,
|
||||
and other variables travel with the pack rather than being declared by the user.
|
||||
At startup, before `TYPE` is dispatched, the container can load environment
|
||||
variables from a file on disk, a URL, an entry inside an archive, or from the
|
||||
`.env` of each `GENERIC_PACK(S)` entry.
|
||||
|
||||
- `LOAD_ENV_FROM_GENERIC_PACK`: when `true`, each entry in `GENERIC_PACKS` (after
|
||||
`GENERIC_PACKS_PREFIX`/`SUFFIX` expansion) is probed for a top-level `.env`
|
||||
and each one found is sourced in the same order the packs are applied (later
|
||||
packs override earlier ones, matching the layering of the unpack itself). Packs
|
||||
without a `.env` are skipped without error. URLs are downloaded into
|
||||
`/data/packs/` and reused by the regular generic-pack unpack step, so they are
|
||||
not fetched twice.
|
||||
- `LOAD_ENV_FROM_FILE`: container path or URL of a shell-style env file (one
|
||||
`KEY=VALUE` per line). Comments and blank lines are allowed.
|
||||
- `LOAD_ENV_FROM_ARCHIVE`: container path or URL of a zip/tar archive containing
|
||||
an env file. The entry is sourced into the environment.
|
||||
- `LOAD_ENV_FROM_ARCHIVE_ENTRY`: relative path of the env file inside the archive.
|
||||
Defaults to `.env`.
|
||||
|
||||
These can be combined. Load order is: generic packs first, then
|
||||
`LOAD_ENV_FROM_FILE`, then `LOAD_ENV_FROM_ARCHIVE` — later loads override
|
||||
earlier ones, and all of them **override** values passed via `docker run -e` (or
|
||||
compose `environment:`), so the pack's declared values win.
|
||||
|
||||
```shell
|
||||
docker run -d \
|
||||
-e EULA=TRUE \
|
||||
-e GENERIC_PACK=https://cdn.example.org/my-pack.zip \
|
||||
-e LOAD_ENV_FROM_GENERIC_PACK=true \
|
||||
itzg/minecraft-server
|
||||
```
|
||||
|
||||
Where `my-pack.zip` contains a `.env` at its root such as:
|
||||
|
||||
```env
|
||||
TYPE=FABRIC
|
||||
VERSION=1.21.1
|
||||
FABRIC_LOADER_VERSION=0.16.0
|
||||
```
|
||||
|
||||
!!! warning
|
||||
The env file is sourced by `bash`, so any shell syntax it contains will be
|
||||
evaluated. Only point these variables at sources you trust. `EULA` cannot be
|
||||
set this way — it is checked before the env file is loaded.
|
||||
|
||||
## Mods/plugins list
|
||||
|
||||
You may also download or copy over individual mods/plugins using the `MODS` or `PLUGINS` environment variables. Both are a comma or newline delimited list of
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
click==8.3.2
|
||||
click==8.3.3
|
||||
colorama==0.4.6
|
||||
deepmerge==2.0
|
||||
ghp-import==2.1.0
|
||||
@@ -10,10 +10,10 @@ mergedeep==1.3.4
|
||||
mkdocs==1.6.1
|
||||
mkdocs-autorefs==1.4.4
|
||||
mkdocs-get-deps==0.2.2
|
||||
mkdocstrings==1.0.3
|
||||
mkdocstrings==1.0.4
|
||||
mkdocstrings-python==2.0.3
|
||||
packaging==26.1
|
||||
pathspec==1.0.4
|
||||
packaging==26.2
|
||||
pathspec==1.1.1
|
||||
platformdirs==4.9.6
|
||||
Pygments==2.20.0
|
||||
pymdown-extensions==10.21.2
|
||||
@@ -22,4 +22,4 @@ PyYAML==6.0.3
|
||||
pyyaml_env_tag==1.1
|
||||
six==1.17.0
|
||||
watchdog==6.0.0
|
||||
zensical==0.0.33
|
||||
zensical==0.0.40
|
||||
@@ -212,6 +212,11 @@
|
||||
},
|
||||
"valhelsia-5": {
|
||||
"excludes": ["modernfix"]
|
||||
},
|
||||
"wolds-vaults": {
|
||||
"forceIncludes": [
|
||||
"just-enough-resources-jer"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@
|
||||
"AmbientSounds",
|
||||
"amecs",
|
||||
"Animation_Overhaul",
|
||||
"appleskin",
|
||||
"auudio",
|
||||
"axolotlbuckets",
|
||||
"BadOptimizations",
|
||||
@@ -28,7 +27,6 @@
|
||||
"compass-coords",
|
||||
"colorwheel",
|
||||
"connectedness",
|
||||
"connector",
|
||||
"continuity",
|
||||
"controlling",
|
||||
"craftpresence",
|
||||
|
||||
@@ -152,6 +152,31 @@ fi
|
||||
|
||||
cd /data || exit 1
|
||||
|
||||
##########################################
|
||||
# Optionally load environment variables from a file or archive entry,
|
||||
# allowing packs/artifacts to declare TYPE, VERSION and other settings
|
||||
# inside-out. Loaded values override anything passed in through docker -e.
|
||||
# Generic packs are processed first so that LOAD_ENV_FROM_FILE and
|
||||
# LOAD_ENV_FROM_ARCHIVE can override any values they set.
|
||||
|
||||
if isTrue "${LOAD_ENV_FROM_GENERIC_PACK:-false}"; then
|
||||
if ! loadEnvFromGenericPack; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ${LOAD_ENV_FROM_FILE:-} ]]; then
|
||||
if ! loadEnvFromFile "${LOAD_ENV_FROM_FILE}"; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ${LOAD_ENV_FROM_ARCHIVE:-} ]]; then
|
||||
if ! loadEnvFromArchive "${LOAD_ENV_FROM_ARCHIVE}" "${LOAD_ENV_FROM_ARCHIVE_ENTRY:-.env}"; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
export DECLARED_TYPE=${TYPE^^}
|
||||
export DECLARED_VERSION="$VERSION"
|
||||
|
||||
|
||||
+116
-3
@@ -26,6 +26,117 @@ function applyResultsFile() {
|
||||
set +a
|
||||
}
|
||||
|
||||
function loadEnvFromFile() {
|
||||
local source=${1?Missing required source argument}
|
||||
local downloaded=
|
||||
|
||||
if isURL "$source"; then
|
||||
mkdir -p /data/.tmp
|
||||
downloaded=$(mktemp -p /data/.tmp)
|
||||
log "Downloading env file from $source"
|
||||
if ! get -o "$downloaded" "$source"; then
|
||||
logError "Failed to download env file from $source"
|
||||
rm -f "$downloaded"
|
||||
return 1
|
||||
fi
|
||||
log "Loading env vars from $source"
|
||||
applyResultsFile "$downloaded"
|
||||
rm -f "$downloaded"
|
||||
elif [ -f "$source" ]; then
|
||||
log "Loading env vars from $source"
|
||||
applyResultsFile "$source"
|
||||
else
|
||||
logError "Env file not found: $source"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
function loadEnvFromArchive() {
|
||||
local source=${1?Missing required source argument}
|
||||
local entry=${2:-.env}
|
||||
local archive=
|
||||
local downloaded=
|
||||
local tmpdir
|
||||
local rc=0
|
||||
|
||||
mkdir -p /data/.tmp
|
||||
|
||||
if isURL "$source"; then
|
||||
downloaded=$(mktemp -p /data/.tmp)
|
||||
log "Downloading archive from $source"
|
||||
if ! get -o "$downloaded" "$source"; then
|
||||
logError "Failed to download archive from $source"
|
||||
rm -f "$downloaded"
|
||||
return 1
|
||||
fi
|
||||
archive=$downloaded
|
||||
elif [ -f "$source" ]; then
|
||||
archive=$source
|
||||
else
|
||||
logError "Archive not found: $source"
|
||||
return 1
|
||||
fi
|
||||
|
||||
tmpdir=$(mktemp -d -p /data/.tmp)
|
||||
if extract "$archive" "$tmpdir" "$entry" && [ -f "$tmpdir/$entry" ]; then
|
||||
log "Loading env vars from '$entry' in $source"
|
||||
applyResultsFile "$tmpdir/$entry"
|
||||
else
|
||||
logError "Failed to load env entry '$entry' from $source"
|
||||
rc=1
|
||||
fi
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
[[ -n "$downloaded" ]] && rm -f "$downloaded"
|
||||
return $rc
|
||||
}
|
||||
|
||||
function loadEnvFromGenericPack() {
|
||||
: "${GENERIC_PACKS:=${GENERIC_PACK:-}}"
|
||||
: "${GENERIC_PACKS_PREFIX:=}"
|
||||
: "${GENERIC_PACKS_SUFFIX:=}"
|
||||
|
||||
if [[ -z "${GENERIC_PACKS}" ]]; then
|
||||
logWarning "LOAD_ENV_FROM_GENERIC_PACK is set but GENERIC_PACK(S) is empty"
|
||||
return 0
|
||||
fi
|
||||
|
||||
mkdir -p /data/.tmp
|
||||
IFS=',' read -ra packs <<< "${GENERIC_PACKS}"
|
||||
local loaded=0
|
||||
local pack packEntry packFile tmpdir
|
||||
for packEntry in "${packs[@]}"; do
|
||||
pack="${GENERIC_PACKS_PREFIX}${packEntry}${GENERIC_PACKS_SUFFIX}"
|
||||
if isURL "$pack"; then
|
||||
mkdir -p /data/packs
|
||||
if ! packFile=$(get -o /data/packs --output-filename --skip-up-to-date "$pack"); then
|
||||
logError "Failed to download generic pack $pack"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
packFile=$pack
|
||||
fi
|
||||
|
||||
if [[ ! -f "$packFile" ]]; then
|
||||
logError "Generic pack not found: $packFile"
|
||||
return 1
|
||||
fi
|
||||
|
||||
tmpdir=$(mktemp -d -p /data/.tmp)
|
||||
# Packs without a .env are valid — silently skip; the unpack step still applies them.
|
||||
if extract "$packFile" "$tmpdir" .env 2>/dev/null && [ -f "$tmpdir/.env" ]; then
|
||||
log "Loading env vars from .env in $pack"
|
||||
applyResultsFile "$tmpdir/.env"
|
||||
loaded=$((loaded + 1))
|
||||
fi
|
||||
rm -rf "$tmpdir"
|
||||
done
|
||||
|
||||
if (( loaded == 0 )); then
|
||||
logWarning "LOAD_ENV_FROM_GENERIC_PACK is set but no pack in GENERIC_PACK(S) contained a .env"
|
||||
fi
|
||||
}
|
||||
|
||||
function join_by() {
|
||||
local d=$1
|
||||
shift
|
||||
@@ -445,17 +556,19 @@ function isType() {
|
||||
function extract() {
|
||||
src=${1?}
|
||||
destDir=${2?}
|
||||
shift 2
|
||||
# remaining args are paths within the archive to extract; if none, extract everything
|
||||
|
||||
type=$(file -b --mime-type "${src}")
|
||||
case "${type}" in
|
||||
application/zip)
|
||||
unzip -o -q -d "${destDir}" "${src}"
|
||||
unzip -o -q -d "${destDir}" "${src}" "$@"
|
||||
;;
|
||||
application/x-tar | application/gzip | application/x-gzip | application/x-bzip2)
|
||||
tar -C "${destDir}" -xf "${src}"
|
||||
tar -C "${destDir}" -xf "${src}" "$@"
|
||||
;;
|
||||
application/zstd | application/x-zstd)
|
||||
tar -C "${destDir}" --use-compress-program=unzstd -xf "${src}"
|
||||
tar -C "${destDir}" --use-compress-program=unzstd -xf "${src}" "$@"
|
||||
;;
|
||||
*)
|
||||
logError "Unsupported archive type: $type"
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
services:
|
||||
mc:
|
||||
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
|
||||
environment:
|
||||
EULA: "true"
|
||||
SETUP_ONLY: "true"
|
||||
LOAD_ENV_FROM_ARCHIVE: /test/load-env.zip
|
||||
MOTD: from-compose
|
||||
LOG_TIMESTAMP: "true"
|
||||
DEBUG: "true"
|
||||
# the following are only used to speed up test execution
|
||||
TYPE: CUSTOM
|
||||
CUSTOM_SERVER: /servers/fake.jar
|
||||
VERSION: 1.18.1
|
||||
volumes:
|
||||
- ./data:/data
|
||||
- ./load-env.zip:/test/load-env.zip
|
||||
- ./fake.jar:/servers/fake.jar
|
||||
Whitespace-only changes.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
mc-image-helper assert propertyEquals --file=server.properties --property=motd --expect=from-archive
|
||||
@@ -0,0 +1,18 @@
|
||||
services:
|
||||
mc:
|
||||
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
|
||||
environment:
|
||||
EULA: "true"
|
||||
SETUP_ONLY: "true"
|
||||
LOAD_ENV_FROM_FILE: /test/load-env.env
|
||||
MOTD: from-compose
|
||||
LOG_TIMESTAMP: "true"
|
||||
DEBUG: "true"
|
||||
# the following are only used to speed up test execution
|
||||
TYPE: CUSTOM
|
||||
CUSTOM_SERVER: /servers/fake.jar
|
||||
VERSION: 1.18.1
|
||||
volumes:
|
||||
- ./data:/data
|
||||
- ./load-env.env:/test/load-env.env
|
||||
- ./fake.jar:/servers/fake.jar
|
||||
Whitespace-only changes.
@@ -0,0 +1,2 @@
|
||||
# Loaded by LOAD_ENV_FROM_FILE during start-configuration
|
||||
MOTD=from-env-file
|
||||
@@ -0,0 +1 @@
|
||||
mc-image-helper assert propertyEquals --file=server.properties --property=motd --expect=from-env-file
|
||||
@@ -0,0 +1,19 @@
|
||||
services:
|
||||
mc:
|
||||
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
|
||||
environment:
|
||||
EULA: "true"
|
||||
SETUP_ONLY: "true"
|
||||
GENERIC_PACK: /packs/pack.zip
|
||||
LOAD_ENV_FROM_GENERIC_PACK: "true"
|
||||
MOTD: from-compose
|
||||
LOG_TIMESTAMP: "true"
|
||||
DEBUG: "true"
|
||||
# the following are only used to speed up test execution
|
||||
TYPE: CUSTOM
|
||||
CUSTOM_SERVER: /servers/fake.jar
|
||||
VERSION: 1.18.1
|
||||
volumes:
|
||||
- ./data:/data
|
||||
- ./pack.zip:/packs/pack.zip
|
||||
- ./fake.jar:/servers/fake.jar
|
||||
Whitespace-only changes.
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
mc-image-helper assert propertyEquals --file=server.properties --property=motd --expect=from-generic-pack
|
||||
mc-image-helper assert fileExists config/dummy.yml
|
||||
Reference in new issue
Block a user