Skip to content

Commit

Permalink
refactor(docker): multistage build / support for running as random uid
Browse files Browse the repository at this point in the history
- refactor docker image to use builder multistage pattern
- separate storage directories
- verdaccio code directories are not user writeable
- add generic support for random user uid on environments where the startup
  user for docker is randomized (e.g. openshift)
  • Loading branch information
dlouzan authored and juanpicado committed Aug 2, 2018
1 parent 5982515 commit 4862acd
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 35 deletions.
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# we try to aoid adding files to the docker images that change often
# we try to avoid adding files to the docker images that change often
# or that are not needed for running the docker image
# tis greatly reduces the amount of times we need to rerun `npm install` when building image locally
# https://codefresh.io/blog/not-ignore-dockerignore/
Expand Down
63 changes: 36 additions & 27 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,50 +1,59 @@
FROM node:10.7-alpine
LABEL maintainer="https://github.com/verdaccio/verdaccio"
FROM node:10.3-alpine as builder

RUN apk --no-cache add wget openssl && \
wget -O /usr/local/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64 && \
chmod +x /usr/local/bin/dumb-init && \
apk del openssl && \
apk --no-cache add ca-certificates wget && \
apk --no-cache add g++ gcc libgcc libstdc++ linux-headers make python && \
RUN apk --no-cache add openssl ca-certificates wget && \
wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://raw.githubusercontent.com/sgerrand/alpine-pkg-glibc/master/sgerrand.rsa.pub && \
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.25-r0/glibc-2.25-r0.apk && \
wget -q https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.25-r0/glibc-2.25-r0.apk && \
apk add glibc-2.25-r0.apk

ENV APPDIR /usr/local/app

WORKDIR $APPDIR

ADD . $APPDIR
WORKDIR /opt/verdaccio-build
COPY . .

ENV NODE_ENV=production
ENV NODE_ENV=production \
VERDACCIO_BUILD_REGISTRY=https://registry.npmjs.org/

RUN npm config set registry http://registry.npmjs.org/ && \
yarn global add -s [email protected] && \
RUN yarn config set registry $VERDACCIO_BUILD_REGISTRY && \
yarn install --production=false && \
yarn lint && \
yarn code:docker-build && \
yarn build:webui && \
yarn cache clean && \
yarn install --production=true --pure-lockfile



FROM node:10.3-alpine
LABEL maintainer="https://github.com/verdaccio/verdaccio"

RUN apk --no-cache add openssl dumb-init

RUN mkdir -p /verdaccio/storage /verdaccio/plugins /verdaccio/conf

ENV VERDACCIO_APPDIR=/opt/verdaccio
WORKDIR $VERDACCIO_APPDIR

COPY --from=builder /opt/verdaccio-build .

ADD conf/docker.yaml /verdaccio/conf/config.yaml

RUN addgroup -S verdaccio && adduser -S -G verdaccio verdaccio && \
chown -R verdaccio:verdaccio "$APPDIR" && \
chown -R verdaccio:verdaccio /verdaccio
ENV PATH=${VERDACCIO_APPDIR}/bin:${PATH} \
HOME=${VERDACCIO_APPDIR} \
VERDACCIO_USER_NAME=verdaccio \
VERDACCIO_USER_UID=10001

RUN adduser -u ${VERDACCIO_USER_UID} -S -D -h ${VERDACCIO_APPDIR} -g "${VERDACCIO_USER_NAME} user" -s /sbin/nologin ${VERDACCIO_USER_NAME} && \
chmod -R +x ${VERDACCIO_APPDIR}/bin && \
chown -R ${VERDACCIO_USER_UID}:root /verdaccio/storage && \
chmod -R g=u /verdaccio/storage /etc/passwd

USER verdaccio
USER $VERDACCIO_USER_UID

ENV PORT 4873
ENV PROTOCOL http
ENV VERDACCIO_PORT 4873
ENV VERDACCIO_PROTOCOL http

EXPOSE $PORT
EXPOSE $VERDACCIO_PORT

VOLUME ["/verdaccio"]
VOLUME /verdaccio/storage

ENTRYPOINT ["/usr/local/bin/dumb-init", "--"]
ENTRYPOINT ["uid_entrypoint"]

CMD $APPDIR/bin/verdaccio --config /verdaccio/conf/config.yaml --listen $PROTOCOL://0.0.0.0:${PORT}
CMD $VERDACCIO_APPDIR/bin/verdaccio --config /verdaccio/conf/config.yaml --listen $VERDACCIO_PROTOCOL://0.0.0.0:${VERDACCIO_PORT}
9 changes: 9 additions & 0 deletions bin/uid_entrypoint
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/sh

if ! whoami &> /dev/null; then
if [ -w /etc/passwd ]; then
echo "${VERDACCIO_USER_NAME:-default}:x:$(id -u):0:${VERDACCIO_USER_NAME:-default} user:${HOME}:/sbin/nologin" >> /etc/passwd
fi
fi

exec /usr/bin/dumb-init -- "$@"
4 changes: 2 additions & 2 deletions conf/docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#

# path to a directory with all packages
storage: /verdaccio/storage
storage: /verdaccio/storage/data
# path to a directory with plugins to include
plugins: /verdaccio/plugins

Expand All @@ -22,7 +22,7 @@ web:

auth:
htpasswd:
file: /verdaccio/conf/htpasswd
file: /verdaccio/storage/htpasswd
# Maximum amount of users allowed to register, defaults to "+infinity".
# You can set this to -1 to disable registration.
#max_users: 1000
Expand Down
6 changes: 3 additions & 3 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ services:
build: .
container_name: verdaccio
environment:
- PORT
- VERDACCIO_PORT
ports:
- $PORT:$PORT
- $VERDACCIO_PORT:$VERDACCIO_PORT
volumes:
- verdaccio:/verdaccio
- verdaccio-storage:/verdaccio/storage
volumes:
verdaccio:
driver: local
4 changes: 2 additions & 2 deletions test/unit/api/config.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ describe('Config file', () => {
test('parse docker.yaml', () => {
const config = new Config(parseConfigFile(resolveConf('docker')));
checkDefaultUplink(config);
expect(config.storage).toBe('/verdaccio/storage');
expect(config.auth.htpasswd.file).toBe('/verdaccio/conf/htpasswd');
expect(config.storage).toBe('/verdaccio/storage/data');
expect(config.auth.htpasswd.file).toBe('/verdaccio/storage/htpasswd');
checkDefaultConfPackages(config);
});

Expand Down

0 comments on commit 4862acd

Please sign in to comment.