This repo was generated to start in the docker world. Just for learning purposes.
All these docs have been taken from
docker
run-d -p 80:80 docker/getting-started
- docker installation
- docker desktop
- docker hub account
webappcreated in react and will use its own containermysqlserver in an isolated container
First we have to create a Dockerfile in our repo. Make sure you do not use any extension
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "src/index.js"]
FROMwhich image to use
WORKDIRwhich dir will now be used as root from now on inside the container
COPYfrom which directory in the code to whichWORKDIRin the container
RUNwhich command to run after previous step
CMDspecifies the instruction that is to be executed when a Docker container starts.
Taking a look at the Dockerfile that is the command used to build the image and then run:
tag-nameis the name of the app
.(at the end) as parameter will tell docker to use Dockerfile in the root of the folder
dockerbuild-t getting-started .
Now that we have an image, we should start the container
docker
run-dp 3000:3000 getting-started
After a few seconds you will see the webapp running in
You can do any change in the app, and then you can deploy again make sure you stop and remove the container first!
- Let's list all the containers and to get the
container-id
docker
ps
- Stop the running container
docker
stopcontainer-id
- Remove the container
docker
rmcontainer-id
- Build the container again (make sure to use tags to identify your container)
docker
build-t getting-started
- Run the container again with the new changes
docker
run-dp 3000:3000 getting-started\
-dwill run in detached mode
-pport forwarding option (short version)
You can share your app using dockerhub. If you are new to DockerHub, it is something similar to GitHub but with docker containers :)
- Login to DockerHub
docker
login-u YOUR-USER-NAME
- Use a tag to identify your container
docker
tagtag-name YOUR-USER-NAME/tag-name
- Push your changes
docker
pushYOUR-USER-NAME/tag-name
You can test your container online with https://labs.play-with-docker.com and run the image using the command docker run
docker
run-dp 3000:3000 YOUR-USER-NAME/getting-started
note: Make sure you use the DockerHub YOUR-USER-NAME/tag-name and not the local tag-name as this will pull the image from DockerHub
If you want to persist the data, you should use volumes. Think of volumes as a simple bucket of data
- Create a volume
docker
volumecreate todo-db
- Run the container but binding the volume to the route you want to persist the data to
docker
run-dp 3000:3000 -v todo-db:/app getting-started
-voption will use the previously created volume and will use the /app path to make the data persist
- Use the volume inspect command if you want to know more about the volume
docker
volumeinspect todo-db
To run the container in dev mode hot reloading to have the changes in your code base reflected inside the container:
Run the following command
docker run -dp 3000:3000
-w /app -v "$(pwd):/app"
node:18-alpine
sh -c "yarn install && yarn run dev"
-dp 3000:3000same as before port forwarding
-w /appworking directory inside the container
-v "$(pwd):/app"bind mount (link) the host present dir with the containers route dir/appbut docker requires absolute path, for that we usepsdinstruction
node:18-alpineimage to use
sh -cinitial command to run
- if you want to see the logs, use the instruction:
docker
logs-f container-id
- Do any kind of changes in the code, and you will see them reflected
Usually an app is build using different services, and to achieve that you can deploy multiple containers each one with one single responsibility but connected by one internal network
If two containers are on the same network, they can talk to each other. If they aren't, they can't.
Let's create a new network
docker
networkcreate todo-app
For this example, we will create a MySQL container to have db functionality in the app
docker run -d \
--network todo-app --network-alias mysql \
-v todo-mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=secret \
-e MYSQL_DATABASE=todos \
mysql:8.0
--networktodo-app will be the network we created before
--network-aliasadds network-scoped alias for the container, in this case: mysql (works as the host name/IP address)
-vwill create a volume todo-mysql-data and will be linked to the path /var/lib/mysql which is the place where mysql stores the data
-eset environment var
mysql:8.0image to use
Now we can run our app in development mode connecting it to the previous MYSQL server and passing the required env vars to connect to db and telling docker which network to use
docker run -dp 3000:3000 \
-w /app -v "$(pwd):/app" \
--network todo-app \
-e MYSQL_HOST=mysql \
-e MYSQL_USER=root \
-e MYSQL_PASSWORD=secret \
-e MYSQL_DB=todos \
node:18-alpine \
sh -c "yarn install && yarn run dev"
Now both of the containers are connected in the same network and the data is being persisted
Is a tool to help develop, define and share Multi-container apps with a single file docker-compose.yml the file always starts with the services tag and the next level will be the app name (it can be what ever name, but it will become a --network-alias)
services:
app: //we will define the web app here
mysql: //we will define the mysql server here
Let's now migrate our previous scripts into the docker-compose.yml file:
- WebApp
As previously defined this into one script we will transpile the script into docker compose config:
services:
app:
image: node:18-alpine
command: sh -c "yarn install && yarn run dev"
ports:
- 3000:3000
working_dir: /app
volumes:
- ./:/app
environment:
MYSQL_HOST: mysql
MYSQL_USER: root
MYSQL_PASSWORD: secret
MYSQL_DB: todos
appname of the service, it will be used as --network-aliasimagename of the image to use
portsport forwarding short syntax (long syntax here)
working_dirworking dir inside the container
volumesshort syntax for volumes VOLUME:CONTAINER_PATH (long syntax here)
environmentlist of all the env vars needed
- MYSQL service
Now let's migrate the MYSQL command to the yml configuration
services:
app:
# The previous app service definition
mysql:
image: mysql:8.0
volumes:
- todo-mysql-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: todos
volumes:
todo-mysql-data:
mysqlname of the service, it will be used as --network-alias
imageimage to usevolumesshort syntax VOLUME:CONTAINER_PATH
environmentenv vars
volumes(root level) config new volumes to be created
todo-mysql-dataname of the new volume to be used
- Put all together in one
docker-compose.ymlfile and run the command
docker
composeup
Now the whole app including the web service and the db service are running into one single container and this will look something similar to this:
Once you are ready, simply run
docker
composedown
docker
execcontainer-id command
docker
logs-f container-id
docker
exec-it mysql -p
docker
run-it --network todo-app nicolaka/netshoot
//Official docs from docker getting started
dockerrun-d -p 80:80 docker/getting-started



