Containers

uBlog containers

uBlog is available at Docker hub.

Quickstart

Pull and execute the image.

podman run --rm \
  -p 127.0.0.1:8080:8080 \
  docker.io/ublog/ublog:1.0.0

Log in using admin / test.

Configuration

uBlog can be configured either via an app.properties placed into the execution paths root or by environment variables. Environment variables take precedence before app.properties. Every configuration attribute has a default set by the application.

Folder configuration

uBlog expects a few folders to be available for its operation. By default all folders are present in the container image for demo purposes. It is recommended to override these folders when running in production.

Folder name Env. variable Key in app.properties Container default Description
Blog folder BLOG_FOLDER blog.folder /app/blogFolder It is used as the root for the blogs markdown entries. Two files are to be expected in this folder: Index.md and Error.md.
File folder FILE_FOLDER file.folder /app/fileFolder Used to store uploaded files.
Image folder IMAGE_FOLDER image.folder /app/imageFolder Used to store uploaded image files.
User folder USER_FOLDER user.folder /app/userFolder Folder containing the user property files.
Template folder MUSTACHE_TEMPLATES_FOLDER mustache.templates.folder /app/template/personal Folder containing the templates to be used by uBlog.

Additional configuration values are following.

The following configuration values can be changed to increase performance.

Env. variable Key in app.properties Container default Description
LOG_LEVEL log.level ERROR Log level to be used by uBlog. Values are: ERROR, WARNING, INFO, TRACE, DEBUG.
SITE_BASE_URL `` The base URL to be used for sitemap.xml and robots.txt.
MUSTACHE_TEMPLATES_CACHING_ENABLED mustache.templates.caching.enabled true Turns template caching on / off. If caching is turned off, templates are re-parsed upon every request.
MUSTACHE_TEMPLATE_UPDATE mustache.template.update false The mustache implementation used by uBlog can check for changes in the templates before executing. Set to true during development to reload changed templates without restarting uBlog.
MUSTACHE_CONTENT_CACHING_ENABLED true Enable caching of the rendered data omitting template render entirely.
MUSTACHE_CONTENT_CACHE_SIZE_KB 1024 Sets the size of the cache for the rendered pages.
SERVER_PORT server.port 8080 Default server port used by the uBlog webesrver.
SESSION_TIMEOUT session.timeout 60 Timeout for a session created. By default set to 60 minutes.
SESSION_COOKIE_SECURE session.cookie.secure false If set to true, the Secure flag is set on the session cookie.
SOCKET_HANDLER_THREAD_POOL_SIZE socket.handler.thread.pool.size 10 Size of the socket handler thread pool.
SOCKET_HANDLER_QUEUE_CAPACITY socket.handler.queue.capacity 100 The amount of connections waiting in the queue before discarding new connections.

User configuration

Users are configured via simple property files. The name of the property file is the username used during log in. E.g. admin.properties or mike2345.properties.

By default the container image contains an administrator user with login admin and password test. The configuration for the administration is in the containers /app/userFolder/admin.properties with the following values.

password=test
name=John Doe
status=active
editor=true

The password is either plaintext as in the example, or hashed using Argon2id upon first login.

The name is merely decorative, shown in the user settings view.

The status is checked upon login. If user is set to inactive, login for that user is denied.

The editor if set to true, the user can create, delete and modify entries, files, settings etc. and is able to see unlisted entries. If set to false the user will see unlisted entries but not do any changes on the system.

MCP

uBlog offers MCP integration. You have to have a user for which you generate a bearer token which is then used to connect to the /mcp endpoint. If the user who is connected to the token is created as an editor, the MCP client is able to create unpublished entries. Otherwise it is only reading entries and categories.

Initial setup and execution

uBlog by default comes with a single admin user and a few pages to browse around. It is recommended to re-define the folders and crate the files necessary for a first successful execution.

The Index.md and Error.md are expected to be present in the folder defined in BLOG_FOLDER. The Index.md is used as a default view rendered at root level / or /index. The Error.md is rendered in case of an error.

