Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[REVERT][REVERRT] Add group and user in dockerfile to run container as unprivileged #502

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 68 additions & 52 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,52 +1,68 @@
FROM node:16.13.2-alpine AS BUILD_IMAGE

# Set the platform to build image for
ARG TARGETPLATFORM
ENV TARGETPLATFORM=${TARGETPLATFORM:-linux/amd64}

# Install additional tools needed if on arm64 / armv7
RUN \
case "${TARGETPLATFORM}" in \
'linux/arm64') apk add --no-cache python3 make g++ ;; \
'linux/arm/v7') apk add --no-cache python3 make g++ ;; \
esac

# Create and set the working directory
WORKDIR /app

# Install app dependencies
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile --network-timeout 1000000

# Copy over all project files and folders to the working directory
COPY . ./

# Build initial app for production
RUN yarn build

# Production stage
FROM node:16.13.2-alpine

# Define some ENV Vars
ENV PORT=80 \
DIRECTORY=/app \
IS_DOCKER=true

# Create and set the working directory
WORKDIR ${DIRECTORY}

# Install tini for initialization and tzdata for setting timezone
RUN apk add --no-cache tzdata tini

# Copy built application from build phase
COPY --from=BUILD_IMAGE /app ./

# Finally, run start command to serve up the built application
ENTRYPOINT [ "/sbin/tini", "--" ]
CMD [ "yarn", "build-and-start" ]

# Expose the port
EXPOSE ${PORT}

# Run simple healthchecks every 5 mins, to check that everythings still great
HEALTHCHECK --interval=5m --timeout=2s --start-period=30s CMD yarn health-check
FROM node:16.13.2-alpine AS BUILD_IMAGE

# Set the platform to build image for
ARG TARGETPLATFORM
ENV TARGETPLATFORM=${TARGETPLATFORM:-linux/amd64}

# Install additional tools needed if on arm64 / armv7
RUN \
case "${TARGETPLATFORM}" in \
'linux/arm64') apk add --no-cache python3 make g++ ;; \
'linux/arm/v7') apk add --no-cache python3 make g++ ;; \
esac

# Create and set the working directory
WORKDIR /app

# Install app dependencies
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile --network-timeout 1000000

# Copy over all project files and folders to the working directory
COPY . ./

# Build initial app for production
RUN yarn build

# Production stage
FROM node:16.13.2-alpine

# Define some ENV Vars
ENV PORT=8080 \
DIRECTORY=/app \
IS_DOCKER=true \
USER=docker \
UID=12345 \
GID=23456

# Install tini for initialization and tzdata for setting timezone
RUN apk add --no-cache tzdata tini \
# Add group
&& addgroup --gid ${GID} "${USER}" \
# Add user
&& adduser \
--disabled-password \
--ingroup "${USER}" \
--gecos "" \
--home "${DIRECTORY}" \
--no-create-home \
--uid "$UID" \
"$USER"

USER ${USER}

# Create and set the working directory
WORKDIR ${DIRECTORY}

# Copy built application from build phase
COPY --from=BUILD_IMAGE --chown=${USER}:${USER} /app ./
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
COPY --from=BUILD_IMAGE --chown=${USER}:${USER} /app ./
COPY --from=BUILD_IMAGE /app ./

As long as the code doesn't need permissions to modify the source itself, I'd set the permissions so root owns the files and everyone else can read them (644). Otherwise, if there was a way for someone to take over the node process, they could add their own files and/or modify the source code.


# Finally, run start command to serve up the built application
ENTRYPOINT [ "/sbin/tini", "--" ]
CMD [ "yarn", "build-and-start" ]

# Expose the port
EXPOSE ${PORT}

# Run simple healthchecks every 5 mins, to check that everythings still great
HEALTHCHECK --interval=5m --timeout=2s --start-period=30s CMD yarn health-check
94 changes: 47 additions & 47 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,47 +1,47 @@
---
# Welcome to Dashy! To get started, run `docker compose up -d`
# You can configure your container here, by modifying this file
version: "3.8"
services:
dashy:
container_name: Dashy
# Pull latest image from DockerHub
image: lissy93/dashy
# To build from source, replace 'image: lissy93/dashy' with 'build: .'
# build: .
# Or, to use a Dockerfile for your archtecture, uncomment the following
# context: .
# dockerfile: ./docker/Dockerfile-arm32v7
# You can also use an image with a different tag, or pull from a different registry, e.g:
# image: ghcr.io/lissy93/dashy or image: lissy93/dashy:arm64v8
# Pass in your config file below, by specifying the path on your host machine
# volumes:
# - /path/to/my-config.yml:/app/public/conf.yml
# - /path/to/item-icons:/app/public/item-icons
# Set port that web service will be served on. Keep container port as 80
ports:
- 4000:80
# Set any environmental variables
environment:
- NODE_ENV=production
# Specify your user ID and group ID. You can find this by running `id -u` and `id -g`
# - UID=1000
# - GID=1000
# Specify restart policy
restart: unless-stopped
# Configure healthchecks
healthcheck:
test: ['CMD', 'node', '/app/services/healthcheck']
interval: 1m30s
timeout: 10s
retries: 3
start_period: 40s
---
# Welcome to Dashy! To get started, run `docker compose up -d`
# You can configure your container here, by modifying this file
version: "3.8"
services:
dashy:
container_name: Dashy

# Pull latest image from DockerHub
image: lissy93/dashy

# To build from source, replace 'image: lissy93/dashy' with 'build: .'
# build: .

# Or, to use a Dockerfile for your archtecture, uncomment the following
# context: .
# dockerfile: ./docker/Dockerfile-arm32v7

# You can also use an image with a different tag, or pull from a different registry, e.g:
# image: ghcr.io/lissy93/dashy or image: lissy93/dashy:arm64v8

# Pass in your config file below, by specifying the path on your host machine
# volumes:
# - /path/to/my-config.yml:/app/public/conf.yml
# - /path/to/item-icons:/app/public/item-icons

# Set port that web service will be served on. Keep container port as 8080
ports:
- 4000:8080

# Set any environmental variables
environment:
- NODE_ENV=production
# Specify your user ID and group ID. You can find this by running `id -u` and `id -g`
# - UID=1000
# - GID=1000

# Specify restart policy
restart: unless-stopped

# Configure healthchecks
healthcheck:
test: ['CMD', 'node', '/app/services/healthcheck']
interval: 1m30s
timeout: 10s
retries: 3
start_period: 40s
4 changes: 2 additions & 2 deletions server.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ const ENDPOINTS = require('./src/utils/defaults').serviceEndpoints; // API endpo
/* Checks if app is running within a container, from env var */
const isDocker = !!process.env.IS_DOCKER;

/* Checks env var for port. If undefined, will use Port 80 for Docker, or 4000 for metal */
const port = process.env.PORT || (isDocker ? 80 : 4000);
/* Checks env var for port. If undefined, will use Port 8080 for Docker, or 4000 for metal */
const port = process.env.PORT || (isDocker ? 8080 : 4000);

/* Attempts to get the users local IP, used as part of welcome message */
const getLocalIp = () => {
Expand Down
2 changes: 1 addition & 1 deletion services/ssl-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ module.exports = (app) => {
};

const isDocker = !!process.env.IS_DOCKER;
const SSLPort = process.env.SSL_PORT || (isDocker ? 443 : 4001);
const SSLPort = process.env.SSL_PORT || (isDocker ? 8081 : 4001);

const printSuccess = () => {
console.log(`🔐 HTTPS server successfully started (port: ${SSLPort} ${isDocker ? 'of container' : ''})`);
Expand Down