This article takes you through deploying a complete front – and back-end separation project, starting with a brand new CentOS server. Operation steps are very detailed, novice friendly article ~

Backend technology stack: SpringCloud microservices + Redis + RabbitMQ + MySql;

Front-end technology stack: Vue + ElementUI;

Deployment tool: Docker container is used for back-end deployment, and the command is encapsulated into scripts for automatic execution; The front end uses Nginx as a proxy.

First, preliminary preparation

The system version is CentOS 7.6 64-bit.

1.1 Connecting to the Server

To operate on a remote server, you must first connect to the server. To remotely connect to the server, open the command line tool and enter the following command and the password of the server instance.

ssh [email protected]
Copy the code

After @ is the public IP address of the server. If the server IP address is 120.456.78.123, run the following command to connect to the server:

SSH [email protected]Copy the code

After hitting enter, you will be asked to enter the password. Enter the correct password.

1.2 installation Docker

The advantages of Docker container deployment are not discussed, but how to install Docker directly.

Copy the command from the code box to the command line.

Remove the old version first (if any) :

sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-selinux \
                  docker-engine-selinux \
                  docker-engine
Copy the code

Install the necessary tools:

sudo yum install -y yum-utils device-mapper-persistent-data lvm2
Copy the code

Adding software source information:

sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
Copy the code

Update the yum cache:

sudo yum makecache fast
Copy the code

Install the Docker – ce:

sudo yum -y install docker-ce
Copy the code

Start the Docker background service

sudo systemctl start docker
Copy the code

Test run helloworld (this step is optional, the purpose is to verify the identity of the Docker successfully installed, if successful, will print Hello world)

docker run hello-world
Copy the code

Install mysql 1.3

Pull the mirror for mysql5.7 version

Docker pull mysql: 5.7Copy the code

Running MySql

docker run -p 3306:3306 --name mysql -v $PWD/conf:/etc/mysql/conf.d -v $PWD/logs:/logs -v $PWD/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -dMysql: 5.7Copy the code

Command description:

  • -p 3306:3306: maps port 3306 of a container to port 3306 of a host.
  • – v $PWD/conf: / etc/mysql/conf. D: will host the current directory of the conf/my CNF mounted to the container of the/etc/mysql/my CNF.
  • -v $PWD/logs:/logs: Mounts the logs directory under the current directory of the host to /logs of the container.
  • -v $PWD/data:/var/lib/mysql: mount the data directory in the current host directory to /var/lib/mysql in the container.
  • **-e MYSQL_ROOT_PASSWORD=123456: ** Initialize the password of user root.

Be careful to switch to the appropriate directory before running, because the directory the MySql container maps to native is a relative directory to the current directory mapped. For example, if the current directory is /root/abc, directories and files mounted by MySql will be created in /root/abc after the preceding command is executed.

1.4 installation redis

You can also run the command directly. If the system detects that the image is not installed, it will pull the image and run it again.

Download and run Redis :4.0.8:

Docker run -P 6379:6379-t-dit Redis :4.0.8Copy the code

1.5 install the RabbitMQ

Install and run rabbitmq:3.7.7:

docker run -d--hostname my-rabbit -P 5672:5672 -p 15672:15672 RabbitMQ :3.7.7- ManagementCopy the code

The pre-environment preparation tools to deploy the microservice back-end project here have been completed. If you want to deploy the front end, you also need to install Nginx, which will be covered in the front end deployment section.

Back-end deployment

There are two things you need to do to deploy the backend, one is to modify the application. Yml configuration file for each microservice module, and the other is to write the Dockerfile.

First look at the directory structure:

There are altogether 5 modules, among which common is pure Java code used to extract the common code of each module, and the remaining four are independent micro-service modules, so we need to deploy eureka, User, Education and Gateway modules. That is, you end up running four separate Docker containers.

I won’t go into the details of the business logic, this article is just about deployment.

2.1 Configuration Fileapplication.yml

