Baikal
Stack
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
Configuration
TypeComposelinuxckulka/baikal:nginx8220:80/var/www/baikal/config : /portainer/Files/AppData/Config/baikal/config/var/www/baikal/Specific : /portainer/Files/AppData/Config/baikal/dataalwaysStandalone Install
Select an install method, to see config/commands for deploying Baikal
Install on Portainer
Import all app templates into your Portainer instance, for easy 1-click deploys
- Ensure both Docker and Portainer are installed, and up-to-date
- Log into your Portainer web UI
- Under Settings → App Templates, paste the below URL
- Head to Home → App Templates, and the list of apps will show up
- 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
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 -dMore install options in our documentation.
Baikal
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:latestandapacheare re-builds of the latest*-apacheversionapache-php8.2are re-builds of the latest*-apache-php8.2versionnginxare re-builds of the latest*-nginxversionnginx-php8.2are re-builds of the latest*-nginx-php8.2version
I follow the same version naming scheme as Baikal themselves.
The following tags support multiple architectures, e.g.
amd64, arm32v7, arm64v8 and i386.0.10.1,0.10.1-apache0.10.1-apache-php8.2,0.10.1-php8.20.10.1-nginx0.10.1-nginx-php8.20.10.0,0.10.0-apache0.10.0-apache-php8.2,0.10.0-php8.20.10.0-nginx0.10.0-nginx-php8.20.9.5,0.9.5-apache0.9.5-apache-php8.2,0.9.5-php8.20.9.5-nginx0.9.5-nginx-php8.2
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:
- Supported architectures (more info):
amd64, arm32v7, arm64v8, i386- Image updates:
- Source of this description:
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:nginxAlternatively, use the provided examples/docker-compose.yaml from the Git repository:
docker compose upYou 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
Theckulka/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:
137means killed, usually out of memory.126or127means 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:80only 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 loginto 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
noso 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.
- Bug within the app: Open an issue within baikal's repo
- Template not working: Open an issue on xneo1/portainer_templates
- This website not working: Open an issue on lissy93/portainer-templates
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/configfrom/portainer/Files/AppData/Config/baikal/configon the host/var/www/baikal/Specificfrom/portainer/Files/AppData/Config/baikal/dataon 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.