Deployment
Starting from Version 2.1, a Structr application can be exported to disk to be synchronized with a source code repository, or imported into a Structr instance.
That includes the user interface (pages, shared components and templates), schema information, business logic, localizations, mail templates, resource access grants, etc. The deployment process provides an easy way to transfer the application to another Structr instance or set up a staging process, and separate the application from its user data.
Deployment workflow
When using a source code repository, the Structr deployment workflow usually includes the following steps.
- Set up a Structr instance and create an initial page from template or scratch
- Create additional pages, define a first application outline
- Mark directories to be included in the export (
includeInFrontendExport: true
) if applicable - Export an initial version of the application using the command detailed below under Export
- Add and commit the initial version to the source code repository
- Continue application development
- Export application
- Add and commit to the repository
- Pull and merge changes from collaborators
- Import sources using the command detailed below under Import
- Go to step #6
Export
To export an application to the directory /tmp/my-structr-app
, use the deploy
maintenance command with the parameters mode: export
and target: /tmp/my-structr-app
. The command has to be run with admin privileges.
The following example illustrates the use of curl
to export an application on UNIX-based systems.
curl -HX-User:admin -HX-Password:admin http://localhost:8082/structr/rest/maintenance/deploy -d '{"mode":"export", "target": "/tmp/my-structr-app"}'
If the target directory doesn’t exist, it will be created by the deploy command.
Please note that you must use an absolute path for the target
directory.
The minimum filesystem structure of an otherwise empty Structr instance looks like this afterwards:
my-structr-app/
└── webapp
├── components
├── components.json
├── files
├── files.json
├── localizations.json
├── mail-templates.json
├── pages
├── pages.json
├── schema
│ └── schema.json
├── schema-methods.json
├── security
│ └── grants.json
├── templates
└── templates.json
There are directories for each type of category of objects (Pages, Templates, Files and Shared Components) containing the serialized content of the database objects, and a JSON file on the root level for each category, containing meta-data (attributes, permissions etc.) .
The information about custom types is stored in one or more files in JSON Schema format in the schema/
subdirectory. Schema methods are stored in form of a JSON array in the file schema-methods.json
on the root level.
Information about the permissions granted to access the REST endpoints are stored in the file security/grants.json
.
Import
To import an application from the directory /tmp/my-structr-app
, use the deploy
maintenance command with the parameters mode: import
and source: /tmp/my-structr-app
. The command has to be run with admin privileges.
The following example illustrates the use of curl
to import an application on UNIX-based systems.
curl -HX-User:admin -HX-Password:admin http://localhost:8082/structr/rest/maintenance/deploy -d '{"mode":"import", "source": "/tmp/my-structr-app"}'
Please note that you must use an absolute path for the source
directory.
Initial configuration
In some cases it will be necessary to apply configuration settings, set up initial users, groups or other data elements. There are two configuration scripts that are applied before and after a deployment. Both files can contain StructrScript or JavaScript expressions like in the following examples. The files need to be placed in the root directory of the export (webapp
in the example above).
pre-deploy.conf (JavaScript)
${{
// Create initial users
if (Structr.find('User', 'name', 'user1').length === 0) {
Structr.create('User', {
name: 'user1',
password: 'test'
});
}
}}
post-deploy.conf (JavaScript)
${{
// make all pages visible after deployment
Structr.find('Page').forEach(function(p) {
p.visibleToAuthenticatedUsers = true;
p.visibleToPublicUsers = true;
});
}}