Add files

This commit is contained in:
kenzuya
2026-03-10 17:42:34 +07:00
commit f159a507af
5 changed files with 225 additions and 0 deletions

53
Dockerfile Normal file
View File

@@ -0,0 +1,53 @@
FROM archlinux:latest
ARG SHAKA_PACKAGER_URL="https://github.com/shaka-project/shaka-packager/releases/download/v2.6.1/packager-linux-x64"
ARG UNSHACKLE_REPO_URL
ARG UNSHACKLE_APP_DIR="/opt/unshackle"
ENV LANG=C.UTF-8 \
LC_ALL=C.UTF-8 \
TS_STATE_DIR=/var/lib/tailscale \
TS_SOCKET=/var/run/tailscale/tailscaled.sock \
START_TAILSCALED=1 \
UNSHACKLE_APP_DIR="${UNSHACKLE_APP_DIR}"
RUN pacman -Syu --noconfirm && \
pacman -S --noconfirm --needed \
aria2 \
bash \
ca-certificates \
curl \
fish \
fuse3 \
git \
iproute2 \
iptables \
less \
procps-ng \
python \
rclone \
tailscale \
uv && \
pacman -Scc --noconfirm
RUN mkdir -p /var/lib/tailscale /var/run/tailscale /workspace "${UNSHACKLE_APP_DIR}"
RUN curl -L "${SHAKA_PACKAGER_URL}" -o /tmp/packager-linux-x64 && \
install -Dm755 /tmp/packager-linux-x64 /usr/local/bin/packager && \
ln -sf /usr/local/bin/packager /usr/local/bin/shaka-packager && \
rm -f /tmp/packager-linux-x64
RUN git clone "${UNSHACKLE_REPO_URL}" "${UNSHACKLE_APP_DIR}"
WORKDIR ${UNSHACKLE_APP_DIR}
RUN uv sync --frozen
COPY docker/entrypoint.sh /usr/local/bin/container-entrypoint.sh
COPY docker/fish/unshackle-venv.fish /etc/fish/conf.d/unshackle-venv.fish
RUN chmod +x /usr/local/bin/container-entrypoint.sh
ENV PATH="${UNSHACKLE_APP_DIR}/.venv/bin:${PATH}"
ENTRYPOINT ["/usr/local/bin/container-entrypoint.sh"]
CMD ["fish"]

47
docker-compose.yml Normal file
View File

@@ -0,0 +1,47 @@
services:
unshackle:
build:
context: .
dockerfile: Dockerfile
args:
SHAKA_PACKAGER_URL: https://github.com/shaka-project/shaka-packager/releases/download/v2.6.1/packager-linux-x64
UNSHACKLE_REPO_URL: https://oauth2:f8c4a9d0472d2b8d0170e78a76b57c62e97cd3bb@gitea.soay-dory.ts.net/unshackle-dl/unshackle.git
UNSHACKLE_APP_DIR: /opt/unshackle
container_name: unshackle
hostname: unshackle
working_dir: /opt/unshackle
stdin_open: true
tty: true
environment:
START_TAILSCALED: "1"
START_RCLONE: "1"
TS_STATE_DIR: /var/lib/tailscale
TS_SOCKET: /var/run/tailscale/tailscaled.sock
TS_AUTHKEY: tskey-auth-kjHgE6GKB611CNTRL-oK3BfNaC2FSDFkSERE2WFS4BPJngTVbv
TS_EXTRA_ARGS: ${TS_EXTRA_ARGS:-}
TS_UP_ARGS: ${TS_UP_ARGS:---ssh}
RCLONE_CONFIG: /etc/rclone/rclone.conf
RCLONE_REMOTE: "ketuakenzuya:"
RCLONE_MOUNT_DIR: /mnt/ketuakenzuya
RCLONE_CACHE_DIR: /tmp/rclone
RCLONE_CACHE_MAX_SIZE: 4G
RCLONE_EXTRA_ARGS: ${RCLONE_EXTRA_ARGS:-}
UNSHACKLE_APP_DIR: /opt/unshackle
cap_add:
- NET_ADMIN
- NET_RAW
- SYS_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
- /dev/fuse:/dev/fuse
security_opt:
- apparmor:unconfined
volumes:
- .:/workspace
- /tmp:/tmp
- ./docker/rclone.conf:/etc/rclone/rclone.conf
- tailscale-state:/var/lib/tailscale
command: fish
volumes:
tailscale-state:

97
docker/entrypoint.sh Normal file
View File

