Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# syntax=docker/dockerfile:1.20.0
ARG BASE_IMAGE=libops/ojs:php83
ARG BASE_IMAGE=libops/ojs:nginx-1.30.3-php84
FROM ${BASE_IMAGE}

ARG TARGETARCH
Expand Down
40 changes: 14 additions & 26 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,33 +1,21 @@
.PHONY: build deps init init-if-needed up down rollout lint run test
SHELL := /bin/bash

DOCKER_IMAGE=libops/ojs:php83
.PHONY: help rollout test lint
.SILENT:

deps:
docker compose pull --ignore-buildable
-include custom.Makefile

build: deps
docker compose build --pull
help: ## Show this help message
echo 'Usage: make [target]'
echo ''
echo 'Available targets:'
awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " \033[36m%s\033[0m\t%s\n", $$1, $$2}' $(MAKEFILE_LIST) | sort | column -t -s $$'\t'

lint:
./scripts/lint.sh


init: build
docker compose run --rm init

init-if-needed: build
./scripts/init-if-needed.sh

up: init-if-needed
docker compose up --remove-orphans -d

down:
docker compose down

rollout:
rollout: ## Roll out the currently checked out OJS stack
./scripts/rollout.sh

run: up

test:
test: ## Run template checks
./scripts/test.sh

lint: ## Lint template files
./scripts/lint.sh
169 changes: 53 additions & 116 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,146 +1,83 @@
# Open Journal Systems (OJS) Docker Container
# Open Journal Systems Docker Template

