test
This commit is contained in:
parent
b88b906a39
commit
d98a8cc4c9
@ -1,34 +1,55 @@
|
||||
# Caddy recommended way to build the custom image
|
||||
FROM registry.belway.me/belwayhome/almalinux9-minimal:latest
|
||||
# FoundryVTT Container Image
|
||||
# Built on Red Hat UBI10 Minimal for security and stability
|
||||
FROM registry.access.redhat.com/ubi10/ubi-minimal:latest
|
||||
|
||||
ARG foundry_url
|
||||
ARG nodejs_version
|
||||
ENV foundry_url $foundry_url
|
||||
ENV nodejs_version $nodejs_version
|
||||
# OCI Labels
|
||||
LABEL org.opencontainers.image.title="FoundryVTT"
|
||||
LABEL org.opencontainers.image.description="FoundryVTT Virtual Tabletop on Red Hat UBI10"
|
||||
LABEL org.opencontainers.image.source="https://gitea.belway.me/Public/foundryvtt_container"
|
||||
LABEL org.opencontainers.image.vendor="BelwayHome"
|
||||
|
||||
# Because pipeline is rootless
|
||||
VOLUME /var/lib/containers
|
||||
VOLUME /home/podman/.local/share/containers
|
||||
ARG FOUNDRY_URL
|
||||
ARG FOUNDRY_VERSION=latest
|
||||
ARG NODEJS_VERSION=22
|
||||
|
||||
RUN microdnf update --assumeyes \
|
||||
&& microdnf --assumeyes install \
|
||||
openssl-devel \
|
||||
# Install dependencies and Node.js via dnf module
|
||||
RUN microdnf update -y --nodocs && \
|
||||
microdnf install -y --nodocs --setopt=install_weak_deps=0 \
|
||||
nodejs \
|
||||
npm \
|
||||
openssl \
|
||||
tar \
|
||||
unzip \
|
||||
wget \
|
||||
&& rm -rf /var/cache/yum
|
||||
shadow-utils && \
|
||||
microdnf clean all && \
|
||||
rm -rf /var/cache/yum
|
||||
|
||||
RUN curl --silent --location https://rpm.nodesource.com/setup_${nodejs_version}.x | bash - \
|
||||
&& microdnf --assumeyes install \
|
||||
nodejs \
|
||||
&& rm -rf /var/cache/yum
|
||||
# Create non-root user
|
||||
RUN groupadd -r foundry && \
|
||||
useradd -r -g foundry -d /foundryvtt -s /sbin/nologin foundry
|
||||
|
||||
WORKDIR /foundryvtt/foundryvtt
|
||||
RUN wget -O foundryvtt.zip ${foundry_url} && unzip foundryvtt.zip && rm foundryvtt.zip
|
||||
# Download and extract FoundryVTT
|
||||
WORKDIR /foundryvtt/app
|
||||
RUN wget -q -O foundryvtt.zip "${FOUNDRY_URL}" && \
|
||||
unzip -q foundryvtt.zip && \
|
||||
rm foundryvtt.zip && \
|
||||
chown -R foundry:foundry /foundryvtt
|
||||
|
||||
# Create data directory
|
||||
RUN mkdir -p /foundryvtt/data && \
|
||||
chown -R foundry:foundry /foundryvtt/data
|
||||
|
||||
WORKDIR /foundryvtt
|
||||
|
||||
VOLUME /foundryvtt/foundrydata
|
||||
# Set ownership and switch to non-root user
|
||||
USER foundry
|
||||
|
||||
VOLUME /foundryvtt/data
|
||||
EXPOSE 30000
|
||||
|
||||
ENTRYPOINT /usr/bin/node /foundryvtt/foundryvtt/resources/app/main.js --dataPath=/foundryvtt/foundrydata
|
||||
# Version label (set at build time)
|
||||
LABEL org.opencontainers.image.version="${FOUNDRY_VERSION}"
|
||||
|
||||
# Use exec form for proper signal handling
|
||||
ENTRYPOINT ["/usr/bin/node", "/foundryvtt/app/resources/app/main.js", "--dataPath=/foundryvtt/data"]
|
||||
|
||||
128
README.md
128
README.md
@ -1,32 +1,75 @@
|
||||
# foundryvtt_container
|
||||
If you don't want to build and host your own container image feel free to skip ahead and leverage the publicly hosted container. Head over to "Running the Container" if this is the better use-case for you.
|
||||
# FoundryVTT Container
|
||||
|
||||
## Builidng the Container
|
||||
Just run the script with the URL and Version declared as follows:
|
||||
A containerized FoundryVTT Virtual Tabletop built on Red Hat UBI10 Minimal.
|
||||
|
||||
## Features
|
||||
- Red Hat UBI10 Minimal base image
|
||||
- Runs as non-root user for security
|
||||
- OCI-compliant image labels
|
||||
- Automated CI/CD builds
|
||||
|
||||
## Quick Start
|
||||
|
||||
Pull the latest image:
|
||||
```bash
|
||||
./build.sh -U $FOUNDRY_URL -I -v $VERSION
|
||||
podman pull registry.belway.me/public/foundryvtt:latest
|
||||
```
|
||||
|
||||
## Running the Container
|
||||
When setting hostname, make sure you use the hostname of the baremetal server or VM that you are running the container on. Otherwise you will need to accept the license at each initialization.
|
||||
Assuming you are using rootless like I am, you'll need to have created a rootless user and enabled lingering.
|
||||
I'm using quadlets, so here's an example quadlet:
|
||||
Run with persistent data:
|
||||
```bash
|
||||
# in your rootless podman container directory, ie: /etc/containers/systemd/users/${USER_UID}/
|
||||
# foundryvtt.container
|
||||
podman run -d \
|
||||
--name foundryvtt \
|
||||
-p 30000:30000 \
|
||||
-v /path/to/data:/foundryvtt/data:Z \
|
||||
--hostname $(hostname) \
|
||||
registry.belway.me/public/foundryvtt:latest
|
||||
```
|
||||
|
||||
> **Note:** Set `--hostname` to your server's hostname to avoid re-accepting the license on each restart.
|
||||
|
||||
## Building the Container
|
||||
|
||||
### Prerequisites
|
||||
- A valid FoundryVTT license
|
||||
- The timed download URL from your FoundryVTT account (Purchased Licenses → Linux/NodeJS)
|
||||
|
||||
### Manual Build
|
||||
```bash
|
||||
./build.sh -U "$FOUNDRY_URL" -I -v "$VERSION"
|
||||
```
|
||||
|
||||
### CI/CD
|
||||
The repository includes a Gitea Actions workflow that automatically builds when:
|
||||
- Changes are pushed to `main` branch
|
||||
- Manually triggered via workflow dispatch
|
||||
|
||||
Required secrets:
|
||||
- `FOUNDRY_URL` - Timed download URL from FoundryVTT
|
||||
- `BELWAY_REGISTRY_USER` / `BELWAY_REGISTRY_TOKEN` - Registry credentials
|
||||
|
||||
## Running with Quadlets (Recommended)
|
||||
|
||||
Create a quadlet file at `~/.config/containers/systemd/foundryvtt.container`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=FoundryVTT Custom Container
|
||||
Requires=var-mnt-data01.mount
|
||||
Description=FoundryVTT Virtual Tabletop
|
||||
After=network-online.target
|
||||
|
||||
[Container]
|
||||
AutoUpdate=registry
|
||||
HostName=${VM_HOSTNAME}
|
||||
Image=registry.belway.me/public/foundryvtt_container:latest
|
||||
Label=registry
|
||||
Network=slirp4netns:port_handler=slirp4netns
|
||||
Image=registry.belway.me/public/foundryvtt:latest
|
||||
HostName=your-server-hostname
|
||||
PublishPort=30000:30000
|
||||
Timezone=America/Montreal
|
||||
Volume=${YOUR_DATA_DIRECTORY_HERE}:/foundryvtt/foundrydata:z
|
||||
Volume=/path/to/your/data:/foundryvtt/data:Z
|
||||
|
||||
# Healthcheck at runtime (OCI images don't include healthcheck)
|
||||
HealthCmd=curl -f http://localhost:30000 || exit 1
|
||||
HealthInterval=30s
|
||||
HealthTimeout=10s
|
||||
HealthStartPeriod=60s
|
||||
HealthRetries=3
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
@ -35,8 +78,55 @@ Restart=always
|
||||
WantedBy=multi-user.target default.target
|
||||
```
|
||||
|
||||
Then as the user, run:
|
||||
Then start the service:
|
||||
```bash
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user start foundryvtt
|
||||
systemctl --user enable foundryvtt
|
||||
```
|
||||
|
||||
## Healthcheck Options
|
||||
|
||||
Since OCI-compliant images don't include healthchecks, add them at runtime:
|
||||
|
||||
### With podman run:
|
||||
```bash
|
||||
podman run -d \
|
||||
--name foundryvtt \
|
||||
--health-cmd="curl -f http://localhost:30000 || exit 1" \
|
||||
--health-interval=30s \
|
||||
--health-timeout=10s \
|
||||
--health-start-period=60s \
|
||||
-p 30000:30000 \
|
||||
-v /path/to/data:/foundryvtt/data:Z \
|
||||
registry.belway.me/public/foundryvtt:latest
|
||||
```
|
||||
|
||||
### With Quadlet:
|
||||
Add to `[Container]` section:
|
||||
```ini
|
||||
HealthCmd=curl -f http://localhost:30000 || exit 1
|
||||
HealthInterval=30s
|
||||
HealthTimeout=10s
|
||||
HealthStartPeriod=60s
|
||||
```
|
||||
|
||||
## Volume Mounts
|
||||
|
||||
| Container Path | Purpose |
|
||||
|---------------|---------|
|
||||
| `/foundryvtt/data` | Persistent data (worlds, systems, modules) |
|
||||
|
||||
## Ports
|
||||
|
||||
| Port | Protocol | Purpose |
|
||||
|------|----------|---------|
|
||||
| 30000 | TCP | Web interface |
|
||||
|
||||
## Environment Variables
|
||||
|
||||
FoundryVTT supports various command-line options that can be passed as arguments. See the [official documentation](https://foundryvtt.com/article/configuration/) for details.
|
||||
|
||||
## License
|
||||
|
||||
See [LICENSE](LICENSE) file.
|
||||
|
||||
44
build.sh
44
build.sh
@ -12,7 +12,7 @@
|
||||
####################################################################
|
||||
# General Variables
|
||||
REGISTRY="registry.belway.me"
|
||||
REGISTRY_NAMESPACE="public/foundryvtt_container"
|
||||
REGISTRY_NAMESPACE="public/foundryvtt"
|
||||
|
||||
###############################################################################################################################
|
||||
# Functions
|
||||
@ -24,18 +24,17 @@ cat << EOF
|
||||
|
||||
usage: ${SCRIPT_NAME} [options]
|
||||
|
||||
This script exports data from one database to be compared with data from another database
|
||||
This script builds the FoundryVTT container and pushes to the registry.
|
||||
|
||||
OPTIONS:
|
||||
-D Enable DEBUG mode
|
||||
-f Custom Containerfile with absolute or relative directory
|
||||
-F Format of containerfile
|
||||
-F Format of containerfile (default: oci)
|
||||
-h Show this message
|
||||
-I Initialize the registry
|
||||
-n Node version
|
||||
-R For rebuild the image.
|
||||
-S Scheduled build, should only be used by automation (gitea actions).
|
||||
-U Foundry URL for downloading the version
|
||||
-R Rebuild the image
|
||||
-S Scheduled build, should only be used by automation (gitea actions)
|
||||
-U Foundry URL for downloading the version (required)
|
||||
-v Version to build, defaults to 'latest'
|
||||
EOF
|
||||
exit 1
|
||||
@ -59,9 +58,6 @@ get_parameters() {
|
||||
"I")
|
||||
INITIALIZE="TRUE"
|
||||
;;
|
||||
"n")
|
||||
NODEJS_VERSION="$OPTARG"
|
||||
;;
|
||||
"R")
|
||||
OPT_REBUILD="TRUE"
|
||||
;;
|
||||
@ -71,7 +67,7 @@ get_parameters() {
|
||||
"U")
|
||||
FOUNDRY_URL="$OPTARG"
|
||||
if [[ "$FOUNDRY_URL" != *"verify"* ]]; then
|
||||
echo "Not a valid foundry URL, please use the TIMED URL option when at the Purchased LIcenses page on foundry website in your account."
|
||||
echo "Not a valid foundry URL, please use the TIMED URL option when at the Purchased Licenses page on foundry website in your account."
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
@ -104,7 +100,7 @@ get_parameters() {
|
||||
fi
|
||||
|
||||
if [[ -z $OPT_FORMAT_TYPE ]]; then
|
||||
OPT_FORMAT="--format docker"
|
||||
OPT_FORMAT="--format oci"
|
||||
elif [[ $OPT_FORMAT_TYPE == "podman" ]]; then
|
||||
OPT_FORMAT=""
|
||||
else
|
||||
@ -133,10 +129,6 @@ get_parameters() {
|
||||
OPT_REBUILD="FALSE"
|
||||
fi
|
||||
|
||||
if [[ -z $NODEJS_VERSION ]]; then
|
||||
NODEJS_VERSION=$(curl https://foundryvtt.com/article/installation/ | grep nodesource | grep rpm | tr -d -c 0-9)
|
||||
fi
|
||||
|
||||
TAG="$OPT_VERSION"
|
||||
|
||||
}
|
||||
@ -149,7 +141,11 @@ container_initialize() {
|
||||
fi
|
||||
echo "Initializing container build..."
|
||||
podman login ${REGISTRY}
|
||||
podman build -f ${OPT_CONTAINERFILE} -t ${REGISTRY}/${REGISTRY_NAMESPACE}:${TAG} -t ${REGISTRY}/${REGISTRY_NAMESPACE}:latest --build-arg foundry_url=${FOUNDRY_URL} --build-arg nodejs_version=${NODEJS_VERSION}
|
||||
podman build ${OPT_FORMAT} -f ${OPT_CONTAINERFILE} \
|
||||
-t ${REGISTRY}/${REGISTRY_NAMESPACE}:${TAG} \
|
||||
-t ${REGISTRY}/${REGISTRY_NAMESPACE}:latest \
|
||||
--build-arg FOUNDRY_URL="${FOUNDRY_URL}" \
|
||||
--build-arg FOUNDRY_VERSION="${TAG}"
|
||||
podman push ${REGISTRY}/${REGISTRY_NAMESPACE}:${TAG}
|
||||
podman push ${REGISTRY}/${REGISTRY_NAMESPACE}:latest
|
||||
podman logout ${REGISTRY}
|
||||
@ -158,9 +154,13 @@ container_initialize() {
|
||||
|
||||
container_scheduled_build() {
|
||||
echo "Scheduled build starting..."
|
||||
if [[ "${CADDY_IMAGE_VERSION}" != "${STABLE[0]}" ]]; then
|
||||
if [[ "${FOUNDRY_IMAGE_VERSION}" != "${STABLE[0]}" ]]; then
|
||||
podman login ${REGISTRY}
|
||||
podman build -f ${OPT_CONTAINERFILE} -t ${REGISTRY}/${REGISTRY_NAMESPACE}:${TAG} -t ${REGISTRY}/${REGISTRY_NAMESPACE}:latest --build-arg foundry_url=${FOUNDRY_URL}
|
||||
podman build ${OPT_FORMAT} -f ${OPT_CONTAINERFILE} \
|
||||
-t ${REGISTRY}/${REGISTRY_NAMESPACE}:${TAG} \
|
||||
-t ${REGISTRY}/${REGISTRY_NAMESPACE}:latest \
|
||||
--build-arg FOUNDRY_URL="${FOUNDRY_URL}" \
|
||||
--build-arg FOUNDRY_VERSION="${TAG}"
|
||||
podman push ${REGISTRY}/${REGISTRY_NAMESPACE}:${TAG}
|
||||
podman push ${REGISTRY}/${REGISTRY_NAMESPACE}:latest
|
||||
podman logout ${REGISTRY}
|
||||
@ -174,7 +174,11 @@ container_scheduled_build() {
|
||||
container_rebuild() {
|
||||
echo "Rebuilding container..."
|
||||
podman login ${REGISTRY}
|
||||
podman build -f ${OPT_CONTAINERFILE} -t ${REGISTRY}/${REGISTRY_NAMESPACE}:${TAG} -t ${REGISTRY}/${REGISTRY_NAMESPACE}:latest --build-arg foundry_url=${FOUNDRY_URL}
|
||||
podman build ${OPT_FORMAT} -f ${OPT_CONTAINERFILE} \
|
||||
-t ${REGISTRY}/${REGISTRY_NAMESPACE}:${TAG} \
|
||||
-t ${REGISTRY}/${REGISTRY_NAMESPACE}:latest \
|
||||
--build-arg FOUNDRY_URL="${FOUNDRY_URL}" \
|
||||
--build-arg FOUNDRY_VERSION="${TAG}"
|
||||
podman push ${REGISTRY}/${REGISTRY_NAMESPACE}:${TAG}
|
||||
podman push ${REGISTRY}/${REGISTRY_NAMESPACE}:latest
|
||||
podman logout ${REGISTRY}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user