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"