# Dockerfiles Deep Dive solution
## Phase 1
```dockerfile=
# Project: Extend an existing official image from Docker Hub to run a webserver
# Step 1: Use the 'nginx' official image, with the latest version for alpine
# Pinning a version makes development so much easier because it is predictable
FROM nginx:1.18.0-alpine
# Step 2: Change our working directory to the root of nginx webhost
# Using 'WORKDIR /some/path' is preferred to using 'RUN cd /some/path'
WORKDIR /usr/share/nginx/html
# Step 3: Copy in the file or files or folder!
COPY index.html ./
# BONUS: add in a healthcheck!
HEALTHCHECK CMD curl -f http://localhost:80/ || exit 1
# No need to specify EXPOSE or CMD because they're include in the base (FROM)
```
## Phase 2
```dockerfile=
# Project: Run an express app in a Docker container
# Step 1: Use the 'node' official image (a recent version with an alpine base)
FROM node:15.8.0-alpine3.10
# Step 2: Look in the app.js to determine which port to expose
EXPOSE 8081
# Step 3: Use alpine package manager to install tini: 'apk add --update tini'
# (tini is a package that can be used as an entry point in a container)
RUN apk add --update tini
# Step 4: With a single command, create a new directory for app files at the
# path '/usr/src/app' and make that your current directory
WORKDIR /usr/src/app
# In the next steps, you will load and install packages before applications
# files for better caching
# Step 5: Since node uses a "package manager", copy in 'package.json' and the
# corresponding lock file
COPY package.json package-lock.json ./
# Step 6: Install dependencies using npm
# To keep the image clean and small, run 'npm cache clean --force' after
RUN npm install && npm cache clean --force
# Step 7: Copy in all files from current directory
COPY . .
# Step 8. Run the application with command '/sbin/tini -- node app.js'.
# Remember to use the "exec form" which is the preferred syntax
# Here is the documentation for CMD if you need a reminder:
# https://docs.docker.com/engine/reference/builder/#cmd
CMD ["/sbin/tini", "--", "node", "app.js"]
```
## Phase 3
```dockerfile=
# Project: Build a React app and serve it with nginx
# Step 1: Base image for build stage - use official node image with alpine base
# Name it build-stage
FROM node:15.8.0-alpine3.10 as build-stage
# Step 2: Set the working directory to /app
WORKDIR /app
# Step 3: Copy in all the files needed to install dependencies
COPY package*.json ./
# Step 4: Install dependencies using npm
# To keep the image small, (force) clean the npm cache after
# Chain the commands to reduce the number of layers in the image
RUN npm install && npm cache clean --force
# Step 5: Copy in all the files from the current directory
COPY . .
# Step 6: Build application
RUN npm run build
# Step 7: Bring in the base image for NGINX (alpine)
FROM nginx:1.18.0-alpine
# (There will be no need to EXPOSE a port because this base image
# already has an EXPOSE command)
# Step 8: Set working directory to the html folder for nginx
# (Hint: This directory was also used in phase 1)
WORKDIR /usr/share/nginx/html
# Step 9: Copy over the build files from build-stage
# The build directory was created inside the app directory in the
# build-stage. The files inside that folder can be put directly into
# the html folder that you just set as your working directory
COPY --from=build-stage /app/build ./
# Step 10: Replace the default NGINX config with the application's version
# The absolute path to the default NGINX config file is
# /etc/nginx/conf.d/default.conf —replace it with the nginx.conf file
# provided in this folder
COPY nginx.conf /etc/nginx/conf.d/default.conf
# (No need to add a CMD because it's included in the base image)
```