In order to keep local debugging and server deployment together, we split the original application.yml into three files:

  • application.yml: General configuration, specifying which of the following configuration should be used
  • application-dev.yml: Development environment configuration
  • application-pro.yml: Generates the environment configuration

Also for convenience, put Dockerfile in the same directory. As shown in figure:

Here is the code for the three configuration files:

application.yml

spring:
  profiles:
    active: pro

Copy the code

application-dev.yml

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true

server:
  port: 8899

spring:
  application:
    name: education
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: 123456
    url: JDBC: mysql: / / 127.0.0.1 / edu? characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
  jpa:
    show-sql: true
  If the field value is null, no return is returned
  jackson:
    default-property-inclusion: non_null

  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest

  redis:
    port: 6379
    database: 0
    host: 127.0. 01.
    password:
    jedis:
      pool:
        max-active: 8
        max-wait: - 1ms
        max-idle: 8
        min-idle: 0
    timeout: 5000ms

Copy the code

application-pro.yml

eureka:
  client:
    service-url:
      defaultZone: ${SPRING-CLOUD-EUREKA-ZONE}
  instance:
    prefer-ip-address: true

server:
  port: 8899

spring:
  application:
    name: education
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: 123456
    url: jdbc:mysql://${SPRING-CLOUD-MYSQL-HOST}/${SPRING-CLOUD-DB-NAME}? characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
  jpa:
    show-sql: true
  If the field value is null, no return is returned
  jackson:
    default-property-inclusion: non_null

  rabbitmq:
    host: ${SPRING-CLOUD-RABBIT-MQ-HOST}
    port: 5672
    username: guest
    password: guest

  redis:
    port: 6379
    database: 0
    host: ${SPRING-CLOUD-REDIS-HOST}
    password:
    jedis:
      pool:
        max-active: 8
        max-wait: - 1ms
        max-idle: 8
        min-idle: 0
    timeout: 5000ms
Copy the code

This project has complete configuration, redis, rabbitMQ, mysql, JPA all have configuration.

Localhost = 127.0.0.1; localhost = 127.0.0.1; ${spring-cloud-eureka-zone}, ${spring-cloud-rabbit-mq-host}, etc.

So where are these variables set? When writing Dockerfile, you can see that these variables will be set as environment variables in Dockerfile. When starting the Docker container, the program will read the value set in Dockerfile and apply it to the project.

2.2 write Dockerfile

Below is the Dockerfile for the Education module

FROM java:8
VOLUME /tmp
ADD education.jar app.jar
RUN bash -c 'touch /app.jar'

ENV SPRING-CLOUD-EUREKA-ZONE http://123.456.789.10:8761/eureka/
ENV SPRING-CLOUD-MYSQL-HOST 123.456.789.10
ENV SPRING-CLOUD-DB-NAME edu
ENV SPRING-CLOUD-RABBIT-MQ-HOST 123.456.789.10
ENV SPRING-CLOUD-REDIS-HOST 123.456.789.10

ENTRYPOINT ["java"."-Djava.security.egd=file:/dev/./urandom"."-jar"."/app.jar"]
EXPOSE 8899
Copy the code

Briefly explain what each sentence does

FROM Java :8: Specifies the base image, must be the first command

VOLUME/TMP: specifies the persistent directory

Jar: ADD the local file education.jar to the container and name it app.jar. Jar: ADD abc.jar app.jar: ADD abc.jar app.jar: ADD abc.jar app.jar: ADD abc.jar app.jar

RUN bash -c ‘touch /app.jar’ : RUN the command in the image container to RUN the JAR package.

ENV *** : These lines start with ENV to set environment variables. Remember the ${} variables in the application-pro.yml file above? That’s where it’s set up. This configuration assumes that the address of your server is 123.456.789.10. When using this address, change it to your own server address.

ENTRYPOINT *** : Configure the container to make it executable.

EXPOSE 8899: exposes port 8899 to the public. This port must be the same as that set in the server. Port in the project configuration file.

