How to deploy your own project using docker

Keywords: PHP Docker Container

How to deploy your own project using docker?

A while ago, the company had a need to deploy the project to the local privatization. I didn't study the server and it was very laborious to build it, so I used docker to make a series of images of project privatization deployment. Now I write a blog to record the process of learning and building.

Take my current project for example, which is divided into front-end (vue Implementation), back-end (PHP laravel framework), OnlineJudge (online problem judgment), and data layer and cache (mysql, redis). The idea is to first create an image for each project, upload it to the docker hub, and then use docker compose for one click deployment

Create a mirror for the Laravel project

  1. Enter the project directory and create a dockerfile file with the following contents
FROM php:7.4-fpm

RUN  sed -i 's/deb.debian.org/mirrors.aliyun.com/' /etc/apt/sources.list && \
    sed -i 's/security.debian.org/mirrors.aliyun.com/' /etc/apt/sources.list && \
    sed -i 's/security-cdn.debian.org/mirrors.aliyun.com/' /etc/apt/sources.list

RUN sed -i 's/9000/\/run\/php\/php7.4-fpm.sock/' /usr/local/etc/php-fpm.d/zz-docker.conf

RUN mkdir /run/php \
    && touch /run/php/php7.4-fpm.sock \
    && chmod 777 /run/php/php7.4-fpm.sock \
    && chmod +s /run/php/php7.4-fpm.sock

#### install PHP extend ######################

RUN pecl install redis-5.1.1 && \
     docker-php-ext-enable redis

RUN docker-php-ext-install pdo && \
     docker-php-ext-install pdo_mysql && \
     docker-php-ext-enable pdo pdo_mysql

#### install nginx and supervisor extend ######################

RUN apt-get update -yqq && \
    apt-get install -yqq \
        nginx supervisor cron

RUN echo "* * * * * cd /var/www/kaoshi.web.server && php artisan schedule:run >> /dev/null 2>&1" >> /etc/crontab

#### Copy profile to mirror ######################

COPY ./ /var/www/kaoshi.web.server/
COPY ./php-fpm/www.conf /usr/local/etc/php-fpm.d/
COPY ./sites/default /etc/nginx/sites-enabled/
COPY ./supervisor.conf /etc/supervisor/conf.d/

###### modify laravel Various configurations of the project #########################
RUN chown -R www-data:www-data /var/www/kaoshi.web.server \
    && mv /var/www/kaoshi.web.server/.env.docker /var/www/kaoshi.web.server/.env

ENV MYSQL_HOST=127.0.0.1
ENV MYSQL_DATABASE=exam
ENV MYSQL_USER=root
ENV MYSQL_PASSWORD=root
ENV REDIS_HOST=127.0.0.1
ENV REDIS_PORT=6379
ENV JUDGE_SERVER_HOST=kaoshi_judge_server
ENV JUDGE_SERVER_PORT=8080

WORKDIR /var/www/kaoshi.web.server

ADD ./startup.sh /opt/startup.sh
RUN sed -i 's/\r//g' /opt/startup.sh
CMD ["/bin/bash", "/opt/startup.sh"]

EXPOSE 80

This file is relatively long. The general construction idea is based on php7.4 image. Switch apt get source - > install PHP extension - > install nginx and other required extensions - > copy various configuration files in the project directory - > set startup script - > set exposed port number.

