
ΠΠ° Π₯Π°Π±ΡΠ΅ ΠΈΠΌΠ° ΠΌΠ½ΠΎΠ³ΠΎ ΡΡΠ°ΡΠΈΠΈ Π·Π° Jenkins, Π½ΠΎ ΠΈΠΌΠ° ΠΌΠ°Π»ΠΊΠΎ ΠΏΡΠΈΠΌΠ΅ΡΠΈ Π·Π° ΡΠ°Π±ΠΎΡΠ° Ρ Jenkins ΠΈ Docker Π°Π³Π΅Π½ΡΠΈ. ΠΡΠΈΡΠΊΠΈ ΠΏΠΎΠΏΡΠ»ΡΡΠ½ΠΈ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΈ Π·Π° ΠΈΠ·Π³ΡΠ°ΠΆΠ΄Π°Π½Π΅ Π½Π° ΠΏΡΠΎΠ΅ΠΊΡΠΈ ΠΊΠ°ΡΠΎ , , , ΠΈ Π΄ΡΡΠ³ΠΈ, ΠΌΠΎΠ³Π°Ρ Π΄Π° ΠΈΠ·Π³ΡΠ°ΠΆΠ΄Π°Ρ Π²ΡΠΈΡΠΊΠΎ Π² ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠΈ. ΠΠΎ ΠΊΠ°ΠΊΠ²ΠΎ Π΄Π° ΠΊΠ°ΠΆΠ΅ΠΌ Π·Π° Jenkins?
ΠΡΠΌ Π΄Π½Π΅ΡΠ½Π° Π΄Π°ΡΠ° ΠΈΠΌΠ° ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ Π½Π° ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ°: Jenkins 2 ΠΎΡΠ»ΠΈΡΠ½ΠΎ ΡΠ°Π±ΠΎΡΠΈ Ρ . Π ΡΡΠ°ΡΠΈΡΡΠ° ΠΈΡΠΊΠ°ΠΌ Π΄Π° ΡΠΏΠΎΠ΄Π΅Π»Ρ ΠΎΠΏΠΈΡ ΠΈ Π΄Π° ΠΏΠΎΠΊΠ°ΠΆΠ° ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π³ΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈΡΠ΅ ΡΠ°ΠΌΠΈ.
ΠΠ°ΡΠΎ ΡΠ΅ Π·Π°Π½ΠΈΠΌΠ°Π²Π°ΠΌ Ρ ΡΠ΅ΡΠ°Π²Π°Π½Π΅ΡΠΎ Π½Π° ΡΠΎΠ·ΠΈ ΠΏΡΠΎΠ±Π»Π΅ΠΌ?
Π’ΡΠΉ ΠΊΠ°ΡΠΎ Π² ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΡΡΠ° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ, Π½Π° ΡΡΡΠΎΠΈΡΠ΅Π»Π½Π°ΡΠ° ΠΌΠ°ΡΠΈΠ½Π° ΡΡΡΠ±Π²Π° Π΄Π° ΠΈΠΌΠ°ΠΌΠ΅ ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ Π²Π΅ΡΡΠΈΠΈ Π½Π° Node.JS, Gradle, Ruby, JDK ΠΈ Π΄ΡΡΠ³ΠΈ. ΠΠΎ ΡΠ΅ΡΡΠΎ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΠΈΠ·Π±Π΅Π³Π½Π΅ΠΌ ΠΊΠΎΠ½ΡΠ»ΠΈΠΊΡΠΈ ΠΌΠ΅ΠΆΠ΄Ρ Π²Π΅ΡΡΠΈΠΈΡΠ΅. ΠΠ°, ΠΏΡΠ°Π²ΠΈ ΡΡΠ΅, Π°ΠΊΠΎ ΠΊΠ°ΠΆΠ΅ΡΠ΅, ΡΠ΅ ΠΈΠΌΠ° ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ ΠΌΠ΅Π½ΠΈΠ΄ΠΆΡΡΠΈ Π½Π° Π²Π΅ΡΡΠΈΠΈ ΠΊΠ°ΡΠΎ nvm, rvm, Π½ΠΎ Π½Π΅ Π²ΡΠΈΡΠΊΠΎ Π΅ ΡΠΎΠ»ΠΊΠΎΠ²Π° ΠΏΡΠΎΡΡΠΎ Ρ ΡΡΡ ΠΈ ΡΠ΅Π·ΠΈ ΡΠ΅ΡΠ΅Π½ΠΈΡ ΠΈΠΌΠ°Ρ ΡΠ²ΠΎΠΈ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΈ:
- Π³ΠΎΠ»ΡΠΌΠΎ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΠ°Π½ΡΠ°ΠΉΠΌΠΎΠ²Π΅, ΠΊΠΎΠ΅ΡΠΎ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΡΠΈΡΠ΅ Π·Π°Π±ΡΠ°Π²ΡΡ Π΄Π° ΠΏΠΎΡΠΈΡΡΡΡ;
- ΠΈΠΌΠ° ΠΊΠΎΠ½ΡΠ»ΠΈΠΊΡΠΈ ΠΌΠ΅ΠΆΠ΄Ρ ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ Π²Π΅ΡΡΠΈΠΈ Π½Π° Π΅Π΄Π½ΠΈ ΠΈ ΡΡΡΠΈ ΡΠ°Π½ΡΠ°ΠΉΠΌΠΎΠ²Π΅;
- Π½Π° Π²ΡΠ΅ΠΊΠΈ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊ ΠΌΡ ΡΡΡΠ±Π²Π° ΡΠ°Π·Π»ΠΈΡΠ΅Π½ Π½Π°Π±ΠΎΡ ΠΎΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΈ.
ΠΠΌΠ° ΠΈ Π΄ΡΡΠ³ΠΈ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΈ, Π½ΠΎ ΠΏΠΎ-Π΄ΠΎΠ±ΡΠ΅ ΡΠ΅ ΡΠ°Π·ΠΊΠ°ΠΆΠ° Π·Π° ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ΡΠΎ.
Jenkins Π² Docker
Π’ΡΠΉ ΠΊΠ°ΡΠΎ Docker Π²Π΅ΡΠ΅ Π΅ Π΄ΠΎΠ±ΡΠ΅ ΡΡΠ²ΡΡΠ΄Π΅Π½ Π² ΡΡΠ΅ΡΠ°ΡΠ° Π½Π° ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ°ΡΠ°, ΠΏΠΎΡΡΠΈ Π²ΡΠΈΡΠΊΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΡΠ΄Π΅ ΡΡΠ°ΡΡΠΈΡΠ°Π½ΠΎ Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° Docker. ΠΠΎΠ΅ΡΠΎ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ Π΅ Π΄Π° ΠΈΠΌΠ°ΠΌΠ΅ Jenkins Π² Docker ΠΈ ΡΠΎΠΉ Π΄Π° ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΡΠ°ΡΡΠΈΡΠ° Π΄ΡΡΠ³ΠΈ Docker ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠΈ. Π’ΠΎΠ·ΠΈ Π²ΡΠΏΡΠΎΡ ΡΠ΅ Π·Π°Π΄Π°Π²Π° ΠΎΡΠ΅ ΠΏΡΠ΅Π· 2013 Π³ΠΎΠ΄ΠΈΠ½Π° Π² ΡΡΠ°ΡΠΈΡΡΠ° "Β«.
Π ΠΊΡΠ°ΡΡΠ΅, ΠΏΡΠΎΡΡΠΎ Π΅ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ Π² ΡΠ°Π±ΠΎΡΠ½ΠΈΡ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ Π΄Π° ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°ΡΠ΅ ΡΠ°ΠΌΠΈΡ Docker ΠΈ Π΄Π° ΠΌΠΎΠ½ΡΠΈΡΠ°ΡΠ΅ ΡΠ°ΠΉΠ»Π° /var/run/docker.sock.
ΠΡΠΎ ΠΏΡΠΈΠΌΠ΅Ρ Π½Π° Dockerfile, ΠΊΠΎΠΉΡΠΎ ΠΏΠΎΠ»ΡΡΠΈΡ ΠΌΠ΅ Π·Π° Jenkins.
FROM jenkins/jenkins:lts
USER root
RUN apt-get update &&
apt-get -y install apt-transport-https
ca-certificates
curl
gnupg2
git
software-properties-common &&
curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg > /tmp/dkey; apt-key add /tmp/dkey &&
add-apt-repository
"deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")
$(lsb_release -cs)
stable" &&
apt-get update &&
apt-get -y install docker-ce &&
usermod -aG docker jenkins
RUN curl -L https://github.com/docker/compose/releases/download/1.25.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose
RUN apt-get clean autoclean && apt-get autoremove βyes && rm -rf /var/lib/{apt,dpkg,cache,log}/
USER jenkinsΠΠΎ ΡΠΎΠ·ΠΈ Π½Π°ΡΠΈΠ½ ΠΏΠΎΠ»ΡΡΠΈΡ ΠΌΠ΅ Docker ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ, ΠΊΠΎΠΉΡΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠ·ΠΏΡΠ»Π½ΡΠ²Π° Docker ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π½Π° Ρ ΠΎΡΡ ΠΌΠ°ΡΠΈΠ½Π°ΡΠ°.
ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° Π½Π° ΠΈΠ·Π³ΡΠ°ΠΆΠ΄Π°Π½Π΅ΡΠΎ
ΠΠ΅ ΡΠΎΠ»ΠΊΠΎΠ²Π° ΠΎΡΠ΄Π°Π²Π½Π° Jenkins ΠΏΠΎΠ»ΡΡΠΈ Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡΠ° Π΄Π° ΠΎΠΏΠΈΡΠ²Π° ΠΏΡΠ°Π²ΠΈΠ»Π°ΡΠ° ΡΠΈ Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡ, ΠΊΠΎΠ΅ΡΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ²Π° ΡΡΠ°Π²Π½ΠΈΡΠ΅Π»Π½ΠΎ Π»Π΅ΡΠ½ΠΎ ΠΏΡΠΎΠΌΠ΅Π½ΡΠ½Π΅ Π½Π° ΡΠΊΡΠΈΠΏΡΠ° Π·Π° ΠΈΠ·Π³ΡΠ°ΠΆΠ΄Π°Π½Π΅ ΠΈ Π½Π΅Π³ΠΎΠ²ΠΎΡΠΎ ΡΡΡ ΡΠ°Π½Π΅Π½ΠΈΠ΅ Π² ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ.
ΠΠ΅ΠΊΠ° Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π² ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ ΡΠΏΠ΅ΡΠΈΠ°Π»Π΅Π½ Dockerfile, ΠΊΠΎΠΉΡΠΎ ΡΠ΅ ΡΡΠ΄ΡΡΠΆΠ° Π²ΡΠΈΡΠΊΠΈ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ Π·Π° ΠΈΠ·Π³ΡΠ°ΠΆΠ΄Π°Π½Π΅. ΠΠΎ ΡΠΎΠ·ΠΈ Π½Π°ΡΠΈΠ½ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΡΡ ΡΠ΅ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΏΠΎΠ΄Π³ΠΎΡΠ²ΠΈ ΠΏΠΎΠ²ΡΠΎΡΡΠ΅ΠΌΠ° ΡΡΠ΅Π΄Π° ΠΈ Π½ΡΠΌΠ° Π΄Π° Π΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° ΠΌΠΎΠ»ΠΈ OPS Π΄Π° ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ° ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π° Π²Π΅ΡΡΠΈΡ Π½Π° Node.JS Π½Π° Ρ ΠΎΡΡΠ°.
FROM node:12.10.0-alpine
RUN npm install yarn -gΠ’ΠΎΠ·ΠΈ ΡΠ±ΠΎΡΠ΅Π½ ΠΎΠ±ΡΠ°Π· Π΅ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΡΡ Π·Π° ΠΏΠΎΠ²Π΅ΡΠ΅ΡΠΎ Node.JS ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. Π Π°ΠΊΠΎ Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ Π²ΠΈ ΡΡΡΠ±Π²Π° ΠΎΠ±ΡΠ°Π· Π·Π° ΠΏΡΠΎΠ΅ΠΊΡ Π½Π° JVM Ρ Π²Π³ΡΠ°Π΄Π΅Π½ Sonar ΡΠΊΠ΅Π½Π΅Ρ? ΠΠΈΠ΅ ΡΠ°ΠΌΠΈ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΈΠ·Π±Π΅ΡΠ΅ΡΠ΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΈΡΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΈ Π·Π° ΠΈΠ·Π³ΡΠ°ΠΆΠ΄Π°Π½Π΅.
FROM adoptopenjdk/openjdk12:latest
RUN apt update
&& apt install -y
bash unzip wget
RUN mkdir -p /usr/local/sonarscanner
&& cd /usr/local/sonarscanner
&& wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-3.3.0.1492-linux.zip
&& unzip sonar-scanner-cli-3.3.0.1492-linux.zip
&& mv sonar-scanner-3.3.0.1492-linux/* ./
&& rm sonar-scanner-cli-3.3.0.1492-linux.zip
&& rm -rf sonar-scanner-3.3.0.1492-linux
&& ln -s /usr/local/sonarscanner/bin/sonar-scanner /usr/local/bin/sonar-scanner
ENV PATH $PATH:/usr/local/sonarscanner/bin/
ENV SONAR_RUNNER_HOME /usr/local/sonarscanner/bin/
ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ Π½Π° ΡΠ±ΠΎΡΠ½Π°ΡΠ° ΡΡΠ΅Π΄Π°, Π½ΠΎ ΠΊΠ°ΠΊΠ²Π° Π΅ Π²ΡΡΠ·ΠΊΠ°ΡΠ° Ρ Jenkins? Jenkins Π°Π³Π΅Π½ΡΠΈΡΠ΅ ΠΌΠΎΠ³Π°Ρ Π΄Π° ΡΠ°Π±ΠΎΡΡΡ Ρ ΡΠ΅Π·ΠΈ Docker ΠΎΠ±ΡΠ°Π·ΠΈ ΠΈ Π΄Π° ΠΏΡΠΎΠ²Π΅ΠΆΠ΄Π°Ρ ΡΠ±ΠΎΡΠΊΠ°ΡΠ° Π²ΡΡΡΠ΅ Π² ΡΡΡ .
stage("Build project") {
agent {
docker {
image "project-build:${DOCKER_IMAGE_BRANCH}"
args "-v ${PWD}:/usr/src/app -w /usr/src/app"
reuseNode true
label "build-image"
}
}
steps {
sh "yarn"
sh "yarn build"
}
}ΠΠΈΡΠ΅ΠΊΡΠΈΠ²Π° Π°Π³Π΅Π½Ρ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ docker, ΠΊΡΠ΄Π΅ΡΠΎ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΏΠΎΡΠΎΡΠΈΡΠ΅:
- ΠΈΠΌΠ΅ΡΠΎ Π½Π° ΡΠ±ΠΎΡΠ½ΠΈΡ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ ΡΡΠ³Π»Π°ΡΠ½ΠΎ Π²Π°ΡΠ°ΡΠ° ΠΏΠΎΠ»ΠΈΡΠΈΠΊΠ° Π·Π° ΠΈΠΌΠ΅Π½ΡΠ²Π°Π½Π΅;
- Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΈΡΠ΅, Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΈ Π·Π° ΡΡΠ°ΡΡΠΈΡΠ°Π½Π΅ Π½Π° ΡΠ±ΠΎΡΠ½ΠΈΡ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ, ΠΊΡΠ΄Π΅ΡΠΎ Π² Π½Π°ΡΠΈΡ ΡΠ»ΡΡΠ°ΠΉ ΠΌΠΎΠ½ΡΠΈΡΠ°ΠΌΠ΅ ΡΠ΅ΠΊΡΡΠ°ΡΠ° Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ ΠΊΠ°ΡΠΎ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ Π²ΡΡΡΠ΅ Π² ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ°.
Π Π² ΡΡΡΠΏΠΊΠΈΡΠ΅ Π·Π° ΠΈΠ·Π³ΡΠ°ΠΆΠ΄Π°Π½Π΅ ΠΏΠΎΡΠΎΡΠ²Π°ΠΌΠ΅ ΠΊΠΎΠΈ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π΄Π° ΠΈΠ·ΠΏΡΠ»Π½ΠΈΠΌ Π²ΡΡΡΠ΅ Π² ΡΠ±ΠΎΡΠ½ΠΈΡ Docker Π°Π³Π΅Π½Ρ. Π’ΠΎΠ²Π° ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΡΠ΄Π΅ Π²ΡΠΈΡΠΊΠΎ, ΠΏΠΎ ΡΠΎΠ·ΠΈ Π½Π°ΡΠΈΠ½ Π°Π· ΡΡΡΠΎ ΡΡΠ°ΡΡΠΈΡΠ°ΠΌ ΡΠ°Π·Π³ΡΡΡΠ°Π½Π΅ Π½Π° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° ansible.
ΠΠΎ-Π΄ΠΎΠ»Ρ ΠΈΡΠΊΠ°ΠΌ Π΄Π° ΠΏΠΎΠΊΠ°ΠΆΠ° ΠΎΠ±Ρ Jenkinsfile, ΠΊΠΎΠΉΡΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠ·Π³ΡΠ°Π΄ΠΈ ΠΏΡΠΎΡΡ Node.JS ΠΏΡΠΎΠ΅ΠΊΡ.
def DOCKER_IMAGE_BRANCH = ""
def GIT_COMMIT_HASH = ""
pipeline {
options {
buildDiscarder(
logRotator(
artifactDaysToKeepStr: "",
artifactNumToKeepStr: "",
daysToKeepStr: "",
numToKeepStr: "10"
)
)
disableConcurrentBuilds()
}
agent any
stages {
stage("ΠΡΠΈΠ³ΠΎΡΠ²Π΅ΡΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ Π½Π° ΡΠ±ΠΎΡΠΊΠ°ΡΠ°") {
steps {
sh "docker build -f Dockerfile.build . -t project-build:${DOCKER_IMAGE_BRANCH}"
}
}
stage("Π‘ΡΠ·Π΄Π°Π²Π°Π½Π΅ Π½Π° ΠΏΡΠΎΠ΅ΠΊΡΠ°") {
agent {
docker {
image "project-build:${DOCKER_IMAGE_BRANCH}"
args "-v ${PWD}:\/usr\/src\/app -w \/usr\/src\/app"
reuseNode true
label "build-image"
}
}
steps {
sh "yarn"
sh "yarn build"
}
}
post {
always {
step([$class: "WsCleanup"])
cleanWs()
}
}
}ΠΠ°ΠΊΠ²ΠΎ ΡΠ΅ ΠΏΠΎΠ»ΡΡΠΈ?
Π‘ ΡΠΎΠ·ΠΈ ΠΌΠ΅ΡΠΎΠ΄ ΡΠ΅ΡΠΈΡ ΠΌΠ΅ ΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΈ:
- Π²ΡΠ΅ΠΌΠ΅ΡΠΎ Π·Π° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠΈΡΠ°Π½Π΅ Π½Π° ΡΡΠ΅Π΄Π°ΡΠ° Π·Π° ΡΠ±ΠΎΡΠΊΠ° Π΅ ΡΠ²Π΅Π΄Π΅Π½ΠΎ Π΄ΠΎ 10 β 15 ΠΌΠΈΠ½ΡΡΠΈ Π·Π° ΠΏΡΠΎΠ΅ΠΊΡ;
- ΠΏΡΠ»Π½ΠΎ ΠΏΠΎΠ²ΡΠΎΡΡΠ΅ΠΌΠΎ ΡΡΠ΅Π΄Π° Π·Π° ΡΠ±ΠΎΡΠΊΠ° Π½Π° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ, ΡΡΠΉ ΠΊΠ°ΡΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΡΡΠ±ΠΈΡΠ° ΠΈ Π½Π° Π»ΠΎΠΊΠ°Π»Π΅Π½ ΠΊΠΎΠΌΠΏΡΡΡΡ;
- Π½ΡΠΌΠ° ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΈ Ρ ΠΊΠΎΠ½ΡΠ»ΠΈΠΊΡΠΈΡΠ΅ Π½Π° ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ Π²Π΅ΡΡΠΈΠΈ Π½Π° ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΈΡΠ΅ Π·Π° ΡΠ±ΠΎΡΠΊΠ°;
- Π²ΠΈΠ½Π°Π³ΠΈ ΡΠΈΡΡ ΡΠ°Π±ΠΎΡΠ΅Π½ ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²o, ΠΊΠΎΠ΅ΡΠΎ Π½Π΅ ΡΠ΅ Π½Π°ΡΠΎΠ²Π°ΡΠ²Π°.
Π‘Π°ΠΌΠΎΡΠΎ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ Π΅ ΠΏΡΠΎΡΡΠΎ ΠΈ ΠΎΡΠ΅Π²ΠΈΠ΄Π½ΠΎ ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ²Π° Π΄Π° ΠΏΠΎΠ»ΡΡΠΈΡΠ΅ ΡΠ°ΠΌΠΎ ΠΏΡΠ΅Π΄ΠΈΠΌΡΡΠ²Π°. ΠΠ°, Π²Ρ ΠΎΠ΄Π½ΠΈΡΡ ΠΏΡΠ°Π³ Π΅ ΠΌΠ°Π»ΠΊΠΎ ΠΏΠΎΠ²ΠΈΡΠ΅Π½ Π² ΡΡΠ°Π²Π½Π΅Π½ΠΈΠ΅ Ρ ΠΏΡΠΎΡΡΠΈΡΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π·Π° ΡΠ±ΠΎΡΠΊΠ°, Π½ΠΎ ΡΠ΅Π³Π° ΠΈΠΌΠ° Π³Π°ΡΠ°Π½ΡΠΈΡ, ΡΠ΅ ΡΠ΅ ΡΠ΅ ΡΠ³Π»ΠΎΠ±ΡΠ²Π° Π²ΠΈΠ½Π°Π³ΠΈ ΠΈ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΡΡ ΡΠ°ΠΌ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠ·Π±Π΅ΡΠ΅ Π²ΡΠΈΡΠΊΠΎ, ΠΊΠΎΠ΅ΡΠΎ Π΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π·Π° Π½Π΅Π³ΠΎΠ²ΠΈΡ ΠΏΡΠΎΡΠ΅Ρ Π½Π° ΡΠ±ΠΎΡΠΊΠ°.
Π‘ΡΡΠΎ ΡΠ°ΠΊΠ° ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΡΠ΅ Π²ΡΠ·ΠΏΠΎΠ»Π·Π²Π°ΡΠ΅ ΠΎΡ ΡΡΠ·Π΄Π°Π΄Π΅Π½ΠΈΡ ΠΎΡ ΠΌΠ΅Π½ ΠΎΠ±ΡΠ°Π· . ΠΡΠΈΡΠΊΠΈ ΠΈΠ·Ρ ΠΎΠ΄Π½ΠΈ ΠΊΠΎΠ΄ΠΎΠ²Π΅ ΡΠ° ΠΎΡΠ²ΠΎΡΠ΅Π½ΠΈ ΠΈ ΡΠ΅ Π½Π°ΠΌΠΈΡΠ°Ρ Π½Π° .
ΠΠΎ Π²ΡΠ΅ΠΌΠ΅ Π½Π° Π½Π°ΠΏΠΈΡΠ²Π°Π½Π΅ΡΠΎ Π½Π° ΡΡΠ°ΡΠΈΡΡΠ° Π²ΡΠ·Π½ΠΈΠΊΠ½Π° Π΄ΠΈΡΠΊΡΡΠΈΡ ΠΎΡΠ½ΠΎΡΠ½ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ΡΠΎ Π½Π° Π°Π³Π΅Π½ΡΠΈ Π½Π° ΠΎΡΠ΄Π°Π»Π΅ΡΠ΅Π½ΠΈ ΡΡΡΠ²ΡΡΠΈ, Π·Π° Π΄Π° Π½Π΅ Π½Π°ΡΠΎΠ²Π°ΡΠ²Π°ΠΌΠ΅ ΠΎΡΠ½ΠΎΠ²Π½Π°ΡΠ° Π½ΠΎΠ΄Π° Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° ΠΏΠ»ΡΠ³ΠΈΠ½Π° . ΠΠΎ Π·Π° ΡΠΎΠ²Π° ΡΠ΅ ΡΠ°Π·ΠΊΠ°ΠΆΠ° Π² Π±ΡΠ΄Π΅ΡΠ΅.
ΠΠ·ΡΠΎΡΠ½ΠΈΠΊ: habr.com
