Skip to content

Hosting with Docker

You can use docker and docker compose to host the Open Web Calendar.

Build the Image

First, clone the repository:

git clone
cd open-web-calendar

To build the container yourself, run:

docker build --tag niccokunzmann/open-web-calendar .
This will create the image niccokunzmann/open-web-calendar.

Run the Docker Image

You can use the existing image: niccokunzmann/open-web-calendar.

docker run -d --rm -p 5000:80 niccokunzmann/open-web-calendar

Then, you should see your service running at http://localhost:5000.

Container Tags

The container niccokunzmann/open-web-calendar:latest contains the latest release. Containers are also tagged with the version from the changelog, e.g. niccokunzmann/open-web-calendar:v1.10.

If you wish to run the latest development version, use niccokunzmann/open-web-calendar:master. This includes unchecked translations.

Docker Compose

Use the pre-build Dockerhub image with docker compose:

version: '3'
    image: niccokunzmann/open-web-calendar
      - '80:80'
    restart: unless-stopped

To deploy the Open Web Calendar with docker compose, follow these steps:

  1. Copy the docker-compose.yml file to the directory from where you want to run the container.
  2. If needed change the port mapping and environment variables.
  3. Start the container:

    docker compose up -d
  4. The container will be pulled automatically from Dockerhub and then starts.

Important Note: If you use this service, consider setting up log rotation as it is very talkative.

Update pre-build image with Docker Compose

If you want to update your image with the latest version from Dockerhub run this:

docker compose pull

Note: You need to restart the container after pulling in order for the update to apply:

docker compose up -d

Preventing SSRF attacks using a Tor proxy

The Open Web Calendar can be configured to use a proxy to request .ics and other files. The following example shows the usage of a Tor proxy. You can try it out at

version: '3'
    image: niccokunzmann/open-web-calendar:master
    restart: unless-stopped
    # use socks5h for *.onion
    # see
      - HTTP_PROXY=socks5h://tor-socks-proxy:9150
      - HTTPS_PROXY=socks5h://tor-socks-proxy:9150
      - ALL_PROXY=socks5h://tor-socks-proxy:9150
    # optional: create a private network so OWC cannot access the Internet directly
      - no-internet-only-tor

  # from
    image: peterdavehello/tor-socks-proxy # use :test for arm64
    restart: unless-stopped
    # optional: allow access to OWC and the Internet
      - default
      - no-internet-only-tor

      driver: default
  no-internet-only-tor: # see
    driver: bridge
    internal: true

The configuration above prevents access to the internal network as the requests are sent over the Tor network. A bonus feature is that calendars can be accessed and hosted as a Tor Hidden Service using an .onion address. E.g. a calendar file can be served from a Raspberry Pi behind a home network’s firewall. This example calendar uses this onion address.

See also:

Automatic Updates

If you have not fixed your version but you use the latest or master tag, you can automatically update all the services required.

Create an file next to your docker-compose.yml file and add this content:

# update the services

cd "`dirname \"$0\"`"

docker compose pull
docker compose create
docker compose up -d --remove-orphans

# clean up
# see
docker system prune -a -f
docker rm -v $(docker ps -a -q -f status=exited)
docker rmi -f  $(docker images -f "dangling=true" -q)
  docker volume ls -qf dangling=true | xargs -r docker volume rm

Make executable.

chmod +x

Add a cron job to update everything at 3am daily (when there is an update). Run this as the user who has access to the docker command:

crontab -e

And add this line:

3 * * * * /path/to/ 1> /path/to/ 2> /path/to/

Further Configuration

After you have set up your own server, you can configure the behavior.