https://jenkins.io/doc/tutorials/build-a-node-js-and-react-app-with-npm/

이 예제를 따라 가면서 기록 남기는 용도이다.

Github fork

https://github.com/jenkins-docs/simple-node-js-react-npm-app

이 곳에 가서 우 상단 fork 버튼을 클릭한다.

github가 가입되어있고, 내 레파지토리로 상위가 포크 된다는 전제이다.

Jenkins File을 레파지토리에 직접 넣어 줘야 해서 필요하다.

아니면 예제에 나온것처럼 로컬 작업을 해야 하는데 그게 더 힘들 것 같다.

파이프라인만들기

젠킨스 대쉬보드 > 새로운아이템 > 파이프라인 선택 > 저장(이름 넣고)

  • 파이프라인 : Pipeline script from SCM 선택
  • SCM : git
  • Repository url : fork한 내 GitHub url
  • Credential : github credentails이 있으면 선택하고 없으면 비게 놔둬도 된다. (단, 프라이빗 레포가 아니라는 전제이다.)
  • Script Path : Jenkinsfile

Jenkins file 만들기

github에 가서 내 레파지토리로 fork가 된 simple-node-js-react-npm-app 레포에 진입한다

  • Create new file : 버튼 클릭
  • 파일명 : Jenkinsfile (Script Path의 이름과 같아야 한다. 대소문자 주의)
