Add incremental dockerfiles

This commit is contained in:
sid palas
2023-01-25 17:55:51 -05:00
parent dc832ac671
commit dd5d7bff0b
29 changed files with 467 additions and 49 deletions

View File

@ -0,0 +1,3 @@
Makefile
README.md
Dockerfile*

View File

@ -1,19 +0,0 @@
# syntax=docker/dockerfile:1
# Alpine is chosen for its small footprint
# compared to Ubuntu
FROM golang:1.19-alpine
WORKDIR /app
# Download necessary Go modules
COPY go.mod ./
COPY go.sum ./
RUN go mod download
COPY . .
CMD ["go", "run", "./main.go"]
# TODO use best practices: https://snyk.io/blog/containerizing-go-applications-with-docker/

View File

@ -0,0 +1,9 @@
FROM golang
WORKDIR /app
COPY . .
RUN go mod download
CMD ["go", "run", "./main.go"]

View File

@ -0,0 +1,11 @@
# Pin specific version for stability
# Use alpine for reduced image size
FROM golang:1.19-alpine
WORKDIR /app
COPY . .
RUN go mod download
CMD ["go", "run", "./main.go"]

View File

@ -0,0 +1,14 @@
# Pin specific version for stability
# Use alpine for reduced image size
FROM golang:1.19-alpine
WORKDIR /app
COPY . .
RUN go mod download
# Compile application during build rather than at runtime
RUN go build -o api-golang
CMD ["./api-golang"]

View File

@ -0,0 +1,17 @@
# Pin specific version for stability
# Use alpine for reduced image size
FROM golang:1.19-alpine
WORKDIR /app
# Copy only files required to install dependencies (better layer caching)
COPY go.mod go.sum ./
RUN go mod download
COPY . .
# Compile application during build rather than at runtime
RUN go build -o api-golang
CMD ["./api-golang"]

View File

@ -0,0 +1,29 @@
# Pin specific version for stability
# Use separate stage for building image
# Use debian for easier build utilities
FROM golang:1.19-bullseye AS build
WORKDIR /app
# Copy only files required to install dependencies (better layer caching)
COPY go.mod go.sum ./
RUN go mod download
COPY . .
# Compile application during build rather than at runtime
# Add -w and -s flags to
RUN go build \
-ldflags="-linkmode external -extldflags -static" \
-o api-golang
# Use separate stage for deployable image
FROM scratch
WORKDIR /
# Copy the binary from the build stage
COPY --from=build /app/api-golang api-golang
CMD ["/api-golang"]

View File

@ -0,0 +1,35 @@
# Pin specific version for stability
# Use separate stage for building image
# Use debian for easier build utilities
FROM golang:1.19-bullseye AS build
WORKDIR /app
# Copy only files required to install dependencies (better layer caching)
COPY go.mod go.sum ./
RUN go mod download
COPY . .
# Compile application during build rather than at runtime
# Add flags to statically link binary
RUN go build \
-ldflags="-linkmode external -extldflags -static" \
-o api-golang
# Use separate stage for deployable image
FROM scratch
# Set gin mode
ENV GIN_MODE=release
WORKDIR /
# Copy the binary from the build stage
COPY --from=build /app/api-golang api-golang
# Indicate expected port
EXPOSE 8080
CMD ["/api-golang"]

View File

@ -0,0 +1,47 @@
# Pin specific version for stability
# Use separate stage for building image
# Use debian for easier build utilities
FROM golang:1.19-bullseye AS build
# Add non root user
RUN useradd -u 1001 nonroot
WORKDIR /app
# Copy only files required to install dependencies (better layer caching)
COPY go.mod go.sum ./
# Use cache mount to speed up install of existing dependencies
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
go mod download
COPY . .
# Compile application during build rather than at runtime
# Add flags to statically link binary
RUN go build \
-ldflags="-linkmode external -extldflags -static" \
-o api-golang
# Use separate stage for deployable image
FROM scratch
# Set gin mode
ENV GIN_MODE=release
WORKDIR /
# Copy the passwd file
COPY --from=build /etc/passwd /etc/passwd
# Copy the binary from the build stage
COPY --from=build /app/api-golang api-golang
# Use nonroot user
USER nonroot
# Indicate expected port
EXPOSE 8080
CMD ["/api-golang"]

