Week 11: Docker, App Deployment 1 Agenda Docker Packaging a SPA Packaging an Express API Cont ainer orchest rat ion Cont ainer regist ries 2 Docker O pen source cont ainer client and runt ime Allows you t o package an applicat ion and it s dependencies int o a cont ainer Docker allows you t o kindof ship your machine t o your client s Recap: Cont ainers vs VMs 3 Docker architecture 4 5 Building a SPA Usually just npm run build O ut put s minif ied and bundled: .html , .css , .js T ry it ! Set up a project via npm create vite T hen run npm run build , inspect t he dist f older 6 HTTP server We need a web server t o serve t he st at ic f iles Express can do t hat : express.static middleware BUT : Dedicat ed high-perf ormance servers are a bet t er choice Nginx High-perf ormance, open-source web server Very versat ile, can be used as an app gat eway, reverse proxy, load balancer, et c. Very good at serving st at ic f iles, requires next t o none resources 7 Nginx Conf Nginx is conf igured via an nginx.conf f ile A lot of opt ions! Visit nginx.com f or examples Here's a simple example: events { worker_connections 1024; } http { server { listen 80; location / { root /www/data; } } } T akes a direct ory /www/data and serves it on port 80 8 user nginx; worker_processes auto; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; keepalive_timeout 65; sendfile on; # static site serving gzip on; # enable compression server { listen 80; server_name _; root /usr/share/nginx/html; try_files $uri $uri.html $uri/index.html /index.html; index index.html; location ~ /\.ht { deny all; # create a rule to deny access to .ht files } } } 9 Dockerfile A Dockerf ile is a script t hat cont ains a collect ion of commands and inst ruct ions t hat will be aut omat ically execut ed in sequence in t he docker environment f or building a new docker image Given you have locally built t he SPA in t he dist f older, you can creat e a Dockerf ile like t his: FROM nginx:alpine COPY nginx.conf /etc/nginx/nginx.conf COPY dist /usr/share/nginx/html EXPOSE 80 CMD ["nginx", "-g", "daemon off;"] docker build -t my-nginx . builds t he image, t ags it as my-nginx And t hen: docker run -d -p 8086:80 my-nginx runs t he cont ainer on port 8086 10 Building an Express API Slight ly more complex Wit h SPA, we are " only" giving st at ic f iles t o a ready-made server Here we need t o make one: We need nodejs and npm We need t o inst all node dependencies 11 Dockerfile Basic Dockerf ile f or an Express API: FROM node:latest WORKDIR /app COPY . /app RUN npm install EXPOSE 3000 CMD ["tsx", "src/index.ts"] # tsx is an alternative to ts-node Not e: Docker layers - each command creat es a new layer, which can be cached and can be reused by lat er builds T ry running docker build mult iple t imes! 12 Dockerfile T he previous example has a f ew issues: using mut able t ags such as latest is not recommended, you never know what you get use a version t ag inst ead COPY . /app copies everyt hing, including local node_modules use .dockerignore t o exclude f iles npm install is run every t ime any of t he f iles change bet t er ut ilize Docker layers t o cache dependencies COPY package*.json and npm install bef ore copying sources cont ainer runs as root use USER t o swit ch t o a non-root user base image is huge use alpine or slim versions (if possible) 13 Dockerfile T ry improving t he Dockerf ile based on t he previous slide! Use some express BE project you have lying around. O r quickly spin up a new one. npm init -y npm install express npm install typescript tsx echo "console.log('Hello, world!')" > src/index.ts 14 Dockerfile FROM node:20.11.1-alpine # Add package files and install COPY package.json package-lock.json ./ RUN npm ci # Copy sources COPY src ./src COPY tsconfig.json ./tsconfig.json EXPOSE 3000 CMD ["tsx", "src/index.ts"] 15 Docker - Image size Docker images can get quit e large and are of t en passed around via net work or st ored in regist ries consumes bandwidt h and st orage It is a good pract ice t o keep t he image size as small as possible NodeJS - Production image A project generally cont ains a lot of t hings unnecessary f or product ion developer t ooling (t ypescript , nodemon, et c.), general devDependencies t est s, document at ion, et c. A build st ep can be used t o creat e a product ion-ready image T he way t o do t his is via a mult i-st age build 16 Multi-stage build FROM node:20.11.1-alpine as base # Add package file and install COPY package.json package-lock.json ./ RUN npm ci # Copy sources COPY src ./src COPY tsconfig.json ./tsconfig.json # Build the project into the dist folder (`tsc --outDir dist` in this case) RUN npm run build # Start production image build FROM node:20.11.1-alpine # Install production dependencies COPY package.json package-lock.json ./ RUN npm ci --production COPY --from=base /dist /dist # Copy the built project EXPOSE 3000 CMD ["node","dist/src/index.js"] # This will vary based on your project 17 Monorepos 18 Monorepos Monorepos are a common way t o manage mult iple project s in a single reposit ory T hey are especially usef ul f or microservices, where you have mult iple services t hat share common code T hey can be a bit t ricky t o work wit h, especially in a Docker environment Turbo Monorepo t ool creat ed by Vercel Simplif ies t he process of working wit h monorepos T ry it out ! npm create turbo Look around! T ry running t he apps, change t he code, et c. 19 Dockerizing a monorepo Usually t ool specif ic, wit h a det ailed guide on how t o do it T urbo has a nice way of handling t his ht t ps://t urbo.build/repo/docs/handbook/deploying-wit h-docker T ry it out ! 20 Container orchestration 21 Container orchestration Docker is great f or running a single cont ainer But what if you have mult iple cont ainers? How do you manage t hem? How do you scale t hem, run mult iple inst ances? How do you ensure t hey are always running? 22 Container orchestration (docker-compose) Docker-compose is a t ool f or def ining and running mult i-cont ainer Docker applicat ions It uses a docker-compose.yml f ile t o conf igure your applicat ion's services It can be used t o def ine and run mult i-cont ainer Docker applicat ions 23 Docker-compose A simple docker-compose.yml f ile: version: "3" services: web: build: . # build the image from the Dockerfile in the current directory ports: - "8080:8080" environment: - REDIS_URL=redis://redis:6379 redis: image: "redis:alpine" Creat es t wo services: web and redis 24 Docker-compose (added DB) version: "3" services: web: build: . # build the image from the Dockerfile in the current directory ports: - "8080:8080" environment: - REDIS_URL=redis://redis:6379 - POSTGRES_URL=postgres://postgres:postgres@postgres:5432/mydb redis: image: "redis:alpine" postgres: image: "postgres:alpine" environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres - POSTGRES_DB=mydb volumes: - mydata:/var/lib/postgresql/data volumes: mydata: 25 Docker-compose (useful commands) docker-compose up st art s t he services docker-compose down st ops t he services docker-compose up -d st art s t he services in t he background docker-compose logs shows t he logs of t he services 26 Docker (useful features recap) Volumes Persist dat a bet ween cont ainer rest art s Bind mount s Mount host direct ories int o cont ainers Usef ul f or development Net works Connect cont ainers t oget her Environment variables Pass conf igurat ion t o cont ainers Port mappings Expose cont ainer port s t o t he host Bind mount s Mount host direct ories int o cont ainers 27 Container orchestration (Kubernetes) Compose is great f or development , but not t hat much f or product ion It lacks many f eat ures needed f or product ion, has bare necessit ies t hough Cannot run on mult iple machines Kubernet es is an indust ry st andard cont ainer orchest rat ion syst em t hat can manage cont ainers across mult iple host s T here is also Docker Swarm or Hashicorp Nomad, bot h simpler, but less powerf ul 28 Container registries Docker images are st ored in regist ries Docker Hub is t he most popular one Public and privat e reposit ories Git lab has it s own regist ry T ry it out ! Push any of your locally built images t o f acult y regist ry docker tag my-nginx gitlab.fi.muni.cz:5050/my-nginx docker login gitlab.fi.muni.cz:5050 docker push gitlab.fi.muni.cz:5050/my-nginx ht t ps://www.f i.muni.cz/t ech/unix/git lab/ci.ht ml.en# regist ry 29 Thats all folks! 30