preface

Most of us have probably encountered the problem of a feature being developed locally and then deployed to the server, or being pulled locally by someone else to continue development.

Most of the time is due to the system is different, dependent on the emergence of differences caused by. Therefore, in order to solve this problem, the need to build a unified development environment based on Docker arose.

Benefits of using Docker

  • Easy to deploy: it usually takes several hours to set up the environment, and for team collaboration, every new person comes in, it needs to waste the avoidable time, and when setting up the environment, it often produces various problems, leading to the abnormal operation of the project code. If Docker is used, the initial person only needs to write the development container, and others just need to pull down, and the construction of the project environment can be completed, which can effectively avoid meaningless time waste.
  • Isolation: We often deploy multiple project environments on a computer. If we install them directly, they may cause interference with each other. For example, one project needs Node.js 14, while another needs Node.js 12. Docker also ensures that each application uses only the resources allocated to it (including CPU, memory, and disk space). A particular piece of software will not use all of your available resources, or it will degrade performance or even stop other applications working altogether.

implementation

Install the Docker

Linux

I use Arch Linux, so the installation below is based on Arch Linux, and the other distributions are pretty much the same, just with their package management tools.

# Set up domestic mirror station, domestic speed, optional operation
$ sudo pacman-mirrors -i -c China -m rank

Install Docker with Pacman
$ sudo pacman -S docker

Create a docker user group. By default, docker commands communicate with the Docker engine using Unix sockets. Only root users and docker group users can access the Unix socket of the Docker engine. For security reasons, the root user is not directly used on Linux. Therefore, it is better to add the users who need to use Docker to the Docker user group.
$ sudo groupadd docker

Add the current user to the Docker group, exit the terminal and log in again
$ sudo usermod -aG docker $USER

Verify that the installation is successful
$ docker run --rm hello-world
Copy the code

Windows 10

Windows 10 docker installation is relatively simple, there are the following ways:

Manual Download and Installation

Click the link below to download Docker Desktop for Windows.

Double-click Docker Desktop Installer.exe to start the installation.

usewingetThe installation
$ winget install Docker.DockerDesktop
Copy the code
run

Enter Docker in the Windows search bar and click Docker Desktop to start running.

When Docker starts, the whale icon appears in the Windows taskbar.

Wait for a moment, when the whale icon is still, it means Docker started successfully, then you can open PowerShell/CMD/Windows Terminal to use Docker.

macOS

Install using Homebrew

Homebrew Cask already supports Docker Desktop for Mac, so it can be easily installed using Homebrew Cask:

$ brew install --cask docker
Copy the code
Manual Download and Installation

If you need to download it manually, please click the link below to download Docker Desktop for Mac.

Please note that the software of the corresponding chip type is downloaded. The corresponding versions of M1 and Intel chips are not universal.

As with other macOS software, installation is as simple as double-clicking on the downloaded.dmg file and dragging the whale icon called Moby into the Application folder (requiring a user password).

run

Find the Docker icon from the app and click Run.

After running, you will see a whale icon in the upper right corner of the menu bar, this icon indicates the running status of Docker.

Every time you click on the whale icon, the action menu pops up.

After that, you can check the installed Docker version by running commands on the terminal.

$ docker --version
Copy the code

Write Dockerfile

With Docker installed, it’s time to write our own project development environment. This article takes the previous development environment as an example to build Dockerfile.

Included environment:

  • Node. Js 14.17
  • NPM 6.14
  • Yarn of 1.22
# In front-end development, shell commands are often needed, and it is important to have a relatively complete environment, so I choose Ubuntu as the base. If you care about the container size, you can choose the suitable base image by yourself
FROM ubuntu
MAINTAINER Caster "[email protected]"

Set environment variables
ENV DEBIAN_FRONTEND noninteractive

# Set time zone
ARG TZ=Asia/Shanghai
ENV TZ ${TZ}

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

Run the following command as user root
USER root

# Change Ali Yunyuan, can speed up in China
RUN sed -i "s/security.ubuntu.com/mirrors.aliyun.com/" /etc/apt/sources.list && \
    sed -i "s/archive.ubuntu.com/mirrors.aliyun.com/" /etc/apt/sources.list && \
    sed -i "s/security-cdn.ubuntu.com/mirrors.aliyun.com/" /etc/apt/sources.list
RUN  apt-get clean

Update the source and install the appropriate tools
RUNapt-get update && apt-get install -y \ zsh \ vim \ wget \ curl \ python \ git-core

Install ZSH to make it easier to use the shell when entering containers
RUN git clone https://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh \
    && cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc \
    && git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions \
    && git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting \
    && sed -i 's/^plugins=(/plugins=(zsh-autosuggestions zsh-syntax-highlighting z /' ~/.zshrc \
    && chsh -s /bin/zsh

