Portainer Templates logo

Portainer Templates

Baikal Baikal

Stack

CalendarProductivity

Baïkal is a lightweight CalDAV+CardDAV server. It offers an extensive web interface with easy management of users, address books and calendars.

Image details

Pulls: 8.1M
Architecture: amd64, arm64, arm/v7, 386, arm, arm64/v8
Image size: 180 MB
Latest: 0.10.1-php8.2
User: ckulka
Created: Jul 26, 2015
Updated: 6 days ago
Status: active

Configuration

Type
Compose
Platform
linux
Image
ckulka/baikal:nginx
Ports
8220:80
Volumes
/var/www/baikal/config : /portainer/Files/AppData/Config/baikal/config/var/www/baikal/Specific : /portainer/Files/AppData/Config/baikal/data
Restart
always
Source

Template by xneo1·Source

Standalone Install

Select an install method, to see config/commands for deploying Baikal

Installation method

Install on Portainer

Import all app templates into your Portainer instance, for easy 1-click deploys

  1. Ensure both Docker and Portainer are installed, and up-to-date
  2. Log into your Portainer web UI
  3. Under Settings → App Templates, paste the below URL
  4. Head to Home → App Templates, and the list of apps will show up
  5. Select Baikal, fill in any config options, and hit Deploy

Template Import URL

https://raw.githubusercontent.com/Lissy93/portainer-templates/main/templates.json
Show Me demo
Original stackfile

The compose file this template deploys, straight from its repo:

services:
  baikal:
    image: ckulka/baikal:nginx
    restart: always
    ports:
      - "8220:80"
    volumes:
      - /portainer/Files/AppData/Config/baikal/config:/var/www/baikal/config
      - /portainer/Files/AppData/Config/baikal/data:/var/www/baikal/Specific

volumes:
  config:
  data:

Or deploy it directly from the source:

git clone https://github.com/xneo1/portainer_templates
cd portainer_templates
docker compose -f Template/Stack/baikal.yml up -d

More install options in our documentation.

Baikal

Latest images Experimental images Docker Pulls Docker Architectures
This dockerfile provides a ready-to-go Baikal server.
For more details, see ckulka/baikal-docker (GitHub).

Supported tags and respective Dockerfile links

Tags without a version are weekly re-builds to include the latest base image with the most recent updates:
  • latest and apache are re-builds of the latest *-apache version
  • apache-php8.2 are re-builds of the latest *-apache-php8.2 version
  • nginx are re-builds of the latest *-nginx version
  • nginx-php8.2 are re-builds of the latest *-nginx-php8.2 version

I follow the same version naming scheme as Baikal themselves.
The following tags support multiple architectures, e.g. amd64, arm32v7, arm64v8 and i386.

For earlier versions all the way back to version 0.2.7, please search in the tags tab. Version 0.4.5 and older are only available for amd64. Version 0.9.0 and older do not support i386.

Quick reference

  • Where to file issues:
https://github.com/ckulka/baikal-docker/issues amd64, arm32v7, arm64v8, i386
  • Image updates:
PRs for ckulka/baikal-docker
  • Source of this description:
https://github.com/ckulka/baikal-docker

What is Baikal?

From sabre.io/baikal:
Baikal is a Cal and CardDAV server, based on sabre/dav, that includes an administrative interface for easy management.
For more information, read the main website at baikal-server.com.
Baikal is developed by Net Gusto and fruux.

How to use this image

The following command will start Baikal:
docker run --rm -it -p 80:80 ckulka/baikal:nginx

Alternatively, use the provided examples/docker-compose.yaml from the Git repository:
docker compose up

You can now open http://localhost or http://host-ip in your browser and use Baikal.

Persistent Data

The image exposes the /var/www/baikal/Specific and /var/www/baikal/config folders, which contain the persistent data. These folders should be part of a regular backup.
If you want to use local folders instead of Docker volumes, see examples/docker-compose.localvolumes.yaml to avoid file permission issues.
When the container starts, the startup script /docker-entrypoint.d/40-fix-baikal-file-permissions.sh (Apache httpd, nginx) ensures that the file permissions are correct. You can disable this behaviour by setting the environment variable BAIKAL_SKIP_CHOWN to any value, e.g. FALSE.

Further Guides

You can find more installation and configuration guides here:

Image Variants

The ckulka/baikal images come in several flavors, each designed for a specific use case.

ckulka/baikal:<version>

This is the defacto image and follows the official guidelines the closest using Apache httpd.
With that being said, it's worth checking out the nginx variant as it requires fewer resources and produces no warning messages out-of-the-box.
If you are unsure about what your needs are, you probably want to use this one though.

ckulka/baikal:apache

This image relies on Apache httpd and uses the official PHP image that's packaged with the Apache web server.
It also ships with HTTPS support and self-signed certificates, which can be replaced by user-provided certificates - for more details, see the SSL Certificate Guide.
This image uses environment variables to set Apache's ServerName and ServerAlias directives to avoid Apache httpd's warnings in the logs.
The BAIKAL_SERVERNAME environment variable is used to set the global ServerName directive, e.g. dav.example.io. For more details, see Apache Core Features: ServerName Directive.
The BAIKAL_SERVERALIAS environment variable is used to set the ServerAlias directive of the VirtualHosts, e.g. dav.example.org dav.example.com. For more details, see Apache Core Features: ServerAlias Directive.

