2019년에 작성한 노트를 옮겨 적은 것입니다.
This document is a guide to build docker images for MIA simulators.
The following commands are snippets to install Docker Engine - Community on Ubuntu 18.04. For other versions, please refer to the official Docker page.
To install Docker on Ubuntu, type
$ sudo apt-get update
$ sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
$ sudo docker run hello-world
To run docker without sudo
privilege, run the following (Reboot may be needed).
$ sudo groupadd docker
$ sudo usermod -aG docker $USER
$ newgrp docker
$ docker run hello-world
For further details and configurations, refer to Post-installation steps for Linux
Building a docker image runs the same way for any simulators. In this document, dockernizing MIA simulator will be demonstrated.
$ cd mia-simulator
$ npm run docker:build
# or directly execute
$ sh ./tools/build-docker-image.sh
This commands will build an image out of the Dockerfile provided. You can check a list of Docker images by docker image ls
. For more information on Dockerfile, visit this page.
$ npm run docker:start
# or directly execute
$ docker run --rm --net=host --name=mia -d -it \
-v /home/mia/theme:/home/mia/theme \
-v /home/mia/config:/home/mia/config \
mia
--rm
: Automatically remove the container when it exits.
--net=host
: Share host network.
--name=mia
: Name the container.
-d
: Run the container as a demon and prints the container id.
-i
: Keep STDIN open even if not attached.
-t
: Allocate a pseudo-TTY.
-v
: Bind container volume to host volume.
Check the container with docker container ls
. Once you run the container, you can access the container with
$ npm run docker:exec
# or directly execute
$ docker exec -it mia /bin/sh
Now you can also use Simulator CLI inside the docker container.
# Inside the container
$ npm run cli
To see the simulator logs,
$ docker logs -f mia
Another good source to understand dockernizig a Node.js app is this official node page.
Follow Docker Hub Quickstart to create your own private repository.
Once you create a Docker hub account, you can log in to it with docker login
. Push the MIA image to the hub so that you can access to it anywhere.
To pull the simulator image from the hub,
# pull and run
$ docker run --rm --net=host --name=mia -dit [your repository]:[your tag]
# or pull only
$ docker pull [your repository]:[your tag]
While Docker hub provides easy access to maintain repository, it only allows a single private repository for free. Using Docker Registry with AWS EC2 can be an option to maintain 1 or more docker images.
To do this, you need to get your own AWS EC2 instance in hand. Make sure that you open up the port 5000 (default Docker registry port) by adding the EC2 inbound rules.
ubuntu@aws-ec2$ docker pull registry
ubuntu@aws-ec2$ docker run -dit --name docker-registry -p 5000:5000 registry
Docker registry is a stateless, highly scalable server-side application that stores and lets you distribute Docker images. For further information, see here.
Since Docker Registry only allows HTTPS when used out of local environment, you need a CA's certificate. Follow steps below if you need to make a self-signed certificate.
Inside your EC2
$ mkidr -p ~/docker-registry/cert
$ cd ~/docker-registry/cert
# Create your Root Certificate Authority private key
$ openssl genrsa -des3 -out root.key 2048
# Create a Certificate Signing Request
# Enter a registry domain name for Common Name: ex) my.aws.com
$ openssl req -new -key root.key -out server.csr
# Sign the request with your Root CA
$ openssl x509 -req -days 365 -in server.csr -signkey root.key -out server.crt
# Remove the pass phrase
$ cp root.key root.key.orign
$ openssl rsa -in root.key.origin -out root.key
When creating the CSR, enter a domain name that you would use to access to your AWS EC2. You can also use the given Public AWS DNS.
$ sudo cp ~/docker-registry/cert/server.crt /usr/share/ca-certificates/
$ sudo echo "server.crt" | sudo tee -a /etc/ca-certificates.conf
$ sudo update-ca-certificates
$ sudo service docker restart
# if you want to remove,
$ rm /usr/share/ca-certificates/server.crt
$ vi /etc/ca-certificates.conf
remove server.crt
$ update-ca-certificates --fresh
$ sudo servie docker restart
The code below will setup login credentials for the registry with
username: procentric, password: lge123
$ mkdir -p ~/docker-registry/auth
$ cd ~/docker-registry/auth
$ sudo docker run \
$ --entrypoint htpasswd \
$ registry -Bbn procentric lge123 > htpasswd
$ docker run -d -p 5000:5000 --restart=always --name registry \
-v ~/docker-registry/cert:/certs \
-v ~/docker-registry/auth:/auth \
-v ~/docker-registry/data:/data \
-e REGISTRY_AUTH=htpasswd \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
-e REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm \
-e REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/data \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/server.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/root.key \
registry
Or, if you prefer docker-compose you can write your docker-compose.yml.
$ vi docker-compose.yml
version: '3'
services:
docker-registry:
image: registry
restart: always
container_name: registry
ports:
- "5000:5000"
volumes:
- ~/docker-registry/auth:/auth
- ~/docker-registry/cert:/cert
- ~/docker-registry/data:/data
environment:
- REGISTRY_AUTH=htpasswd
- REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm
- REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd
- REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/data
- REGISTRY_HTTP_TLS_CERTIFICATE=/cert/server.crt
- REGISTRY_HTTP_TLS_KEY=/cert/root.key
$ sudo docker-compose up -d
Come back to your local PC
$ cd ~
$ scp ubuntu@[YOUR AWS DNS]:/home/ubuntu/docker-registry/auth/server.crt ~/
$ sudo cp server.crt /usr/share/ca-certificates/
$ sudo echo "server.crt" | sudo tee -a /etc/ca-certificates.conf
$ sudo update-ca-certificates
$ sudo service docker restart
$ vi /etc/hosts
[YOUR AWS IP] my.aws.com
$ docker login my.aws.com:5000
Username:
Password:
$ docker tag mia my.aws.com:5000/mia
$ docker push my.aws.com:5000/mia
Check the push result by
$ curl -k -u 'procentric:lge123' -X GET https://my.aws.com:5000/v2/_catalog
{"repositories":["mia"]}
If you feel the docker image is too big, you can reduce the size by selecting other base images such as Alpine node.
When building, change FROM attribute from the Dockerfile.
$vi Dockerfile
FROM node:8-alpine
RUN addgroup -S mia \
&& adduser -S mia -u 1001 -G mia -s /bin/bash -h mia
...
# note that RUN command should be adjusted accordingly.
Here is the full Dockerfile for MIA simulator.
$ vi Dockerfile
FROM node:8-alpine
##
# Docker volume will be bound to /home/mia/ on PCD
##
# create mia directories
RUN mkdir -p /home/cia/app \
&& mkdir -p /home/cia/app/home \
&& mkdir -p /home/mia/theme \
&& mkdir -p /home/mia/config
# set run environment and user
WORKDIR /home/cia/app
# install dependencies, build and remove rest
COPY mia.tar.gz /home/cia/app
RUN tar -xvf mia.tar.gz \
&& npm install --only=production \
&& npm run init \
&& rm mia.tar.gz
# open api server port
EXPOSE 63000
ENTRYPOINT ["/usr/local/bin/npm", "run", "app"]
Docker Remote API allows you to control docker in a remote server. If you configured Docker Registry with AWS EC2, Docker Remote API can make it easier.
To set up, change the /lib/systemd/system/docker.service
file to let the machine listen to 2375
port.
$ sudo vi /lib/systemd/system/docker.service
...
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 --containerd=/run/containerd/containerd.sock
...
$ sudo systemctl daemon-reload
$ sudo service docker restart
$ curl -X GET http://localhost:2375/version
{RESPONSE FROM DOCKER}