28
loading...
This website collects cookies to deliver better user experience
mkdir ajcwebdev-docker
cd ajcwebdev-docker
npm init -y
npm i express
touch index.js
index.js
.// index.js
const express = require("express")
const app = express()
const PORT = 8080
const HOST = '0.0.0.0'
app.get('/', (req, res) => {
res.send('<h2>ajcwebdev-docker</h2>')
})
app.listen(PORT, HOST)
console.log(`Running on http://${HOST}:${PORT}`)
node index.js
Listening on port 8080
Dockerfile
and .dockerignore
.Dockerfile
. A Dockerfile
is a text document that contains all the commands a user could call on the command line to assemble an image. Using docker build
users can create an automated build that executes several command-line instructions in succession.touch Dockerfile
FROM
instruction initializes a new build stage and sets the Base Image for subsequent instructions. A valid Dockerfile
must start with FROM
. The first thing we need to do is define from what image we want to build from. We will use version 14-alpine
of node
available from Docker Hub because the universe is chaos and you have to pick something so you might as well pick something with a smaller memory footprint.FROM node:14-alpine
LABEL
instruction is a key-value pair that adds metadata to an image.LABEL org.opencontainers.image.source https://github.com/ajcwebdev/ajcwebdev-docker
WORKDIR
instruction sets the working directory for our application to hold the application code inside the image.WORKDIR /usr/src/app
npm
binary. The COPY
instruction copies new files or directories from <src>
. The COPY
instruction bundles our app's source code inside the Docker image and adds them to the filesystem of the container at the path <dest>
.COPY package*.json ./
RUN
instruction will execute any commands in a new layer on top of the current image and commit the results. The resulting committed image will be used for the next step in the Dockerfile
. Rather than copying the entire working directory, we are only copying the package.json
file. This allows us to take advantage of cached Docker layers.RUN npm i
COPY . ./
EXPOSE
instruction informs Docker that the container listens on the specified network ports at runtime. Our app binds to port 8080
so you'll use the EXPOSE
instruction to have it mapped by the docker
daemon.EXPOSE 8080
CMD
which defines our runtime. The main purpose of a CMD
is to provide defaults for an executing container. Here we will use node index.js
to start our server.CMD ["node", "index.js"]
Dockerfile
should now look like this:FROM node:14-alpine
LABEL org.opencontainers.image.source https://github.com/ajcwebdev/ajcwebdev-docker
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm i
COPY . ./
EXPOSE 8080
CMD [ "node", "index.js" ]
.dockerignore
in the root directory of the context. Create a .dockerignore
file in the same directory as our Dockerfile
.touch .dockerignore
node_modules
Dockerfile
.dockerignore
.git
.gitignore
npm-debug.log
docker build
command builds an image from a Dockerfile and a "context". A build’s context is the set of files located in the specified PATH
or URL
. The URL
parameter can refer to three kinds of resources:Dockerfile
and build the Docker image.docker build . -t ajcwebdev-docker
-t
flag lets you tag your image so it's easier to find later using the docker images
command.docker images
command will list all top level images, their repository and tags, and their size.docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ajcwebdev-docker latest cf27411146f2 4 minutes ago 118MB
docker run
, the container process that runs is isolated in that it has its own file system, its own networking, and its own isolated process tree separate from the host.docker run -p 49160:8080 -d ajcwebdev-docker
-d
runs the container in detached mode, leaving the container running in the background. The -p
flag redirects a public port to a private port inside the container.docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d454a8aacc28 ajcwebdev-docker "docker-entrypoint.s…" 13 seconds ago Up 11 seconds 0.0.0.0:49160->8080/tcp, :::49160->8080/tcp sad_kepler
docker logs <container id>
Running on http://0.0.0.0:8080
8080
port inside of the container to the port 49160
on your machine.curl -i localhost:49160
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 25
ETag: W/"19-iWXWa+Uq4/gL522tm8qTMfqHQN0"
Date: Fri, 16 Jul 2021 18:48:54 GMT
Connection: keep-alive
Keep-Alive: timeout=5
<h2>ajcwebdev-docker</h2>
touch docker-compose.yml
docker-compose.yml
so they can be run together in an isolated environment.version: "3.9"
services:
web:
build: .
ports:
- "49160:8080"
docker stop <container id>
docker compose up
command aggregates the output of each container. It builds, (re)creates, starts, and attaches to containers for a service.docker compose up
Attaching to web_1
web_1 | Running on http://0.0.0.0:8080
.gitignore
file for node_modules
and our environment variables.echo 'node_modules\n.DS_Store\n.env' > .gitignore
.env
even though we don't have a .env
file in this project right now.git init
git add .
git commit -m "I can barely contain my excitement"
gh repo create
command with the GitHub CLI. Enter the following command to create a new repository, set the remote name from the current directory, and push the project to the newly created repository.gh repo create ajcwebdev-docker \
--public \
--source=. \
--remote=upstream \
--push
git remote add origin https://github.com/ajcwebdev/ajcwebdev-docker.git
git push -u origin main
xxxx
.export CR_PAT=xxxx
ajcwebdev
.echo $CR_PAT | docker login ghcr.io -u ajcwebdev --password-stdin
docker tag ajcwebdev-docker ghcr.io/ajcwebdev/ajcwebdev-docker
docker push ghcr.io/ajcwebdev/ajcwebdev-docker:latest
docker pull ghcr.io/ajcwebdev/ajcwebdev-docker
Using default tag: latest
latest: Pulling from ajcwebdev/ajcwebdev-docker
Digest: sha256:3b624dcaf8c7346b66af02e9c31defc992a546d82958cb067fb6037e867a51e3
Status: Image is up to date for ghcr.io/ajcwebdev/ajcwebdev-docker:latest
ghcr.io/ajcwebdev/ajcwebdev-docker:latest
28