Postverta Stack base file system image
1.9K
Postverta Stack is a tool to quickly set up reproducible full-stack dev environments. The goal is to make modern applications easy to develop and test. The tool is under active development and there are still quite a few rough edges. Please feel free to submit any bug, feature requests, or general comments to issues.
Similar to tools like docker-compose and vagrant, Stack can easily bootstrap a dev environment with multiple services. There are a few important features that we think make Stack unique:
No dockerization needed: we realize that it does not make sense to dockerize all services (e.g., lambda functions). Always rebuilding docker images is also a non-trivial overhead for fast iterative development. Therefore, Stack does not require a docker image to be built before running the service. A service can be any code or script written in any language.
Live code reloading: Stack automatically syncs local code to the containers running the services (we use containers only for the sake of isolation). No need for complex volume mount configurations.
(Future) online development and testing: currently, all dev services run locally in a VM. In the future, we also plan to support dedicated development cluster for completely online development and testing.
Stack has been tested under Linux (ubuntu 14.04 and 16.04) and macOS (sierra). Currently, the tool requires minikube as a local orchestrator of containers.
The following instructions are copied from the official documentation) for your convenience.
kubectlNote: if you are already using kubectl to manage your other kubernetes
clusters, the installation of minikube may overwrite your current $HOME/.kube
config. Please make a backup of the file before proceeding.
macOS binary:
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl
Linux binary:
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
kubectl executable and move it to your PATHchmod +x ./kubectl && sudo mv ./kubectl /usr/local/bin/kubectl
minikube, a tool to start and stop a local kubernetes clustermacOS binary:
curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.20.0/minikube-darwin-amd64
Linux binary:
curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.20.0/minikube-linux-amd64
minikube executable and move it to your PATHchmod +x minikube && sudo mv minikube /usr/local/bin/minikube
macOS (xhyve driver)
$ brew update
$ brew install docker-machine-driver-xhyve
# docker-machine-driver-xhyve need root owner and uid
$ sudo chown root:wheel $(brew --prefix)/opt/docker-machine-driver-xhyve/bin/docker-machine-driver-xhyve
$ sudo chmod u+s $(brew --prefix)/opt/docker-machine-driver-xhyve/bin/docker-machine-driver-xhyve
Linux (KVM driver)
# For ubuntu 16.04
$ curl -Lo docker-machine-driver-kvm https://github.com/dhiltgen/docker-machine-kvm/releases/download/v0.10.0/docker-machine-driver-kvm-ubuntu16.04
# For ubuntu 14.04
$ curl -Lo docker-machine-driver-kvm https://github.com/dhiltgen/docker-machine-kvm/releases/download/v0.10.0/docker-machine-driver-kvm-ubuntu14.04
$ chmod +x docker-machine-driver-kvm
$ sudo mv docker-machine-driver-kvm /usr/local/bin/docker-machine-driver-kvm
# Install libvirt and qemu-kvm on your system
$ sudo apt install libvirt-bin qemu-kvm
# Add yourself to the libvirtd group (use libvirt group for rpm based distros) so you don't need to sudo
$ sudo usermod -a -G libvirtd $(whoami)
# Update your current session for the group change to take effect
$ newgrp libvirtd
A special driver called none is needed if you are already running Linux in virtualization (e.g., running a VM in AWS EC2). The driver will not start a virtual machine, but instead will run all containers through the host's own docker engine. There is no dependency of the none driver except for docker
macOS
minikube start --vm-driver xhyve
Linux (with KVM)
minikube start --vm-driver kvm
Linux (with none driver)
sudo minikube start --vm-driver none
# Because minikube is started with root, need to change the kube config ownership
sudo chown -R $USER $HOME/.kube
sudo chgrp -R $USER $HOME/.kube
sudo chown -R $USER $HOME/.minikube
sudo chgrp -R $USER $HOME/.minikube
If everything works, you should be able to run kubectl get namespace and see something like the following:
NAME STATUS AGE
default Active 6d
kube-public Active 6d
kube-system Active 6d
The current implementation of Stack is only a single python executable file
(pv). To install it, simply download the file, make it executable, and copy
it to /usr/local/bin:
curl -LO https://raw.githubusercontent.com/postverta/stack/master/pv
chmod +x ./pv
sudo mv ./pv /usr/local/bin/pv
To run pv, you also need the PyYAML library, which can be easily installed with
sudo pip install pyyaml
The example is based on the Sock shop application, a microservice-based E-commerce website with 11 different services written in different languages and frameworks.
To get started, first clone the overall project:
git clone https://bitbucket.org/postverta/project.git
The project contains a file pv.yaml that describes the stack.
Run pv init in the cloned directory to initialize the local workspace and
check-out all source code into the src directory.
$ pv init
Cloning into '/home/angl/project/src/front-end'...
remote: Counting objects: 1003, done.
remote: Compressing objects: 100% (378/378), done.
remote: Total 1003 (delta 554), reused 998 (delta 552)
Receiving objects: 100% (1003/1003), 10.14 MiB | 3.87 MiB/s, done.
Resolving deltas: 100% (554/554), done.
Checking connectivity... done.
Cloning into '/home/angl/project/src/queue-master'...
remote: Counting objects: 243, done.
remote: Compressing objects: 100% (125/125), done.
remote: Total 243 (delta 59), reused 243 (delta 59)
Receiving objects: 100% (243/243), 43.00 KiB | 0 bytes/s, done.
Resolving deltas: 100% (59/59), done.
...
$ ls src
carts catalogue front-end orders payment queue-master shipping user
Use pv up to bring up the dev stack. For each service described in pv.yaml,
the command will sync the corresponding source code in the src directory into
a container, and then build and run the service.
$ pv up
Dev environment created
Service front-end started
Service carts-db started
Service carts started
Service shipping started
Service orders started
Service catalogue started
Service user started
Service orders-db started
Service payment started
Service catalogue-db started
Service user-db started
Use pv status to monitor the status of the services.
$ pv status
NAME STATUS HOST:PORT (CLUSTER_IP:PORT)
carts RUNNING 192.168.64.2:31015 (10.0.0.53:80)
carts-db RUNNING 192.168.64.2:31417 (10.0.0.7:27017)
catalogue RUNNING 192.168.64.2:30832 (10.0.0.79:80)
catalogue-db RUNNING 192.168.64.2:30669 (10.0.0.187:3306)
front-end RUNNING 192.168.64.2:30953 (10.0.0.195:8079)
orders RUNNING 192.168.64.2:30782 (10.0.0.215:80)
orders-db RUNNING 192.168.64.2:30861 (10.0.0.169:27017)
payment RUNNING 192.168.64.2:31861 (10.0.0.247:80)
shipping RUNNING 192.168.64.2:31578 (10.0.0.204:80)
user RUNNING 192.168.64.2:32538 (10.0.0.49:80)
user-db RUNNING 192.168.64.2:31591 (10.0.0.29:27017)
Each service has its own internal IP (CLUSTER_IP), and services can communicate
with each other through that IP or host names. Internal IP/port are also mapped
to host IP/port for external access. For instance, you can use your browser to
open http://192.168.64.2:30953 and see the E-commerce website (some of the
services are Java based, and their compilation can take a while).
The running services also stay in sync with the local source code. Any local
change will be reflected to the services in real time. For instance, try
modifying src/front-end/public/index.html and reloading the E-commerce
website to see your changes take effect.
For debugging, use pv log [service name] to check out the running log of any
service:
$ pv log front-end
...
...
> [email protected] start /home/dev/front-end
> node server.js
Using local session manager
App now running in development mode on port 8079
Request received: /cart, undefined
Customer ID: Qfs3bOGSOW77bxPtS64OWZNOl8bLavZo
GET /catalogue?size=5 200 528.818 ms - -
GET /catalogue/images/colourful_socks.jpg 200 119.743 ms - 486192
To get a shell into the container running a particular service, use pv ssh [service name]:
$ pv ssh front-end
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
dev@front-end:~$
To shutdown the entire stack, use pv shutdown. This will stop and delete all
service containers. It is easy to recreate the stack with pv up again.
pv.yaml is the only configuration file. It must be present at the root
directory of a workspace. It has a similar structure as docker-compose.yaml.
There are two main sections of the file:
The repos section describes the source repositories. They will be
checked-out as part of pv init.
The services section describes the services in the stack. Each service is
based on a repository, and its properties determine how to build and start
the service from the source. In the future we might support other type of
services, for instance, services directly from pre-built docker images.
Born: the service is started as a container running a base file system image.
The file system image is currently non-changeable, and is defined by the
Dockerfile in this repository. The base image is ubuntu-based with all the
basic development tools installed. In the future we might support using
custom docker image as the base file system.
Initialize: run additional commands to customize the base file system (e.g.,
apt-get more packages).
Sync: copy the source code to the container.
Install dependencies: install any dependency based on the source files like
package.json or requirements.txt.
Build: build the service executables (if needed).
Running: start the service process(es) inside the container.
repo: (required) specify a repository to be synced over to the container.
The name must match with one from the repos section. The files are synced
to a directory inside the container specified by the cwd property.
type: (optional) this chooses from certain templates that change the
default values of some properties. For instance, a type mysql would preset
build, start, stop, and ports. Of course, you can still override
these preset values by explicitly specifying them. The currently supported
values are python, javascript, golang, mysql, mongodb. Other
values are accepted but have no effect.
initialize: (optional) a command that is run right after the container is
up and running, before source sync. Can be used to install additional system
packages. Output can be seen from pv log (same for other commands like
start, build).
cwd: (optional, default $HOME/repo_name) the directory inside the
container where the source code is sync'ed to. By default, it is a directory
under $HOME named after the repository.
install-dependencies: (optional) a command that is run after the initial
source sync. The language types (e.g., python and javascript) set some
reasonable defaults for this property. The working directory of the command
would be cwd (same for build, start, and stop commands).
build: (optional) specify a command to build the service executables.
start: (required) specify a command to start the service processes.
stop: (optional, default to kill all processes spawned from start with
SIGTERM) specify a command to stop the service process.
auto-restart: (optional, default true) whether restarts the service after
source code change. Set this to false if the service already listens to
source code change (e.g., webpack dev server).
env: (optional) an array of (key, value) environment variables that are set
for all commands.
ports: (optional) an array of port numbers that are exposed to outside.
Ports that are only used between services do not need to be listed here. Run
pv status to see the port mapping for the exposed ports.
pv init: clone all source repos to localpv up: bring up the dev stackpv shutdown: turn off the dev stackpv status: show the status of the current stackpv log [service-name]: get the running log of service-namepv ssh [service-name]: access the container of service-namepv restart [service-name]: restart the processes of service-name. This is equivalent of running the stop and start commands sequentially.pv reset [service-name]: reset the container for service-name. This will
restart the entire lifecycle of the service. Useful with a service's
configuration has been changed.Content type
Image
Digest
Size
786.7 MB
Last updated
about 9 years ago
docker pull postverta/stack