Filtered by category Cookbook, 1 - 10 of 38 Postings (
all,
summary)
Created by Gustaf Neumann, last modified by Gustaf Neumann 06:54 PM, Friday
Motivation
State-changing operations (e.g., create/update/delete actions, membership or role management, administrative tasks) should not be reachable via HTTP GET requests.
GET requests are easy to trigger unintentionally or via social engineering (for example by clicking a link in an email). In modern browsers, session cookies with SameSite=Lax are still sent on cross-site top-level GET navigations, which makes such endpoints vulnerable to CSRF-style attacks if no additional protection is in place.
To reduce this attack surface, OpenACS applications can explicitly require HTTP POST for state-changing requests.
The ::template::require_post validator
The procedure ::template::require_post enforces that the current request uses the HTTP POST method. If the request is issued using any other method (typically GET), it returns a 405 Method Not Allowed response and aborts request processing.
This validator is intended to be used in the -validate blocks of ad_page_contract and ad_form.
Example A: Using require_post in ad_page_contract
ad_page_contract {
...
} -query {
email ...
} -validate {
method { require_post }
csrf { csrf::validate }
}
# Page implementation follows
In this example:
Placing the method check early in the validation phase ensures that invalid requests are rejected before any state-changing logic is executed.
Example B: Using require_post in ad_form
# If the data is not submitted via a POST request, bail out hard.
# The request might originate from a forged or unintended request.
ad_form \
-name myform \
-form {
{email:text {label "E-Mail"}} ...
} -validate {
{email
{ [require_post] }
"Only POST requests are allowed"
}
} -on_submit {
...
}
This pattern attaches the POST requirement directly to the form validation phase and ensures that the form submission cannot be triggered via a simple GET request.
Caveat: POST is not sufficient by itself
Requiring POST does not replace CSRF protection.
A determined attacker can still trigger cross-site POST requests (for example via auto-submitted forms). Proper CSRF protection therefore must include explicit CSRF token validation.
Requiring POST should be understood as a defense-in-depth measure:
-
It prevents accidental or link-based triggering of state-changing actions.
-
It improves the effectiveness of SameSite=Lax cookies.
-
It reduces the risk of subtle CSRF bugs caused by overlooked GET endpoints.
For full protection, state-changing endpoints should:
-
Require POST
-
Validate a CSRF token
-
(Optionally) perform "Origin" or "Referer" checks for high-risk administrative actions
When to use this pattern
Use require_post for:
-
administrative pages (e.g., under /admin)
-
role or permission changes
-
membership management
-
any operation that modifies server-side state
Do not use require_post for:
-
read-only pages
-
bookmarkable navigation URLs
-
search, filtering, or pagination endpoints
See also
Created by Gustaf Neumann, last modified by Gustaf Neumann 12:55 PM, Friday
Starting with OpenACS 5.9.1, OpenACS offers support for protecting against Cross Site Request Forgery (CSRF). In essence, this attack can cause a user’s web browser to perform an unwanted action on a trusted site for which the user is currently authenticated. The user gets a page presented, which looks harmless, but contains links or images that perform actions with the users credentials without the users consent. Note that the CSP does not protect a user against clicks on a malicious link.
CSRF protection works by ensuring that values for an action (e.g. by from a HTML form) are only accepted from a user that has received the form before. OpenACS generates by its security-procs a secure CSRF token value and provides it to a developer it in a global variable ::__csrf_token. When requests secured with the CSRF token are received, it can be validated on the server side. Note, that this mechanism is similar to "signing" values in OpenACS.
CSRF protection concerns of two parts: add the CSRF token to the form (POST requests) or to the href, and checking the received in the queries expecting input from CSRF protected resources. The first part works technically quite similar as securing CSP via nonces. Add code to the Tcl or ADP page that outputs the global variable (the test for the token is mostly for backwards compatibility)
<form ...>
...
<if @::__csrf_token@ defined>
<input type="hidden" name="__csrf_token" value="@::__csrf_token;literal@">
</if>
...
</form>
Secondly, the page contract on the receiving side has to validate the csrf token. This can be achieved by adding a call to csrf::validate to the validation part of a page contract.
ad_page_contract {
@author ...
@creation-date ...
} -query {
...
} -validate {
...
csrf { csrf::validate }
}
In the code base of OpenACS, CSRF protection was added on several places (e.g. public pages, the list template, etc.) such the checks of OpenACS sites on vulnerability scanners improve. Technically, it would be desirable to secure more places against CSRF attacks in the future. However, it depends on the requirements of a site whether e.g. the API browser or search should be CSRF protected. With protection turned on, one cannot share e.g. a link to a search with some other user (or a search engine). A site admin has to decide, how protected/public such links should be.
When using ad_form, the inclusion of the csrf token is done most conveniently via the -csrf_protection_p flag:
ad_form \
... \
-csrf_protection_p true
Created by Gustaf Neumann, last modified by Gustaf Neumann 02 Oct 2024, at 02:33 PM
The Docker images as presented at the OpenACS/Tcl conference 2024 (slides, recording for NaviServer and OpenACS are available at:
These images are available for Intel 64 bit and ARM 64 (e.g. Apple Silicon). See also the forums posts concerning these images:
Created by Gustaf Neumann, last modified by Gustaf Neumann 06 Aug 2024, at 11:54 AM
This page describes the requirements for managing packages with external libraries.
Requirements:
- R1) Make it possible for users to use always the newest version
- R2) Make it possible to pin a version number, although a newer default version is configured by OpenACS
- R3) It should be possible to copy the database of the production instance to a staging instance without affecting the version number of the external library on the staging instance. The version number on the staging instance might be different to the production site.
When a version is pinned, the site administrator has to change the version number manually, when an upgrade is desired.
OpenACS policy:
The "newest" version is the default version as configured into a package. When upgrading the package, the "newest" version might change.
How to pin a version number:
- Pin version number via configuration file: This works exactly like setting other package parameters via configuration files. Check out the instructions on the site-wide admin page of the package.
- Pin version number via package parameter: The easiest way is to add the parameter via the site-wide admin page. It is always possible to modify the parameter this way or to remove the package parameter (i.e., switch to R1).
Site policies:
Always get the newest tested version tested upstream (use default versions, R1)
Set a different version on the production site than on staging/testing instances:
-
Pin the version number via configuration file on the production instance (R2, R3)
-
On the testing instances, you can use the default version, or fix the version number via configuration file or global package parameter.
Use always the same fixed version number on production and staging/testing instances
Packages following these principles in the oacs-5-10 branch
These principles are implemented for the following packages:
- bootstrap-icons
- fa-icons
- highcharts
- openacs-bootstrap5-theme
- richtext-ckeditor4
- cookie-consent
- openacs-bootstrap3-theme
- richtext-tinymce
Created by Gustaf Neumann, last modified by Gustaf Neumann 29 May 2024, at 11:19 AM
If one is running OpenACS behind a reverse proxy such as NGINX or pound, one should use the following configuration options:
- Make sure, the proxy server adds the following request header fields:
- X-Forwarded-For: containing the IP address of the client making the actual request
- X-SSL-Request: this parameter should be set, to 1 when the incoming requests of the proxy was an HTTPS request. Alternatively, X-SSL-Request could be set to https. This way, OpenACS can treat connections as secure, even when the connection between the reverse proxy and NaviServer is a plain HTTP connection.
- In the configuration file of NaviServer (or AOLserver), make sure, the following parameters are set:
- Parameter ReverseProxyMode in the global parameters (under ns/parameters). This parameter is used by the Tcl code to obtain the right value via [ad_conn peeraddr] or [ad_conn behind_proxy_p]. When the reverse proxy sets the X-SSL-Request header field, also [ad_conn behind_secure_proxy_p] will be true.
- Parameter checkforproxy in the nslog section. By activating it, the entries in the access log will have the value provided from the proxy via the X-Forwarded-For header. If this is not set, the access log will always show the IP address of the proxy server (last mile connection).
In order to check, whether the settings are correct, check the results of the following command calls in ds/shell (when acs-developer-support is installed)
- ad_conn behind_proxy_p
- ad_conn behind_secure_proxy_p
Note that when a server is running behind a secure proxy, but ad_conn behind_secure_proxy_p returns 0, the security ratings of the server will be downgraded, since no secure cookies will be used, etc. To check the settings, run the following command in ds/shell, which should return a non-empty result.
- ad_get_cookie ad_user_login_secure ""
Created by Gustaf Neumann, last modified by Gustaf Neumann 27 Nov 2023, at 05:48 PM
Here is a short summary of my steps to get the version of OpenACS from the branch oacs-5-10 installed on Oracle 19c. It seems there were since a while no fresh installations of OpenACS on Oracle, so several compatibility fixes were necessary in the oacs-5-10 branch to get things running. The branch oacs-5-10 will be released in the future as OpenACS 5.10.1.
Below are the steps to install Oracle on a virtual machine and to configure it such it works with OpenACS. There are probably many more ways to achieve similar tasks, but since the installation is not as trivial was with PostgreSQL, someone might find these notes useful. My installation was on macOS 11.6.3, and should work very similar on, e.g., Linux systems.
The currently recommended version by Oracle is 19c which is the Long Term Release with a support end date of April 30, 2027.
Installing a virtual machine with Oracle Linux and the Oracle Database
Preliminaries:
- install vagrant
- install VirtualBox
- git clone Oracle's vagrant-projects
- for installing Oracle 19c, change to vagrant-projects/OracleDatabase/19.3.0 and read the instructions. These instructions tell you to install the Oracle installation zip file for Linux in this directory. Without the proper Oracle database installation for your architecture, the "vagrant up" command below will fail. The Oracle version for private use is free to use.
Now, run in the vagrant-projects/OracleDatabase/19.3.0 directory the command
vagrant up
This command will install "Oracle Linux Server release 7.9" which is a flavor of Red Hat Enterprise Linux (RHEL) branded by Oracle. The command will run for a couple of minutes. Once the step has finished, you can use ssh to log into this machine
vagrant ssh
On this machine, you will find the Oracle server already running. To ease access to the database and the oracle utilities, add the following lines to the .bash_profile (of the vagrant user)
# User specific environment and startup programs
export ORACLE_HOME=/opt/oracle/product/19c/dbhome_1
PATH=$PATH:$HOME/.local/bin:$ORACLE_HOME/bin:$HOME/bin
To make the shared libraries easy accessible, add these to the standard paths (this will be needed e.g. for the compilation of the Oracle driver for NaviServer).
sudo sh -c "echo /opt/oracle/product/19c/dbhome_1/instantclient > /etc/ld.so.conf.d/oracle-instantclient.conf"
sudo sh -c "echo /opt/oracle/product/19c/dbhome_1/lib > /etc/ld.so.conf.d/oracle-libs.conf"
sudo ldconfig
You might also wish to change the password of the oracle database administrator IDs. We use here "oracle" as password, which is also used in later examples.
su - oracle -c "bash /home/oracle/setPassword.sh oracle"
Once $ORACLE_HOME/bin is on your path, you should be able to list the "status" and "services" provided by the Oracle database:
lsnrctl status
lsnrctl service
You will see there a container database "ORCLCDB" and a pluggable database "ORCLPDB1" (this is Oracle vocabulary). You should also be able to connect to the Oracle Database server via
sqlplus system/oracle@ORCLPDB1
Configuring an Oracle service for OpenACS
If this is working, Oracle and the VM are already functioning. Now we will create an own "service" for OpenACS from sqlplus:
exec dbms_service.CREATE_SERVICE('pdb1','openacs'); -- service_name and network_name
exec dbms_service.start_service('pdb1');
after leaving sqlplus, you should see the new database via "lsnrctl status". Now, you should be able to connect to the new service and save its state:
sqlplus system/oracle@localhost:1521/openacs
SQL> alter pluggable database save state;
Now, we will create an "openacs" user, a tablespace and grant this user the necessary permissions
CREATE TABLESPACE openacs DATAFILE 'openacs_data.dbf' SIZE 100m;
CREATE USER openacs IDENTIFIED BY "openacs" DEFAULT TABLESPACE openacs TEMPORARY TABLESPACE temp;
GRANT CREATE SESSION TO openacs;
GRANT ALL PRIVILEGES TO openacs;
GRANT CTXAPP TO OPENACS;
GRANT EXECUTE ON CTXSYS.CTX_DDL TO OPENACS;
Note that the tablespace is set here to 100 MB, which is fine for simple setups for testing etc. But certainly, you might want to alter this value according to your needs. Note that the tablespace "openacs" is the default tablespace of the user "openacs".
Installing NaviServer and OpenACS on the virtual machine
The installation of NaviServer and OpenACS is done here based on the scripts from naviserver-openacs. Now, install git on the vm, get the installer via git, create the user "nsadmin", deactivate PostgreSQL from the default configuration, and install NaviServer with the module "nsoracle".
sudo yum install git
git clone https://github.com/gustafn/install-ns.git
cd install-ns
sudo useradd -g nsadmin nsadmin
sudo with_postgres=0 with_postgres_driver=0 ns_modules=nsoracle ORACLE_HOME=$ORACLE_HOME bash install-ns.sh build
Now, we install OpenACS from the CVS repository. This will OpenACS with oacs-5-10-compat flag set (the latest published version of the oacs-5-10 branch)
sudo bash install-oacs.sh build
Now get the updated configuration file, which has the right name of the driver, environment variables etc. preconfigured from GitHub
openacs-config.tcl
move it e.g. to /usr/local/ns/config-oacs-5-10-0-ora.tcl, and change "ipaddress" to "0.0.0.0", "server" to "oacs-5-10-0", and "database" to "oracle". Now you can start OpenACS in the foreground on the virtual machine using e.g.:
sudo /usr/local/ns/bin/nsd -u nsadmin -f -t /usr/local/ns/config-oacs-5-10-0-ora.tcl 2>&1
The server will be listening on [0.0.0.0]:8000. We are now essentially done. You should consider exporting port 8000 from the guest machine as e.g. port 9000 on the host by adding the line
config.vm.network "forwarded_port", guest: 8000, host: 9000
in the Vagrantfile (in folder vagrant-projects/OracleDatabase/19.3.0) on the host, such that after a "vagrant halt" and "vagrant up" one can use a browser on the host to connect to OpenACS on the virtual machine.
Enjoy!
Created by Gustaf Neumann, last modified by Gustaf Neumann 24 Jul 2023, at 02:45 PM
With the forthcoming version, OpenACS 5.10.1 (and the current head version in the oacs-5-10 branch) OpenACS provides support for external identity providers, which can be used in parallel to the existing OpenACS authorities. It is possible, that users can
- login alternatively via the configured authority and/or via external identity providers, or
- exclusively over external identity providers
The alternative login requires that the same email address is used for a user in OpenACS and on the identity provider.
Handling of unregistered users
When using alternative logins, the returned user information might match pre-existing OpenACS users, or user information, which is unknown to the system. In such a situation, three scenarios might be possible:
- reject the unknown user
- create a new OpenACS user based on the information returned from the identity provider.
The default behavior of the implementation is to reject the user. When the optional flag "-create_not_registered_users" is activated for an external provider, such users will be created. When creating users (e.g. in dotlrn), it is also possible to add these automatically to certain dotlrn groups (specified in "create_with_dotlrn_role"). Further behavior might be specified by extending the predefined behavior (see example below).
Supported external identity providers for alternative logins
Currently, the following (OAuth 2 based) identity providers are supported
- Microsoft Identity Platform (based on ID-Tokens) based on Azure and Active Directory
- GitHub
OpenACS allows defining one or more identity handlers by defining either different login-handler objects for the same identity provider (e.g. for use on different subsites) to by defining login-handler objects for different identity providers (maybe also for the same subsite).
To enable the external identity providers, the package xooauth has to be installed and one or more external identity providers must be configured on the side of the provider service (to allow its usage for the OpenACS instance) and on the OpenACS instance. So, make sure xooauth is installed and mounted on /oauth (the mount path is relevant for the Redirect URI below).
Microsoft Identity Platform
- Configuration on the provider side:
- Register application via the Azure Portal
- Set the Redirect URI type to Web and value pointing to the redirect page (e.g. YOURLOCATION/oauth/www/azure-login-handler)
- In this process you will obtain the "tenant_id", "client_id" and a "client_secret"
- Microsoft supports its ID token interface in version v1.0 and v2.0. When v2.0 is configured on the OpenACS side (see below), make sure to define in the "Token configuration" the optional claims "upn", "family_name", and "given_name" (latter two only, when allowing automatic account creation).
- Details: Add sign-in with Microsoft to a web app, Microsoft identity platform ID tokens
- Configuration on OpenACS
Using GitHub as Identity Provider
- Configuration on the provider side:
- Register application on GitHub: login on GitHub (with e.g. your ID), goto "Settings", "Developer Settings", "OAuth Apps", "Register a new application"
- Set the Redirect URI: When registering the application, fill in the value of "Authorization callback URL" to YOURLOCATION/oauth/www/github-login-handler
- Details: Authorizing OAuth Apps
- Configuration on OpenACS
The parameters "-debug", "-create_not_registered_users" and "-create_with_dotlrn_role ..." are common parameters and control the behavior.
- When the switch "-debug" is specified, the interface page (e.g. /oauth/github-login-handler) can be used for testing and to see the provided parameters ("claims") returned from the identity provider. In the testing mode, the user is not logged-in. Furthermore, on the public login pages of the OpenACS instance, the external entity is not offered.
- When the switch "-create_not_registered_users" is specified, the users authorized via the external identity provider not existing as users in OpenACS (based on the email address) are automatically created as new OpenACS users (automated account creation). By default, this switch is turned off.
- The parameter "-create_with_dotlrn_role ..." is useful for DotLRN instances. When it is defined, new users will be created as DotLRN users with the specified role (e.g. "student").
The configuration parameter can be provided when the login-handler objects are created, or these can be provided via the OpenACS configuration file. The parameters are looked up from the configuration file on a path based on the name of the login-handler object. So, with the following login-handler objects are defined
::ms::Authorize create ::ms::azure
::xo::oauth::GitHub create ::xo::oauth::github
the parameters for these objects can be specified during
creation (.... -client:id "..." ...) or in the
configuration file in the following sections:
ns/server/[ns_info server]/acs/oauth/ms/azure {
ns_param tenant "..."
ns_param client_id "..."
...
}
ns/server/[ns_info server]/acs/oauth/github {
...
}
the parameters for these objects can be specified during creation (.... -client_id "..." ...) or in the configuration file in the following sections:
ns/server/[ns_info server]/acs/oauth/ms {
...
}
Testing
For testing, it is recommended to define the login-handler objects with the optional "-debug" flag (see above). Add the login-handler object with the following command in xooauth/tcl/oauth-init.tcl file
xo::oauth::GitHub create ::xo::oauth::github \
-debug
This assumes that the GitHub as Identity Provider was defined on GitHub, and at least the parameters "client_id" and "client_secret" are defined in the OpenACS configuration file.
Then restart the server and navigate to YOURLOCATION/oauth/github-login-handler and you will see the option to login via GitHub. By clicking on the link, you will be redirected to GitHub for registering, and then you will be redirected to the interface page showing the claims provided by GitHub, and whether the user_id exists, etc.
When the login-handler objects are created without the "-debug" flag, the login options for all the created login-handler objects are listed on the register/login page of OpenACS (it is possible to omit these via a package parameter set on a subsite).
Example configuration with a custom login handler
Example for xooauth/tcl/oauth-init.tcl:
#
# Potential place for creating login-handler objects for external
# identity providers.
#
# xo::oauth::GitHub create ::xo::oauth::github \
# -client_id "..." \
# -client_secret "..."
#
# ms::Authorize create ms::azure \
# -tenant "..." \
# -client_id "..."
#
#
# This is a custom login handler,
# - configured to create unregistered users,
# - using the "tenant" and "client_id" from the configuration file, and
# - adding some site-specific actions after a successful registration
#
ms::Authorize create ms::LoginHandler -create_not_registered_users
ms::LoginHandler object method register_new_user {
{-first_names}
{-last_name}
{-email}
} -returns integer {
# perform first the "register_new_user" action as usual
set user_id [next]
# on successful registrations (no exception during "next") the user_id is returned.
# Do whatever you want with this user_id, adding it to groups, etc.
ns_log notice "ms::LoginHandler: new registration of user $email returned user_id $user_id"
return $user_id
}
Created by Malte Sussdorff, last modified by Gustaf Neumann 06 Feb 2023, at 04:48 PM
Current documentation for ACS Mail Lite, the standard API for inbound and outbound email is at https://openacs.org/doc/acs-mail-lite/.
Recommendation
The current recommendation for sending outgoing mail is via the NaviServer module nssmtpd, since this handles well large outgoing mails and works as well with >1000 file descriptors open. In OpenACS 5.10, set the package parameter "EmailDeliveryMode" in the acs-mail-lite package to "nssmtpd".
Older Discussion
Outgoing E-Mail at the moment in acs-mail-lite is split in a multitude of procedures, some doubling the efforts of the other. To clean this up, I propose the following (in general):
- Replace acs-mail-lite::send with acs-mail-lite::complex_send, making it a wrapper for complex_send or the other way round (rename complex_send to send and so on).
- Only support sending of e-mails via SMTP. Use smtp::sendmessage from TCLLIB for it (as does complex_send).
- Daveb suggested splitting up complex_send to make it easier to test parts of it. Here are some ideas:
- Sub procedure to generate "to/cc/bcc/_lists" which are used in the respective TO/CC/BCC header. This will also clean up the sending of individual emails.
- Have only one call to smtp::sendmessage and one hook for the complex_send callback.
- Sub-procedure to append file tokens. Not sure if this is useful as we need to do upvar for the tokens and could not do automated tests on them anyway. So I'd not do it.
- Have only one sweeper (the complex_sweeper) with support for multiple mail sending servers (so you can have multiple mail senders in the cluster instead of only one).
- Split of incoming email handing into a separate file
- Delete acs-mail-lite-procs.tcl :-). Just kidding, but deprecate most of the procedures.
Sadly, it is not a straightforward approach, as there is a catch. Using smtp::sendmessage forces us to figure out a new way for setting the bounce-email address header, as the old approach will not work any more (using the SMTP command "FROM" set to the bounce address). Another option is to use the non-standard "Errors-To" Header instead.
Created by Gustaf Neumann, last modified by Gustaf Neumann 02 Nov 2022, at 06:06 PM
Many users tend to click twice on links/and forms, causing therefore multiple identical requests, that can kill the performance of a server, especially when these are expensive requests. On one site, we saw users firing up to several hundred identical requests, probably via a “rapid fire” function available for some mice, coming from the gaming world.
There are essentially two generic ways to handle double clicks in OpenACS:
- Server-side double click handling: The xotcl-request-monitor has since a long time the feature to block (optionally) multiple identical requests from the same client. The user will receive for subsequent identical requests the message “Repeated Operation, please resubmit”, which as some “educative” value. It has several heuristics built in to allow certain double requests (e.g., for embedded resources).
- Client-side double click handling: Via HTML markup, one can disable the same requests for a certain time on the client side (i.e., in the browser). For this time, double-clicks are blocked (the button/link is disabled), such that the true double-click, or “rapid fire” functions are mitigated. The request is only one time executed. Potential problems are potential confusion, when a user wants to open the same page in rapid sequence in multiple tabs, windows. Furthermore, repeated requests from bots are not mitigated. This is a new feature which will part of the OpenACS 5.10.1 release.
The client-side double click handling is activated by a content developer for a link prone to this concern by adding the CSS class “prevent-double-click” to the HTML anchor or button. The double click prevention deactivates a button or an anchor element after clicking for a short time (per default for 2s) and ignores in this time window further clicks. The default time window can be specified via the package parameter DefaultPreventDoubleClickTimeoutMs of acs-templating. The time window can be specified for every occurrence via the data element “oacs-timeout”. When a double click occurs, the duplicate click is determined at the client side (in the browser) such that the first request will continue to run and will render its result when finished. Without double click prevention (or with the double click-prevention on the server side), the results of the first request are lost for the client, although these are still computed at the server side.
Usage Example:
<p>text with a <a class="prevent-double-click" href="/slow.tcl?t=10s">link</a>
<p>
<form action="/slow.tcl">
<input class="btn prevent-double-click" data-oacs-timeout="4000" type="submit" value="Submit">
...
</form>
Created by Gustaf Neumann Vlad V, last modified by Vlad V 22 Sep 2022, at 11:20 PM
Basic installation
A quick way to install and test-drive OpenACS is via docker. The s6 docker images were developed by Vlad and use the docker overlay structures as supported by docker-compose, which is a tool for defining and running multi-container Docker applications.
The minimal setup for testing is to get the repository
git clone https://github.com/oupfiz5/openacs-s6
cd openacs-s6/src
and to run it there, e.g.
docker compose up
This command installs OpenACS (oacs-5-10) from GitHub, PostgreSQL (14.1) and NaviServer 4.99.23 and starts the server on port 8080. We are planning to merge and probably move this repository to the OpenACS project on GitHub.
More advanced installations
In some cases, a developer might need more control over versions used, running multiple different OpenACS versions and instances in parallel, etc. Docker allows composing newly configured setups more or less on the fly via specifying more command line options, or via .env files. Such a setup can be provided by creating the docker-compose setup on a common place on the machine and by creating multiple .env files.
git clone https://github.com/oupfiz5/openacs-s6 /var/www/openacs/docker-s6
cd /var/www/openacs/docker-s6/src
Create in this directory e.g. a file named oacs1.env with the following content:
# * Define port and project name
COMPOSE_PROJECT_NAME="${COMPOSE_PROJECT_NAME:-oacs-8071}"
# * Using potentially different compose files
COMPOSE_FILE="${COMPOSE_FILE:-docker-compose.yaml}"
# * Common
TZ="${TZ:-UTC}"
# * Postgres
PGDATABASE="${PGDATABASE:-openacs}"
PGHOST="${PGHOST:-postgres}"
PGPASSWORD="${PGPASSWORD:-testing}"
PGPORT="${PGPORT:-5432}"
PGUSER="${PGUSER:-openacs}"
POSTGRES_DB="${PGDATABASE}"
POSTGRES_PASSWORD="${PGPASSWORD}"
POSTGRES_REPOSITORY="postgres"
POSTGRES_TAG="14.1-alpine"
POSTGRES_USER="${PGUSER}"
# * OpenACS
NS_CONF="${NS_CONF:-/usr/local/ns/conf/openacs-config.tcl}"
OACS_REPOSITORY="${OACS_REPOSITORY:-oupfiz5}"
OACS_IMAGE_NAME="${OACS_IMAGE_NAME:-openacs-s6}"
OACS_IMAGE_TAG="${OACS_IMAGE_TAG:-v3-oacs-5-10}"
OACS_LISTEN_PORT="${OACS_LISTEN_PORT:-8071}"
oacs_httpport='8000'
oacs_db_user="${PGUSER}"
oacs_db_passwod="${PGPASSWORD}"
oacs_db_name="${PGDATABASE}"
oacs_db_host="${PGHOST}"
oacs_db_port="${PGPORT}"
oacs_ipaddress='0.0.0.0'
Important variables are the listen port (OACS_LISTEN_PORT), the project name (COMPOSE_PROJECT_NAME) for running multiple instances at the same time without conflicting. In order to install other versions than the default (v3-oacs-5-10), the variable OACS_TAG can be used. See for more details the README file on GitHub (openacs-s6). For multiple instances, multiple such .env-files can be created.
To use an .env file oacs1.env one can run it as follows
(cd /var/www/openacs/docker-s6/src; docker compose up --env-file oacs1.env)
or run it in daemon mode by adding a “-d” after up.
Preliminaries
To use this setup, recent versions of docker and docker-compose are needed. There is a constant development, especially on docker-compose. The setup is tested with docker-compose 1.27 (as provided by macPorts on macOS) and with docker compose v2.10.2 under Linux. For docker compose under Linux, it is usually sufficient to get the binary (single file) from the docker download pages.
https://docs.docker.com/
https://docs.docker.com/compose/