At least one user should be created to be able to log in. Create a user according to the example above and mount an external USER_FOLDER.

Security notice: The container includes a demonstration administrator account (admin / test). Do not expose the default installation to the public internet. For production, mount a separate user directory containing your own credentials and use HTTPS.

The IMAGE_FOLDER and FILE_FOLDER should point to two different folders.

It is recommended to use an external template folder to be able to do necessary modifications.

Example of a script to download the image and execute it by using externalized folders.


#!/usr/bin/env bash
set -euo pipefail

ENGINE="${ENGINE:-podman}"
IMAGE="docker.io/ublog/ublog:1.0.0"
CONTAINER="ublog"
BASE_DIR="${BASE_DIR:-$PWD/ublog-data}"

# 1. Create directories
mkdir -p \
    "$BASE_DIR/template" \
    "$BASE_DIR/blog" \
    "$BASE_DIR/image" \
    "$BASE_DIR/file" \
    "$BASE_DIR/user"

# 2. Pull the image
echo "Pulling uBlog..."
"$ENGINE" pull "$IMAGE"

# 3. Initialize templates from the container image
if [ -z "$(ls -A "$BASE_DIR/template")" ]; then
    echo "Installing default templates..."

    TEMP_CONTAINER=$("$ENGINE" create "$IMAGE")

    "$ENGINE" cp \
        "$TEMP_CONTAINER:/app/template/." \
        "$BASE_DIR/template/"

    "$ENGINE" rm "$TEMP_CONTAINER"
fi

# 4. Create an example administrator
if [ ! -f "$BASE_DIR/user/admin.properties" ]; then
    ADMIN_PASSWORD=$(openssl rand -hex 12)

    cat > "$BASE_DIR/user/admin.properties" <<EOF
name=Administrator
password=$ADMIN_PASSWORD
status=active
EOF

    echo "Administrator created."
    echo "Username: admin"
    echo "Password: $ADMIN_PASSWORD"
    echo "Save this password."
fi

# 5. Create example content
if [ ! -f "$BASE_DIR/blog/Index.md" ]; then
    cat > "$BASE_DIR/blog/Index.md" <<'EOF'
# Welcome to uBlog!

Your new blog is up and running.

Log in as the administrator to start creating
topics and writing Markdown entries.

For documentation, visit:
https://github.com/szabogabriel/ublog
EOF
fi

if [ ! -f "$BASE_DIR/blog/Error.md" ]; then
    cat > "$BASE_DIR/blog/Error.md" <<'EOF'
# Something went wrong

The requested page could not be found,
or an error occurred.

[Return to homepage](/)
EOF
fi

# 6. Start container
if "$ENGINE" container inspect "$CONTAINER" >/dev/null 2>&1; then
    echo "Container '$CONTAINER' already exists."
    echo "Remove it before recreating:"
    echo "  $ENGINE rm -f $CONTAINER"
    exit 1
fi

echo "Starting uBlog..."

"$ENGINE" run -d \
    --name "$CONTAINER" \
    --restart unless-stopped \
    -p 127.0.0.1:8080:8080 \
    -e BLOG_FOLDER=/app/blogFolder \
    -e USER_FOLDER=/app/userFolder \
    -e IMAGE_FOLDER=/app/imageFolder \
    -e FILE_FOLDER=/app/fileFolder \
    -e MUSTACHE_TEMPLATES_FOLDER=/app/template/personal \
    -v "$BASE_DIR/blog:/app/blogFolder:Z" \
    -v "$BASE_DIR/user:/app/userFolder:Z" \
    -v "$BASE_DIR/image:/app/imageFolder:Z" \
    -v "$BASE_DIR/file:/app/fileFolder:Z" \
    -v "$BASE_DIR/template:/app/template:Z" \
    "$IMAGE"

echo
echo "uBlog is starting!"
echo "Visit: http://localhost:8080"
echo "Data directory: $BASE_DIR"