Skip to content

Conversation

@nvrlivenvrdie
Copy link

Docker file creates /data directory and sets permissions for app to write to /data and /app directories
resubmit of #101

fixes #95
fixes #96

/data and /app directories

removed chown for /app it was not needed
@nvrlivenvrdie
Copy link
Author

After further testing, i found you only need to create the /data directory and chown it to app:app

chown-ing the /app directory seems to be redundant if the data directory is writable.

I've updated the PR to represent this

@linux4life798
Copy link

linux4life798 commented Oct 31, 2025

Does this approach still work if you mount a docker volume to /data?

I would have assumed that this chown app:app /data runs during the docker container build step, that Tailscale does on their side (github ci). When the end user launches this container, they bind mount a new /data directory (as a docker volume) with different permissions and the chown app:app /data doesn't run.

@nvrlivenvrdie
Copy link
Author

nvrlivenvrdie commented Oct 31, 2025

yes i was able to use the docker compose example in the readme. Mounting a volume to /data

My understanding is /data would be owned by root and where its been switched to run as the app user (1001) we no longer have access to write to /data

I was going to chown /data to app:app only. but because the container hadn't started yet it wasn't created, so i found i had to create it first in the build stage

After that mounting works normal. I haven't tried using it with a bind mount yet but i can attempt that

@nvrlivenvrdie
Copy link
Author

nvrlivenvrdie commented Oct 31, 2025

Yes it seems to work for both a docker volume as stated in the example compose as such

services:
  tsidp:
    container_name: tsidp
    image: ghcr.io/tailscale/tsidp:latest
    volumes:
      - tsidp-data:/data
    environment:
      - TAILSCALE_USE_WIP_CODE=1 # tsidp is experimental - needed while version <1.0.0
      - TS_STATE_DIR=/data # store persistent tsnet and tsidp state
      - TS_HOSTNAME=idp # Hostname on tailnet (becomes idp.your-tailnet.ts.net)
      - TSIDP_ENABLE_STS=1 # Enable OAuth token exchange
      # Optional: Tailscale auth key for automatic node registration
      # - TS_AUTHKEY=tskey-auth-xxxxx
volumes:
  tsidp-data:

or using a bind mount like so

services:
  tsidp:
    container_name: tsidp
    image: ghcr.io/tailscale/tsidp:latest
    volumes:
      - ./test_data:/data
    environment:
      - TAILSCALE_USE_WIP_CODE=1 # tsidp is experimental - needed while version <1.0.0
      - TS_STATE_DIR=/data # store persistent tsnet and tsidp state
      - TS_HOSTNAME=idp # Hostname on tailnet (becomes idp.your-tailnet.ts.net)
      - TSIDP_ENABLE_STS=1 # Enable OAuth token exchange
      # Optional: Tailscale auth key for automatic node registration
      # - TS_AUTHKEY=tskey-auth-xxxxx

in my test i substituted the image file with my own built from the dockerfile i suggested

edit:
I should have probably said as well if it wasn't clear that, not only does it not throw errors but the data in the /data directory remains persistent as expected as well

@linux4life798
Copy link

Nice!

My last concern is that your change bakes the /data into the Dockerfile, but elsewhere the configuration allows changing the tsnet state at runtime.

Maybe just propose removing this environment variable and specify VOLUME /data in the Dockerfile?
Or, fix the runtime selectability by moving the mkdir+chown into the run.sh? This would mean a lot more changes, though, like running run.sh as root and then stepping down to the app user when launching /tsidp-server, at the bottom.

@nvrlivenvrdie
Copy link
Author

nvrlivenvrdie commented Oct 31, 2025

To achieve the ability to let the user pick a directory with an environment I made these 2 changes to the main branch

##DockerFile

-RUN apk --no-cache add ca-certificates

+RUN apk --no-cache add ca-certificates su-exec 

-USER app:app 
##scripts/docker/run.sh

+if [ -n "$TS_STATE_DIR" ]; then
+    mkdir -p "$TS_STATE_DIR"
+    chown app:app "$TS_STATE_DIR"
+fi
+

-exec /tsidp-server $ARGS "$@"

+su-exec app:app /tsidp-server $ARGS "$@"

if this seems like the route i can add the PR for it instead

If you want to run the whole entrypoint as app user though i believe you would have to not allow the user to pick the internal folder for the docker location and just do a Volume in the dockerfile?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Failed to create OIDC client TSIDP errors when starting from docker compose file

2 participants