ããã«ãŒãã¡ã€ã«ã¯ãããã«ãŒã€ã¡ãŒãžãäœæããããã®éå§ç¹ã§ãã ãã¡ã€ã«åœ¢åŒã«ã¯ããã¡ã€ã«ããã©ã«ããŒã®ã³ããŒãã³ãã³ãã®å®è¡ãç°å¢å€æ°ã®èšå®ãããã³ã³ã³ãã㌠ã€ã¡ãŒãžã®äœæã«å¿ èŠãªãã®ä»ã®ã¿ã¹ã¯ãå®è¡ã§ãããæç¢ºã«å®çŸ©ãããäžé£ã®ãã£ã¬ã¯ãã£ããçšæãããŠããŸãã çµæã®ã€ã¡ãŒãžãå®å šãã€å°ããããã°ããæ§ç¯ãããã°ããæŽæ°ããããã«ãDockerfileãé©åã«äœæããããšãéåžžã«éèŠã§ãã
ãã®æçš¿ã§ã¯ãéçºãããŒãé«éåãããã«ãã®åçŸæ§ã確ä¿ããèªä¿¡ãæã£ãŠéçšç°å¢ã«ãããã€ã§ããã€ã¡ãŒãžãçæããããã®åªããDockerfileãäœæããæ¹æ³ã«ã€ããŠèª¬æããŸãã
泚:ãã®ããã°æçš¿ã§ã¯ãDockerfileã®äŸã ãawesome-compose ãªããžããªã® react-java-mysqlãµã³ãã« ã«åºã¥ããŠããŸãã
éçºã®æµã
éçºè ãšããŠãéçºç°å¢ãã¿ãŒã²ããã®éçšã³ã³ããã¹ãã«ã§ããã ãäžèŽãããŠããã«ããããã®ããããã€æã«æ©èœããããã«ããããšèããŠããŸãã
ãŸããè¿
éã«éçºã§ããããã«ãããã®ã§ããã«ããé«éåãããããã¬ãŒãªã©ã®éçºè
ããŒã«ã䜿çšã§ããããã«ããå¿
èŠããããŸãã ã³ã³ããã¯éçºç°å¢ãäœç³»åããããã®åªããæ¹æ³ã§ãããã³ã³ãããšãã°ãã察話ã§ããããã«ããã«ã¯ãDockerfileãæ£ããå®çŸ©ããå¿
èŠããããŸãã
ã€ã³ã¯ãªã¡ã³ã¿ã«ãã«ã
Dockerfile ã¯ãã³ã³ãã㌠ã€ã¡ãŒãžããã«ãããããã®æé ã®äžèЧã§ãã Docker ãã«ããŒã¯åã¹ãããã®çµæãã€ã¡ãŒãž ã¬ã€ã€ãŒãšããŠãã£ãã·ã¥ããŸããããã£ãã·ã¥ãç¡å¹ã«ãããšããã£ãã·ã¥ãç¡å¹ã«ããã¹ããããšåŸç¶ã®ãã¹ãŠã®ã¹ããããåå®è¡ãã察å¿ããã¬ã€ã€ãŒãåçæããå¿ èŠããããŸãã
ãã£ãã·ã¥ã¯ãCOPY ãŸã㯠ADD ã«ãã£ãŠåç
§ããããã«ã ã³ã³ããã¹ãå
ã®ãã¡ã€ã«ã倿Žããããšç¡å¹ã«ãªããŸãã ãããã£ãŠãã¹ãããã®é åºã¯ãããã©ãŒãã³ã¹ã«å€§ããªåœ±é¿ãäžããå¯èœæ§ããããŸãã
Dockerfile ã§ NodeJs ãããžã§ã¯ãããã«ãããäŸãèŠãŠã¿ãŸãããã ãã®ãããžã§ã¯ãã§ã¯ãnpm ci ã³ãã³ãã®å®è¡æã«ãã§ãããããäŸåé¢ä¿ã package.json ãã¡ã€ã«ã«ãããŸãã
æãåçŽãªããã«ãŒãã¡ã€ã«ã¯æ¬¡ã®ããã«ãªããŸãã
FROM node:lts
ENV CI=true
ENV PORT=3000
WORKDIR /code
COPY . /code
RUN npm ci
CMD [ "npm", "start" ]
äžèšã®ããã« Dockerfile ãæ§æãããšããã«ã ã³ã³ããã¹ãå ã®ãã¡ã€ã«ã倿Žããããã³ã« COPY è¡ã§ãã£ãã·ã¥ãç¡å¹ã«ãªããŸãã ããã¯ãæéããããå¯èœæ§ã®ããpackage.jsonãã¡ã€ã«ã ãã§ãªãããã¡ã€ã«ã倿ŽããããšäŸåé¢ä¿ããã§ãããããnode_modulesãã£ã¬ã¯ããªããã£ã±ãã«ãªãããšãæå³ããŸãã
ãããåé¿ããäŸåé¢ä¿ã倿Žããããšã(ã€ãŸããpackage.jsonãŸãã¯package-lock.jsonã倿Žããããšã)ã«ã®ã¿äŸåé¢ä¿ããã§ããããã«ã¯ãäŸåé¢ä¿ã®ã€ã³ã¹ããŒã«ãã¢ããªã±ãŒã·ã§ã³ã®ãã«ããšå®è¡ããåé¢ããããšãæ€èšããå¿ èŠããããŸãã
ããæé©åãããããã«ãŒãã¡ã€ã«ã¯æ¬¡ã®ããã«ãªããŸãã
FROM node:lts
ENV CI=true
ENV PORT=3000
WORKDIR /code
COPY package.json package-lock.json /code/
RUN npm ci
COPY src /code/src
CMD [ "npm", "start" ]
ãã®åé¢ã䜿çšãããšãpackage.json ãŸã㯠package-lock.json ã«å€æŽããªãå Žåããã£ãã·ã¥ã¯ RUN npm ci åœä»€ã«ãã£ãŠçæãããã¬ã€ã€ãŒã«äœ¿çšãããŸãã ã€ãŸããã¢ããªã±ãŒã·ã§ã³ãœãŒã¹ãç·šéããŠåæ§ç¯ãããšãã«ãäŸåé¢ä¿ãåããŠã³ããŒããããªããããæéã🎉ç¯çŽãããŸãã
ãŸãã 以åã®æçš¿ã§ èª¬æããããã«ã src 2çªç® COPY ããã£ã¬ã¯ããªã«å¶éããŸãã
ãã¹ããšã³ã³ãããŒã®éã§ã©ã€ã ãªããŒããã¢ã¯ãã£ãã«ããŠãã
ãã®ãã³ãã¯Dockerfileãšã¯çŽæ¥é¢ä¿ãããŸããããã³ã³ããã§ã¢ããªãå®è¡ãããã¹ããã·ã³äžã®IDEãããœãŒã¹ã³ãŒãã倿ŽããŠããéãã©ã€ããªããŒããã¢ã¯ãã£ãã«ããŠããã«ã¯ã©ãããã°ããã§ãã?
ãã®äŸã§ã¯ããããžã§ã¯ããã£ã¬ã¯ããªãã³ã³ããã«ããŠã³ãããç°å¢å€æ°ãæž¡ããŠããã¹ãããã®NodeJSãã¡ã€ã«å€æŽã€ãã³ããã©ãããã Chokidar ãæå¹ã«ããå¿ èŠããããŸãã
$ docker run -e CHOKIDAR_USEPOLLING=true -v ${PWD}/src/:/code/src/ -p 3000:3000 repository/image_name
äžè²«æ§ã®ãããã«ã
Dockerfileã§æãéèŠãªããšã®1ã€ã¯ãåããã«ãã³ã³ããã¹ã(ãœãŒã¹ãäŸåé¢ä¿ãªã©)ãããŸã£ããåãã€ã¡ãŒãžããã«ãããããšã§ãã
åã®ã»ã¯ã·ã§ã³ã§å®çŸ©ãã Dockerfile ãåŒãç¶ãæ¹åããŠãããŸãã
ãœãŒã¹ããäžè²«ããŠæ§ç¯ãã
åã®ã»ã¯ã·ã§ã³ã§èŠãããã«ãDockerfile ã®èª¬æã«ãœãŒã¹ ãã¡ã€ã«ãšäŸåé¢ä¿ã远å ãããããã«å¯ŸããŠã³ãã³ããå®è¡ããããšã§ãã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ã§ããŸãã
ããããåã®äŸã§ã¯ãDockerãã«ããå®è¡ãããã³ã«çæãããã€ã¡ãŒãžãåãã§ããããšã確èªã§ããŸãã...ãªãã§ããããã NodeJSããªãªãŒã¹ããããã³ã«ãltsã¿ã°ãNodeJSã€ã¡ãŒãžã®ææ°ã®LTSããŒãžã§ã³ãæããŠããããšãäºæ³ãããŸãããããã¯æéã®çµéãšãšãã«å€æŽãããç Žå£ç倿Žãçºçããå¯èœæ§ããããŸãã ããŒã¹ã€ã¡ãŒãžã«ãã£ãšå
·äœçãªã¿ã°ã䜿çšããããšã§ããããç°¡åã«ä¿®æ£ã§ããŸã(LTSãŸãã¯ææ°ã®å®å®ããŒãžã§ã³😉ããéžæã§ããŸã)
FROM node:13.12.0
ENV CI=true
ENV PORT=3000
WORKDIR /code
COPY package.json package-lock.json /code/
RUN npm ci
COPY src /code/src
CMD [ "npm", "start" ]
ãææ°ã®ã¿ã°ã¯ãããŸãããã»ã¯ã·ã§ã³ã§ã¯ãããå ·äœçãªåºæ¬ç»åã¿ã°ã䜿çšãã ææ°ã®ã¿ã° ãåé¿ããããšã«ã¯ä»ã«ãå©ç¹ãããããšãããããŸãã
é©åãªç°å¢ã«åããããã«ãã¹ããŒãžãšã¿ãŒã²ãã
éçºãã«ãã«äžè²«æ§ãæãããŸããããæ¬çªã¢ãŒãã£ãã¡ã¯ãã«å¯ŸããŠãããã©ã®ããã«è¡ãããšãã§ããŸãã?
Docker 17.05以éã ãã«ãã¹ããŒãžãã«ã ã䜿çšããŠãæçµçãªã€ã¡ãŒãžãçæããããã®ã¹ããããå®çŸ©ã§ããŸãã Dockerfile ã§ãã®ã¡ã«ããºã ã䜿çšãããšãéçºãããŒã«äœ¿çšããã€ã¡ãŒãžããã¢ããªã±ãŒã·ã§ã³ã®ãã«ãã«äœ¿çšããã€ã¡ãŒãžãšéçšç°å¢ã§äœ¿çšããã€ã¡ãŒãžãåå²ã§ããŸãã
FROM node:13.12.0 AS development
ENV CI=true
ENV PORT=3000
WORKDIR /code
COPY package.json package-lock.json /code/
RUN npm ci
COPY src /code/src
CMD [ "npm", "start" ]
FROM development AS builder
RUN npm run build
FROM nginx:1.17.9 AS production
COPY --from=builder /code/build /usr/share/nginx/html
ããªããèŠã FROM ãã³ã«...... AS ããã¯ãã«ã段éã§ãã
ããã§ãéçºããã«ããããã³æ¬çªã®æ®µéãã§ããŸããã
ãã©ã°ã䜿çšã㊠--target ç¹å®ã®éçºã¹ããŒãžã€ã¡ãŒãžãæ§ç¯ããããšã§ãéçºãããŒã«ã³ã³ãããåŒãç¶ã䜿çšã§ããŸãã
$ docker build --target development -t repository/image_name:development .
ãããŠãã€ãã®ããã«ããã䜿çšããŠãã ãã
$ docker run -e CHOKIDAR_USEPOLLING=true -v ${PWD}/src/:/code/src/ repository/image_name:development
ãã©ã°ã®ãªã --target Docker ãã«ãã§ã¯ãæçµã¹ããŒãž (ãã®å Žåã¯éçšã€ã¡ãŒãž) ããã«ããããŸãã ç§ãã¡ã®ãããã¯ã·ã§ã³ã€ã¡ãŒãžã¯ãåã®æé ã§ãã«ãããããã€ããªãæäŸãããæ£ããå Žæã«çœ®ãããåãªã nginx ã€ã¡ãŒãžã§ãã
çç£æºåå®äº
æ¬çªã€ã¡ãŒãžãå¯èœãªéãç¡é§ãªãå®å šã«ä¿ã€ããšã¯éåžžã«éèŠã§ãã éçšç°å¢ã§ã³ã³ãããŒãå®è¡ããåã«ç¢ºèªããå¿ èŠãããããšãããã€ããããŸãã
ææ°ã®ã€ã¡ãŒãž ããŒãžã§ã³ã¯ãããããŸãã
ã ãœãŒã¹ããäžè²«ããŠãã«ããããã»ã¯ã·ã§ã³ã§åè¿°ããããã«ããã«ã ã¹ãããã«ç¹å®ã®ã¿ã°ã䜿çšãããšãã€ã¡ãŒãžã®ãã«ããåçŸå¯èœã«ããã®ã«åœ¹ç«ã¡ãŸãã ç»åã«ç¹å®ã®ã¿ã°ã䜿çšããçç±ã¯ãä»ã«ãå°ãªããšã2ã€ãããŸããÂ
- ãæ°ã«å ¥ãã®ãªãŒã±ã¹ãã¬ãŒã¿ãŒ (SwarmãKubernetes...) ã®ã€ã¡ãŒãž ããŒãžã§ã³ã§å®è¡ãããŠãããã¹ãŠã®ã³ã³ãããŒãç°¡åã«èŠã€ããããšãã§ããŸãã
# Search in Docker engine containers using our repository/image_name:development image
$ docker inspect $(docker ps -q) | jq -c '.[] | select(.Config.Image == "repository/image_name:development") |"\(.Id) \(.State) \(.Config)"'
"89bf376620b0da039715988fba42e78d42c239446d8cfd79e4fbc9fbcc4fd897 {\"Status\":\"running\",\"Running\":true,\"Paused\":false,\"Restarting\":false,\"OOMKilled\":false,\"Dead\":false,\"Pid\":25463,\"ExitCode\":0,\"Error\":\"\",\"StartedAt\":\"2020-04-20T09:38:31.600777983Z\",\"FinishedAt\":\"0001-01-01T00:00:00Z\"}
{\"Hostname\":\"89bf376620b0\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":false,\"AttachStdout\":true,\"AttachStderr\":true,\"ExposedPorts\":{\"3000/tcp\":{}},\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"CHOKIDAR_USEPOLLING=true\",\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\"NODE_VERSION=12.16.2\",\"YARN_VERSION=1.22.4\",\"CI=true\",\"PORT=3000\"],\"Cmd\":[\"npm\",\"start\"],\"Image\":\"repository/image_name:development\",\"Volumes\":null,\"WorkingDir\":\"/code\",\"Entrypoint\":[\"docker-entrypoint.sh\"],\"OnBuild\":null,\"Labels\":{}}"
#Search in k8s pods running a container with our repository/image_name:development image (using jq cli)
$ kubectl get pods --all-namespaces -o json | jq -c '.items[] | select(.spec.containers[].image == "repository/image_name:development")| .metadata'
{"creationTimestamp":"2020-04-10T09:41:55Z","generateName":"image_name-78f95d4f8c-","labels":{"com.docker.default-service-type":"","com.docker.deploy-namespace":"docker","com.docker.fry":"image_name","com.docker.image-tag":"development","pod-template-hash":"78f95d4f8c"},"name":"image_name-78f95d4f8c-gmlrz","namespace":"docker","ownerReferences":[{"apiVersion":"apps/v1","blockOwnerDeletion":true,"controller":true,"kind":"ReplicaSet","name":"image_name-78f95d4f8c","uid":"5ad21a59-e691-4873-a6f0-8dc51563de8d"}],"resourceVersion":"532","selfLink":"/api/v1/namespaces/docker/pods/image_name-78f95d4f8c-gmlrz","uid":"5c70f340-05f1-418f-9a05-84d0abe7009d"}
- CVE(äžè¬çãªè匱æ§ãšé²åº)ã®å Žåãã³ã³ãããšã€ã¡ãŒãžã®èª¬æã«ããããé©çšããå¿ èŠããããã©ããããã°ããç¥ãããšãã§ããŸãã
ãã®äŸãããéçºã€ã¡ãŒãžãšéçšã€ã¡ãŒãžãé«å±±ããŒãžã§ã³ã§ããããšãæå®ã§ããŸãã
FROM node:13.12.0-alpine AS development
ENV CI=true
ENV PORT=3000
WORKDIR /code
COPY package.json package-lock.json /code/
RUN npm ci
COPY src /code/src
CMD [ "npm", "start" ]
FROM development AS builder
RUN npm run build
FROM nginx:1.17.9-alpine
COPY --from=builder /code/build /usr/share/nginx/html
å ¬åŒç»åã䜿çšãã
Docker Hub ã䜿çšããŠãDockerfile ã§äœ¿çšããåºæ¬ã€ã¡ãŒãžãæ€çŽ¢ã§ããŸããããã®ãã¡ã®ããã€ãã¯å ¬åŒã«ãµããŒããããŠãããã®ã§ãã ãããã®ç»åãæ¬¡ã®ããã«äœ¿çšããããšã匷ããå§ãããŸãã
- ãããã®ã³ã³ãã³ãã¯æ€èšŒãããŠããŸã
- CVEãä¿®æ£ããããšãããã«æŽæ°ãããŸã

image_filterèŠæ±ã¯ãšãªãã©ã¡ãŒã¿ã远å ããŠãå ¬åŒç»åã®ã¿ãååŸã§ããŸãã
https://hub.docker.com/search?q=nginx&type=image&image_filter=official
ãã®æçš¿ã®ä»¥åã®äŸã¯ãã¹ãŠãNodeJSãšNGINXã®å ¬åŒç»åã䜿çšããŠããŸããã
ã¡ããã©ååãªæš©é!
ã³ã³ããã§å®è¡ãããŠãããã©ããã«ãããããããã¹ãŠã®ã¢ããªã±ãŒã·ã§ã³ã¯ãã¢ããªã±ãŒã·ã§ã³ãå¿ èŠãªãªãœãŒã¹ã«ã®ã¿ã¢ã¯ã»ã¹ããå¿ èŠãããããšãæå³ãã æå°ç¹æš©ã®åå ã«åŸãå¿ èŠããããŸããÂ
æªæã®ããåäœã®å ŽåããŸãã¯ãã°ã®ããã«ãããŸãã«ãå€ãã®ç¹æš©ã§å®è¡ãããŠããããã»ã¹ã¯ãå®è¡æã«ã·ã¹ãã å šäœã«äºæããªãçµæãããããå¯èœæ§ããããŸãã
NodeJSã®å ¬åŒã€ã¡ãŒãžã¯é©åã« ã»ããã¢ãããããŠããããã ããã¯ãšã³ãã®Dockerfileã«åãæ¿ããŸãã
ç¹æš©ã®ãªããŠãŒã¶ãŒãšããŠå®è¡ããããã«ã€ã¡ãŒãžãæ§æããã®ã¯éåžžã«ç°¡åã§ãã
FROM maven:3.6.3-jdk-11 AS builder
WORKDIR /workdir/server
COPY pom.xml /workdir/server/pom.xml
RUN mvn dependency:go-offline
RUN mvn package
FROM openjdk:11-jre-slim
RUN addgroup -S java && adduser -S javauser -G java
USER javauser
EXPOSE 8080
COPY --from=builder /workdir/server/target/project-0.0.1-SNAPSHOT.jar /project-0.0.1-SNAPSHOT.jar
CMD ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/project-0.0.1-SNAPSHOT.jar"]
æ°ããã°ã«ãŒããäœæããããã«ãŠãŒã¶ãŒã远å ããUSERãã£ã¬ã¯ãã£ãã䜿çšããã ãã§ãroot以å€ã®ãŠãŒã¶ãŒã§ã³ã³ãããå®è¡ã§ããŸãã
çµè«
ãã®ããã°æçš¿ã§ã¯ãDockerfileãæ éã«äœæããããšã§ãDockerã€ã¡ãŒãžãæé©åããã³ä¿è·ããå€ãã®æ¹æ³ã®ããã€ãã瀺ããŸããã ããã«é²ãã§ã¿ããå Žåã¯ã以äžãã芧ãã ãããÂ
- Dockerfile ã®ãã¹ããã©ã¯ãã£ã¹ã«é¢ããå ¬åŒããã¥ã¡ã³ãÂ
- Tibor Vass ã«ããäž»é¡ã«é¢ãã以åã®æçš¿
- DockerCon 2019 ã§ã® Tibor Vass ãš Sebastiaan van Stijnã«ããã»ãã·ã§ã³Â
- Devoxx 2019ã®å¥ã®ã»ãã·ã§ã³ ã§ã ãžã§ã¬ããŒã»ãã«ãŒãšãš ç§