ed60d5e (parent 2192114)12/18/2023, 2:52:45 AM
~Dockerfile
.dockerfile
Dockerfile
(text/x-dockerfile)
FROM node:alpine as builder

ENV NODE_ENV=development
ENV NODE_OPTIONS=--openssl-legacy-provider

ARG PORT=4100
ENV PORT=${PORT}
ARG HOST="0.0.0.0"
ENV HOST=${HOST}

WORKDIR /usr/src/app

#    [local tree]          [builder tree]

COPY ./patches             /usr/src/app/patches
COPY ./package.json        /usr/src/app/package.json
COPY ./tsconfig.json       /usr/src/app/tsconfig.json
COPY ./yarn.lock           /usr/src/app/yarn.lock

# Install dependencies
RUN apk upgrade --no-cache openssl
RUN yarn install

#    [local tree]          [builder tree]

COPY ./.git                /usr/src/app/.git
COPY ./app                 /usr/src/app/app
COPY ./db                  /usr/src/app/db
COPY ./public              /usr/src/app/public
COPY ./types               /usr/src/app/types

COPY ./.env                /usr/src/app/.env
COPY ./app.manifest.json   /usr/src/app/app.manifest.json
COPY ./paths.ts            /usr/src/app/paths.ts

COPY ./ReadMe.md           /usr/src/app/ReadMe.md
COPY ./LICENSE             /usr/src/app/LICENSE

ENV NODE_ENV=production
ENV NODE_OPTIONS=--openssl-legacy-provider

RUN yarn generate:prisma   # Generate Prisma Client from schema (db/schema.prisma)
RUN yarn typecheck         # Validate TS types are valid first
RUN yarn test              # Test code to ensure it is regression-free (jest)
RUN yarn clean             # Cleanup working dir
RUN yarn build:ts          # Transpile TypeScript to JavaScript (node)
RUN yarn bundle:islands    # Bundle Islands (react-monolith) to ESM/CJS/UMD

#    [local tree]          [builder tree]

COPY ./public              /usr/src/app/public
COPY ./app.manifest.json   /usr/src/app/app.manifest.json

FROM node:slim as base

ENV NODE_ENV=production
ENV NODE_OPTIONS=--openssl-legacy-provider

ARG PORT=4100
ENV PORT=${PORT}
ARG HOST="0.0.0.0"
ENV HOST=${HOST}

RUN apt-get update && \
    apt-get install -y --no-install-recommends git openssl && \
    rm -rf /var/lib/apt/lists/*

WORKDIR /app

#                   [builder tree]              [base tree]

COPY --from=builder /usr/src/app/dist           /app
COPY --from=builder /usr/src/app/db             /app/db
COPY --from=builder /usr/src/app/node_modules   /app/node_modules
COPY --from=builder /usr/src/app/public         /app/public
COPY --from=builder /usr/src/app/.env           /app/.env
COPY --from=builder /usr/src/app/ReadMe.md      /app/ReadMe.md
COPY --from=builder /usr/src/app/LICENSE        /app/LICENSE
COPY --from=builder /usr/src/app/package.json   /app/package.json
COPY --from=builder /usr/src/app/yarn.lock      /app/yarn.lock

# Generate git stamp file
COPY --from=builder /usr/src/app/.git           /app/.git
RUN git rev-parse HEAD > .gitstamp
COPY ./.gitstamp    /app/.gitstamp
RUN rm -rf /app/.git

# Install required dependencies
RUN apt-get update -y && apt-get install git-core openssh-server gnupg sudo curl jq ca-certificates -y
RUN mkdir -p /etc/apt/keyrings && \
    curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \
        | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \
    echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" \
        | tee /etc/apt/sources.list.d/nodesource.list && \
    apt-get -qq update && \
    apt-get -qq -y install --no-install-recommends \
      nodejs=$(apt-cache show nodejs | grep -F 'Version: 20.0.0' | cut -f 2 -d ' ')

# Add git-shell to system shells
RUN echo "/usr/bin/git-shell" >> /etc/shells
# RUN chsh -s /usr/bin/git-shell

# Create git user
RUN adduser git
RUN groupadd -f git
# RUN usermod -u 1000 git

# Add root to git group
RUN sudo usermod -a -G git root

# Change git user shell to use git-shell
# RUN usermod --shell /usr/bin/git-shell git
RUN usermod --shell /usr/bin/sh git

# Setup git user home repos' folder
RUN mkdir /home/git/repos
RUN chown git:git -R /home/git/repos
RUN usermod --home /home/git/repos git

# Make it possible for git user to chsh
RUN sed -i -E 's/auth       required   pam_shells.so/auth       sufficient   pam_shells.so/' /etc/pam.d/chsh
# Enable Password-less SSH Authentication (private-keys only)
RUN sed -i -E 's/#?PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
# RUN echo "ForceCommand /usr/bin/ssh_command" >> /etc/ssh/sshd_config
RUN echo "AllowUsers root git" >> /etc/ssh/sshd_config
RUN echo "AuthorizedKeysFile .ssh/authorized_keys /home/git/.ssh/authorized_keys" >> /etc/ssh/sshd_config

# Empty machine motd
RUN sed -i -E 's|session    optional     pam_motd.so  motd=/run/motd.dynamic|#session    optional     pam_motd.so  motd=/run/motd.dynamic|' /etc/pam.d/sshd
RUN sed -i -E 's|session    optional     pam_motd.so noupdate|#session    optional     pam_motd.so noupdate|' /etc/pam.d/sshd
RUN echo "" > /etc/motd

# Change to git user home dir
WORKDIR /home/git/

# Add git-shell command no-interactive-login 
RUN mkdir git-shell-commands/
COPY ./data/git-shell-commands/no-interactive-login /home/git/git-shell-commands/no-interactive-login
RUN chown git:git git-shell-commands/no-interactive-login
RUN chmod +x git-shell-commands/no-interactive-login

# Add ssh command to force client command
COPY ./data/ssh_command /usr/bin/
COPY ./data/ssh_command_node /usr/bin/
RUN chmod +x /usr/bin/ssh_command
RUN chmod +x /usr/bin/ssh_command_node

# Setup ssh folder and keys
RUN mkdir -p .ssh
RUN chmod 700 .ssh
RUN touch .ssh/authorized_keys
COPY ./data/authorized_keys .ssh/authorized_keys
RUN chmod 600 .ssh/authorized_keys
RUN chown git:git -R .ssh

# Switch to root user
USER root
WORKDIR /home/git

RUN service ssh start

EXPOSE 22
EXPOSE ${PORT}

WORKDIR /app

CMD ["/bin/bash", "-c", "/usr/sbin/sshd -D & nohup; node app/server.js"]