ckulka/baikal:experimental

This image has the latest code from the source repository ckulka/baikal-docker, mainly used for testing before a version is released. Use this at your own risk.

ckulka/baikal:nginx

This image relies on nginx and uses the official nginx image.
Compared to the Apache variant, it is significantly smaller (less than half the size) and produces no warning messages out-of-the-box.

Serve Baikal on your own domain behind Caddy, Nginx or Traefik. Fill in your domain and copy the result. It's a starting point, some apps need their own base URL or extra headers set too.

Proxying baikal.example.com to http://baikal:80

Add this to your Caddyfile

baikal.example.com {
	reverse_proxy http://baikal:80
}

Check the logs first

Nine times out of ten the logs tell you exactly what went wrong.

  • In Portainer, go to Containers, click the container, then Logs. Or run docker logs <container>
  • Exit codes help too: 137 means killed, usually out of memory. 126 or 127 means the command inside the image is broken.

Port already in use

If deployment fails with "Bind for 0.0.0.0:8220 failed: port is already allocated", something else on your server is using that port.

  • Find what's using it: sudo ss -tlnp | grep :8220
  • Stop the other service, or pick a different host port. In 8220:80 only the left number is yours to change, the right one belongs to the app.

Running but the page won't load

The container is up but nothing appears in your browser.

  • Use your server's real IP: http://your-server-ip:8220. The 0.0.0.0 link Portainer shows isn't a real address.
  • Give it a minute after first deploy, baikal can take a while to initialise.
  • Make sure your firewall allows the port, e.g. sudo ufw allow 8220

Permission denied on volumes

If the logs show "permission denied", the app can't write to its data folder on the host.

  • Fix the ownership: sudo chown -R 1000:1000 /portainer/Files/AppData/Config/baikal/config (and the same for the other mapped folders)

Image won't pull

Test the pull directly on the host: docker pull ckulka/baikal:nginx

  • "manifest unknown" means the tag no longer exists.
  • "toomanyrequests" is the Docker Hub rate limit. Log in with docker login to raise it.
  • "no space left on device" means a full disk. Reclaim space with docker system prune

"exec format error"

This means the image was built for a different CPU architecture than your server.

  • This image supports: amd64, arm64, arm/v7, 386, arm, arm64/v8
  • Check yours with uname -m: x86_64 is amd64, aarch64 is arm64. Raspberry Pi and other ARM boards are the usual culprits.

Container keeps restarting

The always restart policy relaunches the app after every crash, so the real error can scroll past.

  • Check the logs right after a restart, the last few lines before it died are the useful ones.
  • Get the exit code with docker inspect <container> --format '{{.State.ExitCode}}'
  • Still stuck? Redeploy once with the restart policy set to no so the failure stays visible.

Stack won't deploy

Compose stacks fail fast on small mistakes, and Portainer shows the reason just above the editor.

  • YAML only accepts spaces for indentation, a single tab breaks the whole file.

Raise an issue

Found something which isn't working as it should? Here's how to report it.

A Compose stack

Baikal is a Compose stack, a set of containers defined in one file and brought up together by Portainer, then started and stopped as a single app.

The app image

An image is the app packed up ready to go, everything Baikal needs bundled into one download. This template pulls ckulka/baikal:nginx, which Docker fetches once (about 180 MB) and then starts your own copy from.

Where the image comes from

Docker pulls its images from registries, public libraries of ready-built apps. Baikal's comes from Docker Hub, published by ckulka.

Version tags

The bit after the colon in the image name is the version tag. This one pins nginx, so every redeploy gives you that exact build until you bump it yourself.

Which machines it runs on

Every image is built for particular CPU types. This one ships for amd64, arm64, arm/v7, 386, arm, arm64/v8, so it runs on both regular x86 servers and ARM boards like a Raspberry Pi.

Ports

A port is the door the app answers on. A mapping like 8220:80 means it's reachable on port 8220 of your server, where the left number is yours to change and the right one belongs to the app. Once it's running, open http://your-server-ip:8220 in a browser. It opens:

  • 8220:80, likely the web interface

Volumes

A volume is where Baikal keeps its files so they survive an update or a restart. Without one, anything it saves would sit inside the container and vanish the moment it's recreated. This template mounts:

  • /var/www/baikal/config from /portainer/Files/AppData/Config/baikal/config on the host
  • /var/www/baikal/Specific from /portainer/Files/AppData/Config/baikal/data on the host

Restart policy

The restart policy here is always, so Docker brings Baikal back up after a crash and again when the server reboots. Good for anything you want running around the clock. You can change this on the deploy screen. The choices are no (never restart), on-failure (only after a crash), unless-stopped (restart unless you stop it), and always (bring it back no matter what).

Networking

Nothing custom is set, so Baikal sits on Docker's default bridge network: its own private space that reaches the outside world only through the ports it publishes.

Container name

Once it's deployed, Portainer names the container baikal. That's what you'll spot in the containers list and use in commands like docker logs baikal.

Platform

The platform is linux, the kind of system the container is built to run on. Docker and Portainer handle this on a normal Linux server.

Portainer app templates

Zooming out, this whole page comes from a Portainer app template: a short recipe telling Portainer how to set Baikal up. Add the template list to Portainer once, then deploying Baikal is a click rather than a wall of config.