Skip to content

Commit cc13ec3

Browse files
committed
try it with gosu instead so it can be automatic
1 parent 9cf10f1 commit cc13ec3

4 files changed

Lines changed: 92 additions & 58 deletions

File tree

docker-compose.yml-example

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ services:
3636
# # build: ./tools/linesync
3737
# container_name: linesync
3838
# restart: unless-stopped
39-
# # Match your host user's UID:GID for bind mount permissions
40-
# user: "${UID}:${GID}"
4139
# depends_on:
4240
# - nefarious
4341
# volumes:

tools/linesync/Dockerfile

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@
66
# setup - Clone the linesync repository (initial setup)
77
# sync - Continuous sync loop (default)
88
#
9-
# Supports UID/GID remapping via fixuid. In docker-compose:
10-
# user: "${UID}:${GID}"
9+
# Automatically detects UID/GID from mounted directories for proper permissions.
1110

1211
FROM debian:12-slim
1312

14-
# Default UID/GID (can be remapped at runtime via fixuid)
15-
ENV GID=1234
16-
ENV UID=1234
13+
# Default UID/GID (will be overridden at runtime based on mounted directory ownership)
14+
ENV LINESYNC_UID=1000
15+
ENV LINESYNC_GID=1000
1716

1817
# Install required tools
1918
RUN apt-get update && apt-get install -y --no-install-recommends \
@@ -25,6 +24,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
2524
ca-certificates \
2625
curl \
2726
gnupg \
27+
gosu \
2828
&& rm -rf /var/lib/apt/lists/*
2929

3030
# Install Docker CLI (for sending signals to nefarious container)
@@ -36,16 +36,9 @@ RUN install -m 0755 -d /etc/apt/keyrings \
3636
&& apt-get install -y --no-install-recommends docker-ce-cli \
3737
&& rm -rf /var/lib/apt/lists/*
3838

39-
# Create user
40-
RUN groupadd -g ${GID} linesync \
41-
&& useradd -u ${UID} -g ${GID} -m linesync
42-
43-
# Install fixuid for UID/GID remapping at runtime
44-
RUN ARCH="$(dpkg --print-architecture)" && \
45-
curl -fsSL "https://github.com/boxboat/fixuid/releases/download/v0.6.0/fixuid-0.6.0-linux-${ARCH}.tar.gz" | tar -C /usr/local/bin -xzf - && \
46-
chmod 4755 /usr/local/bin/fixuid && \
47-
mkdir -p /etc/fixuid && \
48-
printf "user: linesync\ngroup: linesync\npaths:\n - /home/linesync\n" > /etc/fixuid/config.yml
39+
# Create user (UID/GID will be adjusted at runtime)
40+
RUN groupadd -g ${LINESYNC_GID} linesync \
41+
&& useradd -u ${LINESYNC_UID} -g ${LINESYNC_GID} -m linesync
4942

5043
# Create directories
5144
RUN mkdir -p /home/linesync/.ssh \
@@ -57,12 +50,11 @@ COPY gitsync.sh /home/linesync/gitsync.sh
5750
COPY linesync-entrypoint.sh /home/linesync/entrypoint.sh
5851
RUN chmod +x /home/linesync/gitsync.sh /home/linesync/entrypoint.sh
5952

60-
USER linesync:linesync
61-
WORKDIR /home/linesync
53+
# SSH config template (will be copied to user's .ssh at runtime)
54+
RUN echo "Host *\n StrictHostKeyChecking accept-new\n UserKnownHostsFile /home/linesync/.ssh/known_hosts" > /etc/ssh/ssh_config.d/linesync.conf
6255

63-
# SSH config for git
64-
RUN echo "Host *\n StrictHostKeyChecking accept-new\n UserKnownHostsFile /home/linesync/.ssh/known_hosts" > /home/linesync/.ssh/config \
65-
&& chmod 600 /home/linesync/.ssh/config
56+
WORKDIR /home/linesync
6657

67-
ENTRYPOINT ["fixuid", "-q", "/home/linesync/entrypoint.sh"]
58+
# Run as root initially; entrypoint will drop privileges after detecting UID/GID
59+
ENTRYPOINT ["/home/linesync/entrypoint.sh"]
6860
CMD ["sync"]

tools/linesync/README.md

Lines changed: 20 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ A Docker sidecar container for automated git-based configuration synchronization
99
- Configurable sync interval
1010
- Support for SSL certificate sync via git tags
1111
- Multiple operation modes: keygen, setup, sync, once
12-
- Automatic UID/GID remapping via fixuid for bind mount compatibility
12+
- Automatic UID/GID detection from bind mounts (no manual configuration needed)
1313

1414
## Quick Start
1515

@@ -24,7 +24,7 @@ docker build -t linesync .
2424

2525
```bash
2626
mkdir -p ./linesync-ssh ./linesync
27-
docker run --rm -u "$(id -u):$(id -g)" \
27+
docker run --rm \
2828
-v ./linesync-ssh:/home/linesync/.ssh \
2929
linesync keygen
3030
```
@@ -34,7 +34,7 @@ This outputs a public key. Add it to your git repository's deploy keys.
3434
### 3. Initial repository setup
3535

3636
```bash
37-
docker run --rm -u "$(id -u):$(id -g)" \
37+
docker run --rm \
3838
-v ./linesync-ssh:/home/linesync/.ssh \
3939
-v ./local.conf:/home/linesync/ircd/local.conf \
4040
-v ./linesync:/home/linesync/ircd/linesync \
@@ -47,7 +47,6 @@ docker run --rm -u "$(id -u):$(id -g)" \
4747
```bash
4848
docker run -d \
4949
--name linesync \
50-
-u "$(id -u):$(id -g)" \
5150
-v ./linesync-ssh:/home/linesync/.ssh \
5251
-v ./local.conf:/home/linesync/ircd/local.conf \
5352
-v ./linesync:/home/linesync/ircd/linesync \
@@ -60,20 +59,18 @@ docker run -d \
6059

6160
## Command Line Usage
6261

63-
**Note:** Use `-u "$(id -u):$(id -g)"` to match your host user's UID/GID for proper file permissions on bind mounts.
64-
6562
### Generate SSH keypair
6663

6764
```bash
6865
mkdir -p ./linesync-ssh
6966

7067
# Generate ed25519 key (default, recommended)
71-
docker run --rm -u "$(id -u):$(id -g)" \
68+
docker run --rm \
7269
-v ./linesync-ssh:/home/linesync/.ssh \
7370
linesync keygen
7471

7572
# Generate RSA key
76-
docker run --rm -u "$(id -u):$(id -g)" \
73+
docker run --rm \
7774
-v ./linesync-ssh:/home/linesync/.ssh \
7875
linesync keygen rsa
7976
```
@@ -82,7 +79,7 @@ docker run --rm -u "$(id -u):$(id -g)" \
8279

8380
```bash
8481
mkdir -p ./linesync
85-
docker run --rm -u "$(id -u):$(id -g)" \
82+
docker run --rm \
8683
-v ./linesync-ssh:/home/linesync/.ssh \
8784
-v ./local.conf:/home/linesync/ircd/local.conf \
8885
-v ./linesync:/home/linesync/ircd/linesync \
@@ -93,7 +90,7 @@ docker run --rm -u "$(id -u):$(id -g)" \
9390
### Run sync once
9491

9592
```bash
96-
docker run --rm -u "$(id -u):$(id -g)" \
93+
docker run --rm \
9794
-v ./linesync-ssh:/home/linesync/.ssh \
9895
-v ./local.conf:/home/linesync/ircd/local.conf \
9996
-v ./linesync:/home/linesync/ircd/linesync \
@@ -105,7 +102,7 @@ docker run --rm -u "$(id -u):$(id -g)" \
105102
### Interactive shell (debugging)
106103

107104
```bash
108-
docker run --rm -it -u "$(id -u):$(id -g)" \
105+
docker run --rm -it \
109106
-v ./linesync-ssh:/home/linesync/.ssh \
110107
-v ./local.conf:/home/linesync/ircd/local.conf \
111108
-v ./linesync:/home/linesync/ircd/linesync \
@@ -129,8 +126,6 @@ services:
129126
linesync:
130127
image: ghcr.io/evilnet/nefarious2-linesync:latest
131128
container_name: linesync
132-
# Match your host user's UID:GID for bind mount permissions
133-
user: "${UID}:${GID}"
134129
depends_on:
135130
- nefarious
136131
volumes:
@@ -158,17 +153,17 @@ mkdir -p ./linesync-ssh ./linesync
158153
touch ./local.conf
159154

160155
# 1. Generate SSH key
161-
UID=$(id -u) GID=$(id -g) docker compose run --rm linesync keygen
156+
docker compose run --rm linesync keygen
162157

163158
# 2. Add the public key to your git repo's deploy keys
164159

165160
# 3. Clone the linesync repository
166-
UID=$(id -u) GID=$(id -g) docker compose run --rm \
161+
docker compose run --rm \
167162
-e GIT_REPOSITORY=git@github.com:yourorg/linesync-data.git \
168163
linesync setup
169164

170165
# 4. Start the services
171-
UID=$(id -u) GID=$(id -g) docker compose up -d
166+
docker compose up -d
172167
```
173168

174169
## Environment Variables
@@ -229,18 +224,19 @@ docker run ... -e CERT_TAG=myserver-cert linesync sync
229224
- The Docker socket mount grants significant privileges. The container can control other containers.
230225
- Use read-only deploy keys in your git repository
231226
- Consider running the sidecar with `--read-only` filesystem (with tmpfs for `/tmp`)
232-
- SSH keys should be stored in a named volume or secrets manager
227+
- SSH keys should be stored securely
233228

234-
## UID/GID Remapping
229+
## UID/GID Auto-Detection
235230

236-
The container uses [fixuid](https://github.com/boxboat/fixuid) to automatically remap the internal user's UID/GID to match yours at runtime. This ensures files created in bind-mounted directories are owned by your host user.
231+
The container automatically detects the UID/GID of your bind-mounted directories and runs as that user. This means files created by the container will be owned by your host user without any manual configuration.
237232

238233
**How it works:**
239-
1. You specify `user: "${UID}:${GID}"` in docker-compose (or `-u "$(id -u):$(id -g)"` on command line)
240-
2. fixuid runs at container startup and remaps the `linesync` user to match
241-
3. All file operations use your host UID/GID
234+
1. Container starts as root
235+
2. Entrypoint detects the owner of mounted directories (e.g., `./linesync-ssh`)
236+
3. Modifies the internal `linesync` user to match that UID/GID
237+
4. Drops privileges and runs the actual command as that user
242238

243-
**Without UID/GID mapping:** Files would be owned by UID 1234 (the container's default), causing permission issues.
239+
This happens automatically - no `-u` flags or environment variables needed.
244240

245241
## Troubleshooting
246242

@@ -259,19 +255,9 @@ Run `setup` mode first to clone the repository.
259255
### "Could not signal container"
260256
Ensure the Docker socket is mounted and the container name matches `NEFARIOUS_CONTAINER`.
261257

262-
### Permission denied on bind mounts
263-
Make sure you're passing the UID/GID:
264-
```bash
265-
# Command line
266-
docker run -u "$(id -u):$(id -g)" ...
267-
268-
# Docker compose
269-
UID=$(id -u) GID=$(id -g) docker compose up
270-
```
271-
272258
### Debug with shell access
273259
```bash
274-
docker run --rm -it -u "$(id -u):$(id -g)" \
260+
docker run --rm -it \
275261
-v ./linesync-ssh:/home/linesync/.ssh \
276262
-v ./local.conf:/home/linesync/ircd/local.conf \
277263
-v ./linesync:/home/linesync/ircd/linesync \

tools/linesync/linesync-entrypoint.sh

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,64 @@
44

55
set -e
66

7+
# =============================================================================
8+
# UID/GID Auto-Detection and Privilege Dropping
9+
# =============================================================================
10+
# If running as root, detect the UID/GID from mounted directories and drop
11+
# privileges to match. This allows bind mounts to work without manual -u flags.
12+
13+
if [ "$(id -u)" = "0" ]; then
14+
# Detect UID/GID from mounted directories (in order of preference)
15+
TARGET_UID=""
16+
TARGET_GID=""
17+
18+
for detect_path in /home/linesync/.ssh /home/linesync/ircd; do
19+
if [ -d "$detect_path" ]; then
20+
TARGET_UID=$(stat -c %u "$detect_path")
21+
TARGET_GID=$(stat -c %g "$detect_path")
22+
# Skip if owned by root (probably not a bind mount)
23+
if [ "$TARGET_UID" != "0" ]; then
24+
break
25+
fi
26+
fi
27+
done
28+
29+
# Default to 1000:1000 if detection failed or got root
30+
: "${TARGET_UID:=1000}"
31+
: "${TARGET_GID:=1000}"
32+
33+
# Get current linesync UID/GID
34+
CURRENT_UID=$(id -u linesync)
35+
CURRENT_GID=$(id -g linesync)
36+
37+
# Modify user/group if needed
38+
if [ "$TARGET_GID" != "$CURRENT_GID" ]; then
39+
groupmod -g "$TARGET_GID" linesync 2>/dev/null || true
40+
fi
41+
if [ "$TARGET_UID" != "$CURRENT_UID" ]; then
42+
usermod -u "$TARGET_UID" linesync 2>/dev/null || true
43+
fi
44+
45+
# Fix ownership of home directory
46+
chown -R linesync:linesync /home/linesync 2>/dev/null || true
47+
48+
# Ensure SSH config exists
49+
if [ ! -f /home/linesync/.ssh/config ]; then
50+
mkdir -p /home/linesync/.ssh
51+
echo -e "Host *\n StrictHostKeyChecking accept-new\n UserKnownHostsFile /home/linesync/.ssh/known_hosts" > /home/linesync/.ssh/config
52+
chmod 700 /home/linesync/.ssh
53+
chmod 600 /home/linesync/.ssh/config
54+
chown -R linesync:linesync /home/linesync/.ssh
55+
fi
56+
57+
# Re-exec this script as linesync user
58+
exec gosu linesync "$0" "$@"
59+
fi
60+
61+
# =============================================================================
62+
# Main Entrypoint (running as linesync user)
63+
# =============================================================================
64+
765
# Configuration with defaults
866
: "${SYNC_INTERVAL:=300}" # Sync interval in seconds (default: 5 minutes)
967
: "${IRCD_CONF:=/home/linesync/ircd/ircd.conf}"
@@ -58,7 +116,7 @@ do_keygen() {
58116
# Check if directory is writable
59117
if [ ! -w "$sshdir" ]; then
60118
echo "Error: SSH directory $sshdir is not writable"
61-
echo "Fix permissions on the host: chmod 700 ./linesync-ssh && chown $(id -u):$(id -g) ./linesync-ssh"
119+
echo "Check that the directory exists and has correct permissions"
62120
exit 1
63121
fi
64122

0 commit comments

Comments
 (0)