preface
Just know nuggets article still has word limit, can divide development.
I used Vue family bucket to develop my personal blog and deployed it on Ali cloud server. Recently, I learned React, so I developed and reconstructed my blog with React.
-
The old vue_blog:vue.cl8023.com
-
The new react_blog:cl8023.com
The main technology stack is as follows:
- The front page: Next. Js builds the server side rendering page, which is conducive to SEO
- Background management interface: create-react-app quick setup
- Service interface: egg.js + Mysql
- Deployment: Linux + Docker
React Hooks+ egg.js React Hooks+ egg.js React Hooks+ egg.js
The deployment part will be mainly explained here, because it is the first time to contact Docker. I only record my learning experience here, and please give me more advice if there is something wrong.
In this project, the foreground page is node running, the background interface is static HTML, and the service interface needs to be connected to Mysql. I think the deployment of Docker is also a comprehensive example, which can be used as a reference for the later students. The content is rather wordy, and I hope it can help the later students to make less mistakes. Because some are their own understanding, there may be mistakes, but also please correct, learn from each other.
The project address
Source code address: github.com/Moon-Future…
Clone down to the directory oh ~
A, the React
The blog foreground is built with the Next. Js server rendering framework, the background management interface is built with the create-React-app scaffolding, and the service interface is built with the Egg framework (based on Koa). There is nothing to be said about React management and service interfaces. Here are some of the React basics and some of the problems encountered in Next.
Project Contents:
Blog: Foreground interface, next.js
Admin: Create-react-app scaffolding is set up on the background management interface
Service: front and back service interfaces
1. Obtain render data
GetStaticProps and getServerSideProps are the two official apis for rendering the page on the server side, so the initial data is retrieved on the server side and returned to the front-end. (For Next. Js versions 9.3 and older, use getStaticProps or getServerSideProps instead of getInitialProps.)
GetStaticProps: The server gets static data, generates a static HTML page when it gets the data, and then reuses that page on every request
const Article = (props) = > {
return()}/* Export default class Article extends React.Component {render() {return}} */
export async function getStaticProps(context) {
try {
const result = await axios.post(api.getArticleList)
return {
props: { articleList: result.data }, // will be passed to the page component as props}}catch (e) {
return {
props: { articleList: []},// will be passed to the page component as props}}}export default Article
Copy the code
GetServerSideProps: On each request, the server reobtains the generated HTML page
const Article = (props) = > {
return()}/* Export default class Article extends React.Component {render() {return}} */
export async function getServerSideProps(context) {
try {
const result = await axios.post(api.getArticleList)
return {
props: { articleList: result.data }, // will be passed to the page component as props}}catch (e) {
return {
props: { articleList: []},// will be passed to the page component as props}}}export default Article
Copy the code
You can see that they are used the same way.
In development mode, NPM run dev is the same as NPM run Dev, and the page is refetched every time it is requested.
In production, NPM run build is used to generate the static HTML page. To get the data from getStaticProps, run start is used to generate the static HTML page. Using getServerSideProps reobtains the data on each request.
The returned data is in the form of objects, and only objects. The key is props, which is passed to the props in the class or function.
Blog: getServerSideProps is used to get a list of blog posts, and the data can change at any time.
In this case, try and catch are used to catch exceptions to prevent data acquisition failure or back-end interface error, and server rendering error cannot return the page.
2. Request after the page is loaded
There is also some data that we don’t want to get rendered to the page on the server, but we want the page to load.
React Hook: useEffect
const Article = (props) = > {
useEffect(async() = > {await axios.get(' ')}, [])return()}export async function getServerSideProps(context) {
try {
const result = await axios.post(api.getArticleList)
return {
props: { articleList: result.data }, // will be passed to the page component as props}}catch (e) {
return {
props: { articleList: []},// will be passed to the page component as props}}}export default Article
Copy the code
Note here that useEffect, the second parameter, represents whether or not a dependency is executed.
- No second argument: useEffect the first argument function is executed every time return re-renders the page
- Parameter [], as shown in the preceding example, indicates that the command is executed only once, independent of any variable
- Pass [value], an array, which can depend on multiple variables: represents the dependency on the value variable (the value in state). UseEffect is executed only when the value changes
With Class, you can operate in componenDidMount:
export default class Article extends React.Component {
componenDidMount() {
await axios.get(' ')}render() {
return}}export async function getServerSideProps(context) {
try {
const result = await axios.post(api.getArticleList)
return {
props: { articleList: result.data }, // will be passed to the page component as props}}catch (e) {
return {
props: { articleList: []},// will be passed to the page component as props}}}export default Article
Copy the code
3. Page animation
Page to enter and exit the animation to find a more useful libraries framer – motion, www.framer.com/api/motion/
Pages /_app.js will be updated to include Framer-motion
npm install framer-motion -S
Copy the code
import { AnimatePresence } from 'framer-motion'
export default function MyApp({ Component, pageProps, router }) {
return (
<AnimatePresence exitBeforeEnter>
<Component {. pageProps} route={router.route} key={router.route} />
</AnimatePresence>)}Copy the code
Animate each page by placing motion in front of the element tag, such as pages/article.js
const postVariants = {
initial: { scale: 0.96.y: 30.opacity: 0 },
enter: { scale: 1.y: 0.opacity: 1.transition: { duration: 0.5.ease: [0.48.0.15.0.25.0.96]}},exit: {
scale: 0.6.y: 100.opacity: 0.transition: { duration: 0.5.ease: [0.48.0.15.0.25.0.96]}}},const sentenceVariants = {
initial: { scale: 0.96.opacity: 1 },
exit: {
scale: 0.6.y: 100.x: -300.opacity: 0.transition: { duration: 0.5.ease: [0.48.0.15.0.25.0.96]}}},const Article = (props) = > {
const { articleList, route } = props
const [poetry, setPoetry] = useState(null)
const getPoetry = (data) = > {
setPoetry(data)
}
return (
<div className="container article-container">
<Head>
<title>There is no end to learning</title>
</Head>
<Header route={route} />
<div className="page-background"></div>
<div style={{ height: '500px' }}></div>
<Row className="comm-main comm-main-index" type="flex" justify="center">
<Col className="comm-left" xs={0} sm={0} md={0} lg={5} xl={4} xxl={3}>
<Author />
<Project />
<Poetry poetry={poetry} />
</Col>
<Col className="comm-center" xs={24} sm={24} md={24} lg={16} xl={16} xxl={16}>
<motion.div className="sentence-wrap" initial="initial" animate="enter" exit="exit" variants={sentenceVariants}>
<PoetrySentence staticFlag={true} handlePoetry={getPoetry} />
</motion.div>
<div className="comm-center-bg"></div>
<motion.div initial="initial" animate="enter" exit="exit" variants={postVariants} className="comm-center-content">
<BlogList articleList={articleList} />
</motion.div>
</Col>
</Row>
</div>)}Copy the code
“Motion” will be added to the tag of the element that you want to animate and will pass in parameters like Initial, Animate, exit and variants
const postVariants = {
initial: { scale: 0.96.y: 30.opacity: 0 },
enter: { scale: 1.y: 0.opacity: 1.transition: { duration: 0.5.ease: [0.48.0.15.0.25.0.96]}},exit: {
scale: 0.6.y: 100.opacity: 0.transition: { duration: 0.5.ease: [0.48.0.15.0.25.0.96]}}},// initial Indicates the initial state
// Enter to enter the animation
// exit Indicates the exit status
// Do not want an exit animation, do not write exit variable
Copy the code
< span style = “color: RGB (0, 0, 0); font-size: 14px! Important; line-height: 20px! Important;”
const Article = (props) = >{
return (
<motion.div initial="initial" animate="enter" exit="exit">.</motion.div>)}Copy the code
4. Switch status
Use import Link from ‘Next/Link’ in next.js to switch pages without refreshing them
import Link from 'next/link'
const BlogList = (props) = > {
return (
<>
<Link href={'/detailed?id=' + item.id}>
{item.title}
)}export default BlogList
Copy the code
Because it is rendered on the server side, when the Link is clicked, the page does not react for a while. By default, Next. Js has a rotating black triangle in the lower right corner, but it does not attract the user’s attention.
The plugin nProgress is used to load the progress bar from the top
npm install nprogress -S
Copy the code
Change _app.js again
import 'antd/dist/antd.css'
import '.. /static/style/common.less'
import { AnimatePresence } from 'framer-motion'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import Router from 'next/router'
NProgress.configure({
minimum: 0.3.easing: 'ease'.speed: 800.showSpinner: false,
})
Router.events.on('routeChangeStart'.() = > NProgress.start())
Router.events.on('routeChangeComplete'.() = > NProgress.done())
Router.events.on('routeChangeError'.() = > NProgress.done())
export default function MyApp({ Component, pageProps, router }) {
return (
<AnimatePresence exitBeforeEnter>
<Component {. pageProps} route={router.route} key={router.route} />
</AnimatePresence>)}Copy the code
The next/ Router is used to monitor the route switching status. You can also customize the loading status.
5. The CSS fails to be loaded
In the Next. Js development mode, when entering a page for the first time, it is found that the current page style fails to load, and must be refreshed to load successfully.
next-css: Routing to another page doesn’t load CSS in development mode
Cant change page with ‘next/link’ & ‘next-css’
Github also found related problems, said to _app.js, but I tried, still not work, but fortunately this situation is only in the development mode, production mode is not a problem, so it is not troubled, so refresh it.
6. Implement setInterval in React Hoos
In the components/PoetrySentence js achieve the effect of dynamic to write a poem, in the class can be used with through setInterval simple implementation, In React Hoot, useEffect is executed every time render is re-rendered, or useEffect is executed only once again depending on [], which is implemented by relying on a single variable plus setTimeout.
The components/PoetrySentence. Js
import { useState, useEffect } from 'react'
import { RedoOutlined } from '@ant-design/icons'
import { getPoetry, formatTime } from '.. /util/index'
const PoetrySentence = (props) = > {
const [sentence, setSentence] = useState(' ')
const [finished, setFinished] = useState(false)
const [words, setWords] = useState(null)
const { staticFlag, handlePoetry } = props // Whether static display
useEffect(
async() = > {if (words) {
if (words.length) {
setTimeout(() = > {
setWords(words)
setSentence(sentence + words.shift())
}, 150)}else {
setFinished(true)}}else {
let tmp = await todayPoetry()
if (staticFlag) {
setFinished(true)
setSentence(tmp.join(' '))}else {
setWords(tmp)
setSentence(tmp.shift())
}
}
},
[sentence]
)
const todayPoetry = () = > {
return new Promise((resolve) = > {
const now = formatTime(Date.now(), 'yyyy-MM-dd')
let poetry = localStorage.getItem('poetry')
if (poetry) {
poetry = JSON.parse(poetry)
if (poetry.time === now) {
handlePoetry && handlePoetry(poetry)
resolve(poetry.sentence.split(' '))
return
}
}
getPoetry.load((result) = > {
poetry = {
time: now,
sentence: result.data.content,
origin: {
title: result.data.origin.title,
author: result.data.origin.author,
dynasty: result.data.origin.dynasty,
content: result.data.origin.content,
},
}
handlePoetry && handlePoetry(poetry)
localStorage.setItem('poetry'.JSON.stringify(poetry))
resolve(poetry.sentence.split(' '))})})}const refresh = () = > {
getPoetry.load((result) = > {
const poetry = {
time: formatTime(Date.now(), 'yyyy-MM-dd'),
sentence: result.data.content,
origin: {
title: result.data.origin.title,
author: result.data.origin.author,
dynasty: result.data.origin.dynasty,
content: result.data.origin.content,
},
}
handlePoetry && handlePoetry(poetry)
localStorage.setItem('poetry'.JSON.stringify(poetry))
if (staticFlag) {
setSentence(poetry.sentence)
} else {
setFinished(false)
setWords(null)
setSentence(' ')}}}return (
<p className="poetry-sentence">
{sentence}
{finished ? <RedoOutlined style={{ fontSize: '14px'}}onClick={()= > refresh()} /> : null}
<span style={{ visibility: finished ? 'hidden' :"'}} >|</span>
</p>)}export default PoetrySentence
Copy the code
UseEffect depends on the variable sentence, and then changes sentence in useEffect. After sentence is updated, it triggers re-rendering, and then re-executes useEffect. The setInterval effect is perfectly implemented.
7. node-sass
Sass was used in the original project, but in the later deployment and installation of docker dependencies, it was too slow and various errors were reported, which was also frequently encountered before, so it was simply changed to less, with similar syntax and much easier installation.
Second, the Docker
1. What is Docker
Docker is an open source application container engine that allows developers to package their applications and dependencies into a lightweight, portable container that can then be distributed to any popular Linux machine, as well as virtualization.
Containers are completely sandboxed, have no interfaces with each other (like iPhone apps), and most importantly, have very low performance overhead.
2. Why Docker
For me, because I am using Ali cloud server now, I have deployed several projects. If the server expires and the server is replaced, I will need to migrate all projects to the new server, and each project will have to install dependencies, run, nginx configuration and so on in sequence, which is a big headache to think about. With Docker, individual projects and their dependencies are packaged into images that can be produced in any Linux container, making migration and deployment much easier.
In addition, Docker can make the development environment, test environment and production environment consistent, and each container is a service, and it is convenient for the back-end to implement the microservice architecture.
3. The installation
The best way to install Docker is to refer to the official documentation to avoid version updates. Docs.docker.com/engine/inst… English laboured, these two recommend a magic dictionary Continental Dictionary, where will not point where, who use who say good.
Mac and Windows both have clients that can be easily downloaded and installed. In addition, Windows should be distinguished from professional, Enterprise, Education and Home editions
Windows Pro, Enterprise, and Education
Windows home edition
Because I use aliyun Centos 7 server here, so a brief introduction to the Centos installation.
Centos install Docker
First of all, if you have already installed Docker and want to install the latest version, please help the old version first
$sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
Copy the code
There are three installation methods:
- Install using the repository
- Install from a package
- Install using the convenience script
Choose the official recommended first way to Install using the Repository.
1, SET UP THE REPOSITORY
Install the yum-utils toolkit and set up the repository
$ sudo yum install -y yum-utils
$sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo
Copy the code
2. Install Docker
$ sudo yum install docker-ce docker-ce-cli containerd.io
Copy the code
This will install the latest version, or you can choose to install the specified version
View the version list:
$ yum list docker-ce --showduplicates | sort -rLoading mirror speeds from cached hostfile Loaded plugins: Fastestmirror Installed Packages Docker-ce.x86_64 3:20.10.0-3.EL7 Docker-CE-Stable Docker-CE.x86_64 3:20.10.0-3.EL7 X86_64 3:19.03.9-3.el7 docker-ce-stable docker-ce. X86_64 3:19.03.8-3.el7 docker-ce-stable X86_64 3:19.03.7-3.el7 docker-ce-stable docker-ce. X86_64 3:19.03.6-3.el7 docker-ce-stable docker-ce X86_64 3:19.03.4-3.el7 docker-ce-stable docker-ce. X86_64 3:19.03.3-3.el7 Docker-ce-stable docker-ce X86_64 3:19.03.2-3.el7 docker-ce-stable docker-ce. X86_64 3:19.03.14-3.el7 docker-ce-stable .Copy the code
Select the specified version to install
$ sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
Copy the code
After the installation is complete, check the version
$ docker -v
Docker version 20.10.0, build 7287ab3
Copy the code
3. Start Docker
$ sudo systemctl start docker
Copy the code
Close the docker
$ sudo systemctl stop docker
Copy the code
Restart the docker
$ sudo systemctl restart docker
Copy the code
4. Mirror Image
**Docker packages the application and its dependencies in an image file. ** Only from this file can you generate a Docker Container. The image file can be thought of as a template for the container. Docker generates instances of containers from the image file. The same image file can generate multiple container instances running at the same time.
Image files are universal, and can be copied from one machine to another. In general, to save time, we should try to use image files made by others rather than making them ourselves. Even if you want to customize it, it should be based on someone else’s image file, not from scratch.
There is an official image library Docker Hub, many environment images can be pulled from it.
4.1 Viewing A Mirror
$ docker images
Copy the code
or
$ docker image ls
Copy the code
Just installed Docker, there is no image
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
Copy the code
Only all mirror ids are displayed
$ docker images -q
#or
$ docker image ls -q
Copy the code
4.2 Downloading an Image
Here we try to download an nginx image from the official library. The image is similar to the NPM global dependency. After pulling the image, all nginx images that need to be used can rely on the nginx.
Download the nginx image at hub.docker.com/_/nginx
$ docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
6ec7b7d162b2: Pull complete
cb420a90068e: Pull complete
2766c0bf2b07: Pull complete
e05167b6a99d: Pull complete
70ac9d795e79: Pull complete
Digest: sha256:4cf620a5c81390ee209398ecc18e5fb9dd0f5155cd82adcbae532fec94006fb9
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest ae2feff98a0c 13 hours ago 133MB
Copy the code
Docker images displays the nginx image, with 5 titles, including the image name, TAG, id, creation time, and size. The default TAG is latest latest version, followed by the version number
$Docker pull nginx: 1.19
Copy the code
4.3 Deleting a Mirror
To delete a mirror, run the following command
$ docker rmi [image]
Copy the code
or
$ docker image rm [image]
Copy the code
[image] Can be the image name + label, or the image ID, ru
$ docker rmi nginx:latest
$ docker rmi ae2feff98a0c
Copy the code
Deleting all Mirrors
$ docker rmi $(docker images -q)
Copy the code
Delete all None mirrors
Some subsequent operations will repeatedly create the same mirror, the original mirror will be overwritten into, can be deleted in batches
$ docker rmi $(docker images | grep "none" | awk '{print $3}')
Copy the code
4.4 Creating an Image
We downloaded the Nginx image above, but to run our own project, we need to make an image of our own project and then generate the container to run the project.
To make an image, you need to use a Dockerfile file, using the admin background interface of this project as an example (or any HTML file), because it can be packaged and accessed only using Nginx.
First, run the command NPM run build under admin to generate the build folder, and create the index. HTML file. Then create the Dockerfile file under admin/docker
FROM nginx
COPY ../build /usr/share/nginx/html
EXPOSE 80
Copy the code
Put the build and docker folders in the same directory on the server, for example, /dockerProject/admin
├─admin └─build ├─ index.html ├─ trashCopy the code
Run the command in the docker directory
$ docker build ./ -t admin:v1Sending build context to Docker Daemon 4.096kB Step 1/3: FROM nginx ---> ae2feff98a0cStep 2/3 : COPY .. /build /usr/share/nginx/html COPY failed: forbidden path outside the build context: .. /build ()Copy the code
/ Based on the current directory as the build context, -t specifies the name of the image to be made.
You can see that there is an error,
The path must be inside the context of the build; you cannot ADD .. /something/something, because the first step of a docker build is to send the context directory (and subdirectories) to the docker daemon.
Once the build context is determined, some intermediate file operations can only be performed between the current contexts. There are two ways to resolve this problem
-
Dockfile is in the same directory as build
├ ─ admin └ ─ build └ ─ index. The HTML └ ─ DockerfileCopy the code
Dockerfile:
FROM nginx COPY ./build /usr/share/nginx/html EXPOSE 80 Copy the code
Run commands in the admin directory
$ docker build ./ -t admin:v1Sending build context to Docker Daemon 3.094MB Step 1/3: FROM nginx ---> ae2feff98a0c Step 2/3 : COPY ./build /usr/share/nginx/html ---> Using cache ---> 0e54c36f5d9a Step 3/3 : EXPOSE 80 ---> Using cache ---> 60db346d30e3 Successfully built 60db346d30e3 Successfully tagged admin:v1 Copy the code
-
Dokcerfile is still put into docker for unified management
├─admin └─build ├─ index.html ├─ trashCopy the code
Dockerfile:
FROM nginx COPY ./build /usr/share/nginx/html EXPOSE 80 Copy the code
Run commands in the admin directory
$ docker build -f docker/Dockerfile ./ -t admin:v1Sending build context to Docker Daemon 3.094MB Step 1/3: FROM nginx ---> ae2feff98a0c Step 2/3 : COPY ./build /usr/share/nginx/html ---> Using cache ---> 0e54c36f5d9a Step 3/3 : EXPOSE 80 ---> Using cache ---> 60db346d30e3 Successfully built 60db346d30e3 Successfully tagged admin:v1 Copy the code
Notice the./build path here. -f (-file) specifies a Dockfile file./ uses the current path as the build context, so the build path is still./build
The Dockerfile file is used above, but it will not be described here because it is relatively small, and will be explained later when deploying next.js.
5. The Container vessel
Let’s take a look at the admin:v1 image generated above
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
admin v1 60db346d30e3 51 minutes ago 136MB
nginx latest ae2feff98a0c 14 hours ago 133MB
Copy the code
If you want to create an nginx image, you need to create an nginx image. If you want to create an nginx image, you need to create an nginx image.
The project runs inside a container, and we need to create a container with an image.
5.1 Viewing Containers
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Copy the code
or
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Copy the code
These two commands display only the containers that are running, not the containers that are stopped, and the -a (–all) argument will display all of them
$ docker container ls -a
$ docker ps -a
Copy the code
View only all container ids
$ docker ps -aq
Copy the code
5.2 Generating Containers
Here we generate a container with admin:v1
$ docker create -p 9001:80 --name admin admin:v1
Copy the code
- -p: port mapping. Host (server) : container. 9001:80 indicates that port 9000 of the host can access port 80 of the container
- –name: generated container name, unique value
- Admin :v1: used mirror and label
:v1
The default is:latest
There are many parameters, can understand docs.docker.com/engine/refe…
Now that the container is generated, let’s see
$ docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8d755bab5C73 admin:v1 "/ docker-entryPoint...." 5 minutes ago Created adminCopy the code
You can see that the container has been generated, but it is not running yet, so all ps using Docker are invisible
Run the container: docker start [container iD], [] can use the container iD, can use the container name, both are unique
$ docker start admin
$ docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8d755bab5C73 admin:v1 "/ docker-entryPoint...." 8 minutes ago Up 3 seconds 0.0.0.0:9001->80/ TCP adminCopy the code
The container is running, and you can access the container through the server IP address + port 9001 (Mac address, Windows directly localhost:9001).
The above generates containers, which can also be run with a command
$ docker run -p 9001:80 --name admin admin:v1
Copy the code
5.3 Deleting a Container
To delete a container, run the following command
$ docker rm admin # id or name
Copy the code
Stop the container if it is running
$ docker stop admin
Copy the code
Or forcibly delete
$ docker rm -f admin
Copy the code
Stop all containers
$ docker stop $(docker ps -aq)
Copy the code
Delete all containers
$ docker rm $(docker ps -aq)
Copy the code
Stop and delete all containers
$ docker stop $(docker ps -aq) & docker rm $(docker ps -aq)
Copy the code
5.4 Container Logs
If the container fails to run, you can view the logs to locate the error
$ docker logs admin
Copy the code
5.5 Entering the Container
A container is like a file system, and we can also go inside and look at the files inside. Use the following command to enter the container
$ docker exec -it admin /bin/sh
Copy the code
-i
The argument keeps the container’s standard input on, –interactive-t
The argument lets Docker assign a dummy terminal and bind it to the container’s standard input, –tty- Admin: indicates the container ID or name
Once inside the container, you can access the internal files using Linux commands
$ ls
bin boot dev docker-entrypoint.d docker-entrypoint.sh etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
$ cd usr/share/nginx/html
$ ls
50x.html asset-manifest.json favicon.ico index.html manifest.json robots.txt static
Copy the code
The default nginx HTML directory is usr/share/nginx/ HTML, and you can see the file we copied from the Dockfile
6. docker-compose
Docker-compose can be composed by using a simple command. Of course, this is only a small part of its functions. Docker-compose can be composed by using a simple command.
The official synopsis is as follows:
Compose is a tool for defining and running multi-container Docker applications. With Compose, you can use YAML files to configure your application’s services. Then, with a single command, you can create and start all the services from the configuration.
Using Compose is basically a three-step process:
- Use Dockerfile to define the application’s environment so that it can be copied anywhere.
- Define the services that make up your application in docker-comemage.yml so that they can run together in an isolated environment.
- Run docker-compose up, and compose starts up and runs the entire application.
6.1 installation docker – compose
Refer to the official documentation Install Docker Compose for a brief introduction to Linux installation
-
Run the command
Sudo curl - L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname - s) - $(uname -m)" - o /usr/local/bin/docker-composeCopy the code
If the installation is slow, you can download it using DaoCloud
Sudo curl -l https://get.daocloud.io/docker/compose/releases/download/1.25.1/docker-compose- ` ` uname - s - ` uname -m ` - o /usr/local/bin/docker-composeCopy the code
-
Add executable permissions
sudo chmod +x /usr/local/bin/docker-compose Copy the code
-
Check whether the installation is complete
docker-compose --version Copy the code
6.2 docker – compose. Yml
Docker-compose. Yml is docker-compose runtime file, which is configured with some parameters of the image and container, here to implement the above image creation, generate container, run container.
version: '3'
services:
admin:
build:
context: ../
dockerfile: ./docker/Dockerfile
image: admin:v1
ports:
- 9001: 80
container_name: admin
Copy the code
Configuration parameters have many docs.docker.com/compose/com… , the official website can be explained in detail, here and later only talk about some of the configuration used.
- Varsion: Optional 1, 2, 2.x, 3.x
- Services: indicates a service group
- Admin: service name, unique, multiple docker-comemage. yml have the same name, the following container will overwrite
- Docker-comemage. yml, Dockfile, Dockfile, Dockfile, and docker-comemage. yml If docker-comemage. yml and Dockfile are stored in the docker folder, specify the build context context and dokcerfile
- Context: Build context
- Dockerfile: Specifies the path to the dockerfile
- Image: Specifies the image to use. If the image exists, it will be used directly, otherwise it will be built using the dockerfile above
- Ports: Multiple ports can be mapped. In the file – means the argument is an array, and can be multiple
- Container_name: specifies the name of the container. if not specified, this defaults to the current directory _admin_index.
- Admin: service name, unique, multiple docker-comemage. yml have the same name, the following container will overwrite
Put docker-comemage. yml into the docker directory
├─admin └─build ├─ index.html ├─ docker ├─ docker-teach.ymlCopy the code
Run in the docker directory
$ docker-compose up -d --build
Copy the code
- -d: indicates the daemon running in the background. If no -d is added, the build process will be displayed. Finally, you can only exit with Ctrl + C, and the container will stop and start again
- –build: indicates that the Dockerfile will be re-executed for each build (NPM package will be re-installed). Otherwise, if the image exists, the Dockerfile will not be executed
Docker-compose is in the same directory as build
├─admin └─build ├─ index.html ├─ docker-teach.txtCopy the code
The docker – compose. Yml
version: '3'
services:
admin:
build: . /
image: admin:v1
ports:
- 9001: 80
container_name: admin
Copy the code
Run it in the build directory
$ docker-compose up -d --build
Copy the code
The word is over, to be continued, deployment ~