# create me user
RUN useradd --create-home --no-log-init --shell /bin/zsh -G sudo me 
RUN adduser me sudo
RUN echo 'me:password' | chpasswd

Install OMZ for me
USER me
RUN git clone https://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh \
    && cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc \
    && git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions \
    && git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting \
    && sed -i 's/^plugins=(/plugins=(zsh-autosuggestions zsh-syntax-highlighting z /' ~/.zshrc

Install NVM and Node
ENV NVM_DIR /home/me/.nvm
ENV NODE_VERSION v14
RUN mkdir -p $NVM_DIR && \
    curl -o- https://gitee.com/mirrors/nvm/raw/master/install.sh | bash \
        && . $NVM_DIR/nvm.sh \
        && nvm install ${NODE_VERSION} \
        && nvm use ${NODE_VERSION} \
        && nvm alias ${NODE_VERSION} \
        && ln -s `npm bin --global` /home/me/.node-bin \
        && npm install --global nrm \
        && nrm use taobao

USER me
RUN echo ' ' >> ~/.zshrc \
    && echo 'export NVM_DIR="$HOME/.nvm"' >> ~/.zshrc \
    && echo '[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm' >> ~/.zshrc

# installation of yarn
RUN curl -o- -L https://yarnpkg.com/install.sh | bash; \
    echo ' ' >> ~/.zshrc && \
    echo 'export PATH="$HOME/.yarn/bin:$PATH"' >> ~/.zshrc

# Add NVM binaries to root's .bashrc
USER root

RUN echo ' ' >> ~/.zshrc \
    && echo 'export NVM_DIR="/home/me/.nvm"' >> ~/.zshrc \
    && echo '[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm' >> ~/.zshrc

USER root

RUN echo ' ' >> ~/.zshrc \
    && echo 'export YARN_DIR="/home/me/.yarn"' >> ~/.zshrc \
    && echo 'export PATH="$YARN_DIR/bin:$PATH"' >> ~/.zshrc

# Add PATH for node
ENV PATH $PATH:/home/me/.node-bin

# Add PATH for YARN
ENV PATH $PATH:/home/me/.yarn/bin

# Delete apt/lists, you can reduce the final image size, see details: https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#general-guidelines-and-recommendations
USER root
RUN rm -rf /var/lib/apt/lists/*

WORKDIR /var/www
Copy the code

After writing the Dockerfile, build:

docker build -t frontend/react:v1 .
Copy the code

Once built, you can run it directly:

# Run as me, recommended
docker run --user=me -it frontend/react:v1 /bin/zsh

Run as root
docker run -it frontend/react:v1 /bin/zsh
Copy the code

Write the docker – compose. Yml

In development, we usually need to use multiple containers together. For example, when we need to use mysql or other containers, docker-comemage. yml can better organize them.

version: '2'
services:
  react:
    build:
      context: .
      dockerfile: react/Dockerfile
    tty: true
    ports:
      - 30000: 3000
    volumes:
      - ./react/www:/var/www
    networks:
      - frontend
  mysql:
    image: Mysql: 5.7
    ports:
      - 33060: 3306
    volumes:
      - ./mysql/data:/var/lib/mysql
      - ./mysql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
    environment:
      - MYSQL_ROOT_PASSWORD=password
    networks:
      - frontend

The container can be accessed directly by the container name
networks:
  frontend:
    driver: bridge
Copy the code

Start the container

After playing with Dockerfile and docker-comemage. yml, you can happily start developing!

Docker-comemess. yml = docker-comemess. yml
cd frontend

Docker-composemess. yml: all containers in docker-composemess. yml will be built first if the container is not already built
docker compose up -d

Enter the React container for command-line interaction
docker compose exec --user=me react /bin/zsh
Copy the code

To test whether containers can access each other, you can write the following file, which the database needs to create itself:

// index.js
const mysql = require('mysql')
const connection = mysql.createConnection({
	host: 'mysql'.user: 'root'.password: 'password'.database: 'test',
})

connection.connect();

connection.query(`SELECT * FROM users`.function (error, results, fields) {
  if (error) throw error;
  console.log(results)
})

connection.end();
Copy the code

Then run it and see the result:

$ node index.js
[ RowDataPacket { id: 1.name: 'Caster'}]Copy the code

conclusion

It is very convenient to use Docker to build a development environment. Once built, it can be used for many times on many machines. Even if the system needs to be reinstalled, there is no need to configure it repeatedly.

If you do not like to write Dockerfile, you can also directly open a container, and then enter the container after configuration, use docker save/export export can be exported.

Source: github.com/MoeCasts/do…

Synchronization in

  • Personal blog: www.tore.moe/post/build-…
  • Language finch: www.yuque.com/docs/share/…