To summarize, there are only three things you need to change in Dockerfile:

  • The third line education.jar is the name of the jar package you packaged
  • ENV environment variables start with their ownapplication-pro.ymlTo set the configuration
  • The last lineEXPOSE 8899Change the port number for your project

Add another module’s Dockerfile for comparison:

FROM java:8
VOLUME /tmp
ADD gateway.jar app.jar
RUN bash -c 'touch /app.jar'

ENV SPRING-CLOUD-EUREKA-ZONE http://123.456.789.10:8761/eureka/
ENV SPRING-CLOUD-REDIS-HOST 123.456.789.10

ENTRYPOINT ["java"."-Djava.security.egd=file:/dev/./urandom"."-jar"."/app.jar"]
EXPOSE 8888
Copy the code

In this way, write the Dockerfile for each microservice project that needs to be packaged.

2.3 packaging

Configure the three applicaton. yml and Dockerfile (Dockerfile is not needed for packaging), and execute the following command in the project root directory:

mvn clean package -Dmaven.test.skip=true
Copy the code

If you see the console output SUCCESS, the package is successful

The finished package is in the project directory /target, as shown below:

Check the size of the jar package. If it is tens of MB, there is no problem. If it is hundreds of MB, there is a problem with the package configuration.

Attached

configuration:

<build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <executions>
          <execution>
            <goals>
              <goal>repackage</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
    <finalName>education</finalName>
  </build>
Copy the code

2.4 Write automatic scripts

After writing the Dockerfile file, you need to execute commands to package it into image images, and also need to run the container. Although two lines of code are not many, it is still troublesome to write each time. Encapsulate it into an SH script, and run the script directly each time to save time and effort.

Create the education_deploy.sh file and place two lines of code in it:

docker build -t education .
docker run -p 8899:8899 -t -dit --restart=always education
Copy the code

Note that there is a dot at the end of the first line. If you want to call the typed mirror ABC and expose port 6666, you should write:

docker build -t abc .
docker run -p 6666:6666 -t -dit --restart=always abc
Copy the code

2.4 Uploading files to the Server

Create a new folder and a new folder for each microservice module to store JAR packages, Dockerfiles and automated deployment files. The directory structure is shown as follows:

To compress back_end, run the following command:

tar -cvf back_end.tar ./back_end
Copy the code

After the command is executed, the back_end.tar file is displayed in the directory.

Use SSH to log in to the server, create an EDU folder under the root directory, go to this folder, view the current directory, remember this directory

// create a folder edu mkdir edu // and go to the edu foldercdEdu// If you view the current directory, /root/edu is displayedpwd
Copy the code

Tar to the /root/edu directory on the server where back_end.tar was compressed.

SCP back_end. Tar [email protected]: / root/eduCopy the code

After uploading, unpack it on the server

tar -xvf back_end.tar
Copy the code

Then go to each module folder one by one and execute the SH script

sh ./education_deploy.sh
Copy the code

The back-end microservice is deployed when it is all run!

2.5 Common Docker Commands

After deployment, check whether the deployment is correct. First check from Docker, and finally enter the interface address in the browser to see whether it can be adjusted.

The following commands are executed on the CentOS server.

Check the current running containers to see if mysql, Redis, rabbitMQ and your own projects are running

docker ps
Copy the code

See the log

To enter the container to view the log:

Docker logs container IDCopy the code

For example, to view the container logs whose container ID is 378AF204F7BC, run the following command:

docker logs 378af204f7bc
Copy the code

If the container is run for a long time, many logs will be generated. Using docker logs directly will print all the logs. Can only print the last number of lines or logs from a certain time ago? B: Sure.

To view the log after the specified time, only the last 100 lines are displayed:

docker logs -f -t --since="2019-10-24" --tail=100 CONTAINER_ID
Copy the code

Print only the last 50 lines of the log:

Docker logs --tail=50 Container idCopy the code

View logs generated in the last 30 minutes:

Docker logs --since 30M container IDCopy the code

To view logs after a certain time:

docker logs -t --since="2019-10-24T13:23:37" CONTAINER_ID
Copy the code