Dockerized deployment of [Open Journal Systems](https://pkp.sfu.ca/software/ojs/) based on the [Islandora Buildkit](https://github.com/Islandora-Devops/isle-buildkit) OJS PHP/nginx base image.
LibOps Docker Compose template for running [Open Journal Systems](https://pkp.sfu.ca/software/ojs/) with Traefik, MariaDB, and the LibOps OJS PHP/nginx image.

## Quick Start

```bash
make up
```

Access OJS at `http://localhost`.

`make up` runs `scripts/init-if-needed.sh`, which inspects the rendered Docker Compose config and only runs the `init` service when required secrets or named volumes are missing.

The installation will run automatically on first startup. The default admin credentials are:
- Username: `admin` (configurable via `OJS_ADMIN_USERNAME`)
- Password: Contents of `./secrets/OJS_ADMIN_PASSWORD`
- Email: `admin@example.com` (configurable via `OJS_ADMIN_EMAIL`)

## Configuration

### OJS Configuration

| Environment Variable | Default | Source | Description |
| :------------------- | :------ | :----- | :---------- |
| DB_HOST | mariadb | environment | MariaDB hostname |
| DB_PORT | 3306 | environment | MariaDB port |
| DB_NAME | ojs | environment | Database name |
| DB_USER | ojs | environment | Database user |
| DB_PASSWORD | (generated) | secret | Database password (stored in `./secrets/OJS_DB_PASSWORD`) |
| OJS_SALT | (generated) | secret | Salt for password hashing (stored in `./secrets/OJS_SALT`) |
| OJS_API_KEY_SECRET | (generated) | secret | Secret for API key encoding (stored in `./secrets/OJS_API_KEY_SECRET`) |
| OJS_SECRET_KEY | (generated) | secret | Internally this is used for any encryption (specifically cookie encryption if enabled) (stored in `./secrets/OJS_SECRET_KEY`) |
| OJS_ADMIN_USERNAME | admin | environment | Initial admin username |
| OJS_ADMIN_EMAIL | admin@example.com | environment | Initial admin email |
| OJS_ADMIN_PASSWORD | (generated) | secret | Initial admin password (stored in `./secrets/OJS_ADMIN_PASSWORD`) |
| OJS_LOCALE | en | environment | Primary locale/language |
| OJS_TIMEZONE | UTC | environment | System timezone |
| OJS_FILES_DIR | /var/www/files | environment | Directory for uploaded files |
| OJS_OAI_REPOSITORY_ID | ojs.localhost | environment | OAI-PMH repository identifier |
| OJS_ENABLE_BEACON | 1 | environment | Enable PKP usage statistics beacon (1=enabled, 0=disabled) |
| OJS_SESSION_LIFETIME | 30 | environment | How long to stay logged in (in days) |
| OJS_X_FORWARDED_FOR | Off | environment | Trust X-Forwarded-For header. Enable PKP usage statistics beacon (Off, On) |
| OJS_SMTP_SERVER | host.docker.internal | environment | SMTP server for outgoing mail; defaults to the Docker host relay |
| OJS_SMTP_PORT | 25 | environment | SMTP server port |
| OJS_DEFAULT_ENVELOPE_SENDER | (empty) | environment | Optional default envelope sender for outgoing mail |

OJS sends mail through the Docker host by default. On LibOps production hosts, the host MTA forwards to the managed relay; for local testing, copy `docker-compose.override-example.yaml` to `docker-compose.override.yaml` to add Mailpit and point OJS at `mailpit:1025`.

### Nginx and PHP Settings

See https://github.com/Islandora-Devops/isle-buildkit/tree/main/nginx#nginx-settings

## Ingress

Traefik is the only published ingress for the stack. The OJS container listens only on the internal Compose network, while Traefik publishes `${HOST_INSECURE_PORT:-80}` and routes requests to OJS.

`docker-compose.yaml` is the production-shaped default. Local development changes should be copied from `docker-compose.override-example.yaml` to `docker-compose.override.yaml`; the example only exposes MariaDB for debugging and does not change the ingress path.
## Requirements

- `sitectl` installed on the host that will run the site.
- Docker with the Compose v2 plugin installed on the same host.

Set `DOMAIN` to the site hostname and `ACME_EMAIL` to the Let's Encrypt registration email before enabling the TLS override.
## Quick start

## Secrets Management
Create a new OJS site from this template:

Secrets are stored in the `./secrets/` directory and mounted into the container at runtime. The `generate-secrets.sh` script creates secure random values for:

- `DB_ROOT_PASSWORD` - MariaDB root password
- `OJS_DB_PASSWORD` - OJS database user password
- `OJS_ADMIN_PASSWORD` - OJS admin user password
- `OJS_API_KEY_SECRET` - Secret for API key encoding/decoding
- `OJS_SALT` - Salt for password hashing

## Customization

You can customize the installation by:

1. Setting environment variables in `docker-compose.yaml`
2. Overriding default values in the Dockerfile
3. Adding custom plugins to `plugins/`
```bash
sitectl create ojs/default \
--template-repo https://github.com/libops/ojs \
--path ./my-ojs-site \
--type local \
--checkout-source template \
--default-context
```

### Adding Plugins
The site is served through Traefik at `http://localhost`. The first boot installs OJS automatically. The default admin account is `admin`; its password is generated in `./secrets/OJS_ADMIN_PASSWORD`.

Place plugin directories in the appropriate subdirectory under `plugins/`:
## Basic operations with sitectl

- `blocks/` - Block plugins
- `gateways/` - Gateway plugins
- `generic/` - Generic plugins
- `importexport/` - Import/export plugins
- `metadata/` - Metadata plugins
- `oaiMetadataFormats/` - OAI metadata format plugins
- `paymethod/` - Payment method plugins
- `pubIds/` - Public identifier plugins
- `reports/` - Report plugins
- `themes/` - Theme plugins
Run these from the generated checkout, or add `--context <name>` when operating from elsewhere.

Plugins with `composer.json` files will automatically have their dependencies installed during the build.
```bash
# Start or update the Compose stack
sitectl compose up --remove-orphans -d

## Volumes
# Check the site and context configuration
sitectl healthcheck
sitectl validate

The following volumes are created for data persistence:
# Update image tags or pin a full image reference
sitectl image set --tag ojs=nginx-1.30.3-php84
sitectl image set --image ojs=libops/ojs:nginx-1.30.3-php84@sha256:...

- `mariadb-data` - MariaDB database files
- `ojs-cache` - OJS cache files
- `ojs-files` - Uploaded files (submissions, etc.)
- `ojs-public` - Public files
# Enable local development bind mounts
sitectl set dev-mode enabled
sitectl converge

## Updating OJS Version
# Switch TLS modes
sitectl traefik tls mkcert --domain ojs.localhost
sitectl traefik tls letsencrypt --email ops@example.org

To update the OJS version, modify the `OJS_VERSION` build argument in the Dockerfile:
# Trust an upstream load balancer or reverse proxy
sitectl set reverse-proxy enabled --trusted-ip 203.0.113.10/32
sitectl converge

```dockerfile
ARG OJS_VERSION=3_5_0-3
# Raise upload limits for larger submissions
sitectl set upload-limits enabled --max-upload-size 2G --upload-timeout 10m
sitectl converge
```

Version tags follow the format used in the [PKP OJS repository](https://github.com/pkp/ojs/tags).
See the [OJS sitectl plugin docs](https://github.com/libops/sitectl-docs/blob/main/plugins/ojs.mdx) for lifecycle operations, OJS tools, PKP tools, and recurring maintenance.

## Troubleshooting
## Makefile

### Installation Logs

If the automatic installation fails, check the container logs:
The Makefile is intentionally small. It only keeps template-specific targets that are not core sitectl operations:

```bash
docker compose logs ojs
make rollout
make test
make lint
```

### Database Connection Issues

Ensure the MariaDB container is healthy before the OJS container starts:
Use `sitectl compose ...`, `sitectl traefik ...`, and `sitectl set ...` directly for normal stack operations.

```bash
docker compose ps
```
## Template notes

### Resetting Installation
- `traefik` is the only published ingress.
- `ojs` is built from this repository and based on the LibOps OJS PHP/nginx image.
- `mariadb` stores application data.
- Secrets are generated into `./secrets/`.
- Custom plugins can be added under `plugins/`.

To completely reset and reinstall:

```bash
docker compose down -v
docker compose run --rm init
docker compose up --remove-orphans -d
```
OJS sends mail through the Docker host by default. For local SMTP testing, use the override example to add Mailpit and point OJS at `mailpit:1025`.

## License

Expand Down
7 changes: 4 additions & 3 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ secrets:

services:
init:
image: libops/base@sha256:4a8d3997ac565981cd91ca36fd5a2b64955bac8d78a3632abd5a7137609be631
image: libops/base:3.2.2.0
restart: no
volumes:
- ./secrets:/secrets:rw
Expand All @@ -45,6 +45,7 @@ services:
- --providers.file.filename=/etc/traefik/dynamic/ojs.yml
- --providers.file.watch=true
- --entrypoints.web.address=:80
- --entrypoints.web.transport.respondingTimeouts.readTimeout=300s
environment:
DOMAIN: "${DOMAIN:-localhost}"
TRAEFIK_TLS_ENABLED: "false"
Expand All @@ -58,12 +59,12 @@ services:

ojs:
<<: *common
image: libops/ojs:php83
image: libops/ojs:nginx-1.30.3-php84
build:
context: .
pull: true
args:
BASE_IMAGE: libops/ojs:php83
BASE_IMAGE: libops/ojs:nginx-1.30.3-php84
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
Expand Down
Loading