@@ -0,0 +1,97 @@
#!/usr/bin/env bash
set -euo pipefail
STATE_DIR="${TS_STATE_DIR:-/var/lib/tailscale}"
SOCKET="${TS_SOCKET:-/var/run/tailscale/tailscaled.sock}"
RCLONE_CONFIG="${RCLONE_CONFIG:-/etc/rclone/rclone.conf}"
RCLONE_REMOTE="${RCLONE_REMOTE:-ketuakenzuya:}"
RCLONE_MOUNT_DIR="${RCLONE_MOUNT_DIR:-/mnt/ketuakenzuya}"
RCLONE_CACHE_DIR="${RCLONE_CACHE_DIR:-/tmp/rclone}"
RCLONE_CACHE_MAX_SIZE="${RCLONE_CACHE_MAX_SIZE:-4G}"
mkdir -p \
"$STATE_DIR" \
"$(dirname "$SOCKET")" \
"$RCLONE_MOUNT_DIR" \
"$RCLONE_CACHE_DIR"
extra_args=()
if [[ -n "${TS_EXTRA_ARGS:-}" ]]; then
# shellcheck disable=SC2206
extra_args=( ${TS_EXTRA_ARGS} )
fi
up_args=()
if [[ -n "${TS_UP_ARGS:-}" ]]; then
# shellcheck disable=SC2206
up_args=( ${TS_UP_ARGS} )
fi
declare -a bg_pids=()
cleanup() {
for pid in "${bg_pids[@]}"; do
kill "$pid" 2>/dev/null || true
done
for pid in "${bg_pids[@]}"; do
wait "$pid" 2>/dev/null || true
done
}
trap cleanup EXIT
if [[ "${START_TAILSCALED:-1}" == "1" ]]; then
if [[ ! -c /dev/net/tun ]]; then
echo "warning: /dev/net/tun tidak tersedia, tailscaled tidak dijalankan" >&2
else
tailscaled \
--state="${STATE_DIR}/tailscaled.state" \
--socket="$SOCKET" \
"${extra_args[@]}" &
bg_pids+=( "$!" )
if [[ -n "${TS_AUTHKEY:-}" || ${#up_args[@]} -gt 0 ]]; then
for _ in {1..30}; do
if tailscale --socket="$SOCKET" status >/dev/null 2>&1; then
break
fi
sleep 1
done
tailscale up \
--socket="$SOCKET" \
${TS_AUTHKEY:+--authkey="$TS_AUTHKEY"} \
"${up_args[@]}"
fi
fi
fi
extra_rclone_args=()
if [[ -n "${RCLONE_EXTRA_ARGS:-}" ]]; then
# shellcheck disable=SC2206
extra_rclone_args=( ${RCLONE_EXTRA_ARGS} )
fi
if [[ "${START_RCLONE:-1}" == "1" ]]; then
if [[ ! -c /dev/fuse ]]; then
echo "warning: /dev/fuse tidak tersedia, rclone mount tidak dijalankan" >&2
elif [[ ! -f "$RCLONE_CONFIG" ]]; then
echo "warning: config rclone tidak ditemukan di $RCLONE_CONFIG, mount tidak dijalankan" >&2
else
rclone mount \
--config "$RCLONE_CONFIG" \
--cache-dir "$RCLONE_CACHE_DIR" \
--vfs-cache-mode full \
--vfs-cache-max-size "$RCLONE_CACHE_MAX_SIZE" \
"${extra_rclone_args[@]}" \
"$RCLONE_REMOTE" \
"$RCLONE_MOUNT_DIR" &
bg_pids+=( "$!" )
fi
fi
if [[ $# -eq 0 ]]; then
exec fish
fi
exec "$@"

View File

@@ -0,0 +1,3 @@
if test -f /opt/unshackle/.venv/bin/activate.fish
source /opt/unshackle/.venv/bin/activate.fish
end

25
docker/rclone.conf Normal file
View File

@@ -0,0 +1,25 @@
[Kenzuya-Drive]
type = drive
token = {"access_token":"ya29.a0AfB_byC1Q968bYjCUHBS9ZapXYolipvgFutwUSVfw0pmqMBUrovkKEqklK8f-q-mQmjnVx6sF84dFnqba4opkDmqQFfa5cku2fWJEKggQGQ32-O8WSQb7v374FM3jeIy-shZGqzMOO3gT406DeFHpf6kME2zWbHQ0_2TaCgYKAS4SARMSFQHGX2Mivt4xa4dOq8WugShFzvLkUg0171","token_type":"Bearer","refresh_token":"1//0geUqgMWTDXuCCgYIARAAGBASNwF-L9Irvx77Ew1oXQt3GgCD0Pe_XU_dPrrit5dg9FcODwtn8XR0rZlCywUgA8bQW9CgHjJnxuE","expiry":"2024-01-14T00:08:13.4396591+07:00"}
team_drive =
[samlekom7225]
type = drive
token = {"access_token":"ya29.a0AQQ_BDSuPNTZGoLrHG9B22-BbjQ0ABm1tn5djZouV1z-dvemkeJjinp46I4HfS7pu1_ske9Uj4GNksy8MbPCVoWE0bQyBtcKPZFhpovb4Ig9SN2fQSTos2vEEeEyQq4IF7a-LL1zrANcJwLUzWOhmMUWFaJGyLXsf56DMFcQiZNNCmxZ1GyapSbN_RKZQKDgZcXPo9NeUwaCgYKAckSARASFQHGX2Mi9xBB9p8F1A4BczLbI3fzjw0209","token_type":"Bearer","refresh_token":"1//0gGYpJMT-YdmGCgYIARAAGBASNwF-L9IrxB4YzT0VMX2323xqJ5rRCSKSYUxG6EJnWDkgGAmnpsqsfUIeBgQCIt53c3oG46M0U_s","expiry":"2025-09-27T11:25:57.549990864Z","expires_in":3599}
team_drive =
[manusiabiasa7225]
type = drive
token = {"access_token":"ya29.a0AS3H6NzOxL6lFsvTt6z3_vUyT4MgV0Uz7pKr6E7AlMyJte_XwmG-lHSu7FhfT3-oS-5yW0HBDB8ivI9MqsWTlrwwTHoyciRd5X-9N-Zq3qM_nCbRuimeZiUrwIB2mD4eYd-Wpu5P0qpu28Fa-KkGZ8nqCqoPCMbgtK8gYbbPyoIaCgYKATYSARUSFQHGX2MikXvvpJKtYScwt7oolm7g5A0178","token_type":"Bearer","refresh_token":"1//0g0fAYLjPI9W9CgYIARAAGBASNwF-L9Ir1WG0ZfOVEraWomqHWtf7mjFWxFFKnubbwz_el52ZKCiecygI-s0Kh0ZDY3O1KXMLcAI","expiry":"2025-08-01T00:32:47.641261661Z"}
team_drive =
[maskenzuya]
type = drive
token = {"access_token":"ya29.a0ATkoCc548BNfJo1sUp0J_yLg-fsWeOmoL4k951BiA2AwVIwmdG7kQBApEXP5I1YQWKNy_jsQO6rvCOdwe_00_fX9QXOb4sna5U9cFbtGK93U2q7WcEd7nxg2fxeKl7w_aR6yanJ6SO9c_JwgpErTO7s5mDnCuM7Hu5LPG_mND2ta23hZcVbtXReeebE5S6BvxeoyCP86wQaCgYKAQsSARQSFQHGX2Miq1fYC2Be50191U9B3rPR5A0209","token_type":"Bearer","refresh_token":"1//0gaYzi2c_icLYCgYIARAAGBASNwF-L9IrwjUcto84AkbxLTHwMHEy-NbjE8J8OettG8B-iwURL8ZNoMpmXEnXniTU-aP1kQt8bgs","expiry":"2026-03-06T03:43:13.080112856+07:00","expires_in":3599}
team_drive =
[ketuakenzuya]
type = drive
token = {"access_token":"ya29.a0ATkoCc7OeqSFyK0VtO45OuWDjatekS8Avwf1ilzj3ZaAfC6lmmTWwZ8hlpwG-WeXPwQ6LAjV82f4_OYkoinmcFlAOZgMBvN2x_I2D4esHxLfxlHQK5cgiEZMYlNOOQ6Pt1sQuax5xeTgi588mCNU7B2ecAU_4zxkXwBeuwqb1BdKrYv9O4Rq09BCarJYGH8mTor49GHfVwaCgYKAYUSARMSFQHGX2Mi1_DsxQhMr8MHifl0pgnZvw0209","token_type":"Bearer","refresh_token":"1//0gEwdJqyr-PpWCgYIARAAGBASNwF-L9Ir_tyLJKmiZ-4ms72S9Pr1Dy-hzD91KVS4uaoTe6T2BJ-DVH3lMd94FlT4yZYEAOCqX_o","expiry":"2026-03-06T03:43:41.268825918+07:00","expires_in":3599}
team_drive =