View File

@ -1,19 +0,0 @@
FROM node:19.4-alpine
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY package*.json ./
RUN npm install
# If you are building your code for production
# RUN npm ci --only=production
# Bundle app source
COPY ./src/ .
EXPOSE 3000
CMD [ "node", "index.js" ]

View File

@ -0,0 +1,7 @@
FROM node
COPY . .
RUN npm install
CMD [ "node", "index.js" ]

View File

@ -0,0 +1,9 @@
# Pin specific version
# Use alpine for reduced image size
FROM node:19.4-alpine
COPY . .
RUN npm install
CMD [ "node", "index.js" ]

View File

@ -0,0 +1,12 @@
# Pin specific version
# Use alpine for reduced image size
FROM node:19.4-alpine
# Specify working directory other than /
WORKDIR /usr/src/app
COPY . .
RUN npm install
CMD [ "node", "index.js" ]

View File

@ -0,0 +1,18 @@
# Pin specific version for stability
# Use alpine for reduced image size
FROM node:19.4-alpine
# Specify working directory other than /
WORKDIR /usr/src/app
# Copy only files required to install
# dependencies (better layer caching)
COPY package*.json ./
RUN npm install
# Copy remaining source code AFTER installing dependencies.
# Again, copy only the necessary files
COPY ./src/ .
CMD [ "node", "index.js" ]

View File

@ -0,0 +1,22 @@
# Pin specific version for stability
# Use alpine for reduced image size
FROM node:19.4-alpine
# Specify working directory other than /
WORKDIR /usr/src/app
# Copy only files required to install
# dependencies (better layer caching)
COPY package*.json ./
RUN npm install
# Use non-root user
# Use --chown on COPY commands to set file permissions
USER node
# Copy remaining source code AFTER installing dependencies.
# Again, copy only the necessary files
COPY --chown=node:node ./src/ .
CMD [ "node", "index.js" ]

View File

@ -0,0 +1,26 @@
# Pin specific version for stability
# Use alpine for reduced image size
FROM node:19.4-alpine
# Set NODE_ENV
ENV NODE_ENV production
# Specify working directory other than /
WORKDIR /usr/src/app
# Copy only files required to install
# dependencies (better layer caching)
COPY package*.json ./
# Install only production dependencies
RUN npm ci --only=production
# Use non-root user
# Use --chown on COPY commands to set file permissions
USER node
# Copy remaining source code AFTER installing dependencies.
# Again, copy only the necessary files
COPY --chown=node:node ./src/ .
CMD [ "node", "index.js" ]

View File

@ -0,0 +1,29 @@
# Pin specific version for stability
# Use alpine for reduced image size
FROM node:19.4-alpine
# Set NODE_ENV
ENV NODE_ENV production
# Specify working directory other than /
WORKDIR /usr/src/app
# Copy only files required to install
# dependencies (better layer caching)
COPY package*.json ./
# Install only production dependencies
RUN npm ci --only=production
# Use non-root user
# Use --chown on COPY commands to set file permissions
USER node
# Copy remaining source code AFTER installing dependencies.
# Again, copy only the necessary files
COPY --chown=node:node ./src/ .
# Indicate expected port
EXPOSE 3000
CMD [ "node", "index.js" ]

View File

@ -0,0 +1,36 @@
# Pin specific version for stability
# Use alpine for reduced image size
FROM node:19.4-alpine
# Set NODE_ENV
ENV NODE_ENV production
# Specify working directory other than /
WORKDIR /usr/src/app
# Copy only files required to install
# dependencies (better layer caching)
COPY package*.json ./
# Install only production dependencies
# Use cache mount to speed up install of existing dependencies
RUN --mount=type=cache,target=/usr/src/app/.npm \
npm set cache /usr/src/app/.npm && \
npm ci --only=production
# Use non-root user
# Use --chown on COPY commands to set file permissions
USER node
# Copy remaining source code AFTER installing dependencies.
# Again, copy only the necessary files
COPY --chown=node:node ./src/ .
# Indicate expected port
EXPOSE 3000
CMD [ "node", "index.js" ]
# TODO: Use multi-stage with distroless image or chainguard image?
# https://github.com/GoogleContainerTools/distroless/blob/main/examples/nodejs/Dockerfile
# https://edu.chainguard.dev/chainguard/chainguard-images/reference/node/overview/