Here, you need to use the ENV command to set various configurations of laravel, because these configurations can be freely modified when creating containers in docker compose later

  1. Write the startup script file. I started supervisor and crond additionally because the queue service is needed`
#!/bin/bash

sed -i "s/MYSQL_HOST/${MYSQL_HOST}/" /var/www/kaoshi.web.server/.env && 
    sed -i "s/MYSQL_DATABASE/${MYSQL_DATABASE}/" /var/www/kaoshi.web.server/.env && 
    sed -i "s/MYSQL_USER/${MYSQL_USER}/" /var/www/kaoshi.web.server/.env && 
    sed -i "s/MYSQL_PASSWORD/${MYSQL_PASSWORD}/" /var/www/kaoshi.web.server/.env && 
    sed -i "s/MYSQL_USER/${MYSQL_USER}/" /var/www/kaoshi.web.server/.env && 
    sed -i "s/MY_REDIS_HOST/${REDIS_HOST}/" /var/www/kaoshi.web.server/.env && 
    sed -i "s/MY_REDIS_PORT/${REDIS_PORT}/" /var/www/kaoshi.web.server/.env

supervisord -c /etc/supervisor/supervisord.conf

supervisorctl start all

# Start php-fpm cron in background
php-fpm -D

/etc/init.d/cron start

# Start nginx in foreground
nginx -g "daemon off;"

  1. Build image and upload

Preparatory work: Here you need to have a docker account. After passing the authentication, the constructed image is uploaded to your own image library.

Enter the project directory and execute the build command

> docker build -t youdockerid:backend_server ./

There are two ways to upload. You can directly use docker to log in and upload, or docker push can be very simple.

Foreground project construction image

The construction process is basically similar to the file, but the specific configuration is different. It can also be uploaded after the construction is completed

dockerfile:

FROM node:16.3

RUN  sed -i 's/deb.debian.org/mirrors.aliyun.com/' /etc/apt/sources.list && \
    sed -i 's/security.debian.org/mirrors.aliyun.com/' /etc/apt/sources.list && \
    sed -i 's/security-cdn.debian.org/mirrors.aliyun.com/' /etc/apt/sources.list 

RUN npm config set registry https://registry.npm.taobao.org

####### Copy project files ###########################################
COPY ./ /var/www/kaoshi.frontend/

####### install nginx ###########################################
RUN apt-get update -yqq && \
    apt-get install -yqq \
        nginx 

COPY ./sites/default /etc/nginx/sites-enabled/

RUN mv /var/www/kaoshi.frontend/nuxt.config.docker.js /var/www/kaoshi.frontend/nuxt.config.js \
    && npm install -g pm2


ENV LISTEN_HOST=127.0.0.1
ENV LISTEN_PORT=3306
ENV PROXY_HOST=api.kaoshi.test

WORKDIR /var/www/kaoshi.frontend

ADD ./startup.sh /opt/startup.sh
RUN sed -i 's/\r//g' /opt/startup.sh
CMD ["/bin/bash", "/opt/startup.sh"]

EXPOSE 80

startup.sh:

#!/bin/bash

sed -i "s/LISTEN_HOST/${LISTEN_HOST}/" /var/www/kaoshi.frontend/nuxt.config.js && 
sed -i "s/LISTEN_PORT/${LISTEN_PORT}/" /var/www/kaoshi.frontend/nuxt.config.js &&
sed -i "s/PROXY_HOST/${PROXY_HOST}/" /var/www/kaoshi.frontend/nuxt.config.js &&
sed -i "s/LISTEN/http:\/\/${LISTEN_HOST}:${LISTEN_PORT}/" /etc/nginx/sites-enabled/default

cd /var/www/kaoshi.frontend && pm2 start npm --name "kaoshi" -- start 

# Start nginx in foreground
nginx -g "daemon off;"

Build:

> docker build -t youdockerid:fronend_server ./

Write docker compose one click deployment

  1. First, create a new directory as the deployment directory. The directory structure is as follows
├── .env                                  //configuration file
├── .env.example
├── data																	//The data of mysql or redis or other modules are stored here
│   ├── mysql
│   └── redis
│       └── appendonly.aof
├── docker-compose.yml										//Deployment file
└── initdb.d															//Database initialization file
    └── init.sql			

docker-compose.yml:

version: '3.5'

networks:
    backend:
        driver: bridge
      
services:
### backend ##################################
    backend_server:
        container_name: backend_server
        image: yourdockerid/backend_server:latest
        restart: always
        networks:
            - backend
        environment:
            MYSQL_HOST: ${MYSQL_HOST}
            MYSQL_USER: ${MYSQL_USER}
            MYSQL_PASSWORD: ${MYSQL_PASSWORD}
            MYSQL_DATABASE: ${MYSQL_DATABASE}
            REDIS_HOST: ${REDIS_HOST}
            REDIS_PORT: ${REDIS_PORT}
            JUDGE_SERVER_HOST: ${JUDGE_SERVER_HOST}
            JUDGE_SERVER_PORT: ${JUDGE_SERVER_PORT}

### frontend ##################################
    frontend_server:
        container_name: frontend_server
        image: yourdockerid/frontend_server:latest
        restart: always
        ports:
            - "0.0.0.0:80:80"
        networks:
            - backend
        environment:
            LISTEN_HOST: ${FRONTEND_LISTEN_HOST}
            LISTEN_PORT: ${FRONTEND_LISTEN_PORT}

### mysql ##################################
    mysql_server:
        container_name: mysql_server
        image: mysql:8.0
        command: --default-authentication-plugin=mysql_native_password
        restart: always
        volumes:
            - ./data/mysql:/data
            - ./initdb.d:/docker-entrypoint-initdb.d
        networks:
            - backend
        environment:
            MYSQL_ROOT_PASSWORD: ${MYSQL_PASSWORD}
            MYSQL_DATABASE: ${MYSQL_DATABASE}

### redis ##################################
    redis_server:
        container_name: redis_server
        image: redis:5.0-alpine
        command: redis-server --appendonly yes
        restart: always
        networks:
            - backend
        volumes:
            - ./data/redis:/data

.env:

### MYSQL #################################################

MYSQL_HOST=mysql_server
MYSQL_USER=root
MYSQL_PASSWORD=root
MYSQL_DATABASE=example

### REDIS #################################################

REDIS_HOST=redis_server
REDIS_PORT=6379

### frontend #################################################

FRONTEND_LISTEN_HOST=127.0.0.1
FRONTEND_LISTEN_PORT=3306

When you're done, you can happily build:

> docker-composer up -d
Starting mysql_server              ... done
Starting redis_server              ... done
Starting frontend_server           ... done
Starting backend_server            ... done

be accomplished!

tail

Because it was made quite a long time ago, you may have forgotten to prompt some details about stepping on the pit. If you don't know anything or need correction, please leave a message

dockerhub: https://registry.hub.docker.com/

Posted by kye on Wed, 10 Nov 2021 11:56:29 -0800