diff --git a/.devcontainer/dev.docker-compose.yml b/.devcontainer/dev.docker-compose.yml index 2d990b2..3590072 100644 --- a/.devcontainer/dev.docker-compose.yml +++ b/.devcontainer/dev.docker-compose.yml @@ -18,8 +18,6 @@ services: dockerfile: configs/docker/dev.Dockerfile args: USERNAME: devu - USER_UID: 1000 - USER_GID: 1000 WORK_DIR: "/workspace" UV: ${UV_INSTALL_DIR} PNPM: ${PNPM_BIN} @@ -27,6 +25,7 @@ services: SSH_AUTH_SOCK: /ssh-agent BIN_DEPLOY_PREP: ${BIN_DEPLOY_PREP} BIN_DEPLOY_REQ: ${BIN_DEPLOY_REQ} + BIN_DEPLOY_USER: ${BIN_DEPLOY_USER} BIN_DEPLOY_ENTRY_DEV: ${BIN_DEPLOY_ENTRY_DEV} volumes: - ${SSH_AUTH_SOCK:-/dev/null}:/ssh-agent:ro diff --git a/Dockerfile b/Dockerfile index 8eb95eb..e2f73e4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,26 +30,21 @@ FROM docker.io/almalinux:10 AS main ARG USERNAME=runner ARG USER_UID=1001 -ARG USER_GID=${USER_UID} -ARG HOME_MAIN="/home/${USERNAME}" +ARG USER_GID=1001 +ARG HOME_MAIN="/home/runner" ARG BIN_DEPLOY_ENTRY_PROD ARG BIN_DEPLOY_HEALTH ARG NODE_VERSION RUN dnf clean all && dnf install -y bash -RUN groupadd --force --gid ${USER_GID} ${USERNAME} && \ - useradd --uid ${USER_UID} --gid ${USER_GID} -m -d ${HOME_MAIN} ${USERNAME} || \ - usermod -u ${USER_UID} -g ${USER_GID} ${USERNAME} - -RUN mkdir -p "${HOME_MAIN}/.local/bin" \ - && chown ${USERNAME}:${USERNAME} -R ${HOME_MAIN} - ARG BIN_DEPLOY_PREP ARG BIN_DEPLOY_REQ +ARG BIN_DEPLOY_USER COPY ./${BIN_DEPLOY_PREP} /prep.sh COPY ./${BIN_DEPLOY_REQ} /req.sh +COPY ./${BIN_DEPLOY_USER} /user.sh COPY --from=appbuilder /tmp/app/dist /tmp/build COPY ./${BIN_DEPLOY_ENTRY_PROD} /entry.sh @@ -58,6 +53,7 @@ COPY ./${BIN_DEPLOY_HEALTH} /health.sh WORKDIR /tmp/build RUN bash /prep.sh && rm /prep.sh RUN bash /req.sh && rm /req.sh +RUN bash /user.sh && rm /user.sh HEALTHCHECK --interval=5m --timeout=3s CMD /health.sh diff --git a/bin/deploy/user.sh b/bin/deploy/user.sh new file mode 100755 index 0000000..406121e --- /dev/null +++ b/bin/deploy/user.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +# SPDX-FileCopyrightText: 2026 Artur Lissin +# +# SPDX-License-Identifier: Unlicense + +set -eux + +USERNAME="${USERNAME:-devu}" +USER_UID="${USER_UID:-1000}" +USER_GID="${USER_GID:-1000}" +HOME_MAIN="/home/${USERNAME}" + +[ -n "${USERNAME}" ] || { echo "ERROR: USERNAME is empty!" >&2; exit 1; } +[ -n "${USER_UID}" ] || { echo "ERROR: USER_UID is empty!" >&2; exit 1; } +[ -n "${USER_GID}" ] || { echo "ERROR: USER_GID is empty!" >&2; exit 1; } + +GROUP_NAME="$(getent group "${USER_GID}" | cut -d: -f1 || true)" + + +if [ -n "${GROUP_NAME}" ] && [ "${GROUP_NAME}" != "${USERNAME}" ]; then + groupmod \ + --new-name "${USERNAME}" \ + "${GROUP_NAME}" +elif [ -z "${GROUP_NAME}" ]; then + groupadd \ + --gid "${USER_GID}" \ + "${USERNAME}" +fi + +USER_NAME="$(getent passwd "${USER_UID}" | cut -d: -f1 || true)" + +if [ -n "${USER_NAME}" ] && [ "${USER_NAME}" != "${USERNAME}" ]; then + usermod \ + --login "${USERNAME}" \ + --home "${HOME_MAIN}" \ + --move-home \ + --gid "${USER_GID}" \ + "${USER_NAME}" +elif [ -z "${USER_NAME}" ]; then + useradd \ + --uid "${USER_UID}" \ + --gid "${USER_GID}" \ + --create-home \ + --home-dir "${HOME_MAIN}" \ + --shell /bin/bash \ + "${USERNAME}" +fi +mkdir -p "${HOME_MAIN}/.local/bin" +chown -R "${USER_UID}:${USER_GID}" "${HOME_MAIN}" diff --git a/configs/docker/dev.Dockerfile b/configs/docker/dev.Dockerfile index 94fb0fb..cae1642 100644 --- a/configs/docker/dev.Dockerfile +++ b/configs/docker/dev.Dockerfile @@ -3,8 +3,9 @@ FROM docker.io/almalinux:10 ARG UV ARG PNPM ARG USERNAME=devu +# USER_UID and USER_GID will be mapped by devcontainer ARG USER_UID=1000 -ARG USER_GID=$USER_UID +ARG USER_GID=1000 ARG WORK_DIR=/workspace ENV HOME_MAIN="/home/${USERNAME}" ENV PATH="${HOME_MAIN}/.local/bin:${WORK_DIR}/${UV}:${WORK_DIR}/${PNPM}:${PATH}" @@ -16,6 +17,7 @@ ENV HISTFILESIZE=0 ARG NODE_VERSION ARG BIN_DEPLOY_PREP ARG BIN_DEPLOY_REQ +ARG BIN_DEPLOY_USER ARG BIN_DEPLOY_ENTRY_DEV COPY . /tmp/app @@ -25,16 +27,12 @@ WORKDIR /tmp/app COPY ./${BIN_DEPLOY_ENTRY_DEV} /entry_dev.sh RUN dnf clean all && dnf install -y bash -RUN bash "./${BIN_DEPLOY_PREP}" && bash "./${BIN_DEPLOY_REQ}" +RUN bash "./${BIN_DEPLOY_PREP}" && bash "./${BIN_DEPLOY_REQ}" && bash "./${BIN_DEPLOY_USER}" WORKDIR / RUN rm -rf /tmp/app -RUN groupadd --force --gid ${USER_GID} ${USERNAME} && \ - useradd --uid ${USER_UID} --gid ${USER_GID} -m -d ${HOME_MAIN} ${USERNAME} || \ - usermod -u ${USER_UID} -g ${USER_GID} ${USERNAME} - RUN mkdir -p ${WORK_DIR} && \ chown ${USERNAME}:${USERNAME} -R ${WORK_DIR} && \ chown ${USERNAME}:${USERNAME} -R ${HOME_MAIN} diff --git a/docker-compose.yml b/docker-compose.yml index a6a3053..25d0d05 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,6 +17,7 @@ services: NODE_VERSION: ${NODE_VERSION} BIN_DEPLOY_PREP: ${BIN_DEPLOY_PREP} BIN_DEPLOY_REQ: ${BIN_DEPLOY_REQ} + BIN_DEPLOY_USER: ${BIN_DEPLOY_USER} BIN_DEPLOY_HEALTH: ${BIN_DEPLOY_HEALTH} BIN_DEPLOY_ENTRY_PROD: ${BIN_DEPLOY_ENTRY_PROD} diff --git a/package.env b/package.env index 3a73436..a5b0098 100644 --- a/package.env +++ b/package.env @@ -35,6 +35,7 @@ DOCS_ENV=packages/docs/.env # Configuration which are required for docker compose and should be copied to ROOT/.env BIN_DEPLOY_PREP=bin/deploy/prep.sh BIN_DEPLOY_REQ=bin/deploy/req.sh +BIN_DEPLOY_USER=bin/deploy/user.sh BIN_DEPLOY_HEALTH=bin/deploy/health.sh BIN_DEPLOY_ENTRY_DEV=bin/deploy/entry_dev.sh