---
# System prepended metadata

title: Dockerfiles Deep Dive solution

---

# 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)

```