IMPORTANT: |
---|
In the Hannover sprint, we decided to mutate this repository into an easy howto for running OJS with the official dockerHub containers. This is now the recommended way to run dockerized OJS in test and production. |
To be safe in case dockerHub changes it's usage terms and to test alternative CI/CD tools, we also created a temporary gitLab repository, that is the one we use to build the images you can find in dockerHub. This is a temporary change as most likely in the near future, we will move back to this same repository and use gitHubActions. Sorry for the inconvenience. |
Anyway, generated in gitLab or gitHub, as long as it is a free service, we will keep pushing images to dockerHub. |
Open Journal Systems (OJS) is a journal management and publishing system that has been developed by the Public Knowledge Project through its federally funded efforts to expand and improve access to research.
The images in this repository are built on top of Alpine Linux and come in several variants (see Versions).
This project is maintained by Marc Bria. This repository is a fork of the work formerly done by Lucas Dietrich and Marc Bria
Be sure you properly installed docker
and docker-compose
and the docker
service is running.
git clone https://github.com/pkp/docker-ojs.git
mv docker-ojs journalName && cd journalName
mv .env.TEMPLATE .env
vim .env # Set environment variables as you wish (ojs version, ports, url...)
source .env && wget "https://github.com/pkp/ojs/raw/${OJS_VERSION}/config.TEMPLATE.inc.php" -O ./volumes/config/ojs.config.inc.php
sudo chown 100:101 ./volumes -R && chown 999:999 ./volumes/db -R # Ensure folders got the propper permissions
docker compose up -d
# Visit your new site and complete the installation as usual (Read about DB access credentials below, in step 5).
If you want to run it locally (or in your own server), first you need to install docker (even docker-compose it's also recommended).
You can have it all up and running in less than 10 minutes following this brief howto: https://www.digitalocean.com/community/tutorials/how-to-install-docker-compose-on-debian-10
After this, notice that for all available versions, we provide a docker-compose configuration file so you will be able to start a full OJS stack (web app + database containers) in 4 easy steps:
Clone this repository in your machine (if youprefer, you can also download and unzip it):
$ git clone https://github.com/pkp/docker-ojs.git
$ mv docker-ojs journalName && cd journalName
Replace "journalName" with a short name of your journal (probably you will like to set the same value you use for COMPOSE_PROJECT_NAME variable).
Set your environment variables
$ mv .env.TEMPLATE .env
Edit your .env file to fit your need to fit your needs. You will probably like to chage your OJS_VERSION, ports, and names. For a detailed description of all the environment variables take a look to "Environment Variables" sectionj.
Download the ojs config file related to your desired version
$ source .env && wget "https://github.com/pkp/ojs/raw/${OJS_VERSION}/config.TEMPLATE.inc.php" -O ./volumes/config/ojs.config.inc.php
If your are running docker on windows (with Powershell), specify the version you like to download:
$ wget "https://github.com/pkp/ojs/raw/3_3_0-14/config.TEMPLATE.inc.php" -O ./volumes/config/ojs.config.inc.php
Run the stack:
$ docker compose up
Docker-compose will pull images from dockerHub and do all the hard work for you to rise a full functional OJS stack. If all goes as expected you will see your app_container informing apache is RUNNING successfully.
INFO success: apache entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
You can add the "-d" parameter to the call if you like to run it detached.
Access http://127.0.0.1:8081 and continue through web installation process.
Note that the database connection needs the following options:
mysqli
(or "mysql" if your php is lower than 7.3)db
(which is the name of the container in the internal Docker network)ojs
ojs
(change with the password you set in your environment variables)ojs
And the "Directory for uploads:" acording to your docker-compose.yml "/var/www/files"
TIP: |
---|
To go through the OJS installation process automatically, set the environment variable OJS_CLI_INSTALL=1 , and use the other .env variables to automatize the process. |
That's all. Easy peasy, isn't it?
Ok, let's talk talk about more complex concepts and scenarios.
Different OJS versions are combined with different versions of PHP (5 to 8...). In future we are planning to add variants with different web servers (Apache HTTP Server, nginx) and tools.
Currently, not all these combinations work! We are mostly focused in Apache2. PR are welcome
All version tags can be found at Docker Hub Tags tab.
(If no webserver is mentioned in the tag, then Apache is used).
The image understand the following environment variables:
NAME | Default | Info |
---|---|---|
SERVERNAME | localhost | Used to generate httpd.conf and certificate |
OJS_IMAGE | ojs | PKP tool to be used (ojs, omp, ops). Only OJS images avaliable right now |
OJS_VERSION | 3_3_0-14 | OJS version to be deployed |
COMPOSER_PROJECT_NAME | journal | |
OJS_CLI_INSTALL | 0 | Used to install ojs automatically when start container |
OJS_DB_HOST | db | Database host |
OJS_DB_USER | ojs | Database |
OJS_DB_PASSWORD | ojsPwd | Database password |
OJS_DB_NAME | ojs | Database name |
HTTP_PORT | 8081 | Http port |
HTTPS_PORT | 8481 | Https port |
_Note: OJS_CLIINSTALL and certificate features are under construction.
Docker content is efimerous by design, but in some situations you would like to keep some stuff persistent between docker restarts (ie: database content, upload files, plugin development...)
By default we include an structure of directories in the version folders (see ./volumes), but they are empty and disabled by default in your compose. To enable them, you only need to uncomment the volume lines in your docker-compose.yml and fill the folders properly.
When you run the docker-compose
it will mount the volumes with persistent
data and will let you share files from your host with the container.
Host | Container | Volume | Description |
---|---|---|---|
./volumes/public | ojs | /var/www/html/public | All public files |
./volumes/private | ojs | /var/www/files | All private files (uploads) |
./volumes/config/db.charset.conf | db | /etc/mysql/conf.d/charset.cnf | mariaDB config file |
./volumes/config/ojs.config.inc.php | ojs | /var/www/html/config.inc.php | OJS config file |
./volumes/config/php.custom.ini | ojs | /usr/local/etc/php/conf.d/custom.ini | PHP custom.init |
./volumes/config/apache.htaccess | ojs | /var/www/html/.htaccess | Apache2 htaccess |
./volumes/logs/app | ojs | /var/log/apache2 | Apache2 Logs |
./volumes/logs/db | db | /var/log/mysql | mariaDB Logs |
./volumes/db | db | /var/lib/mysql | mariaDB database content |
./volumes/migration | db | /docker-entrypoint-initdb.d | DB init folder (with SQLs) |
/etc/localtime | ojs | /etc/localtime | Sync clock with the host one. |
TBD | ojs | /etc/ssl/apache2/server.pem | SSL crt certificate |
TBD | ojs | /etc/ssl/apache2/server.key | SSL key certificate |
In this image we use "bind volumes" with relative paths because it will give you a clear view where your data is stored.
The down sides of those volumes is they can not be "named" and docker will store them with an absolute path (that it’s annoying to make stuff portable) but I prefer better control about where data is stored than leave it in docker hands.
And remember this is just an image, so feel free to modify to fit your needs.
You can add your own volumes. For instance, make sense for a plugin developer or a themer to create a volume with his/her work, to keep a persistent copy in the host of the new plugin or theme.
An alternative way of working for developers is working with his/her own local Dockerfile that will be build to pull the plugin for his/her own repository... but this will be significantly slower than the volume method.
Last but not least, those storage folders need to exist with the right permissions
before you run your docker compose
command or it will fail.
To be sure your volumes have the right permissions, you can run those commands:
$ chown 100:101 ./volumes -R
$ chown 999:999 ./volumes/db -R
$ chown 999:999 ./volumes/logs/db -R
In other words... all the content inside volumes will be owned by apache2 user and group (uid 100 and gid 101 inside the container), execpt for db and logs/db folders that will be owned by mysql user and group (uid and gid 999).
The Dockerfile includes some scritps at "/usr/local/bin" to facilitate common opperations:
Script | Container | Description |
---|---|---|
ojs-run-scheduled | ojs | Runs "php tools/runScheduledTasks.php". Called by cron every hour. |
ojs-cli-install | ojs | Uses curl to call the ojs install using pre-defined variables. |
ojs-pre-start | ojs | Enforces some config variables and generates a self-signed cert based on ServerName. |
ojs-upgrade | ojs | Runs "php tools/upgrade.php upgrade". (issue when config.inc.php is a volume) |
ojs-variable | ojs | Replaces the variable value in config.inc.php (ie: ojs-variable variable newValue) |
ojs-migrate | ojs | Takes a dump.sql, public and private files from "migration" folder and builds and builds a docker site (beta) |
Some of those scripts are still beta, you be careful when you use them.
You can call the scripts outside the container as follows:
$ docker exec -it ojs_app_journalname /usr/local/bin/ojs-variable session_check_ip Off
Thanks to docker, the ugrade process is easy and straightforward.
Stop the stack with the old OJS version (for instance "pkpofficial/ojs:2_4_8-5").
docker compose stop
Set the new version in docker-compose.yml.
Replace the old version: image: pkpofficial/ojs:2_4_5-2
with the new one: image: pkpofficial/ojs:3_2_1-4
Start the container. As you changed the version, docker-compose will automatically pull a new image with an updated version of the OJS code that will replace the old one (remember that containers are not persistent).
$ docker compose up
Run the upgrade script to upgrade the OJS database and files. Easiest was is connecting to your OJS container with docker exec
and run the ojs-upgrade
built in script with this single line:
$ docker exec -it ojs_app_journalname /usr/local/bin/ojs-upgrade
TIP: Discover your container name? |
---|
You can see the name of all your containers with docker ps -a . The ones related with OJS will be something like ojs_app_journalname . |
Use grep to filter as follows: $ docker ps -a | grep ojs_app |
Before the upgrade you will like to diff your config.inc.php
with the version of the new OJS version to learn about new configuration variables. Be specially carefully with the charsets.
WARNING: May I upgrade directly to the last OJS stable version? |
---|
It depends on your initial version. The recommended upgrade route is: 2.x > 2.4.8-5 > 3.1.2-4 > 3.2.1-4 > 3.3.x-x |
As said, right now the only avaliable stack is Apache2, so configuration files and volumes are thought you will work over an apache.
If you want to know the fastest method to set your own config jump to the next section "Easy way to change config stuff".
For those who like to understand what happens behind the courtains, you need to
know that during the image building we ask the Dockerfile to copy the content of
./templates/webServers/apache/phpVersion/root
folder in the root
of your container.
It means, if you like to add your specific php settings you can do it
creating a PHP configuration in ./templates/webServers/php{5,7,73}/conf.d/0-ojs.ini
and build you own image locally.
There are some optimized variables already, you can check them within each
version directory, e.g. /root/etc/apache2/conf.d/ojs.conf
with your virtualhost
or /etc/supervisor.conf
... or, now you know what Dockerfile will do, you
can add your own.
Again: Note that template's /root folder is copied into the Docker image at build time so, if you change it, you must rebuild the image for changes to take effect.
If you don't want to keep you own local images, you can use the ones we
build in dockerHub and map your config files in your docker-compose.yml
.
So if you like to change something in (for instance) your php settings,
you only need to created create a ./volumes/config/php.custom.ini
outside your container and uncomment the volume in your docker-compose.yml
.
Check the volumes section for a list of folders and files we think could be useful to overwrite or extend to fit your needs.
By default the restful_url are enabled and Apache is already configured, so there is no need to use index.php over url.
By default at the start of Apache one script will check if the SSL certificate
is valid and its CN matches your SERVERNAME, if don't it will generate a new one.
The certificate can be overwritten using a volume mount (see docker-compose.yml
file).
Note: This feature is under reveiw and could change in future.
If you have an external service in front handling SSL connections (often referred as
SSL offloading or SSL termination) you need to add a new line containing
PassENV HTTPS
in ojs.conf
, inside the main <VirtualHost *:80>
section.
If you want to join the docker-ojs (aka. docker4ojs) team you will like to contribute with new Dockerfiles or docker-composes. To do this, you will need to clone this project and send us a PR with your contributions.
Before we follow, let us clarify something: Versions of this project fit with OJS tag versions, BUT... if you take a look to PKP's repositories, you will notice the tag naming syntax changed at version 3.1.2-0. We moved from "ojs-3_1_2-0" to "3_1_2-0".
So, to avoid keeping in mind at what momment we changed the syntax, in this project we only use the modern syntax, so you cant/must refer every version with the same notation.
Said this, let's talk about how we generate all this versions:
The files for the different OJS versions and software stacks are generated based
on a number of template files, see directory templates
.
You can re-generate all Dockerfile
, docker-compose(-local).yml
, configuration
files, etc. calling the build.sh
script.
# generate a specific version
$ ./build.sh 3_1_2-4
# generate _all_ versions
$ ./build.sh
Let's say we like us to distribute a "nginx" stack. We have our hands full but you know docker and nginx so... ¿how could you contribute?
Be sure the version number is in the versions.list file (ie: 3_2_1-0).
Create the required files and folders in the templates folder.
Basically you will need:
docker-compose.yml
template (templates/dockerComposes/docker-compose-nginx.template)This is the hard work. Take apache as a reference and contact us if you need indications.
Edit build.sh to add your version to the proper variables.
For the nginx exemple (over alpine) it should be enough extending the webServers array:
webServers=( 'apache' 'nginx' )
Modify the script if you need it to be smarter.
Run build script to generate all versions again:
$ ./build.sh
Test your work running docker compose
with local dockerfiles.
Commit a PR with your new build.sh and templates (ignore the versions folder).
In general with docker, there are some known issues with the new Mac’s ARM architecture : https://stackoverflow.com/questions/73294020/docker-couldnt-create-the-mpm-accept-mutex . Alternative solution (other than hardcoding mutex settings) might be to build docker image also for arm64 platform (https://github.com/bitnami/containers/issues/4679). Some work was started in this line in gitLab building pipelines with promising preliminary results.
Instructions to run are for linux (as fas as linux is the natural platform for docker and servers) but is also possible to run it in windows. The wget instructions use variables defined in the env-file but this is not compatible with windows powershell, so would be nice to find an alternative that works all platforms. As a temporary solution we add clear instructions for windows users, that need to modify the inliner to get the right version of the config.TEMPLATE file.
A nice addition for docker images would be offer nginx image to replace the existing apache2.
One thing you always will need to deal with is plugins. This is now possible but could be improved with a few ideas that appear during the sprint as:
The project is build based on the needs of the participants. If you like to join, contact marc.bria@uab.cat. There is no formal roadmap, but we like to implement all the suggestion we made in the Containers for PKP document. Priorities right now are (by order):
GPL3 © PKP