pipeline {
agent {
docker {
image 'node:6-alpine'
args '-p 3001:3000'
}
}
stages {
stage('Build') {
steps {
sh 'npm install'
}
}
}

jenkins가 동작하는 서버에 docker와 nodejs&npm이 깔려 있다는 전제가 있다.

Agent docker

파이프라인이 독커에서 실행 되는데, 해당 이미지는 node:6-alpine이다. args는 docker 실행시 들어가는 파라메터 값으로 -p 3001:3000 host 머신(젠킨스 돌아가는 서버) 3001 포트로 대외 서비스 하고, 3000번 포트는 독커 포트이다. 이 둘을 연결하는 파라메터 이다.

stage

파이프라인의 순서이자 이름이다. 여기서는 Build만 았고 npm프로젝트를 install 한다.

Build

젠킨스대쉬보드 > 파이프라인 > '위에서 만든 프로젝트'파이프라인 선택 > Build Now

만약에 빌드 중 다음과 같은 오류가 나온다면

npm ERR! Error: EACCES: permission denied, mkdir '/.npm'

파이프라인 코드를 다음과 같이 변경 해보자

> pipeline {
> agent {
> docker {
> image 'node:6-alpine'
> args '-p 3001:3000'
> }
> }
> environment {
> HOME = '.'
> }
> stages {
> stage('Build') {
> steps {
> sh 'npm install'
> }
> }
> }
> }
>

>

https://stackoverflow.com/questions/42743201/npm-install-fails-in-jenkins-pipeline-in-docker/42957034?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa

여기 보고 고치긴 했는데 자세한 이유는 잘 모르겠다. 다음 기회에...

/var/lib/jenkins/workspace/nodejs 디렉토리를 가보면 nodejs가 인스톨 되어 있는 것을 볼 수 있다.

nvm 사용 (agnet를 사용하지 말고)

agent를 사용하지 않고 로컬 서버 환경에 있는 node&npm을 사용하면 node 혹은 npm 둘다 command not found가 발생할 수 있다. bin path가 사용자 환경과 다르기 때문이다.

jenkins plugin install

https://wiki.jenkins.io/display/JENKINS/Nvm+Wrapper+Plugin

이 플러그인을 젠킨스에 설치 한다.

대쉬보드 > 젠킨스관리 > 플러그인 매니저

파이프라인

프리스타일화면 또는 스크립트를 통해서 nvm을 적용 가능하다.

스크립트는 다음과 같이 처리 하면 된다.

node {
checkout scm

stage('build') {
sh "echo $PATH"


nvm(nvmInstallURL: 'https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh',
nvmIoJsOrgMirror: 'https://iojs.org/dist',
nvmNodeJsOrgMirror: 'https://nodejs.org/dist',
version: '10.16.0') {
sh "npm install"
echo "Build main site distribution"
sh "npm run build"
}

}
}

신경 써야 할 것은 2개이다.

  • nvmInstallURL : nvm 설치 url -> 버전이 바뀌면 url도 바뀌게 된다.
  • version : node version 이다.

nvm 환경내에서 작동할 shell script를 이후에 적용해 주면 된다.

Deploy

agent를 사용한 경우는 상관이 없겠지만, master agent를 사용한 경우는 직접 디플로이 처리 까지 해줘야 한다.

아래 코드는 build가 완료된 파일을 httpd(아파치) 디렉토리로 copy하는 내용이다.


node {
checkout scm

stage('build') {
nvm(nvmInstallURL: 'https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh',
nvmIoJsOrgMirror: 'https://iojs.org/dist',
nvmNodeJsOrgMirror: 'https://nodejs.org/dist',
version: '10.16.0') {
sh "npm install"
echo "Build main site distribution"
sh "npm run build"
}

}

stage('Deploy') {
sh "cp -r dist/* /data/test1/"
}

}

상위 stage Deploy가 해당 영역인데, 상위 처럼 적용한 경우 permission denied가 날 가능 성이 높다.

jenkins는 jenkins라고 하는 user 또는 group권한을 바탕으로 마스터 서버에서 작동 하기 때문이다.

그래서 target이 되는 /data/test1/에 대한 그룹 권한을 다음과 같이 변경한다.

sudo chown -R root:jenkins test1/

sudo chmod 775 test1

전제

  • nodejs 설치 완료
  • npm 설치 완료

Npm module

  • Vue-lib : sudo npm install -g @vue/cli

Nvm install

vue를 써야하는데 nodejs 버전 때문에 문제가 된다면 아래 nvm을 사용 하는게 좋다(?).

https://github.com/nvm-sh/nvm

아래는 mac을 기준으로 처리한 내용인데,

주의 할 것은 .bash_profile이 존재하는 곳에서 아래 행위를 해야한다.

시작하기전에 cd ~ 로 홈으로 오자.

만약에 .bash_profile이 없다면 touch .bash_profile로 만들어 주기만 해도 된다.

stevenucBookPro:~ steven$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 13226 100 13226 0 0 37442 0 --:--:-- --:--:-- --:--:-- 37361
=> nvm is already installed in /Users/steven/.nvm, trying to update using git
=> => Compressing and cleaning up git repository

=> nvm source string already in /Users/steven/.bash_profile
=> bash_completion source string already in /Users/steven/.bash_profile
=> Close and reopen your terminal to start using nvm or run the following to use it now:

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
stevenucBookPro:~ steven$ nvm
-bash: nvm: command not found
nvm 사용법
stevenucBookPro:~ steven$ nvm install 6.14.4
Downloading and installing node v6.14.4...
Downloading https://nodejs.org/dist/v6.14.4/node-v6.14.4-darwin-x64.tar.gz...
######################################################################## 100.0%
Computing checksum with shasum -a 256
Checksums matched!
Now using node v6.14.4 (npm v3.10.10)
Creating default alias: default -> 6.14.4 (-> v6.14.4)
stevenucBookPro:~ steven$ node -v
v6.14.4
stevenucBookPro:~ steven$ nvm install 10.10.0
Downloading and installing node v10.10.0...
Downloading https://nodejs.org/dist/v10.10.0/node-v10.10.0-darwin-x64.tar.gz...
######################################################################## 100.0%
Computing checksum with shasum -a 256
Checksums matched!
Now using node v10.10.0 (npm v6.4.1)
stevenucBookPro:~ steven$ node -v
v10.10.0
stevenucBookPro:~ steven$ nvm use 6
Now using node v6.14.4 (npm v3.10.10)
stevenucBookPro:~ steven$ nvm which 10
/Users/steven/.nvm/versions/node/v10.10.0/bin/node

webstorm

Create project
  • webstorm 실행
  • 왼쪽 vue.js 프로젝트 선택
  • 오른쪽 프로젝트 위치, nodejs 버전, vue cli 선택 : 이중에 하나라도 안나오면 node나 vue가 잘못 인스톨 되어있는 거니까 node 다 삭제하고 처음부터 다시 하는게 편할 수 있습니다.
  • wepack project 선택
  • preset default 선택
    • babel : ecma6script를 ecma5script로 변형 시키는 목적
    • eslint : code quality
프로젝트 init
  • webstrom project open 됨

  • npm install

  • npm run serve

    stevenui-MacBookPro:vuetutorial steven$ nvm use 10
    Now using node v10.10.0 (npm v6.4.1)
    stevenui-MacBookPro:vuetutorial steven$ node --version
    v10.10.0
    stevenui-MacBookPro:vuetutorial steven$ npm run serve

    > vuetutorial@0.1.0 serve /Users/steven/WebstormProjects/vuetutorial
    > vue-cli-service serve

    INFO Starting development server...
    98% after emitting CopyPlugin

    DONE Compiled successfully in 3051ms 9:18:16 PM

    App running at:
    - Local: http://localhost:8080/
    - Network: http://192.168.0.114:8080/

    Note that the development build is not optimized.
    To create a production build, run npm run build.
  • 브라우저에서 http://localhost:8080/ 입력 시 정상적으로 뷰 화면이 표시 되면 기본 셋팅은 완료 된것임

Vue 구조

vue에 대해서 잘나온 문서는 많으니까, 그냥 내부 보면서 이런저런 내용을 남기는 걸 목적으로 한다.

(이글을 쓸때는 잘나온 문서를 아직 보기 전이다. 공식 문서와 다르면 이해 부탁...)

  • vue는 typescript로 작성 되어 있다.
vue
Vue 기본 구조
export interface Vue {
readonly $el: Element;
readonly $options: ComponentOptions<Vue>;
readonly $parent: Vue;
readonly $root: Vue;
readonly $children: Vue[];
readonly $refs: { [key: string]: Vue | Element | Vue[] | Element[] };
readonly $slots: { [key: string]: VNode[] | undefined };
readonly $scopedSlots: { [key: string]: NormalizedScopedSlot | undefined };
readonly $isServer: boolean;
readonly $data: Record<string, any>;
readonly $props: Record<string, any>;
readonly $ssrContext: any;
readonly $vnode: VNode;
readonly $attrs: Record<string, string>;
readonly $listeners: Record<string, Function | Function[]>;

$mount(elementOrSelector?: Element | string, hydrating?: boolean): this;
$forceUpdate(): void;
$destroy(): void;
$set: typeof Vue.set;
$delete: typeof Vue.delete;
$watch(
expOrFn: string,
callback: (this: this, n: any, o: any) => void,
options?: WatchOptions
): (() => void);
$watch<T>(
expOrFn: (this: this) => T,
callback: (this: this, n: T, o: T) => void,
options?: WatchOptions
): (() => void);
$on(event: string | string[], callback: Function): this;
$once(event: string | string[], callback: Function): this;
$off(event?: string | string[], callback?: Function): this;
$emit(event: string, ...args: any[]): this;
$nextTick(callback: (this: this) => void): void;
$nextTick(): Promise<void>;
$createElement: CreateElement;
}
options
plugin
Node

centos 7.0 상에서 아파치(httpd)를 설치하고 포트 맵핑 하는 내용을 정리 합니다.

install

아파치 설치
[root@localhost conf]# yum install httpd

[root@localhost conf]# httpd -v
Server version: Apache/2.4.6 (CentOS)
Server built: Apr 24 2019 13:45:48
방화벽 오픈
[root@localhost conf]# firewall-cmd --permanent --add-service=http 
[root@localhost conf]# firewall-cmd --permanent --add-service=https
[root@localhost conf]# firewall-cmd --reload
상시 서비스 등록
[root@localhost conf]# systemctl enable httpd
[root@localhost conf]# systemctl start httpd

서비스 restart
systemctl restart httpd

servier 정상 확인

브라우저

http://<>

path 구조

[root@localhost httpd]# ls -al
합계 16
drwxr-xr-x. 5 root root 92 7월 8 23:03 .
drwxr-xr-x. 151 root root 12288 7월 9 09:26 ..
drwxr-xr-x. 2 root root 55 7월 9 17:18 conf
drwxr-xr-x. 2 root root 100 7월 9 11:16 conf.d
drwxr-xr-x. 2 root root 146 7월 9 10:21 conf.modules.d
lrwxrwxrwx. 1 root root 19 7월 8 23:03 logs -> ../../var/log/httpd
lrwxrwxrwx. 1 root root 29 7월 8 23:03 modules -> ../../usr/lib64/httpd/modules
lrwxrwxrwx. 1 root root 10 7월 8 23:03 run -> /run/httpd
  • conf : 기본 설정파일
  • conf.d : conf에 추가 설정 정보 (Include로 추가 설정을 이곳에서 처리한다)
  • conf.modules.d : module에 대한 로드 정보가 이곳에 있다
  • logs : 아파치 로그를 확인 가능하다

https.conf 구조

급하게 필요 한것만 보고 처리 해서 사실 잘 알지는 못한다 일단 이해 된것 같은것만 대략적으로 쓴다.

httpd 관련 설정 정보 및 로그가 있는 루트 디렉토리

ServerRoot "/etc/httpd"

80포트를 상시 모니터링 하겠음

(8080 포트 모니터링 하겠음은

Listen 8080)

Listen 80

conf.moules.d 이하의 설정 파일을 읽어서 모듈을 로드해라(모듈을 로드해라는 해당 .conf에 있음)

Include conf.modules.d/*.conf

본 아파치 서버가 작동하는 디렉토리에 대한 접근 권한을 설정한다

<Directory />
AllowOverride none
Require all granted
</Directory>

예를 들자면 로컬 서버의 디렉토리 중 /var/www 디렉토리는 httpd가 접근 가능하게 모든 권한을 준다.

<Directory "/var/www">
AllowOverride None
# Allow open access:
Require all granted
</Directory>

모듈 로드를 확인한다. 만약에 dir_module이 있으면 디렉토리상 인덱스는 index.html 이다.

<IfModule dir_module>
DirectoryIndex index.html
</IfModule>

2개의 url에 서로 다른 index.html 나타나게 하기

http.conf 수정
####파일 마지막에 넣음######
<Directory "/data/">
AllowOverride None
Require all granted
</Directory>

Include /etc/httpd/conf/vhost.conf

/data/ 디렉토리 이하를 접근 하겠음

vhost.conf 컨피그를 포함 하겠음 ( 해당 파일 만들지 않고 파일내에 있는 내용을 이곳에 직접 타이핑 해도 동일 작동함 )

vhost.conf 생성 및 수정
[root@localhost conf]# vi vhost.conf 
[root@localhost conf]# pwd
/root/httpd/conf
NameVirtualHost *:80


<VirtualHost *:80>

DocumentRoot "/data/test1"

ServerName test.com

ServerAlias www.test.com

</VirtualHost>



<VirtualHost *:80>

DocumentRoot "/data/test2"

ServerName sub.test.com

</VirtualHost>
  • NameVirtualHost *:80 : 80 포트 대상으로 이름 별 분리를 처리할 것임
  • <VirtualHost *:80> : 80으로 들어오는 내용을 본다
  • ServerName test.com : 요청들어온 url이 test.com이거나 www.test.com 이면,
  • DocumentRoot "/data/test1" : 의 index.html을 보여라

상위는 test.com이라는 DNS를 사용자가 취득 했고 DNS를 통해서 해당 서버에 접근 가능하다는 것이 전제 사항이다. 해당 관련 내용은 DNS Server관련 영역임으로 다루지 않으려고 한다.

해당 내용과 상관없이 hosts를 수정해서 테스트를 많이 하던데… 저는 pass

[root@localhost conf]# cd /
[root@localhost /]# mkdir data
[root@localhost data]# mkdir test1 test2
[root@localhost data]# ls
test1 test2

test1과 test2디렉토리로 들어가서 다음과 같은 index.html을 만들어 준다.

[root@localhost test1]#vi index.html 
test1
[root@localhost test2]#vi index.html
test2
permission denied
[core:error] [pid 24938] (13)Permission denied: [client 222.222.222.222:53283] AH00035: access to /index.html denied (filesystem path '/data/test1/index.html') because search permissions are missing on a component of the path

상위와 같은 오류가 난다면 다음과 같은 명령어를 사용해서 data디렉토리 이하에 아파치에서 접근이 가능하도록 해줘야 한다.

SELinus의 접근 권한 처리 때문에 생기는 문제이다.

chcon -R -t httpd_sys_content_t data/
[root@localhost /]# ls -alZ | grep data
drwxr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 data

상위와 같이 권한이 처리 되면 된다.

subdomain을 활용한 타 web서비스 실행

sub.test.com으로 들어오면 내부적으로 test.com:8888번 서비스로 자동 포워딩 되는 내용이다.

NameVirtualHost *:80


<VirtualHost *:80>

DocumentRoot "/data/test1"

ServerName test.com

ServerAlias www.test.com

</VirtualHost>



<VirtualHost *:80>
ProxyPreserveHost On

ServerName sub.test.com

proxyPass / http://test.com:8888/
proxyPassReverse / http://test.com:8888/

</VirtualHost>

일반적으로 상위처럼 수정후 sub.test.com을 실행하면 8888포트의 서비스가 브라우저에 표시 되게 된다.

그러나 SELinus로 인해 다음과 같은 오류가 날 수 있다.

[proxy:error] [pid 17800] (13)Permission denied: AH00957: HTTP: attempt to connect to 222.222.222.222:8888 (test.com) failed

아파치는 http_port_t에 등록된 포트만 프록시 패스가 가능하다. 해서 해당 포트를 등록 해줘야 한다

[root@localhost logs]# semanage port -l | grep http_port_t
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000

semanage port -a -p tcp -t http_port_t 8888 명령어를 실행 후 다시 확인 해보자.

[root@localhost logs]# semanage port -l | grep http_port_t
http_port_t tcp 8888, 80, 81, 443, 488, 8008, 8009, 8443, 9000

상위와 같이 나오면 된다.

오류를 잡다보면 퍼미션 관련 로그가 나오는 경우가 많은데, 아파치 오류만으로는 분석 하기 어려운 경우가 많다

이 경우는 다음 파일을 확인 하면 된다.

/var/log/audit

만약에 8888 포트가 다른 서비스에 이미 맵핑 되어 있다면 다음과 같이 명령어를 사용하면 된다.

semanage port -m -p tcp -t http_port_t 8888

만약에 포트에 따라서 사용자가 변경 할 수 없는 포트는 아래와 같이 처리 해주면 된다.

semanage port -m -t http_port_t -p tcp 8888

[root@localhost logs]# semanage port -l | grep 8888
us_cli_port_t tcp 8082, 8888
us_cli_port_t udp 8082, 8888
[root@localhost logs]# semanage port -a -p tcp -t http_port_t 8083
ValueError: 포트 tcp/8083가 이미 지정되어 있습니다
[root@localhost logs]# semanage port -d -p tcp -t htus_cli_port_t 8083
ValueError: 포트 tcp/8083가 정책에 지정되어 있습니다, 삭제할 수 없습니다
[root@localhost logs]# semanage port -m -t http_port_t -p tcp 8083
[root@localhost logs]# semanage port -l | grep 8083
http_port_t tcp 8888, 9888, 9999, 8888, 80, 81, 443
us_cli_port_t tcp 8888, 8083
us_cli_port_t udp 8888, 8083

docker container 설정 수정하기

docker run 이후 policy의 수정을 위해서는 다음 2가지 방법이 있음

  • docker update
docker update --restart=always <container>
  • /var/lib/docker/containers/CONTAINER_ID/hostconfig.json 파일 edit
{"Binds":["/nexus-data:/nexus-data"],"ContainerIDFile":"","LogConfig":{"Type":"journald","Config":{}},"NetworkMode":"default","PortBindings":{"8081/tcp":[{"HostIp":"","HostPort":"8081"}]},"RestartPolicy":{"Name":"always","MaximumRetryCount":0},"AutoRemove":false,"VolumeDriver":"","VolumesFrom":null,"CapAdd":null,"CapDrop":null,"Dns":[],"DnsOptions":[],"DnsSearch":[],"ExtraHosts":null,"GroupAdd":null,"IpcMode":"","Cgroup":"","Links":[],"OomScoreAdj":0,"PidMode":"","Privileged":true,"PublishAllPorts":false,"ReadonlyRootfs":false,"SecurityOpt":["label=disable"],"UTSMode":"","UsernsMode":"","ShmSize":67108864,"Runtime":"docker-runc","ConsoleSize":[0,0],"Isolation":"","CpuShares":0,"Memory":0,"NanoCpus":0,"CgroupParent":"","BlkioWeight":0,"BlkioWeightDevice":null,"BlkioDeviceReadBps":null,"BlkioDeviceWriteBps":null,"BlkioDeviceReadIOps":null,"BlkioDeviceWriteIOps":null,"CpuPeriod":0,"CpuQuota":0,"CpuRealtimePeriod":0,"CpuRealtimeRuntime":0,"CpusetCpus":"","CpusetMems":"","Devices":[],"DiskQuota":0,"KernelMemory":0,"MemoryReservation":0,"MemorySwap":0,"MemorySwappiness":-1,"OomKillDisable":false,"PidsLimit":0,"Ulimits":null,"CpuCount":0,"CpuPercent":0,"IOMaximumIOps":0,"IOMaximumBandwidth":0}

docker log 보기

  • docker logs -f <> : 실행중인 로그 확인 할 경우
  • docker events& : event 발생 로그 확인 (터미널을 2개 여는게 좋음)
  • docker start -a <> : 실행시 일어나는 오류 확인 가능

docker inspect

container의 상세 정보를 확인하는 명령어 이다.

docker inspect <<containerid>>

해당 명령어를 실행 하면 아래와 같이 모든 container low level 정보를 return 한다.

[devops@localhost ~]$ docker inspect nexus
[
{
"Id": "67826ba9e0179b6009c9c7a177fe1815fd320cdac65ea91d479413f7c4e5e81a",
"Created": "2019-06-26T03:19:12.069213873Z",
"Path": "sh",
"Args": [
"-c",
"${SONATYPE_DIR}/start-nexus-repository-manager.sh"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 19383,
"ExitCode": 0,
"Error": "",
"StartedAt": "2019-07-02T07:49:00.930407162Z",
"FinishedAt": "2019-07-02T07:48:08.216626691Z"
},
"Image": "sha256:36b0df681a47e5948f2088a446652766132141175dece2d6d47ef6e749385c05",
"ResolvConfPath": "/var/lib/docker/containers/67826ba9e0179b6009c9c7a177fe1815fd320cdac65ea91d479413f7c4e5e81a/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/67826ba9e0179b6009c9c7a177fe1815fd320cdac65ea91d479413f7c4e5e81a/hostname",
"HostsPath": "/var/lib/docker/containers/67826ba9e0179b6009c9c7a177fe1815fd320cdac65ea91d479413f7c4e5e81a/hosts",
"LogPath": "",
"Name": "/nexus",
"RestartCount": 0,
"Driver": "overlay2",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": [
"/nexus-data:/nexus-data"
],
"ContainerIDFile": "",
"LogConfig": {
"Type": "journald",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {
"8081/tcp": [
{
"HostIp": "",
"HostPort": "8081"
}
]
},
"RestartPolicy": {
"Name": "always",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": true,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": [
"label=disable"
],
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "docker-runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": null,
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DiskQuota": 0,
"KernelMemory": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": -1,
"OomKillDisable": false,
"PidsLimit": 0,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0
},
"GraphDriver": {
"Name": "overlay2",
"Data": {
"LowerDir": "/var/lib/docker/overlay2/bdeae8fe832211ba5059562162cb4eb7098de60657f622a31f0115653c324301-init/diff:/var/lib/docker/overlay2/e3c7b24292cf5ea41f2d3ab9c3b91a3c3b22f09a1cb26cf6048b36802c30b036/diff:/var/lib/docker/overlay2/3f075ffc65dfb1a311d63c70842d0ba2c467ca9bf1289c5a2a45a21e77a8314c/diff:/var/lib/docker/overlay2/32e8540578f9058f575a9051bc28df2f0308da53a20469a3a91c1a6b60f9cb0e/diff",
"MergedDir": "/var/lib/docker/overlay2/bdeae8fe832211ba5059562162cb4eb7098de60657f622a31f0115653c324301/merged",
"UpperDir": "/var/lib/docker/overlay2/bdeae8fe832211ba5059562162cb4eb7098de60657f622a31f0115653c324301/diff",
"WorkDir": "/var/lib/docker/overlay2/bdeae8fe832211ba5059562162cb4eb7098de60657f622a31f0115653c324301/work"
}
},
"Mounts": [
{
"Type": "bind",
"Source": "/nexus-data",
"Destination": "/nexus-data",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
"Config": {
"Hostname": "67826ba9e017",
"Domainname": "",
"User": "nexus",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"8081/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"SONATYPE_DIR=/opt/sonatype",
"NEXUS_HOME=/opt/sonatype/nexus",
"NEXUS_DATA=/nexus-data",
"NEXUS_CONTEXT=",
"SONATYPE_WORK=/opt/sonatype/sonatype-work",
"DOCKER_TYPE=docker",
"INSTALL4J_ADD_VM_PARAMS=-Xms1200m -Xmx1200m -XX:MaxDirectMemorySize=2g -Djava.util.prefs.userRoot=/nexus-data/javaprefs"
],
"Cmd": [
"sh",
"-c",
"${SONATYPE_DIR}/start-nexus-repository-manager.sh"
],
"ArgsEscaped": true,
"Image": "sonatype/nexus3",
"Volumes": {
"/nexus-data": {}
},
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"com.sonatype.license": "Apache License, Version 2.0",
"com.sonatype.name": "Nexus Repository Manager base image",
"org.label-schema.build-date": "20190305",
"org.label-schema.license": "GPLv2",
"org.label-schema.name": "CentOS Base Image",
"org.label-schema.schema-version": "1.0",
"org.label-schema.vendor": "CentOS",
"vendor": "Sonatype"
}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "50b3a078a453332680ca6dd09d2cd10fc641fddc49c5b3b34db178c516f8475d",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"8081/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "8081"
}
]
},
"SandboxKey": "/var/run/docker/netns/50b3a078a453",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "b030c131340f1b86c3ce868dae109fee9814310503076f685ff274b42e76eeac",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:02",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "e7bccaaf25cb4ba061b98aab2ef6470301c688b7d99db0f40e7e7bd7b6665379",
"EndpointID": "b030c131340f1b86c3ce868dae109fee9814310503076f685ff274b42e76eeac",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02"
}
}
}
}
]

여기서 특정 영역에 대한 정보만을 얻고 싶다면 다음과 같이 format 설정을 해주면 된다.

docker inspect --format 또는

docker inspect -f

를 사용하면 된다. 사용 법은 다음과 같다.

[devops@localhost ~]$ docker inspect --format='{{.NetworkSettings.Networks}}' nexus
map[bridge:0xc420130300]

inspect 해서 나온 모든 정보 중에서 필요로 하는 정보의 Name을 .Name.Name 식으로 표현 하면 특정 값을 얻어 낼 수가 있다. 가령 IPAddress를 얻어 오고자 하면 다음과 같이 하면 된다.

[devops@localhost ~]$ docker inspect --format='{{.NetworkSettings.Networks.bridge.IPAddress}}' nexus
172.17.0.2

만약 해당 결과 값을 json 형태의 템플릿으로 받고자 하면 다음과 같이 하면 된다.

[devops@localhost ~]$ docker inspect --format='{{json .NetworkSettings.Networks.bridge.IPAddress}}' nexus                   "172.17.0.2"

"" 앞뒤로 이와 같은게 붙은거 빼고는 차이가 없어 보이지만,

[devops@localhost ~]$ docker inspect --format='{{json .NetworkSettings.Networks}}' nexus
{"bridge":{"IPAMConfig":null,"Links":null,"Aliases":null,"NetworkID":"e7bccaaf25cb4ba061b98aab2ef6470301c688b7d99db0f40e7e7bd7b6665379","EndpointID":"b030c131340f1b86c3ce868dae109fee9814310503076f685ff274b42e76eeac","Gateway":"172.17.0.1","IPAddress":"172.17.0.2","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:11:00:02"}}

Networks만을 출력하면 다른걸 확인 할 수있다. 앞서 json없이 출력은 메모리 번지를 출력 했다면, json과 함께 출력 하면 이하 모든 값이 string으로 출력 되는걸 확인 할 수 있다.

이외에 index, range,$variableParm 정의, :=Assignment 등이 추가로 잇는듯 한데 어떻게 사용하는지는 잘 모르겠다.

docker shell 로 바로 진입하기

docker run -it --rm <<이미지id>> /bin/sh or

docker run -it --rm <<이미지id>> /bin/bash