An Indico distribution template.
An Indico distribution is an opinionated project structure with tooling for launching highly customized Indico setups in development environments. These setups include Indico itself, plugins and organization-specific customizations. This template showcases the setup of a fictional organization called Indicorp.
Read this README.md file to know more about:
- Features
- Setting the environment
- Running an Indico instance
- Updating the environment
- Building and deploying artifacts
- Troubleshooting
For information on contributing to this repository, see CONTRIBUTING.md.
Indico can be highly customized to fit the needs of different organizations. Achieving this often involves making contributions to the Indico open source project, enabling Indico plugins and even patching Indico code at runtime. Launching and contributing to different open source projects requires a complex development environment that may not be trivial to setup. This template aims to standardize the setup of such environments and provides a number of utilities to make development easier.
This repository is optimized for the following use cases:
- Set up and run a local Indico instance.
- Make code contributions to Indico and plugin repositories.
- Develop organization-specific customizations as a "distribution plugin".
- Deploy the distribution to a production environment.
This repository contains editable code of:
- Indico as a Git submodule in
indico/ - A few Indico plugins as Git submodules in
plugins/ - Customizations for this "distribution plugin" in
indicorp/
This repository includes other development tools such as:
Makefilewith scripts for common development tasks- Linter and testing settings in line with the Indico code style
- CI workflows for testing and building the distribution
- Issue and pull request templates (coming soon)
This repository also supports deploying the distribution to production environments. Depending on the deployment model, this can be done by:
- Building and installing the distribution as a wheel in the same virtual environment as Indico (see Wheels).
- Building and deploying a container image that bundles Indico, all plugins and the distribution (see Container image).
This section is a step-by-step guide for setting up a development environment for this Indico distribution. For troubleshooting and more details about installing Indico and plugins refer to the official development installation and plugin installation guides.
This guide expects the following tools installed and available in your system PATH:
git(available in most systems)make(available in most systems)uv(installation guide)nvm(installation guide)
Additionally, you will need the following programs installed and running in your system:
- PostgreSQL (>=13) (installation guide)
- Redis (installation guide)
Optionally, for a better development experience, you can install the following tools:
Clone the repository and its submodules with:
git clone --recursive https://github.com/unconventionaldotdev/indicorp.git
cd indicorpIf you didn't clone the repository recursively, clone and initialize submodules at any time with:
git submodule update --init --progressMake sure to have the right versions of python and node installed:
uv python install # reads from .python-version
nvm install # reads from .nvmrcInstall Indico, the distribution plugin and all Python and JavaScript dependencies with:
make depsAdditionally, for each plugin in the plugins/ directory, install its dependencies with:
make deps-plugin plugin=<plugin-path>First, create the directory that Indico will use as its root path with:
export INDICO_APP_PATH=/usr/local/opt/indicorp # Use this in the setup wizard
mkdir -p "${INDICO_APP_PATH}"Launch the setup wizard to configure the Indico instance:
indico setup wizard --devThe wizard will keep your settings in a indico/indico/indico.conf file. Plugins, however, need to be enabled manually in the PLUGINS entry of the configuration file. To enable the distribution plugin, make sure the following entry is present:
PLUGINS = {'indicorp', ...}Note
You can quickly edit the indico.conf file with make config.
Important
You can configure your INDICO_APP_PATH variable in a .envrc.local file to avoid having to set it every time you open a new terminal. For this to work you will need to install direnv and run direnv allow.
Compile the translation catalogs for Indico, plugins and the distribution plugin with:
indico i18n compile indico
indico i18n compile all-plugins ../plugins
indico i18n compile plugin ../srcMake sure that the postgres server is running locally (guide) and then create a database template:
createdb indico_template
psql indico_template -c "CREATE EXTENSION unaccent; CREATE EXTENSION pg_trgm;"Create the indicorp database by copying the indico_template database:
createdb indicorp -T indico_templateOnce the indicorp database exists, prepare the database schemas required by Indico and all enabled plugins with:
indico db prepareIndico uses Webpack to compile static assets such as JavaScript and CSS files from .jsx or .scss files. Compile the static assets for Indico, plugins and the distribution plugin with:
make assetsAdditionally, build the static assets for a each plugin in the plugins/ directory with:
make assets-plugin plugin=<plugin-path>Note
The make assets command needs to be run every time you make changes to the sources of Indico, plugins or the distribution plugin. For convenience, you can run make asset-*-watch commands to automatically re-compile the static assets on changes.
Now that you have a development environment set up, you can launch an instance of Indico. In this section, you will find instructions for launching the web server, rebuilding the static assets on changes and monitoring the logs.
Note
You can run all the commands in this section at the same time in different terminals with tmux, tmuxp and the tmuxp.yaml file included in this repository. There is a convenient make target to launch the tmux session with:
make tmuxRunning Indico in development mode launches a web server that serves the application and handles all the requests from the users. Run the following command to launch the web server in debug mode and restarting on code changes:
make runWhile developing you will often need to make changes in JavaScript and SCSS files and see the results in the browser. To re-compile the static assets on code changes, keep two terminals open with:
make assets-core-watchmake assets-distro-watchIndico prints the application logs to an indico.log file within the INDICO_APP_PATH directory. These logs are useful to gain context about application errors or behavior while debugging. Keep a terminal open to monitor the logs with:
export INDICO_APP_PATH=/usr/local/opt/indicorp # As set in the setup wizard
make log-appIndico also logs the database queries in real-time. These SQL logs are useful to debug performance issues and trace them to SQLAlchemy queries. Keep this real-time log open in another terminal with:
make log-dbIndico expects to have access to a SMTP server for sending emails. One convenient option is installing and running a fake server such as Maildump. This will allow you to intercept and read all outgoing emails while also preventing them from being sent to real users accidentally.
You can install and run the program with:
uvx maildumpUpdate your local development environment to keep up with the changes introduced in Indico core, plugins and the distribution itself. This typically involve updating the submodules, installing new dependencies or upgrading the database schema.
Update your submodules whenever any submodule pointer has changed. Do this in one command for all submodules with:
git fetch --recurse-submodules
git submodule updateInstall all missing Python and Javascript dependencies introduced.
make depsNote
Inspect the Makefile to find more granular dependency targets. You can run make deps-core and make deps-distro, for instance, to install dependencies for Indico core and the distribution plugin respectively.
Run all the Alembic migration scripts for database schema migrations introduced in the distribution itself or any of the submodules with:
indico db upgrade
indico db --all-plugins upgradeThis repository produces two types of build artifacts: Python wheels and a container image. Unlike the development setup described above, these artifacts are self-contained. Static assets and translation catalogs are compiled as part of the build process and bundled into the artifacts, so no separate compilation steps are required when deploying them.
Python wheels are the distributable packages for Indico core and the distribution plugin. They are used both as an intermediate build step when producing the container image and as standalone artifacts that can be installed directly.
Build all wheels (core + distribution plugin) with:
make wheelsWheels are written to the dist/ directory. For granular builds you can use make wheel-core, make wheel-distro, or make wheel-plugin plugin=<path> for a specific plugin.
Note
For production deployments, installing the distribution wheel directly into the same virtual environment as Indico is the recommended approach. After building with make wheels, install with:
pip install dist/indicorp-*.whlThe container image provides a self-contained deployment of the distribution. The image is built in two stages: a builder stage that compiles all wheels and static assets, and a runtime stage based on the official Indico image that installs the resulting wheels and copies the configuration files from etc/.
Build the container image with:
make containerThe default image tag is unconventionaldotdev/indicorp:latest. Override it with the IMAGE_TAG environment variable:
IMAGE_TAG=myrepo/myimage:tag make containerThings don't always go the expected way. This section contains solutions to some common issues that may arise while setting up the development environment.
The Python interpreters installed via uv on Apple Silicon Macs does not find libraries installed via Homebrew in /opt/homebrew/lib by default. This causes WeasyPrint to fail at import time. To fix this, create symbolic links to the required libraries in /usr/local/lib with the following commands:
sudo ln -s /opt/homebrew/opt/glib/lib/libgobject-2.0.0.dylib /usr/local/lib/gobject-2.0
sudo ln -s /opt/homebrew/opt/pango/lib/libpango-1.0.dylib /usr/local/lib/pango-1.0
sudo ln -s /opt/homebrew/opt/harfbuzz/lib/libharfbuzz.dylib /usr/local/lib/harfbuzz
sudo ln -s /opt/homebrew/opt/fontconfig/lib/libfontconfig.1.dylib /usr/local/lib/fontconfig-1
sudo ln -s /opt/homebrew/opt/pango/lib/libpangoft2-1.0.dylib /usr/local/lib/pangoft2-1.0References: