# Using Zrok on docker for multiple services

**URL:** <https://openziti.discourse.group/t/using-zrok-on-docker-for-multiple-services/2757>\
**Category:** zrok\
**Created:** [June 21, 2024, 12:20pm UTC](https://openziti.discourse.group/t/using-zrok-on-docker-for-multiple-services/2757 "2024-06-21T12:20:12Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Delfi\_r](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/delfi_r/32/2245_2.png) [@Delfi\_r](https://openziti.discourse.group/u/Delfi_r)\
**Post date:** [June 21, 2024, 12:20pm UTC](https://openziti.discourse.group/t/using-zrok-on-docker-for-multiple-services/2757/1 "2024-06-21T12:20:12Z")

</div>

I've been using Zrok for a longtime, and I have tried with success the terminal app. I've tried the docker install for another service and worked, and it's cleaner as I have Docker running for those services. The problem is that I want to run more than one service in the docker install and I'm not able to figure how to set it up.

I would be able to add more services in the future

---

<div class="post-metadata">

**Author:** ![TheLumberjack](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/thelumberjack/32/113_2.png) [@TheLumberjack](https://openziti.discourse.group/u/TheLumberjack)\
**Post date:** [June 21, 2024, 5:51pm UTC](https://openziti.discourse.group/t/using-zrok-on-docker-for-multiple-services/2757/2 "2024-06-21T17:51:37Z")

</div>

Hi @Delfi_r, welcome to the community and to zrok (and OpenZiti)!

Generally speaking there's no way to share multiple services on one install. You can run one zrok share container for each service to expose.

Did you also find [this other discourse post](https://openziti.discourse.group/t/zrok-how-do-i-run-multiple-proxies-using-as-a-linux-service/1956) that covers the same topic?

There's also a feature request: [Single Command, Multiple Share|Access · Issue #194 · openziti/zrok · GitHub](https://github.com/openziti/zrok/issues/194) to enable this sort of functionality on the roadmap.

---

<div class="post-metadata">

**Author:** ![Delfi\_r](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/delfi_r/32/2245_2.png) [@Delfi\_r](https://openziti.discourse.group/u/Delfi_r)\
**Post date:** [June 21, 2024, 8:48pm UTC](https://openziti.discourse.group/t/using-zrok-on-docker-for-multiple-services/2757/3 "2024-06-21T20:48:58Z")

</div>

I use zrok on a Mac. On this machine I run different prototype services on different ports. As you have explained I need to set up different pairs .env and compose.yml and compose up each of them so I'll end with different zrok images. I need to rename them different and take care on something in the compose.yml file?

---

<div class="post-metadata">

**Author:** ![michael.quigley](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/michael.quigley/32/1123_2.png) [@michael.quigley](https://openziti.discourse.group/u/michael.quigley)\
**Post date:** [June 21, 2024, 9:00pm UTC](https://openziti.discourse.group/t/using-zrok-on-docker-for-multiple-services/2757/4 "2024-06-21T21:00:18Z")

</div>

Yes. You should be able to just run multiple containers, each container hosting a separate `zrok share` process, as long as you are careful with naming those containers.

---

<div class="post-metadata">

**Author:** ![TheLumberjack](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/thelumberjack/32/113_2.png) [@TheLumberjack](https://openziti.discourse.group/u/TheLumberjack)\
**Post date:** [June 21, 2024, 11:41pm UTC](https://openziti.discourse.group/t/using-zrok-on-docker-for-multiple-services/2757/5 "2024-06-21T23:41:40Z")

</div>

Me personally, I would just use the same .env file. You would want different compose files though because you'll be sharing different shares, yes. Depending on how good you are with docker and how you're running zrok, you might be able to keep the compose file the same but alter the env file. Overall, sounds like you're on the right path though.

---

<div class="post-metadata">

**Author:** ![Delfi\_r](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/delfi_r/32/2245_2.png) [@Delfi\_r](https://openziti.discourse.group/u/Delfi_r)\
**Post date:** [June 22, 2024, 4:40pm UTC](https://openziti.discourse.group/t/using-zrok-on-docker-for-multiple-services/2757/6 "2024-06-22T16:40:16Z")

</div>

i can't use the same .env file as this is where the name of the share is defined and yse, I want to share different services so i'll try to use the same docker compose file and try to get different containers. I'll inform you when all is done

---

<div class="post-metadata">

**Author:** ![qrkourier](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/qrkourier/32/52_2.png) [@qrkourier](https://openziti.discourse.group/u/qrkourier)\
**Post date:** [June 24, 2024, 1:15pm UTC](https://openziti.discourse.group/t/using-zrok-on-docker-for-multiple-services/2757/7 "2024-06-24T13:15:12Z")

</div>

Thanks for sharing your issues and progress on this! Which approach are you using to enable the zrok environment for each share container? The two main approaches are these:

1. Docker bind volume like `~/.zrok:/.zrok` and run-as user `$UID`
2. Docker named volume like `zrok_env:/mnt` and env `STATE_DIRECTORY=/mnt`

The difference is that the first one uses the Docker host user's zrok environment, and the second one manages a separate zrok environment in Docker, separate from the Docker host user.

The first one is a little simpler and more immediate, whereas the second is more like a production service.

With either approach, I think you will find a way to re-use the same zrok environment for all the share containers.

Here's the docs with complete examples and tutorials for both approaches: [Getting Started with Docker | Zrok](https://docs.zrok.io/docs/guides/docker-share/)

---

<div class="post-metadata">

**Author:** ![Delfi\_r](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/delfi_r/32/2245_2.png) [@Delfi\_r](https://openziti.discourse.group/u/Delfi_r)\
**Post date:** [June 26, 2024, 12:11pm UTC](https://openziti.discourse.group/t/using-zrok-on-docker-for-multiple-services/2757/8 "2024-06-26T12:11:21Z")

</div>

Before I try I'll want to ask another question because perhaps it's very important

I'm following [Docker Compose Public Share | Zrok](https://docs.zrok.io/docs/guides/docker-share/docker_public_share_guide/)

I want to expose within Docker four services:

OpenWebhui running on localhost:3000 (now I use a reserved share with a terminal window)  
Searxng running on localhost:4000 (now I use a reserved share with a terminal window)  
Trasformer.lab on localhost:8000

Those will be on docker creating three .env files and composing three Docker containers. I'll try this, But I need first get a solution for a more complex project:

Perplexica has the front-end on 3080 (from the original 3000 all projects configure by default)

But the backend is running on localhost 3001. so I've figured I need a Caddyfile to set up a Reverse proxy:

```auto
your_zrok_share.zrok.io {
    tls off # zrok already provides TLS/SSL, so we disable it here

    reverse_proxy / localhost:3080 {
        header_up Upgrade $http_upgrade
        header_up Connection $http_connection
    }

    reverse_proxy /api/* localhost:3001 {
        to {path}
    }

    reverse_proxy /ws/* localhost:3001 {
        to {path}
        websocket
    }
}

```

My doubts are: I need to reserve a [zrok.io](http://zrok.io) share out of this file or it will be created when I compose the Docjer file?

Where I need to put the caddy file to create a docker container for it? Wich is the right thing to do?

---

<div class="post-metadata">

**Author:** ![qrkourier](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/qrkourier/32/52_2.png) [@qrkourier](https://openziti.discourse.group/u/qrkourier)\
**Post date:** [June 26, 2024, 6:45pm UTC](https://openziti.discourse.group/t/using-zrok-on-docker-for-multiple-services/2757/9 "2024-06-26T18:45:20Z")

</div>

Great. That sounds like it will work well with zrok and Docker.

You're following the Docker public share guide which uses a separate zrok env for the container, not the zrok environment belonging to the Docker host user.

Your compose environment needs the variables mentioned in that guide you linked.

```bash
ZROK_ENABLE_TOKEN=abcd123
ZROK_BACKEND_MODE=caddy
ZROK_TARGET=/Caddyfile
ZROK_UNIQUE_NAME=your_zrok_share

```

In the Docker public share compose.yml, you must mount the Caddyfile in the same path specified as the target, e.g.

```yaml
services:
  zrok-share:
    volumes:
      - ./Caddyfile:/Caddyfile

```

Your Caddyfile must follow the zrok documentation example with `bind {{ .ZrokBindAddress }}`.

```caddyfile
http:// {
    bind {{ .ZrokBindAddress }}

    reverse_proxy / localhost:3080 {
        header_up Upgrade $http_upgrade
        header_up Connection $http_connection
    }

    reverse_proxy /api/* localhost:3001 {
        to {path}
    }

    reverse_proxy /ws/* localhost:3001 {
        to {path}
        websocket
    }
}

```

The Docker public share compose.yml has everything inside to reserve `your_zrok_share` and you will see the share appear in the web console when you do `docker compose up`. Then you can visit `https://your_zrok_share.share.zrok.io`

---

<div class="post-metadata">

**Author:** ![Delfi\_r](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/delfi_r/32/2245_2.png) [@Delfi\_r](https://openziti.discourse.group/u/Delfi_r)\
**Post date:** [June 26, 2024, 7:22pm UTC](https://openziti.discourse.group/t/using-zrok-on-docker-for-multiple-services/2757/10 "2024-06-26T19:22:54Z")

</div>

Thanks a lot for your detailed reply. A simple question: how to name the caddyfile and were to put it?

---

<div class="post-metadata">

**Author:** ![qrkourier](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/qrkourier/32/52_2.png) [@qrkourier](https://openziti.discourse.group/u/qrkourier)\
**Post date:** [June 26, 2024, 7:47pm UTC](https://openziti.discourse.group/t/using-zrok-on-docker-for-multiple-services/2757/11 "2024-06-26T19:47:00Z")

</div>

You can name it `Caddyfile` and put it in the same directory as `compose.yml` to mount it in the container like this. Ensure the file is readable by setting permissive filemode on the Docker host.

```bash
chmod -c a+r ./Caddyfile

```

```yaml
services:
  your_zrok_share:
    image: ${ZROK_CONTAINER_IMAGE:-docker.io/openziti/zrok}
    restart: unless-stopped
    entrypoint: zrok-share.bash
    depends_on:
      zrok-enable:
        condition: service_completed_successfully
    volumes:
      - zrok_env:/mnt
      - ./Caddyfile:/Caddyfile
    environment:
      ZROK_UNIQUE_NAME: "your_zrok_share"
      ZROK_BACKEND_MODE: caddy
      ZROK_TARGET: /Caddyfile
      STATE_DIRECTORY: /mnt # zrok homedir in container

```

You can have many share containers like this, each mounting the zrok\_env volume to provide the enabled environment.

---

<div class="post-metadata">

**Author:** ![Delfi\_r](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/delfi_r/32/2245_2.png) [@Delfi\_r](https://openziti.discourse.group/u/Delfi_r)\
**Post date:** [July 1, 2024, 5:50am UTC](https://openziti.discourse.group/t/using-zrok-on-docker-for-multiple-services/2757/12 "2024-07-01T05:50:22Z")

</div>

Today I'm unable to set up a simple proxy Zrok service on docker, zrok is running on the console. After many retries, the share is visible on the Zrok web console but the service is not running to the target.

What I see now that if I put the .env and compose files on a folder called ZROK2 the container is named ZROK2 so it will be easy to set up many containers

---

<div class="post-metadata">

**Author:** ![qrkourier](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/qrkourier/32/52_2.png) [@qrkourier](https://openziti.discourse.group/u/qrkourier)\
**Post date:** [July 1, 2024, 12:50pm UTC](https://openziti.discourse.group/t/using-zrok-on-docker-for-multiple-services/2757/13 "2024-07-01T12:50:26Z")

</div>

> [@Delfi\_r](#):
>
> I'm unable to set up a simple proxy Zrok service on docker

I suspect the zrok share container couldn't reach the zrok controller, backend target, or both.

> [@Delfi\_r](#):
>
> if I put the .env and compose files on a folder called ZROK2

You'll have many zrok environments this way, one for each share, which may not be what you want. You can instead use a single zrok environment with many share containers by following the YAML snippet for "your\_zrok\_share" as an example.

Here's the concept: in your compose project, have one `zrok-enable` container that enables the zrok environment. Mount the same volume from `zrok-enable` on each share container in the same path, with `STATE_DIRECTORY` env var set to the mountpoint. The shares will use the same environment. You can add numerous shares in the same compose file this way, or use separate files in the same compose project.

---

<div class="post-metadata">

**Author:** ![stefanadelbert](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/stefanadelbert/32/2121_2.png) [@stefanadelbert](https://openziti.discourse.group/u/stefanadelbert)\
**Post date:** [July 3, 2024, 7:19am UTC](https://openziti.discourse.group/t/using-zrok-on-docker-for-multiple-services/2757/14 "2024-07-03T07:19:02Z")

</div>

I've been playing with this idea today as I'm also interested in multiple shares in a single environment from a single docker compose stack/swarm/instance/[insert proper term here].

What I'm showing here doesn't relate directly to the OP's question, but it's in the ballpark and might be interesting to some.

As a starting point, I used the compose file from [here](https://github.com/openziti/zrok/blob/main/docker/compose/zrok-private-share/compose.yml). Using the [`extends` feature of docker compose](https://docs.docker.com/compose/multiple-compose-files/extends/), you can write a kind of _zrok share template service_ and then use it to declare a service for each share in your compose file.

With the following two files in the same directory, try `docker compose up`.

Note services `zrok-share-1` and `zrok-share-2` and the use of `extends`.

`compose.yaml`

```yaml
services:
  zrok-init:
    image: busybox
    # matches uid:gid of "ziggy" in zrok container image
    command: chown -Rc 2171:2171 /mnt/.zrok
    user: root
    volumes:
      - zrok_env:/mnt/.zrok

  # enable zrok environment
  zrok-enable:
    image: ${ZROK_CONTAINER_IMAGE:-docker.io/openziti/zrok}
    depends_on:
      zrok-init:
        condition: service_completed_successfully
    entrypoint: zrok-enable.bash
    volumes:
      - zrok_env:/mnt
    environment:
      STATE_DIRECTORY: /mnt
      ZROK_ENABLE_TOKEN:
      ZROK_API_ENDPOINT:
      ZROK_ENVIRONMENT_NAME: docker-private-share

  zrok-share-1:
    extends:
      file: zrok-share.yaml
      service: zrok-share
    environment:
      ZROK_TARGET: 'http://localhost:8001'

  zrok-share-2:
    extends:
      file: zrok-share.yaml
      service: zrok-share
    environment:
      ZROK_TARGET: 'http://localhost:8002'

volumes:
  zrok_env:

networks:
  default:

```

`zrok-share.yaml`

```yaml
services:
  zrok-share:
    image: ${ZROK_CONTAINER_IMAGE:-docker.io/openziti/zrok}
    restart: no
    entrypoint:
    - bash
    - -euxc
    - |
      env
      echo "DEBUG: HOME=$${HOME}"
      ls -lA /mnt/.zrok/
      exec zrok share private --headless --backend-mode proxy "$${ZROK_TARGET}"
    depends_on:
      zrok-enable:
        condition: service_completed_successfully
    volumes:
      - zrok_env:/mnt
    environment:
      HOME: /mnt
      PFXLOG_NO_JSON: "true"

```

**Note** : In the `zrok-share.yaml`, I wasn't able to find a way to get `${ZROK_TARGET}` to resolve when it's used in the `command` element unless it's present in the `.env` file (which defeats the purpose). I _think_ that the `command` element is resolved at compose file parse time, but variables specified in the `environment` element are not available for resolution at that point. This is why the whole `zrok` command is spelled out in the `entrypoint` element.

---

<div class="post-metadata">

**Author:** ![qrkourier](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/qrkourier/32/52_2.png) [@qrkourier](https://openziti.discourse.group/u/qrkourier)\
**Post date:** [July 3, 2024, 1:13pm UTC](https://openziti.discourse.group/t/using-zrok-on-docker-for-multiple-services/2757/15 "2024-07-03T13:13:30Z")

</div>

Very cool. I hadn't stumbled upon `extends` until now.