Viewing logs of a specified period:

docker logs -t --since="2019-10-24T13:23:37" --until "2019-10-25T12:23:37" CONTAINER_ID
Copy the code

Stop and start

Stop the container

Docker stop Container IDCopy the code

View all containers (including stopped ones)

docker ps -a
Copy the code

Restart the container (the container was stopped, but not deleted)

Docker start Container IDCopy the code

Delete containers and images

If the project changes, it is best to delete the previous container, image, and then run the new container.

Let’s stop the container

Docker stop Container IDCopy the code

Delete the container again

Docker RM Container IDCopy the code

View image

docker images
Copy the code

Remove the mirror

Docker RMI image IDCopy the code

Third, front-end deployment

Package the front-end project, compress it into a tar file, and send it to the server, where it is decompressed.

To use nginx as a proxy, you need to install Nginx first

3.1 install nginx

Start by downloading and installing the base library

yum -y install gcc gcc-c++ autoconf pcre pcre-devel make automake
yum -y install wget httpd-tools vim
Copy the code

Install nginx

sudo yum install nginx
Copy the code

3.2 configure nginx

Nginx configuration file directory

Nginx main configuration file/etc/nginx/nginx. Conf/etc/nginx/etc/nginx/conf. D/etc/nginx/conf. D/default. ConfCopy the code

What is the default configuration of nginx.conf

# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local]. ""$request"'
                      '$status $body_bytes_sent "$http_referer"'
                      '"$http_user_agent""$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80 default_server;
        listen[: :] :80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location/ {}error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

# Settings for a TLS enabled server.
#
# server {
# listen 443 ssl http2 default_server;
# listen [::]:443 ssl http2 default_server;
# server_name _;
# root /usr/share/nginx/html;
#
# ssl_certificate "/etc/pki/nginx/server.crt";
# ssl_certificate_key "/etc/pki/nginx/private/server.key";
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 10m;
# ssl_ciphers HIGH:! aNULL:! MD5;
# ssl_prefer_server_ciphers on;
#
# # Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
#
# location / {
#}
#
# error_page 404 /404.html;
# location = /40x.html {
#}
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
#}
#}

}
Copy the code

Nginx. conf server, we still listen on port 80, change server_name to your domain name, then change location, root to the directory where the front-end file resides, and index to the entry file.

location / {
    root	/root/edu/front_end/;
    index	index.html index.htm;
}
Copy the code

Just make these two changes and leave the rest untouched.

server {
    listen       80 default_server;
    listen[: :] :80 default_server;
    server_name  www.abc.cn abc.cn;
    root         /usr/share/nginx/html;

  # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;

    location / {
        root	/root/edu/front_end/;
        index	index.html index.htm;
    }

        error_page 404 /404.html;
        location = /40x.html {
    }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }
}
Copy the code

Successful indicates that the nginx configuration file has no syntax errors

nginx -t -c /etc/nginx/nginx.conf
Copy the code

Reload configuration

nginx -s reload -c /etc/nginx/nginx.conf
Copy the code

3.3 Nginx error handling

[error] open() “/var/run/nginx.pid” failed

Nginx: [error] open() “/var/run/nginx.pid” failed (2: No such file or directory)

Solution: Execute the following two lines of code in sequence

sudo nginx -c /etc/nginx/nginx.conf
nginx -s reload
Copy the code

The browser accesses report 403

Error 403: nginx error 403: nginx error 403: nginx error 403: nginx error 403 Error_log /var/log/nginx/error.log; error_log /var/log/nginx/error.log;

Run the cat command to view the file contents

cat /var/log/nginx/error.log
Copy the code

If Permission denied is reported, there is a good chance that the current logged-in user does not match the user declared in the first line of the nginx.conf file.

Connect () to 127.0.0.1:8000 failed (13: Permission denied)....Copy the code

Will the user nginx; To the user root; Reloading the configuration again is usually enough.


That’s all about deploying the front and back end. If you have any questions, please share them in the comments section.