View File

@ -6,3 +6,7 @@ run-local:
PGDATABASE=postgres \
PGPORT=5432 \
node ./src/index.js
.PHONY: build-naive
build-naive:
docker build --file ./Dockerfile.naive .

View File

@ -12,6 +12,13 @@ app.get('/', async (req, res) => {
res.send(response);
});
app.listen(port, () => {
const server = app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
process.on('SIGTERM', () => {
debug('SIGTERM signal received: closing HTTP server');
server.close(() => {
debug('HTTP server closed');
});
});

View File

@ -0,0 +1,7 @@
FROM node
COPY . .
RUN npm install
CMD ["npm", "run", "dev"]

View File

@ -0,0 +1,7 @@
FROM node:19.4-bullseye
COPY . .
RUN npm install
CMD ["npm", "run", "dev"]

View File

@ -0,0 +1,14 @@
FROM node:19.4-bullseye AS build
# Specify working directory other than /
WORKDIR /usr/src/app
# Copy only files required to install
# dependencies (better layer caching)
COPY package*.json ./
RUN npm install
COPY . .
CMD ["npm", "run", "dev"]

View File

@ -0,0 +1,24 @@
FROM node:19.4-bullseye AS build
# Specify working directory other than /
WORKDIR /usr/src/app
# Copy only files required to install
# dependencies (better layer caching)
COPY package*.json ./
# Use cache mount to speed up install of existing dependencies
RUN --mount=type=cache,target=/usr/src/app/.npm \
npm set cache /usr/src/app/.npm && \
npm install
COPY . .
RUN npm run build
# Use separate stage for deployable image
FROM nginx:1.23-alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build usr/src/app/dist/ /usr/share/nginx/html

View File

@ -0,0 +1,24 @@
server {
listen 80;
location /api/golang/ {
resolver 127.0.0.1;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://api-golang:8080/;
}
location /api/node/ {
resolver 127.0.0.1;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://api-node:3000/;
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
}
include /etc/nginx/extra-conf.d/*.conf;
}

View File

@ -37,8 +37,8 @@ export function App() {
return (
<QueryClientProvider client={queryClient}>
<h1>Hey Team! 👋</h1>
<Example api="/api/golang"/>
<Example api="/api/node"/>
<Example api="/api/golang/"/>
<Example api="/api/node/"/>
</QueryClientProvider>
);
}

View File

@ -2,15 +2,21 @@ services:
client-react:
build:
context: ./client-react
# Could remove...
depends_on:
- api-node
- api-golang
dockerfile: Dockerfile
ports:
- 5173:5173
client-react-nginx:
build:
context: ./client-react
dockerfile: Dockerfile.3
init: true
ports:
- 5174:80
api-node:
build:
context: ./api-node
dockerfile: Dockerfile.7
init: true
depends_on:
- db
environment:
@ -24,6 +30,8 @@ services:
api-golang:
build:
context: ./api-golang
dockerfile: Dockerfile.6
init: true
depends_on:
- db
environment:

View File

@ -0,0 +1,37 @@
# syntax=docker/dockerfile:1
# escape=\
# ^ OPTIONAL "directives" (must be at top if used)
# THIS IS A COMMENT
# ARG is the only instruction that can come before FROM
ARG BASE_IMAGE_TAG=19.4
# ARGs can be overriden at build time
# > docker build --build-arg BASE_VERSION=19.3 .
FROM node:${BASE_IMAGE_TAG}
RUN echo "Hey Team 👋 (shell form)"
RUN ["echo", "Hey Team 👋 (exec form)"]
# --mount allows for mounting additional files
# into the build context
# RUN --mount=type=bind ...
# RUN --mount=type=cache ...
# RUN --mount=type=secret ...
# RUN --mount=type=ssh ...
# Available only at build time
# (Still in image metadata though...)
ARG BUILD_ARG=foo
# Available at build and run time
ENV ENV_VAR=bar
# Set the default working directory
# Use the convention of your language/framework
WORKDIR path/to/the/working/directory
ENTRYPOINT [ "echo", "Hey Team 👋 (entrypoint)" ]
CMD [ "+ (cmd)" ]