welcome ipfs

This commit is contained in:
Yann Autissier 2022-06-30 23:37:10 +02:00
parent b149a01b75
commit e06266489c
66 changed files with 871 additions and 591 deletions

View File

@ -1,3 +1,5 @@
APP_NAME=myos
APP_TYPE=myos
DOCKER_SERVICE=cli
DOMAIN=localhost
ENV=local
STACK=

View File

@ -1,7 +1,17 @@
# CHANGELOG
## v1.0-beta - 2022-06-30
Pre release, welcome ipfs
* add arm64 support
* add ipfs stack
* add x2go with ssh ecryptfs homedir
* add zen stack
* update docker-compose to v2.5.0
## v1.0-alpha - 2021-07-14
First public release, code is doc
Public release, code is doc
* Licenses update to GPL, as freedom should not allow evil to move faster than god
* update license to GPL as freedom should not allow evil to move faster than god

View File

@ -10,12 +10,16 @@ app-build: user install-build-config
$(foreach service,$(or $(SERVICE),$(SERVICES)),$(call make,app-build-$(service)))
$(call make,docker-commit)
app-install: ansible-run
app-install: ansible-run app-update-default
app-update: ansible-pull app-update-default
app-update-default: ENV_DIST := .env
app-update-default: ENV_FILE := /etc/default/myos
app-update-default: .env-update;
app-tests: ansible-tests
app-start: ssh-add
##
# BOOTSTRAP
@ -24,12 +28,12 @@ app-start: ssh-add
.PHONY: bootstrap-docker
bootstrap-docker: install-bin-docker setup-docker-group setup-binfmt setup-nfsd setup-sysctl
# target bootstrap-host: Fire node target
# target bootstrap-host: Create DOCKER_NETWORK_PUBLIC
# on local host
.PHONY: bootstrap-host
bootstrap-host: node
bootstrap-host: docker-network-create-$(DOCKER_NETWORK_PUBLIC) node-ssl-certs
# target bootstrap-user: Fire User target
# target bootstrap-user: Create DOCKER_NETWORK_PRIVATE
# on local host
.PHONY: bootstrap-user
bootstrap-user: User
bootstrap-user: docker-network-create

View File

@ -1,31 +1,111 @@
# myos - Make Your Own Stack
Docker paas based on docker compose files.
## Disclaimer
This is work in progress ;)
## Usage
### Examples
* Configure myos for domain.tld
```shell
$ make bootstrap DOMAIN=domain.tld
```
* Start myos stacks
```shell
$ make node up STACK='zen'
```
`make node` starts the stack node with docker host services :
- consul (service discovery)
- fabio (load balancer)
- ipfs (inter planetary file system)
- registrator (docker/consul bridge)
`make User` starts the stack User with docker user services :
- myos (ssh-agent)
- ipfs (when STACK=zen)
`make up` starts the stack STACK
- zen (when STACK=zen)
* Stop myos
```shell
$ make shutdown
```
* Install myos
```shell
$ make install
```
### Make variables
### Variables
#### DEBUG
* DEBUG
Show debug informations
Show executed commands
```shell
$ make install DEBUG=true
$ make up DEBUG=true
```
#### DRYRUN
* DRYRUN
Show commands, do nothing
Do nothing, show commands instead of executing it
```shell
$ make install DRYRUN=true
$ make up DRYRUN=true
```
* VERBOSE
Show called functions
```shell
$ make up VERBOSE=true
```
* Show variable VARIABLE
```shell
$ make print-VARIABLE
```
### Debug
* Show docker compose yaml config
```shell
$ make config
```
`make config` show docker compose yaml config for stack STACK
`make stack-node-config` show docker compose yaml config for stack node
`make stack-User-config` show docker compose yaml config for stack User
`make stack-elastic-config` show docker compose yaml config for stack elastic
* Show debug variables
```shell
$ make debug
```
* Generate self documentation
```shell
$ make doc
```
* Show env args
```shell
$ make print-env_args
```
## Status

View File

@ -14,6 +14,7 @@ hosts_packages:
- { "name": "ansible", "state": "present" }
hosts_services:
- { "name": "zram", "state": "started", "enabled": "yes" }
hosts_update: true
hosts_user_env:
- ANSIBLE_AWS_ACCESS_KEY_ID
- ANSIBLE_AWS_SECRET_ACCESS_KEY

View File

@ -10,6 +10,7 @@ hosts_git_repositories:
- { "repo": "{{ lookup('env','ANSIBLE_GIT_REPOSITORY') }}", "dest": "{{ lookup('env','ANSIBLE_GIT_DIRECTORY') }}", "key_file": "{{ lookup('env','ANSIBLE_GIT_KEY_FILE') or '~/.ssh/id_rsa' }}", "version": "{{ lookup('env','ANSIBLE_GIT_VERSION') }}" }
hosts_services:
- { "name": "myos", "state": "stopped", "enabled": "yes" }
hosts_update: true
hosts_user_env:
- ANSIBLE_CONFIG
- ANSIBLE_DOCKER_IMAGE_TAG

View File

@ -1,2 +1,3 @@
PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
0 0 * * * root /etc/init.d/myos ansible-pull
@reboot root make ansible-pull > /var/log/ansible-pull.log
0 0 * * * root make ansible-pull > /var/log/ansible-pull.log

View File

@ -16,44 +16,27 @@ NAME="$(basename "$0")"
type make >/dev/null 2>&1 && [ -d "${MYOS}" ] && cd "${MYOS}" || exit 1
case "$1" in
force-stop)
HOOK="stop stack-node-stop"
shift
;;
force-reload)
HOOK="recreate stack-node-recreate"
shift
;;
force-restart)
HOOK="restart stack-node-restart"
shift
;;
force-shutdown)
HOOK="down stack-node-down"
shift
TARGET='force-recreate'
;;
reload)
HOOK="recreate"
shift
;;
shutdown)
HOOK="down"
shift
TARGET="recreate"
;;
start)
echo "Starting $NAME..."
HOOK="up"
shift
TARGET="up"
;;
status)
HOOK="ps"
shift
TARGET="ps"
;;
stop)
echo "Stopping $NAME..."
TARGET="$1"
;;
*)
TARGET="$1"
;;
esac
shift ||:
IFS=$'\n'; exec env $(cat /etc/default/myos ~/.myos 2>/dev/null) make ${HOOK:-} "${@}"
IFS=$'\n'; exec env $(cat /etc/default/myos 2>/dev/null) make ${TARGET:-} ${TARGET_FORCE:-} $@

View File

@ -2,7 +2,7 @@
# file rc.sh: Call user defined functions
## author: Yann "aya" Autissier
## license: GPL
## version: 20210714
## version: 20220630
case $- in
# if this is an interactive shell
@ -24,7 +24,7 @@ case $- in
fi
done
# load user stuff from RC_* env vars
IFS="$(printf '%b_' '\n')"; IFS="${IFS%_}"; for line in $(printenv 2>/dev/null |awk '$0 ~ /^RC_[1-9A-Z_]*=/'); do
IFS="$(printf '%b_' '\n')"; IFS="${IFS%_}"; for line in $(printenv 2>/dev/null |awk '$0 ~ /^RC_[0-9A-Z_]*=/' |sort); do
func_name=$(printf '%s\n' "${line%%=*}" |awk '{print tolower(substr($0,4))}')
eval func_args=\$"${line%%=*}"
[ "${func_args}" = "false" ] && continue

View File

@ -2,7 +2,7 @@
# file rc_functions.sh: Define shell functions
## author: Yann "aya" Autissier
## license: GPL
## version: 20220620
## version: 20220630
# function force: Run a command sine die
force() {
@ -40,9 +40,8 @@ force8() {
# function load_average; Print the current load average
load_average() {
awk '{printf "%.1f\n" $1}' /proc/loadavg 2>/dev/null\
|| uptime 2>/dev/null |awk '{printf "%.1f\n", $(NF-2)}'
}
uptime 2>/dev/null |awk '{printf "%.1f\n", $(NF-2)}'
}
# function process_count: Print number of "processes"/"running processes"/"D-state"
process_count() {

View File

@ -3,7 +3,7 @@ Description=Call myos ansible-pull
[Service]
Type=oneshot
ExecStart=/etc/init.d/myos ansible-pull
ExecStart=make ansible-pull
[Install]
WantedBy=multi-user.target

View File

@ -1,7 +1,7 @@
---
# file: handlers/main.yml
- name: update boot config
- name: update boot - syslinux
environment:
PATH: "{{ ansible_env.PATH }}:/usr/sbin:/sbin"
with_together:
@ -10,3 +10,12 @@
command: "update-extlinux"
when: item.1.changed and item.0.dest == "/etc/update-extlinux.conf"
- name: update boot - grub
environment:
PATH: "{{ ansible_env.PATH }}:/usr/sbin:/sbin"
with_together:
- '{{ boot_config }}'
- '{{ boot_config_handler_notify.results }}'
command: "update-grub"
when: item.1.changed and item.0.dest == "/etc/default/grub"

View File

@ -4,10 +4,34 @@
- name: boot - define config
set_fact:
boot_config:
# set clocksource at boot
# set docker optimizations - armbian
- dest: /boot/armbianEnv.txt
line: 'docker_optimizations=on'
regex: ''
# set clocksource - grub
- dest: /etc/default/grub
line: 'GRUB_CMDLINE_LINUX="\1 clocksource=tsc tsc=reliable"'
regex: '^GRUB_CMDLINE_LINUX="((?!.*clocksource=tsc tsc=reliable).*)"$'
# set resources limits - grub
- dest: /etc/default/grub
line: 'GRUB_CMDLINE_LINUX="\1 cgroup_enable=memory swapaccount=1"'
regex: '^GRUB_CMDLINE_LINUX="((?!.*cgroup_enable=memory swapaccount=1).*)"$'
# set clocksource - syslinux
- dest: /etc/update-extlinux.conf
line: 'default_kernel_opts="\1 clocksource=tsc tsc=reliable"'
regex: '^default_kernel_opts="((?!.*clocksource=tsc tsc=reliable).*)"$'
# set resources limits - syslinux
- dest: /etc/update-extlinux.conf
line: 'default_kernel_opts="\1 cgroup_enable=memory swapaccount=1"'
regex: '^default_kernel_opts="((?!.*cgroup_enable=memory swapaccount=1).*)"$'
# set clocksource - uboot
- dest: /boot/cmdline.txt
line: '\1 clocksource=tsc tsc=reliable'
regex: '^((?!.*clocksource=tsc tsc=reliable).*)$'
# set resources limits - uboot
- dest: /boot/cmdline.txt
line: '\1 cgroup_enable=memory swapaccount=1'
regex: '^((?!.*cgroup_enable=memory swapaccount=1).*)$'
- name: boot - stat config file
with_items: '{{boot_config|default([])}}'
@ -28,6 +52,7 @@
regex: '{{item.0.regex}}'
become: yes
notify:
- update boot config
- update boot - syslinux
- update boot - grub
register: boot_config_handler_notify

View File

@ -9,13 +9,6 @@
copy: src=../files/{{item}} dest={{item}} owner=root group=root mode=0644
become: yes
- name: files - copy myos cron file
when: hosts_update
with_items:
- /etc/cron.d/myos
copy: src=../files/{{item}} dest={{item}} owner=root group=root mode=0644
become: yes
- name: files - copy binary files
with_items:
- /etc/init.d/myos
@ -26,8 +19,6 @@
- name: files - copy files - systemd
when: ansible_service_mgr|lower == "systemd"
with_items:
- /etc/systemd/system/ansible.service
- /etc/systemd/system/ansible.timer
- /etc/systemd/system/myos.service
- /etc/systemd/system/zram.service
copy: src=../files/{{item}} dest={{item}} owner=root group=root mode=0644

View File

@ -34,6 +34,10 @@
- import_tasks: ssh.yml
tags:
- ssh
- import_tasks: update.yml
tags:
- update
when: hosts_update|default(false)
- import_tasks: user.yml
tags:
- user

View File

@ -0,0 +1,32 @@
---
# file: tasks/update.yml
- name: update - copy files
with_items:
- /etc/cron.d/myos
copy: src=../files/{{item}} dest={{item}} owner=root group=root mode=0644
become: yes
- name: update - copy files - systemd
when: ansible_service_mgr|lower == "systemd"
with_items:
- /etc/systemd/system/ansible.service
- /etc/systemd/system/ansible.timer
copy: src=../files/{{item}} dest={{item}} owner=root group=root mode=0644
become: yes
- name: update - create /root/.myos
become: true
template:
src: myos.j2
dest: ~/.myos
force: no
mode: 0400
- name: update - create /root/Makefile
become: true
template:
src: Makefile.j2
dest: ~/Makefile
force: yes

View File

@ -11,13 +11,6 @@
copy: src="{{ item }}" dest=~/.ssh/ mode=0400
ignore_errors: true
- name: user - create ~/.myos
template:
src: myos.j2
dest: ~/.myos
force: no
mode: 0400
- name: user - create ~/.rc.d
file: path=~/.rc.d/ state={{hosts_user_rc_enable|default(false)|ternary('directory', 'absent')}} mode="0700"
@ -97,9 +90,3 @@
- :filetype plugin indent on
lineinfile: dest=~/.vimrc create=yes line='{{item}}'
- name: user - update ~/Makefile
template:
src: Makefile.j2
dest: ~/Makefile
force: yes

View File

@ -1,6 +1,5 @@
#!/bin/sh
set -euo pipefail
set -o errexit
set -euo errexit
trap 'kill -SIGQUIT $PID' INT

View File

@ -18,5 +18,8 @@ EXPOSE 9998 9999
ENTRYPOINT ["/usr/bin/fabio"]
CMD ["-cfg", "/etc/fabio/fabio.properties"]
HEALTHCHECK CMD status=$(echo -e 'GET /health HTTP/1.0\n' |nc -w 1 localhost 9998 | sed -n '$p') \
&& echo "$status" && [ "$status" = "OK" ] || exit 1
FROM dist as master
ARG DOCKER_BUILD_DIR

View File

@ -15,6 +15,7 @@ ipfs config Pubsub.Router gossipsub
ipfs config --json Experimental.Libp2pStreamMounting true
ipfs config --json Experimental.P2pHttpProxy true
ipfs config Addresses.Gateway "/ip4/0.0.0.0/tcp/8080"
ipfs config Addresses.Api "/ip4/0.0.0.0/tcp/5001"
## REMOVE IPFS BOOTSTRAP
ipfs bootstrap rm --all

3
docker/myos/.screenrc Normal file
View File

@ -0,0 +1,3 @@
hardstatus alwayslastline "%{= kw}[%{G}%H%{-}] \# %?%-Lw%?[%{G}%n%f %t%{-}]%?%+Lw%?%?%=%-17< [%{B}%l%{-}]"
defscrollback 1048576
shell -$SHELL

32
docker/myos/.tmux.conf Normal file
View File

@ -0,0 +1,32 @@
# this is aya's tmux configuration !
bind r source-file ~/.tmux.conf\; display-message "tmux.conf reloaded!"
bind R move-window -r
bind C-n switch-client -n\; refresh-client -S
bind C-p switch-client -p\; refresh-client -S
bind Escape copy-mode
bind Y run "tmux save-buffer - |xsel -i"
bind P run "xsel -o |tmux load-buffer -; tmux paste-buffer"
bind C-c run "tmux save-buffer - | xclip -i -sel clipboard >/dev/null"
bind C-v run "tmux set-buffer \"$(xclip -o -sel clipboard)\"; tmux paste-buffer"
bind -n S-down new-window
bind -n S-left prev
bind -n S-right next
bind -n C-left swap-window -t -1
bind -n C-right swap-window -t +1
set -g aggressive-resize on
set -g status-keys vi
setw -g mode-keys vi
setw -g window-status-current-bg blue
setw -g window-status-current-fg white
setw -g monitor-activity on
set -g visual-activity on
setw -g automatic-rename on
set -g default-terminal "screen"
set -g history-limit 4242
set -g status-bg black
set -g status-fg white
set -g status-interval 60
set -g status-left-length 30
set -g status-left '<#[fg=green]#S#[default]> '
set -g status-right '#[fg=yellow] %d/%m %H:%M#[default]'
set -g update-environment "SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID SSH_CONNECTION"

View File

@ -3,6 +3,8 @@ LABEL maintainer aynic.os <support+docker@asycn.io>
ARG DOCKER_BUILD_DIR
ARG GIT_AUTHOR_NAME
ARG GIT_AUTHOR_EMAIL
ARG OPERATING_SYSTEM=Linux
ARG PROCESSOR_ARCHITECTURE=x86_64
ENV GIT_AUTHOR_NAME=${GIT_AUTHOR_NAME}
ENV GIT_AUTHOR_EMAIL=${GIT_AUTHOR_EMAIL}
@ -12,15 +14,20 @@ ENV GIT_COMMITTER_EMAIL=${GIT_AUTHOR_EMAIL}
RUN apk upgrade --no-cache \
&& apk add --no-cache \
bash \
docker \
curl \
gettext \
git \
gpg \
gpg-agent \
make \
mysql-client \
nano \
netcat-openbsd \
openssh \
postgresql-client \
sudo \
zsh
screen \
socat \
tmux \
wget \
xz
RUN git clone https://github.com/ingydotnet/git-subrepo \
&& cd git-subrepo \
@ -33,7 +40,32 @@ RUN git clone https://github.com/ingydotnet/git-subrepo \
&& cd .. \
&& rm -rf git-subrepo
CMD ["bash"]
ARG IPFS_VERSION=0.13.0
RUN { OS="$(echo ${OPERATING_SYSTEM} |awk '{print tolower($0)}')"; \
ARCH="$(echo ${PROCESSOR_ARCHITECTURE})"; \
wget -qO - https://github.com/koalaman/shellcheck/releases/download/stable/shellcheck-stable.${OS}.${ARCH}.tar.xz \
|tar --strip-components 1 -C /usr/local/bin -xJf - shellcheck-stable/shellcheck; } \
&& { ARCH="$(echo ${PROCESSOR_ARCHITECTURE} |awk '/x86_64/ {print "amd64"}; /aarch64/ {print "arm64"}')"; \
wget -qO - https://github.com/ipfs/go-ipfs/releases/download/v${IPFS_VERSION}/go-ipfs_v${IPFS_VERSION}_${OS}-${ARCH}.tar.gz \
|tar --strip-components 1 -C /usr/local/bin -xzf - go-ipfs/ipfs; } \
&& mkdir -p /usr/local/lib/shellspec \
&& wget -qO - https://github.com/shellspec/shellspec/archive/refs/heads/master.tar.gz \
|tar --strip-components 1 -C /usr/local/lib/shellspec -xzf - \
&& ln -s /usr/local/lib/shellspec/shellspec /usr/local/bin/shellspec
ADD https://raw.github.com/kvz/cronlock/master/cronlock /usr/local/bin/cronlock
RUN chmod +rx /usr/local/bin/cronlock
# Setup environment variables; export SSH_AUTH_SOCK from socket directory
ENV SOCKET_DIR /tmp/ssh-agent
ENV SSH_AUTH_SOCK ${SOCKET_DIR}/socket
ENV SSH_AUTH_PROXY_SOCK ${SOCKET_DIR}/proxy-socket
COPY ${DOCKER_BUILD_DIR}/docker-entrypoint.sh /docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["start"]
FROM dist as master
ARG DOCKER_BUILD_DIR
@ -49,6 +81,15 @@ ENV UID=${UID}
ENV GID=${UID}
ENV USER=${USER}
RUN apk add --no-cache \
# docker \
# docker-compose \
# mysql-client \
# postgresql-client \
sudo
# vim \
# zsh
# If we provide a numeric UID
RUN [ "$UID" -eq "$UID" ] 2>/dev/null \
# Remove user with $UID if it is not our $USER
@ -77,9 +118,9 @@ RUN [ "$DOCKER_GID" -eq "$DOCKER_GID" ] 2>/dev/null \
|| true
## User groups
RUN adduser $USER docker \
&& adduser $USER wheel \
&& echo '%wheel ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
RUN adduser $USER wheel \
# && adduser $USER docker \
&& echo '%wheel ALL=(ALL:ALL) NOPASSWD: ALL' >> /etc/sudoers
RUN echo -e "\n\
Host *\n\
@ -103,6 +144,13 @@ Host ssh-bastion\n\
fi \
fi
# Custom rc functions
COPY ansible/roles/hosts/files/etc/profile.d/rc*.sh /etc/profile.d/
RUN mkdir -p $SOCKET_DIR && chown $USER $SOCKET_DIR
VOLUME ${SOCKET_DIR}
USER $USER
ENV SHELL=${SHELL}
WORKDIR /home/$USER
@ -120,3 +168,6 @@ RUN mkdir -p ~/.ssh ~/.config/git \
*.swp\n\
Thumbs.db\n\
" > ~/.config/git/ignore
# dot files
COPY ${DOCKER_BUILD_DIR}/.* /home/$USER/

View File

@ -0,0 +1,31 @@
#!/usr/bin/env sh
set -euo errexit
# Print a debug message if debug mode is on ($DEBUG is not empty)
# @param message
debug_msg ()
{
if [ -n "${DEBUG:-}" -a "${DEBUG:-}" != "false" ]; then
echo "$@"
fi
}
case "${1:-start}" in
start)
debug_msg "Starting..."
# Create proxy-socket for ssh-agent (to give everyone access to the ssh-agent socket)
debug_msg "Create proxy socket..."
rm -f ${SSH_AUTH_SOCK} ${SSH_AUTH_PROXY_SOCK} > /dev/null 2>&1
socat UNIX-LISTEN:${SSH_AUTH_PROXY_SOCK},perm=0666,fork UNIX-CONNECT:${SSH_AUTH_SOCK} &
debug_msg "Launch ssh-agent..."
exec /usr/bin/ssh-agent -a ${SSH_AUTH_SOCK} -D >/dev/null
;;
*)
debug_msg "Exec: $@"
exec "$@"
;;
esac

View File

@ -33,6 +33,7 @@ RUN apk add --no-cache ca-certificates
COPY --from=build /go/bin/registrator /bin/registrator
ENTRYPOINT ["/bin/registrator"]
HEALTHCHECK CMD kill -SIGUSR1 1
FROM dist as master
ARG DOCKER_BUILD_DIR

View File

@ -1,8 +1,6 @@
# this is aya's tmux configuration !
bind r source-file ~/.tmux.conf\; display-message "tmux.conf reloaded!"
bind R move-window -r
bind M-1 source ~/.tmux/sessions/aws-preprod
bind M-2 source ~/.tmux/sessions/aws-prod
bind C-n switch-client -n\; refresh-client -S
bind C-p switch-client -p\; refresh-client -S
bind Escape copy-mode

View File

@ -1,2 +0,0 @@
new-session -A -s aws-preprod
run-shell "ssh sshuser@ssh-bastion make list-nodes |sed '1d' |awk '$1 ~ /^aws\.preprod\.[0-9a-z]+$/' |while read host ip; do type=\${host#*preprod.}; num=\$(printf '%0d' \${ip}); num=\$(echo \${ip} | tr . '\n' | awk '{n = n*256 + $1} END{print n}'); tmux neww -t aws-preprod:\$num -n \$type '/bin/bash -cli \"force ssh -Aqt ssh-bastion ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no 'root@\$ip'\"'; done"

View File

@ -1,2 +0,0 @@
new-session -A -s aws-prod
run-shell "ssh sshuser@ssh-bastion make list-nodes |sed '1d' |awk '$1 ~ /^aws\.prod\.[0-9a-z]+$/' |while read host ip; do type=\${host#*prod.}; num=\$(printf '%0d' \${ip}); num=\$(echo \${ip} | tr . '\n' | awk '{n = n*256 + $1} END{print n}'); tmux neww -t aws-prod:\$num -n \$type '/bin/bash -cli \"force ssh -Aqt ssh-bastion ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no 'root@\$ip'\"'; done"

View File

@ -223,8 +223,8 @@ Host ssh-bastion\n\
User ${SSH_BASTION_USERNAME}\n\
" >> /etc/ssh/ssh_config
# Custom prompt
COPY ${DOCKER_BUILD_DIR}/rc*.sh /etc/profile.d/
# Custom rc functions
COPY ansible/roles/hosts/files/etc/profile.d/rc*.sh /etc/profile.d/
USER $USER
WORKDIR /home/$USER
@ -250,7 +250,6 @@ Thumbs.db\n\
# dot files
COPY ${DOCKER_BUILD_DIR}/.* /home/$USER/
COPY ${DOCKER_BUILD_DIR}/.tmux /home/$USER/.tmux/
ARG GIT_AUTHOR_NAME
ARG GIT_AUTHOR_EMAIL

View File

@ -1,39 +0,0 @@
# verify that default functions are loaded
type force >/dev/null 2>&1 || . /etc/profile.d/rc_functions.sh 2>/dev/null
# test current shell flags
case $- in
# if we are in an interactive shell
*i*)
# load user defined stuffs from ~/.rc.d
for user_func in "${HOME}"/.rc.d/*; do
# read files only
[ -f "${user_func}" ] && func_name=$(basename "${user_func}") || continue
func_args=$(cat "${user_func}")
# at this stage, func_name can start with numbers to allow ordering function calls with file names starting with numbers
# func_name must start with a letter, remove all other characters at the beginning of func_name until a letter is found
while [ "${func_name}" != "" ] && [ "${func_name#[a-z]}" = "${func_name}" ]; do
# remove first char of func_name
func_name="${func_name#?}"
done
# call user function with args passed from the content of the user_func file
[ -n "${func_name}" ] && ${func_name} ${func_args} 2>/dev/null
done
# load user defined stuffs from RC_* env vars
IFS=$'\n'; for func_line in $(env 2>/dev/null |awk '$0 ~ /^RC_/ {print tolower(substr($0,4))}'); do
func_name="${func_line%%=*}"
func_args="${func_line#*=}"
[ "${func_args}" = "false" ] && continue
[ "${func_args}" = "true" ] && unset func_args
# at this stage, func_name can start with numbers to allow ordering function calls with file names starting with numbers
# func_name must start with a letter, remove all other characters at the beginning of func_name until a letter is found
while [ "${func_name}" != "" ] && [ "${func_name#[a-z]}" = "${func_name}" ]; do
# remove first char of func_name
func_name="${func_name#?}"
done
# call user function with args passed from the value of the env var
[ -n "${func_name}" ] && ${func_name} ${func_args} 2>/dev/null
done
unset IFS
;;
esac

View File

@ -1,283 +0,0 @@
# shellcheck shell=sh
## rc_function.sh defines customs shell functions
# author: Yann "aya" Autissier
# license: MIT
# updated: 2021/03/04
## force() runs a command sine die
force() {
if [ $# -gt 0 ]; then
while true; do
"$@"
sleep 1
done
fi
}
## force8() runs a command sine die if not already running
force8() {
if [ $# -gt 0 ]; then
while true; do
# awk expression to match $@
[ "$(ps wwx -o args 2>/dev/null |awk -v field="${PS_X_FIELD:-1}" '
BEGIN { nargs=split("'"$*"'",args); }
# first field matched
$field == args[1] {
matched=1;
# match following fields
for (i=1;i<=NF-field;i++) {
if ($(i+field) == args[i+1]) { matched++; }
};
# all fields matched
if (matched == nargs) { found++; }
}
END { print found+0; }'
)" = 0 ] && "$@"
sleep 1
done
fi
}
## load_average() prints the current load average
load_average() {
awk '{printf "%.1f\n" $1}' /proc/loadavg 2>/dev/null\
|| uptime 2>/dev/null |awk '{printf "%.1f\n", $(NF-2)}'
}
## process_count() prints number of "processes"/"running processes"/"D-state"
process_count() {
ps ax -o stat 2>/dev/null |awk '
$1 ~ /R/ {process_running++};
$1 ~ /D/ {process_dstate++};
END { print NR-1"/"process_running+0"/"process_dstate+0; }'
}
## prompt_set() exports custom PROMPT_COMMAND
prompt_set() {
case "${TERM}" in
screen*)
ESCAPE_CODE_DCS="\033k"
ESCAPE_CODE_ST="\033\\"
;;
linux*|xterm*|rxvt*)
ESCAPE_CODE_DCS="\033]0;"
ESCAPE_CODE_ST="\007"
;;
*)
;;
esac
# in a screen
if [ -n "${STY}" ]; then
export PROMPT_COMMAND='printf\
"${ESCAPE_CODE_DCS:-\033]0;}%s${ESCAPE_CODE_ST:-\007}"\
"${PWD##*/}"'
else
export PROMPT_COMMAND='printf\
"${ESCAPE_CODE_DCS:-\033]0;}%s@%s:%s${ESCAPE_CODE_ST:-\007}"\
"${USER}"\
"${HOSTNAME%%.*}"\
"${PWD##*/}"'
fi
unset ESCAPE_CODE_DCS ESCAPE_CODE_ST
}
## ps1_set() exports custom PS1
ps1_set() {
case "$0" in
*sh)
COLOR_DGRAY="\[\033[1;30m\]"
COLOR_RED="\[\033[01;31m\]"
COLOR_GREEN="\[\033[01;32m\]"
COLOR_BROWN="\[\033[0;33m\]"
COLOR_YELLOW="\[\033[01;33m\]"
COLOR_BLUE="\[\033[01;34m\]"
COLOR_CYAN="\[\033[0;36m\]"
COLOR_GRAY="\[\033[0;37m\]"
COLOR_RESET="\[\033[0m\]"
;;
*)
;;
esac
PS1_STATUS="\$?"
PS1_COUNT="${COLOR_DGRAY}[\`
case \"$PS1_STATUS\" in
0)
printf \"${COLOR_BLUE}${PS1_STATUS}\";;
1)
printf \"${COLOR_YELLOW}${PS1_STATUS}\";;
*)
printf \"${COLOR_RED}${PS1_STATUS}\";;
esac
type process_count >/dev/null 2>&1 && printf\
\"${COLOR_DGRAY}|${COLOR_BLUE}%s\"\
\"\$(process_count 2>/dev/null)\"
type user_count >/dev/null 2>&1 && printf\
\"${PS1_COUNT}${COLOR_DGRAY}|${COLOR_BLUE}%s\"\
\"\$(user_count 2>/dev/null)\"
type load_average >/dev/null 2>&1 && printf\
\"${PS1_COUNT}${COLOR_DGRAY}|${COLOR_BLUE}%s\"\
\"\$(load_average 2>/dev/null)\"
\`${COLOR_DGRAY}]${COLOR_RESET}"
PS1_END="${COLOR_DGRAY}\$(
if [ \"\$(id -u)\" = 0 ]; then
printf \"#\";
else
printf \"\$\";
fi
)${COLOR_RESET}"
PS1_GIT="\$(
if type __git_ps1 >/dev/null 2>&1; then
printf \"\$(__git_ps1 2>/dev/null \" (%s)\")\"
else
printf \"\$(BRANCH=\$(git rev-parse --abbrev-ref HEAD 2>/dev/null);\
[ -n \"\${BRANCH}\" ] && printf \" (\${BRANCH})\")\"
fi
)"
PS1_GIT="${COLOR_CYAN}${PS1_GIT}${COLOR_RESET}"
PS1_HOSTNAME_COLOR="\`case \"\${ENV}\" in
[Pp][Rr][0Oo][Dd]*)
printf \"${COLOR_RED}\";;
*)
if [ -n \"\${ENV}\" ]; then
printf \"${COLOR_YELLOW}\";
else
printf \"${COLOR_GREEN}\";
fi;;
esac\`"
PS1_HOSTNAME="${PS1_HOSTNAME_COLOR}\$(hostname |sed 's/\..*//')${COLOR_RESET}"
PS1_USER_COLOR="\$(
if [ \"\$(id -u)\" = 0 ]; then
printf \"${COLOR_RED}\";
else
printf \"${COLOR_BROWN}\";
fi
)"
PS1_USER="${PS1_USER_COLOR}\$(id -nu):\$(id -u)${COLOR_RESET}"
PS1_WORKDIR="${COLOR_GRAY}\$(
pwd |sed 's|^'\${HOME}'\(/.*\)*$|~\1|'
)${COLOR_RESET}"
PS1="${PS1_COUNT}${PS1_USER}${COLOR_DGRAY}@${PS1_HOSTNAME}"
PS1="${PS1}${COLOR_DGRAY}:${PS1_WORKDIR}${PS1_GIT}${PS1_END} "
export 'PS1'
unset PS1_COUNT PS1_END PS1_GIT PS1_HOSTNAME PS1_HOSTNAME_COLOR\
PS1_USER PS1_USER_COLOR PS1_STATUS PS1_WORKDIR
}
## screen_attach() attaches existing screen session or creates a new one
screen_attach() {
command -v screen >/dev/null 2>&1 || return
SCREEN_SESSION="$(id -nu)@$(hostname |sed 's/\..*//')"
if [ -z "${STY}" ]; then
# attach screen in tmux window 0 only ;)
[ -n "${TMUX}" ] \
&& [ "$(tmux list-window 2>/dev/null |awk '$NF == "(active)" {print $1}'\
|sed 's/:$//')" != "0" ] \
&& return
printf 'Attaching screen.' && sleep 1\
&& printf '.' && sleep 1\
&& printf '.' && sleep 1
exec screen -xRR -S "${SCREEN_SESSION}"
fi
unset SCREEN_SESSION
}
## screen_detach() detaches current screen session
screen_detach() {
screen -d
}
## ssh_add() loads all private keys in ~/.ssh/ to ssh agent
ssh_add() {
command -v ssh-agent >/dev/null 2>&1 && command -v ssh-add >/dev/null 2>&1 || return
SSH_AGENT_DIR="/tmp/ssh-$(id -u)"
SSH_AGENT_SOCK="${SSH_AGENT_DIR}/agent@$(hostname |sed 's/\..*//')"
# launch a new agent
if [ -z "${SSH_AUTH_SOCK}" ]; then
[ ! -d "${SSH_AGENT_DIR}" ] \
&& mkdir -p "${SSH_AGENT_DIR}" 2>/dev/null\
&& chmod 0700 "${SSH_AGENT_DIR}"
# search for an already running agent
if ps wwx -o args |awk '$1 ~ "ssh-agent$" && $3 == "'"${SSH_AGENT_SOCK}"'"' |wc -l |grep -q 0; then
rm -f "${SSH_AGENT_SOCK}"
ssh-agent -a "${SSH_AGENT_SOCK}" >/dev/null 2>&1
fi
fi
# attach to agent
export SSH_AUTH_SOCK="${SSH_AUTH_SOCK:-${SSH_AGENT_SOCK}}"
# list private keys to add
# shellcheck disable=SC2068
for dir in ${@:-${HOME}/.ssh}; do
if [ "${SSH_ADD_RECURSIVE:-}" = true ]; then
GREP_RECURSIVE_FLAG="r"
else
GREP_RECURSIVE_CHAR="*"
fi
SSH_PRIVATE_KEYS="${SSH_PRIVATE_KEYS:-} ${dir}/id_rsa $(grep -l${GREP_RECURSIVE_FLAG:-} 'PRIVATE KEY' "${dir}"/"${GREP_RECURSIVE_CHAR:-}" 2>/dev/null |grep -vw "${dir}"/id_rsa)"
done
# shellcheck disable=SC2086
printf '%s\n' ${SSH_PRIVATE_KEYS} |while read -r file; do
[ -r "${file}" ] || continue
# add private key to agent
ssh-add -l |grep -q "$(ssh-keygen -lf "${file}" 2>/dev/null |awk '{print $2}')" 2>/dev/null || ssh-add "${file}"
done
unset GREP_RECURSIVE_CHAR GREP_RECURSIVE_FLAG SSH_AGENT_DIR SSH_AGENT_SOCK SSH_PRIVATE_KEYS
}
## ssh_del() removes all private keys in ~/.ssh/ from ssh agent
ssh_del() {
command -v ssh-add >/dev/null 2>&1 || return
# attach to agent
if [ -z "${SSH_AUTH_SOCK}" ]; then
return
fi
# list private keys to del
# shellcheck disable=SC2068
for dir in ${@:-${HOME}/.ssh}; do
if [ "${SSH_DEL_RECURSIVE:-}" = true ]; then
GREP_RECURSIVE_FLAG="r"
else
GREP_RECURSIVE_CHAR="*"
fi
SSH_PRIVATE_KEYS="${SSH_PRIVATE_KEYS:-} ${dir}/id_rsa $(grep -l${GREP_RECURSIVE_FLAG:-} 'PRIVATE KEY' "${dir}"/"${GREP_RECURSIVE_CHAR:-}" 2>/dev/null |grep -vw "${dir}"/id_rsa)"
done
# shellcheck disable=SC2086
printf '%s\n' ${SSH_PRIVATE_KEYS} |while read -r file; do
[ -r "${file}" ] || continue
# remove private key from agent
ssh-add -l |grep -q "$(ssh-keygen -lf "${file}" 2>/dev/null |awk '{print $2}')" 2>/dev/null && ssh-add -d "${file}"
done
unset GREP_RECURSIVE_CHAR GREP_RECURSIVE_FLAG SSH_PRIVATE_KEYS
}
## tmux_attach() attaches existing tmux session or creates a new one
tmux_attach() {
command -v tmux >/dev/null 2>&1 || return
TMUX_SESSION="$(id -nu)@$(hostname |sed 's/\..*//')"
if [ -z "${TMUX}" ]; then
printf 'Attaching tmux.' && sleep 1\
&& printf '.' && sleep 1\
&& printf '.' && sleep 1
exec tmux -L"${TMUX_SESSION}" new-session -A -s"${TMUX_SESSION}"
fi
unset TMUX_SESSION
}
## tmux_detach() detaches current tmux session
tmux_detach() {
tmux detach
}
## user_count() prints number of "users sessions"/"users"/"logged users"
user_count() {
ps ax -o user,tty 2>/dev/null |awk '
$2 ~ /^(pts|tty)/ { users_session++; logged[$1]++; };
{ count[$1]++; }
END {
for (uc in count) { c = c" "uc; }; users_count=split(c,v," ")-1;
for (ul in logged) { l = l" "ul; }; users_logged=split(l,v," ")-1;
print users_session+0"/"users_count"/"users_logged;
}'
}
# vim:ts=2:sw=2:sts=2:et

View File

@ -1,6 +1,5 @@
#!/bin/ash
set -euo pipefail
set -o errexit
set -euo errexit
trap 'kill -SIGQUIT $PID' INT

128
docker/zen/Dockerfile Normal file
View File

@ -0,0 +1,128 @@
FROM debian:bullseye as dist
LABEL maintainer aynic.os <support+docker@asycn.io>
ARG DOCKER_BUILD_DIR
ARG GIT_AUTHOR_NAME
ARG GIT_AUTHOR_EMAIL
ARG OPERATING_SYSTEM=Linux
ARG PROCESSOR_ARCHITECTURE=x86_64
ENV GIT_AUTHOR_NAME=${GIT_AUTHOR_NAME}
ENV GIT_AUTHOR_EMAIL=${GIT_AUTHOR_EMAIL}
ENV GIT_COMMITTER_NAME=${GIT_AUTHOR_NAME}
ENV GIT_COMMITTER_EMAIL=${GIT_AUTHOR_EMAIL}
RUN apt-get update \
&& apt-get -fy install \
bash \
curl \
gettext \
git \
gpg \
gpg-agent \
make \
nano \
netcat-openbsd \
openssh-client \
screen \
socat \
tmux \
wget \
xz-utils
ARG IPFS_VERSION=0.13.0
RUN { OS="$(echo ${OPERATING_SYSTEM} |awk '{print tolower($0)}')"; \
ARCH="$(echo ${PROCESSOR_ARCHITECTURE})"; \
wget -qO - https://github.com/koalaman/shellcheck/releases/download/stable/shellcheck-stable.${OS}.${ARCH}.tar.xz \
|tar --strip-components 1 -C /usr/local/bin -xJf - shellcheck-stable/shellcheck; } \
&& { ARCH="$(echo ${PROCESSOR_ARCHITECTURE} |awk '/x86_64/ {print "amd64"}; /aarch64/ {print "arm64"}')"; \
wget -qO - https://github.com/ipfs/go-ipfs/releases/download/v${IPFS_VERSION}/go-ipfs_v${IPFS_VERSION}_${OS}-${ARCH}.tar.gz \
|tar --strip-components 1 -C /usr/local/bin -xzf - go-ipfs/ipfs; } \
&& mkdir -p /usr/local/lib/shellspec \
&& wget -qO - https://github.com/shellspec/shellspec/archive/refs/heads/master.tar.gz \
|tar --strip-components 1 -C /usr/local/lib/shellspec -xzf - \
&& ln -s /usr/local/lib/shellspec/shellspec /usr/local/bin/shellspec
ADD https://raw.github.com/aya/dpgpid/master/keygen /usr/local/bin/keygen
RUN chmod +rx /usr/local/bin/keygen
ADD https://raw.github.com/kvz/cronlock/master/cronlock /usr/local/bin/cronlock
RUN chmod +rx /usr/local/bin/cronlock
ADD https://git.p2p.legal/axiom-team/astrXbian/raw/branch/master/include.sh /
ADD https://git.p2p.legal/axiom-team/astrXbian/raw/branch/master/install.sh /
RUN chmod +r /include.sh \
&& chmod +rx /install.sh
# COPY ${DOCKER_BUILD_DIR}/docker-entrypoint.sh /docker-entrypoint.sh
# ENTRYPOINT ["/docker-entrypoint.sh"]
# CMD ["/bin/sh"]
FROM dist as master
ARG DOCKER_BUILD_DIR
ARG DOCKER_GID
ARG SHELL=/bin/bash
ARG UID
ARG USER
ENV UID=${UID}
ENV GID=${UID}
ENV USER=${USER}
RUN apt-get -fy install \
cron \
pkg-config \
python3 \
sudo
# If we provide a numeric UID
RUN [ "$UID" -eq "$UID" ] 2>/dev/null \
# Remove user with $UID if it is not our $USER
&& if [ "$(getent passwd $UID |awk -F: '{print $1}')" != "$USER" ]; then \
sed -i '/^'$(getent passwd $UID |awk -F: '{print $1}')':x:'$UID':/d' /etc/passwd; \
sed -i '/^'$(getent group $GID |awk -F: '{print $1}')':x:'$GID':/d' /etc/group; \
fi \
# Force $UID if our $USER already exists
&& sed -i 's/^'$USER':x:[0-9]\+:[0-9]\+:/'$USER':x:'$UID':'$GID':/' /etc/passwd \
&& sed -i 's/^'$USER':x:[0-9]\+:/'$USER':x:'$GID':/' /etc/group \
# Create $USER if it does not exist
&& if [ "$(getent passwd $UID)" = "" ]; then \
echo "$USER:x:$UID:$GID::/home/$USER:$SHELL" >> /etc/passwd; \
echo "$USER:\!:$(($(date +%s) / 60 / 60 / 24)):0:99999:7:::" >> /etc/shadow; \
echo "$USER:x:$GID:" >> /etc/group; \
fi \
&& mkdir -p /home/$USER \
&& chown $UID:$GID /home/$USER \
|| true
# If we provide a numeric DOCKER_GID
RUN [ "$DOCKER_GID" -eq "$DOCKER_GID" ] 2>/dev/null \
&& if [ "$(getent group docker |awk -F: '{print $3}')" != "$DOCKER_GID" ]; then \
sed -i 's/^docker:x:[0-9]\+:/docker:x:'$DOCKER_GID':/' /etc/group; \
fi \
|| true
## group sudo
RUN adduser $USER sudo \
&& echo '%sudo ALL=(ALL:ALL) NOPASSWD: ALL' >> /etc/sudoers
USER $USER
ENV SHELL=${SHELL}
WORKDIR /home/$USER
# git config
RUN mkdir -p ~/.config/git \
&& echo -e "\
.DS_Store\n\
.idea/\n\
.nfs*\n\
*~\n\
*.log\n\
*.swp\n\
Thumbs.db\n\
" > ~/.config/git/ignore
RUN bash -c '. /include.sh && install_requirements'
COPY ${DOCKER_BUILD_DIR}/docker-entrypoint.sh /docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["start"]

33
docker/zen/docker-entrypoint.sh Executable file
View File

@ -0,0 +1,33 @@
#!/usr/bin/env sh
set -euo errexit
# Print a debug message if debug mode is on ($DEBUG is not empty)
# @param message
debug_msg ()
{
if [ -n "${DEBUG:-}" -a "${DEBUG:-}" != "false" ]; then
echo "$@"
fi
}
# Install astrXbian/Astroport.ONE
# /install.sh
case "${1:-start}" in
start)
debug_msg "Starting..."
exec sudo /usr/sbin/cron -f -L/dev/stdout
;;
install)
debug_msg "Installing..."
exec /install.sh
;;
*)
debug_msg "Exec: $@"
exec "$@"
;;
esac

View File

@ -81,6 +81,11 @@ exec@%: SERVICE ?= $(DOCKER_SERVICE)
exec@%:
$(call make,ssh-exec,$(MYOS),APP ARGS SERVICE)
# target force-%: Fire targets % and stack-node-%
# on local host
.PHONY: force-%
force-%: % stack-node-%;
# target install app-install: Install application
# on local host
.PHONY: install app-install
@ -150,6 +155,11 @@ run@%:
.PHONY: scale
scale: docker-compose-scale ## Scale SERVICE application to NUM dockers
# target shutdown: remove application, node and user dockers
# on local host
.PHONY: shutdown
shutdown: force-down ## Shutdown all dockers
# target ssh@%: Connect to % ENV
# on first remote host
.PHONY: ssh@%
@ -159,7 +169,7 @@ ssh@%:
# target stack: Call docker-stack for each STACK
## it updates COMPOSE_FILE with all .yml files of the current stack
.PHONY: stack
stack:
stack: docker-network-create
$(foreach stackz,$(STACK),$(call docker-stack,$(stackz)))
# target stack-%: Call docker-compose-% target on STACK
@ -172,7 +182,7 @@ stack-%:
$(eval command := $(lastword $(subst -, ,$*)))
$(if $(findstring -,$*), \
$(if $(filter $(command),$(filter-out %-%,$(patsubst docker-compose-%,%,$(filter docker-compose-%,$(MAKE_TARGETS))))), \
$(call make,docker-compose-$(command) STACK="$(stack)" $(if $(filter $(COMPOSE_PROJECT_NAME_NODE),$(stack)),COMPOSE_PROJECT_NAME=$(COMPOSE_PROJECT_NAME_NODE)),,ARGS COMPOSE_IGNORE_ORPHANS SERVICE)))
$(call make,docker-compose-$(command) STACK="$(stack)",,ARGS COMPOSE_IGNORE_ORPHANS SERVICE User node)))
# target start app-start: Start application dockers
# on local host
@ -192,7 +202,7 @@ tests: app-tests ## Test application
# target up: Create and start application dockers
# on local host
.PHONY: up
up: docker-compose-up app-start ## Create application dockers
up: stack-required docker-compose-up app-start ## Create application dockers
# target update app-update: Update application files
# on local host

View File

@ -29,6 +29,7 @@ DOCKER_BUILD_TARGETS ?= $(ENV_DEPLOY)
DOCKER_BUILD_VARS ?= APP BRANCH COMPOSE_VERSION DOCKER_GID DOCKER_REPOSITORY GID GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME OPERATING_SYSTEM PROCESSOR_ARCHITECTURE SSH_BASTION_HOSTNAME SSH_BASTION_USERNAME SSH_PRIVATE_IP_RANGE SSH_PUBLIC_HOST_KEYS SSH_REMOTE_HOSTS UID USER VERSION
DOCKER_COMPOSE ?= $(if $(DOCKER_RUN),docker/compose:$(COMPOSE_VERSION),$(or $(shell docker compose >/dev/null 2>&1 && printf 'docker compose\n'),docker-compose)) $(COMPOSE_ARGS)
DOCKER_COMPOSE_DOWN_OPTIONS ?=
DOCKER_COMPOSE_RUN_OPTIONS ?= --rm
DOCKER_COMPOSE_UP_OPTIONS ?= -d
DOCKER_IMAGE_TAG ?= $(if $(filter $(ENV),$(ENV_DEPLOY)),$(VERSION),$(if $(DRONE_BUILD_NUMBER),$(DRONE_BUILD_NUMBER),latest))
DOCKER_IMAGES ?= $(patsubst %/,%,$(patsubst docker/%,%,$(dir $(wildcard docker/*/Dockerfile))))
@ -56,32 +57,18 @@ DOCKER_COMPOSE_DOWN_OPTIONS := --rmi all -v
DOCKER_COMPOSE_UP_OPTIONS := -d --build
endif
# https://github.com/docker/libnetwork/pull/2348
ifeq ($(OPERATING_SYSTEM),Darwin)
DOCKER_HOST_IFACE ?= $(shell docker run --rm -it --net=host alpine /sbin/ip -4 route list match 0/0 2>/dev/null |awk '{print $$5}' |awk '!seen[$$0]++' |head -1)
DOCKER_HOST_INET ?= $(shell docker run --rm -it --net=host alpine /sbin/ip -4 addr show $(DOCKER_HOST_IFACE) 2>/dev/null |awk '$$1 == "inet" {sub(/\/.*/,"",$$2); print $$2}')
DOCKER_INTERNAL_DOCKER_GATEWAY ?= $(shell docker run --rm -it alpine getent hosts gateway.docker.internal 2>/dev/null |awk '{print $$1}' |head -1)
DOCKER_INTERNAL_DOCKER_HOST ?= $(shell docker run --rm -it alpine getent hosts host.docker.internal 2>/dev/null |awk '{print $$1}' |head -1)
else
DOCKER_HOST_IFACE ?= $(shell /sbin/ip -4 route list match 0/0 2>/dev/null |awk '{print $$5}' |awk '!seen[$$0]++' |head -1)
DOCKER_HOST_INET ?= $(shell /sbin/ip -4 addr show $(DOCKER_HOST_IFACE) 2>/dev/null |awk '$$1 == "inet" {sub(/\/.*/,"",$$2); print $$2}')
DOCKER_INTERNAL_DOCKER_GATEWAY ?= $(shell /sbin/ip -4 route list match 0/0 2>/dev/null |awk '{print $$3}' |awk '!seen[$$0]++' |head -1)
DOCKER_INTERNAL_DOCKER_HOST ?= $(shell /sbin/ip addr show docker0 2>/dev/null |awk '$$1 == "inet" {sub(/\/.*/,"",$$2); print $$2}')
endif
# function docker-compose: Run docker-compose with arg 1
define docker-compose
$(call INFO,docker-compose,$(1))
$(if $(DOCKER_RUN),$(call docker-build,$(MYOS)/docker/compose,docker/compose:$(COMPOSE_VERSION)))
$(call run,$(DOCKER_COMPOSE) $(patsubst %,-f %,$(COMPOSE_FILE)) -p $(COMPOSE_PROJECT_NAME) $(1))
$(if $(COMPOSE_FILE),$(call run,$(DOCKER_COMPOSE) $(patsubst %,-f %,$(COMPOSE_FILE)) -p $(if $(filter node,$(firstword $(subst /, ,$(STACK)))),$(COMPOSE_PROJECT_NAME_NODE),$(COMPOSE_PROJECT_NAME)) $(1)))
endef
# function docker-compose-exec: Run docker-compose-exec with arg 2 in service 1
define docker-compose-exec
$(call INFO,docker-compose-exec,$(1)$(comma) $(2))
$(if $(DOCKER_RUN),$(call docker-build,$(MYOS)/docker/compose,docker/compose:$(COMPOSE_VERSION)))
$(call run,$(DOCKER_COMPOSE) $(patsubst %,-f %,$(COMPOSE_FILE)) -p $(COMPOSE_PROJECT_NAME) exec -T $(1) sh -c '$(2)')
$(if $(COMPOSE_FILE),$(call run,$(DOCKER_COMPOSE) $(patsubst %,-f %,$(COMPOSE_FILE)) -p $(if $(filter node,$(firstword $(subst /, ,$(STACK)))),$(COMPOSE_PROJECT_NAME_NODE),$(if $(filter User,$(firstword $(subst /, ,$(STACK)))),$(COMPOSE_PROJECT_NAME_USER),$(COMPOSE_PROJECT_NAME))) exec -T $(1) sh -c '$(2)'))
endef
# function docker-build: Build docker image
define docker-build
$(call INFO,docker-build,$(1)$(comma) $(2)$(comma) $(3))

View File

@ -1,5 +1,5 @@
APP_DIR ?= $(CURDIR)
APP_DOMAIN ?= $(addsuffix .,$(filter-out master,$(ENV)))$(DOMAIN)
APP_DOMAIN ?= $(addsuffix .,$(filter-out master,$(ENV)))$(USER).$(DOMAIN)
APP_HOST ?= $(addsuffix .,$(APP))$(APP_DOMAIN)
APP_INSTALLED ?= $(APPS)
APP_PARENT ?= $(MONOREPO)

View File

@ -46,7 +46,7 @@ docker-compose-connect:
.PHONY: docker-compose-down
docker-compose-down: DOCKER_RUN_OPTIONS += -it
docker-compose-down:
$(if $(filter $(SERVICE),$(SERVICES)),$(call docker-compose,rm -fs $(SERVICE)),$(call docker-compose,down $(DOCKER_COMPOSE_DOWN_OPTIONS)))
$(if $(filter $(SERVICE),$(SERVICES)),$(call docker-compose,rm -fs $(SERVICE)),$(call docker-compose,down $(DOCKER_COMPOSE_DOWN_OPTIONS) ||:))
# target docker-compose-exec: Call docker-compose-exec SERVICE ARGS
.PHONY: docker-compose-exec
@ -89,7 +89,7 @@ docker-compose-rm:
docker-compose-run: SERVICE ?= $(DOCKER_SERVICE)
docker-compose-run: DOCKER_RUN_OPTIONS += -it
docker-compose-run:
$(call docker-compose,run $(SERVICE) $(ARGS))
$(call docker-compose,run $(DOCKER_COMPOSE_RUN_OPTIONS) $(SERVICE) $(ARGS))
# target docker-compose-scale: Call docker-compose up --scale SERVICE=NUM
.PHONY: docker-compose-scale

View File

@ -9,7 +9,6 @@ NFS_DISK ?= $(NFS_HOST):/$(notdir $(SHARED))
NFS_OPTIONS ?= rw,rsize=8192,wsize=8192,bg,hard,intr,nfsvers=3,noatime,nodiratime,actimeo=3
NFS_PATH ?= /dns/$(subst $(space),/,$(strip $(call reverse,$(subst ., ,$(NFS_HOST)))))$(subst ..,,$(SHARED))
SHELL ?= /bin/sh
STACK ?= User
env ?= $(ENV)
user ?= $(USER)

View File

@ -1,16 +0,0 @@
##
# NODE
# target node-ssl-certs: Create ${DOMAIN}.key.pem and ${DOMAIN}.crt.pem files
.PHONY: node-ssl-certs
node-ssl-certs:
docker run --rm --mount source=$(COMPOSE_PROJECT_NAME_NODE)_ssl-certs,target=/certs alpine [ -f /certs/$(DOMAIN).crt.pem -a -f /certs/$(DOMAIN).key.pem ] \
|| $(RUN) docker run --rm -e DOMAIN=$(DOMAIN) --mount source=$(COMPOSE_PROJECT_NAME_NODE)_ssl-certs,target=/certs alpine sh -c "\
apk --no-cache add openssl \
&& { [ -f /certs/${DOMAIN}.key.pem ] || openssl genrsa -out /certs/${DOMAIN}.key.pem 2048; } \
&& openssl req -key /certs/${DOMAIN}.key.pem -out /certs/${DOMAIN}.crt.pem \
-addext extendedKeyUsage=serverAuth \
-addext subjectAltName=DNS:${DOMAIN} \
-subj \"/C=/ST=/L=/O=/CN=${DOMAIN}\" \
-x509 -days 365"

View File

@ -11,7 +11,7 @@ ssh: ssh-get-PrivateIpAddress-$(SERVER_NAME) ## Connect to first remote host
ssh-add: DOCKER_RUN_OPTIONS += -it
ssh-add: ssh-key
$(eval SSH_PRIVATE_KEYS := $(foreach file,$(SSH_DIR)/id_rsa $(filter-out $(wildcard $(SSH_DIR)/id_rsa),$(wildcard $(SSH_DIR)/*)),$(if $(shell grep "PRIVATE KEY" $(file) 2>/dev/null),$(notdir $(file)))))
$(call run,sh -c '$(foreach file,$(patsubst %,$(SSH_DIR)/%,$(SSH_PRIVATE_KEYS)),ssh-add -l |grep -qw $$(ssh-keygen -lf $(file) 2>/dev/null |awk '\''{print $$2}'\'') 2>/dev/null || $(RUN) ssh-add $(file) ||: &&) true',-v $(SSH_DIR):$(SSH_DIR) $(DOCKER_IMAGE_CLI) )
$(call run,sh -c '$(foreach file,$(patsubst %,$(SSH_DIR)/%,$(SSH_PRIVATE_KEYS)),ssh-add -l |grep -qw $$(ssh-keygen -lf $(file) 2>/dev/null |awk '\''{print $$2}'\'') 2>/dev/null || $(RUN) ssh-add $(file) ||: &&) true',-v $(SSH_DIR):$(SSH_DIR) $(DOCKER_IMAGE) )
# target ssh-connect: Call ssh-connect make connect SERVICE
.PHONY: ssh-connect
@ -22,7 +22,7 @@ ssh-connect: ssh-get-PrivateIpAddress-$(SERVER_NAME)
.PHONY: ssh-del
ssh-del:
$(eval SSH_PRIVATE_KEYS := $(foreach file,$(SSH_DIR)/id_rsa $(filter-out $(wildcard $(SSH_DIR)/id_rsa),$(wildcard $(SSH_DIR)/*)),$(if $(shell grep "PRIVATE KEY" $(file) 2>/dev/null),$(notdir $(file)))))
$(call run,sh -c '$(foreach file,$(patsubst %,$(SSH_DIR)/%,$(SSH_PRIVATE_KEYS)),ssh-add -l |grep -qw $$(ssh-keygen -lf $(file) 2>/dev/null |awk '\''{print $$2}'\'') 2>/dev/null && $(RUN) ssh-add -d $(file) ||: &&) true',-v $(SSH_DIR):$(SSH_DIR) $(DOCKER_IMAGE_CLI) )
$(call run,sh -c '$(foreach file,$(patsubst %,$(SSH_DIR)/%,$(SSH_PRIVATE_KEYS)),ssh-add -l |grep -qw $$(ssh-keygen -lf $(file) 2>/dev/null |awk '\''{print $$2}'\'') 2>/dev/null && $(RUN) ssh-add -d $(file) ||: &&) true',-v $(SSH_DIR):$(SSH_DIR) $(DOCKER_IMAGE) )
# target ssh-exec: Call ssh-exec make exec SERVICE ARGS
.PHONY: ssh-exec
@ -35,7 +35,7 @@ ssh-get-PrivateIpAddress-%: aws-ec2-get-instances-PrivateIpAddress-%;
# target ssh-key: Add ssh private key SSH_KEY to SSH_DIR
.PHONY: ssh-key
ssh-key: $(if $(DOCKER_RUN),stack-User-up)
ssh-key:
ifneq (,$(filter true,$(DRONE)))
$(call exec,sh -c '[ ! -d $(SSH_DIR) ] && mkdir -p $(SSH_DIR) && chown $(UID) $(SSH_DIR) && chmod 0700 $(SSH_DIR) ||:')
endif

View File

@ -1,16 +1,14 @@
COMPOSE_PROJECT_NAME_NODE ?= node
COMPOSE_PROJECT_NAME_USER ?= $(USER_ENV)_myos
COMPOSE_PROJECT_NAME_USER ?= $(USER)_$(ENV)
COMPOSE_SERVICE_NAME_NODE ?= $(subst _,-,$(COMPOSE_PROJECT_NAME_NODE))
COMPOSE_SERVICE_NAME_USER ?= $(subst _,-,$(COMPOSE_PROJECT_NAME_USER))
DOCKER_ENV_ARGS ?= $(docker_env_args)
DOCKER_EXEC_OPTIONS ?=
DOCKER_GID ?= $(call gid,docker)
DOCKER_IMAGE ?= $(DOCKER_IMAGE_CLI)
DOCKER_IMAGE_CLI ?= $(DOCKER_REPOSITORY_USER)/cli
DOCKER_IMAGE_SSH ?= $(DOCKER_REPOSITORY_USER)/ssh
DOCKER_NAME ?= $(DOCKER_NAME_CLI)
DOCKER_NAME_CLI ?= $(COMPOSE_PROJECT_NAME_USER)_cli
DOCKER_NAME_SSH ?= $(COMPOSE_PROJECT_NAME_USER)_ssh
DOCKER_IMAGE ?= $(DOCKER_REPOSITORY_USER)/myos
DOCKER_NAME ?= $(COMPOSE_PROJECT_NAME_USER)_myos
DOCKER_NETWORK ?= $(DOCKER_NETWORK_PRIVATE)
DOCKER_NETWORK_PRIVATE ?= $(USER_ENV)
DOCKER_NETWORK_PRIVATE ?= $(COMPOSE_PROJECT_NAME_USER)
DOCKER_NETWORK_PUBLIC ?= $(COMPOSE_PROJECT_NAME_NODE)
DOCKER_REPOSITORY_USER ?= $(subst -,/,$(subst _,/,$(COMPOSE_PROJECT_NAME_USER)))
DOCKER_REPOSITORY_NODE ?= $(subst -,/,$(subst _,/,$(COMPOSE_PROJECT_NAME_NODE)))
@ -21,8 +19,21 @@ DOCKER_RUN_OPTIONS += --rm
# DOCKER_RUN_VOLUME: options -v of `docker run` command to mount additionnal volumes
DOCKER_RUN_VOLUME += -v /var/run/docker.sock:/var/run/docker.sock
DOCKER_RUN_WORKDIR ?= -w $(PWD)
DOCKER_VOLUME_SSH ?= $(COMPOSE_PROJECT_NAME_USER)_ssh
ENV_VARS += DOCKER_IMAGE_CLI DOCKER_IMAGE_SSH DOCKER_NAME_CLI DOCKER_NAME_SSH DOCKER_NETWORK_PRIVATE DOCKER_NETWORK_PUBLIC DOCKER_REPOSITORY_USER DOCKER_REPOSITORY_NODE DOCKER_VOLUME_SSH
DOCKER_VOLUME ?= $(COMPOSE_PROJECT_NAME_USER)_myos
ENV_VARS += COMPOSE_PROJECT_NAME_NODE COMPOSE_PROJECT_NAME_USER COMPOSE_SERVICE_NAME_NODE COMPOSE_SERVICE_NAME_USER DOCKER_IMAGE DOCKER_NAME DOCKER_NETWORK_PRIVATE DOCKER_NETWORK_PUBLIC DOCKER_REPOSITORY_USER DOCKER_REPOSITORY_NODE DOCKER_VOLUME
# https://github.com/docker/libnetwork/pull/2348
ifeq ($(OPERATING_SYSTEM),Darwin)
DOCKER_HOST_IFACE ?= $(shell docker run --rm -it --net=host alpine /sbin/ip -4 route list match 0/0 2>/dev/null |awk '{print $$5}' |awk '!seen[$$0]++' |head -1)
DOCKER_HOST_INET4 ?= $(shell docker run --rm -it --net=host alpine /sbin/ip -4 addr show $(DOCKER_HOST_IFACE) 2>/dev/null |awk '$$1 == "inet" {sub(/\/.*/,"",$$2); print $$2}' |head -1)
DOCKER_INTERNAL_DOCKER_GATEWAY ?= $(shell docker run --rm -it alpine getent hosts gateway.docker.internal 2>/dev/null |awk '{print $$1}' |head -1)
DOCKER_INTERNAL_DOCKER_HOST ?= $(shell docker run --rm -it alpine getent hosts host.docker.internal 2>/dev/null |awk '{print $$1}' |head -1)
else
DOCKER_HOST_IFACE ?= $(shell /sbin/ip -4 route list match 0/0 2>/dev/null |awk '{print $$5}' |awk '!seen[$$0]++' |head -1)
DOCKER_HOST_INET4 ?= $(shell /sbin/ip -4 addr show $(DOCKER_HOST_IFACE) 2>/dev/null |awk '$$1 == "inet" {sub(/\/.*/,"",$$2); print $$2}' |head -1)
DOCKER_INTERNAL_DOCKER_GATEWAY ?= $(shell /sbin/ip -4 route list match 0/0 2>/dev/null |awk '{print $$3}' |awk '!seen[$$0]++' |head -1)
DOCKER_INTERNAL_DOCKER_HOST ?= $(shell /sbin/ip addr show docker0 2>/dev/null |awk '$$1 == "inet" {sub(/\/.*/,"",$$2); print $$2}' |head -1)
endif
ifeq ($(DRONE), true)
DOCKER_RUN_OPTIONS := --rm --network $(DOCKER_NETWORK)
@ -36,7 +47,7 @@ endif
ifneq ($(DOCKER_RUN),)
DOCKER_SSH_AUTH := -e SSH_AUTH_SOCK=/tmp/ssh-agent/socket -v $(DOCKER_VOLUME_SSH):/tmp/ssh-agent
DOCKER_SSH_AUTH := -e SSH_AUTH_SOCK=/tmp/ssh-agent/socket -v $(DOCKER_VOLUME):/tmp/ssh-agent
# function docker-run: Run docker image 2 with arg 1
define docker-run

View File

@ -53,7 +53,7 @@ ENV_ARGS ?= $(env_args)
ENV_FILE ?= $(wildcard $(CONFIG)/$(ENV)/$(APP)/.env .env)
ENV_LIST ?= $(shell ls .git/refs/heads/ 2>/dev/null)
ENV_RESET ?= false
ENV_VARS ?= APP BRANCH DOMAIN ENV HOSTNAME GID GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME MONOREPO MONOREPO_DIR OPERATING_SYSTEM PROCESSOR_ARCHITECTURE TAG UID USER VERSION
ENV_VARS ?= APP BRANCH DOMAIN ENV HOME HOSTNAME GID GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME MONOREPO MONOREPO_DIR OPERATING_SYSTEM PROCESSOR_ARCHITECTURE TAG UID USER VERSION
GID ?= $(shell id -g 2>/dev/null)
GIT_AUTHOR_EMAIL ?= $(or $(shell git config user.email 2>/dev/null),$(USER)@my.os)
GIT_AUTHOR_NAME ?= $(or $(shell git config user.name 2>/dev/null),$(USER))
@ -102,7 +102,6 @@ SUDO ?= $(if $(filter-out 0,$(UID)),$(shell type -p s
TAG ?= $(GIT_TAG)
UID ?= $(shell id -u 2>/dev/null)
USER ?= $(shell id -nu 2>/dev/null)
USER_ENV ?= $(USER)_$(ENV)
VERBOSE ?= $(if $(DEBUG),true)
VERSION ?= $(GIT_VERSION)

View File

@ -84,7 +84,7 @@ define .env_update
printenv \
|awk -F '=' 'NR == FNR { if($$1 !~ /^(#|$$)/) { A[$$1]; next } } !($$1 in A)' - $(env_dist) \
|cat $(env_over) - \
|awk 'BEGIN {split("$(MAKECMDVARS)",vars," "); for (var in vars) {print vars[var]"="ENVIRON[vars[var]]};} {print}' \
|awk 'BEGIN {split("$(MAKE_CMD_VARS)",vars," "); for (var in vars) {print vars[var]"="ENVIRON[vars[var]]};} {print}' \
|awk -F '=' '!seen[$$1]++' \
|awk -F '=' 'ARGV[1] == FILENAME { A[$$1]; next } ($$1 in A)' $(env_dist) - 2>/dev/null \
|awk -F '=' 'ARGV[1] == FILENAME { A[$$1]; next } !($$1 in A)' $(env_file) - 2>/dev/null \

View File

@ -1,3 +1,11 @@
# target user: Fire ssh-add
User ?= User/User
# target user: Fire user-agent
.PHONY: User user
User user: bootstrap-docker docker-network-create $(if $(DOCKER_RUN),stack-User-up) ssh-add
User user: bootstrap-docker bootstrap-user $(if $(DOCKER_RUN),stack-User-up) user-agent
# target user-agent: Fire ssh-add
user-agent: ssh-add
# target User-% user-%; Fire target stack-User-%
User-% user-%: stack-User-%;

6
stack/User/.env.dist Normal file
View File

@ -0,0 +1,6 @@
MYOS_RC_PROMPT_SET=true
MYOS_RC_PS1_SET=true
MYOS_RC_SCREEN_ATTACH=false
MYOS_RC_SOURCE=/etc/profile.d/rc_functions.sh
MYOS_RC_SSH_ADD=false
MYOS_RC_TMUX_ATTACH=false

View File

@ -1,13 +1,14 @@
version: '3.6'
services:
cli:
myos:
build:
args:
- DOCKER_BUILD_DIR=docker/cli
- DOCKER_BUILD_DIR=docker/myos
- GID=${GID}
- GIT_AUTHOR_NAME=${GIT_AUTHOR_NAME}
- GIT_AUTHOR_EMAIL=${GIT_AUTHOR_EMAIL}
- IPFS_VERSION=0.13.0
- UID=${UID}
- USER=${USER}
- SSH_BASTION_HOSTNAME=${SSH_BASTION_HOSTNAME}
@ -15,40 +16,33 @@ services:
- SSH_PUBLIC_HOSTS=${SSH_PUBLIC_HOSTS}
- SSH_PRIVATE_IP_RANGE=${SSH_PRIVATE_IP_RANGE}
context: ../..
dockerfile: docker/cli/Dockerfile
command: tail -f /dev/null
container_name: ${DOCKER_NAME_CLI}
depends_on:
- ssh
dockerfile: docker/myos/Dockerfile
container_name: ${DOCKER_NAME}
environment:
- SSH_AUTH_SOCK=/tmp/ssh-agent/socket
image: ${DOCKER_IMAGE_CLI}:${DOCKER_IMAGE_TAG}
- ENV=${ENV}
- RC_00_SOURCE=${MYOS_RC_SOURCE}
- RC_01_PS1_SET=${MYOS_RC_PS1_SET}
- RC_02_PROMPT_SET=${MYOS_RC_PROMPT_SET}
- RC_03_SSH_ADD=${MYOS_RC_SSH_ADD}
- RC_04_TMUX_ATTACH=${MYOS_RC_TMUX_ATTACH}
- RC_05_SCREEN_ATTACH=${MYOS_RC_SCREEN_ATTACH}
- SHELL=${DOCKER_SHELL}
image: ${DOCKER_IMAGE}:${DOCKER_IMAGE_TAG}
networks:
- private
restart: always
user: ${UID}:${GID}
volumes:
- ssh:/tmp/ssh-agent:ro
# - ${HOME}:${HOME}:cached
- ${MONOREPO_DIR}:${MONOREPO_DIR}:cached
- myos:/tmp/ssh-agent
# - /var/run/docker.sock:/var/run/docker.sock
working_dir: ${MONOREPO_DIR}
ssh:
build:
args:
- DOCKER_BUILD_DIR=docker/ssh
- GID=${GID}
- UID=${UID}
- USER=${USER}
context: ../..
dockerfile: docker/ssh/Dockerfile
container_name: ${DOCKER_NAME_SSH}
image: ${DOCKER_IMAGE_SSH}:${DOCKER_IMAGE_TAG}
networks:
- private
restart: always
volumes:
- ssh:/tmp/ssh-agent
volumes:
ssh:
myos:
external: true
name: ${DOCKER_VOLUME}
networks:
private:

View File

@ -0,0 +1 @@
IPFS_SERVICE_8080_TAGS_USER=urlprefix-ipfs.${USER}.${DOMAIN}/

56
stack/User/ipfs/ipfs.yml Normal file
View File

@ -0,0 +1,56 @@
version: '3.6'
services:
ipfs:
build:
args:
- DOCKER_BUILD_DIR=docker/ipfs
- IPFS_VERSION=0.13.0
context: ../..
dockerfile: docker/ipfs/Dockerfile
command: daemon --migrate=true
container_name: ${COMPOSE_PROJECT_NAME_USER}_ipfs
cpus: 0.5
environment:
- IPFS_PROFILE=${IPFS_PROFILE}
image: ${DOCKER_REPOSITORY_USER}/ipfs:${DOCKER_IMAGE_TAG}
labels:
- SERVICE_4001_CHECK_TCP=true
- SERVICE_4001_NAME=${COMPOSE_SERVICE_NAME_USER}-ipfs:4001
- SERVICE_5001_CHECK_TCP=true
- SERVICE_5001_NAME=${COMPOSE_SERVICE_NAME_USER}-ipfs:5001
- SERVICE_8080_CHECK_HTTP=/ipfs/QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG/readme
- SERVICE_8080_NAME=${COMPOSE_SERVICE_NAME_USER}-ipfs:8080
- SERVICE_8080_TAGS=${IPFS_SERVICE_8080_TAGS_USER}
- SERVICE_8081_IGNORE=true
networks:
- private
- public
ports:
- 4001
- 5001/tcp
- 8080/tcp
ulimits:
nofile:
soft: 65536
hard: 65536
volumes:
- ipfs:/data/ipfs:delegated
restart: always
volumes:
ipfs:
driver: local
driver_opts:
type: none
device: ${HOME}/.ipfs
o: bind
name: ${COMPOSE_PROJECT_NAME_USER}_ipfs
networks:
private:
external: true
name: ${DOCKER_NETWORK_PRIVATE}
public:
external: true
name: ${DOCKER_NETWORK_PUBLIC}

1
stack/ipfs/.env.dist Normal file
View File

@ -0,0 +1 @@
IPFS_SERVICE_8080_TAGS=urlprefix-ipfs.${APP_DOMAIN}/

45
stack/ipfs/ipfs.yml Normal file
View File

@ -0,0 +1,45 @@
version: '3.6'
services:
ipfs:
build:
args:
- DOCKER_BUILD_DIR=docker/ipfs
- IPFS_VERSION=0.13.0
context: ../..
dockerfile: docker/ipfs/Dockerfile
command: daemon --migrate=true
cpus: 0.5
environment:
- IPFS_PROFILE=${IPFS_PROFILE}
image: ${DOCKER_REPOSITORY}/ipfs:${DOCKER_IMAGE_TAG}
labels:
- SERVICE_4001_CHECK_TCP=true
- SERVICE_4001_NAME=${COMPOSE_SERVICE_NAME}-ipfs:4001
- SERVICE_5001_CHECK_TCP=true
- SERVICE_5001_NAME=${COMPOSE_SERVICE_NAME}-ipfs:5001
- SERVICE_8080_CHECK_HTTP=/ipfs/QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG/readme
- SERVICE_8080_NAME=${COMPOSE_SERVICE_NAME}-ipfs:8080
- SERVICE_8080_TAGS=${IPFS_SERVICE_8080_TAGS}
- SERVICE_8081_IGNORE=true
networks:
- private
ports:
- 4001
- 5001/tcp
- 8080/tcp
ulimits:
nofile:
soft: 65536
hard: 65536
volumes:
- ipfs:/data/ipfs:delegated
restart: always
volumes:
ipfs:
networks:
private:
external: true
name: ${DOCKER_NETWORK_PRIVATE}

View File

@ -1,6 +1,6 @@
logs ?= sematext/logagent
# target app-build-logagent: Exec 'rm -Rf /root/.npm /log-buufer/*' in docker SERVICE
# target app-build-logagent: Exec 'rm -Rf /root/.npm /log-buffer/*' in docker SERVICE
.PHONY: app-build-logagent
app-build-logagent:
$(call make,docker-compose-exec ARGS='rm -Rf /root/.npm /log-buffer/*' SERVICE=logagent)

View File

@ -1,7 +1,23 @@
ENV_VARS += DOCKER_HOST_IFACE DOCKER_HOST_INET IPFS_PROFILE
IPFS_PROFILE ?= $(if $(filter-out amd64 x86_64,$(PROCESSOR_ARCHITECTURE)),lowpower,server)
node ?= node/node node/ipfs
ENV_VARS += DOCKER_HOST_IFACE DOCKER_HOST_INET4 DOCKER_INTERNAL_DOCKER_HOST IPFS_PROFILE
IPFS_PROFILE ?= $(if $(filter-out amd64 x86_64,$(PROCESSOR_ARCHITECTURE)),lowpower,server)
# target node: Fire docker-network-create-% for DOCKER_NETWORK_PUBLIC node-ssl-certs stack-node-up
.PHONY: node
node: bootstrap-docker docker-network-create-$(DOCKER_NETWORK_PUBLIC) node-ssl-certs stack-node-up
node: bootstrap-docker bootstrap-host stack-node-up
# target node-%; Fire target stack-node-%
node-%: stack-node-%;
# target node-ssl-certs: Create ${DOMAIN}.key.pem and ${DOMAIN}.crt.pem files
.PHONY: node-ssl-certs
node-ssl-certs:
docker run --rm --mount source=$(COMPOSE_PROJECT_NAME_NODE)_ssl-certs,target=/certs alpine [ -f /certs/$(DOMAIN).crt.pem -a -f /certs/$(DOMAIN).key.pem ] \
|| $(RUN) docker run --rm -e DOMAIN=$(DOMAIN) --mount source=$(COMPOSE_PROJECT_NAME_NODE)_ssl-certs,target=/certs alpine sh -c "\
apk --no-cache add openssl \
&& { [ -f /certs/${DOMAIN}.key.pem ] || openssl genrsa -out /certs/${DOMAIN}.key.pem 2048; } \
&& openssl req -key /certs/${DOMAIN}.key.pem -out /certs/${DOMAIN}.crt.pem \
-addext extendedKeyUsage=serverAuth \
-addext subjectAltName=DNS:${DOMAIN} \
-subj \"/C=/ST=/L=/O=/CN=${DOMAIN}\" \
-x509 -days 365"

View File

@ -1,8 +1,7 @@
CONSUL_ACL_TOKENS_MASTER=01234567-89AB-CDEF-0123-456789ABCDEF
CONSUL_CONSUL_HTTP_TOKEN=01234567-89AB-CDEF-0123-456789ABCDEF
CONSUL_SERVICE_8500_TAGS=urlprefix-consul.${APP_DOMAIN}/
CONSUL_SERVICE_8500_TAGS=urlprefix-consul.${DOMAIN}/
FABIO_CONSUL_HTTP_TOKEN=01234567-89AB-CDEF-0123-456789ABCDEF
FABIO_SERVICE_9998_TAGS=urlprefix-fabio.${APP_DOMAIN}/
IPFS_SERVICE_8080_TAGS=urlprefix-ipfs.${APP_DOMAIN}/
PORTAINER_SERVICE_9000_TAGS=urlprefix-portainer.${APP_DOMAIN}/
FABIO_SERVICE_9998_TAGS=urlprefix-fabio.${DOMAIN}/
PORTAINER_SERVICE_9000_TAGS=urlprefix-portainer.${DOMAIN}/
REGISTRATOR_CONSUL_HTTP_TOKEN=01234567-89AB-CDEF-0123-456789ABCDEF

View File

@ -1,2 +1,2 @@
CADVISOR_EXPORTER_SERVICE_8080_TAGS=urlprefix-cadvisor-exporter.${APP_DOMAIN}/
NODE_EXPORTER_SERVICE_9100_TAGS=urlprefix-node-exporter.${APP_DOMAIN}/
CADVISOR_EXPORTER_SERVICE_8080_TAGS=urlprefix-cadvisor-exporter.${DOMAIN}/
NODE_EXPORTER_SERVICE_9100_TAGS=urlprefix-node-exporter.${DOMAIN}/

View File

@ -2,11 +2,12 @@ version: '3.6'
services:
cadvisor-exporter:
image: google/cadvisor:latest
container_name: ${COMPOSE_PROJECT_NAME_NODE}_cadvisor-exporter
hostname: ${HOSTNAME}
image: google/cadvisor:latest
labels:
- SERVICE_8080_CHECK_TCP=true
- SERVICE_8080_NAME=${COMPOSE_SERVICE_NAME}-cadvisor-exporter:8080
- SERVICE_8080_NAME=${COMPOSE_SERVICE_NAME_NODE}-cadvisor-exporter:8080
- SERVICE_8080_TAGS=${CADVISOR_SERVICE_EXPORTER_8080_TAGS}
- SERVICE_9200_IGNORE=true
networks:
@ -25,11 +26,12 @@ services:
- "^/(sys|proc|dev|host|etc|rootfs/var/lib/docker/containers|rootfs/var/lib/docker/overlay2|rootfs/run/docker/netns|rootfs/var/lib/docker/aufs)($$|/)"
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
image: prom/node-exporter:latest
container_name: ${COMPOSE_PROJECT_NAME_NODE}_node-exporter
hostname: ${HOSTNAME}
image: prom/node-exporter:latest
labels:
- SERVICE_9100_CHECK_TCP=true
- SERVICE_9100_NAME=${COMPOSE_SERVICE_NAME}-node-exporter:9100
- SERVICE_9100_NAME=${COMPOSE_SERVICE_NAME_NODE}-node-exporter:9100
- SERVICE_9100_TAGS=${SERVICE_NODE_EXPORTER_HTTP_TAGS}
networks:
- public

View File

@ -0,0 +1 @@
IPFS_SERVICE_8080_TAGS_NODE=urlprefix-ipfs.${DOMAIN}/

53
stack/node/ipfs/ipfs.yml Normal file
View File

@ -0,0 +1,53 @@
version: '3.6'
services:
ipfs:
build:
args:
- DOCKER_BUILD_DIR=docker/ipfs
- IPFS_VERSION=0.13.0
context: ../..
dockerfile: docker/ipfs/Dockerfile
command: daemon --migrate=true
container_name: ${COMPOSE_PROJECT_NAME_NODE}_ipfs
cap_add:
- SYS_ADMIN # --mount
cpus: 0.5
devices:
- /dev/fuse:/dev/fuse # --mount
environment:
- IPFS_PROFILE=${IPFS_PROFILE}
image: ${DOCKER_REPOSITORY_NODE}/ipfs:${DOCKER_IMAGE_TAG}
labels:
- SERVICE_4001_CHECK_TCP=true
- SERVICE_4001_NAME=${COMPOSE_SERVICE_NAME_NODE}-ipfs:4001
- SERVICE_5001_CHECK_TCP=true
- SERVICE_5001_NAME=${COMPOSE_SERVICE_NAME_NODE}-ipfs:5001
- SERVICE_8080_CHECK_HTTP=/ipfs/QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG/readme
- SERVICE_8080_NAME=${COMPOSE_SERVICE_NAME_NODE}-ipfs:8080
- SERVICE_8080_TAGS=${IPFS_SERVICE_8080_TAGS_NODE}
- SERVICE_8081_IGNORE=true
networks:
- public
ports:
- 4001:4001
- 5001/tcp
- 8080/tcp
security_opt:
- apparmor:unconfined # --mount
ulimits:
nofile:
soft: 65536
hard: 65536
volumes:
- ipfs:/data/ipfs:delegated
restart: always
volumes:
ipfs:
name: ${COMPOSE_PROJECT_NAME_NODE}_ipfs
networks:
public:
external: true
name: ${DOCKER_NETWORK_PUBLIC}

View File

@ -8,6 +8,7 @@ services:
- DOCKER_BUILD_DIR=docker/consul
context: ../..
dockerfile: docker/consul/Dockerfile
container_name: ${COMPOSE_PROJECT_NAME_NODE}_consul
image: ${DOCKER_REPOSITORY_NODE}/consul:${DOCKER_IMAGE_TAG}
environment:
CONSUL_BIND_INTERFACE: '${DOCKER_HOST_IFACE}'
@ -30,16 +31,16 @@ services:
- SERVICE_8301_IGNORE=true
- SERVICE_8302_IGNORE=true
- SERVICE_8500_CHECK_HTTP=/v1/health/service/consul
- SERVICE_8500_NAME=${COMPOSE_SERVICE_NAME}-consul:8500
- SERVICE_8500_NAME=${COMPOSE_SERVICE_NAME_NODE}-consul:8500
- SERVICE_8500_TAGS=${CONSUL_SERVICE_8500_TAGS}
- SERVICE_8600_IGNORE=true
- SERVICE_ADDRESS=${DOCKER_HOST_INET}
- SERVICE_CHECK_SCRIPT=docker-healthcheck ${DOCKER_HOST_INET}
- SERVICE_ADDRESS=${DOCKER_HOST_INET4}
- SERVICE_CHECK_SCRIPT=docker-healthcheck ${DOCKER_HOST_INET4}
network_mode: host
restart: always
volumes:
- consul:/consul/data
- ssl-certs:/certs
- consul:/consul/data:delegated
- ssl-certs:/certs:ro
- /var/run/docker.sock:/var/run/docker.sock
fabio:
build:
@ -50,20 +51,21 @@ services:
- PROCESSOR_ARCHITECTURE=${PROCESSOR_ARCHITECTURE}
context: ../..
dockerfile: docker/fabio/Dockerfile
container_name: ${COMPOSE_PROJECT_NAME_NODE}_fabio
image: ${DOCKER_REPOSITORY_NODE}/fabio:${DOCKER_IMAGE_TAG}
command: -registry.backend "consul" -registry.consul.addr "consul:8500" -registry.consul.token "$FABIO_CONSUL_HTTP_TOKEN" -proxy.addr ":80,:443;cs=local" -proxy.cs "cs=local;type=file;cert=/certs/${DOMAIN}.crt.pem;key=/certs/${DOMAIN}.key.pem"
depends_on:
- consul
extra_hosts:
- consul:${DOCKER_HOST_INET}
- consul:${DOCKER_INTERNAL_DOCKER_HOST}
hostname: ${HOSTNAME}
labels:
- SERVICE_80_CHECK_TCP=true
- SERVICE_80_NAME=${COMPOSE_SERVICE_NAME}-fabio:80
- SERVICE_80_NAME=${COMPOSE_SERVICE_NAME_NODE}-fabio:80
- SERVICE_443_CHECK_TCP=true
- SERVICE_443_NAME=${COMPOSE_SERVICE_NAME}-fabio:443
- SERVICE_443_NAME=${COMPOSE_SERVICE_NAME_NODE}-fabio:443
- SERVICE_9998_CHECK_HTTP=/routes
- SERVICE_9998_NAME=${COMPOSE_SERVICE_NAME}-fabio:9998
- SERVICE_9998_NAME=${COMPOSE_SERVICE_NAME_NODE}-fabio:9998
- SERVICE_9998_TAGS=${FABIO_SERVICE_9998_TAGS}
- SERVICE_9999_IGNORE=true
ports:
@ -74,46 +76,7 @@ services:
- public
restart: always
volumes:
- ssl-certs:/certs
ipfs:
build:
args:
- DOCKER_BUILD_DIR=docker/ipfs
- IPFS_VERSION=0.13.0
context: ../..
dockerfile: docker/ipfs/Dockerfile
command: daemon --migrate=true --mount
cap_add:
- SYS_ADMIN
devices:
- /dev/fuse:/dev/fuse
environment:
- IPFS_PROFILE=${IPFS_PROFILE}
image: ${DOCKER_REPOSITORY_NODE}/ipfs:${DOCKER_IMAGE_TAG}
labels:
- SERVICE_4001_CHECK_TCP=true
- SERVICE_4001_NAME=${COMPOSE_SERVICE_NAME}-ipfs:4001
- SERVICE_5001_CHECK_TCP=true
- SERVICE_5001_NAME=${COMPOSE_SERVICE_NAME}-ipfs:5001
- SERVICE_8080_CHECK_HTTP=/ipfs/QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG/readme
- SERVICE_8080_NAME=${COMPOSE_SERVICE_NAME}-ipfs:8080
- SERVICE_8080_TAGS=${IPFS_SERVICE_8080_TAGS}
- SERVICE_8081_IGNORE=true
networks:
- public
ports:
- 4001:4001
- 5001/tcp
- 8080/tcp
security_opt:
- apparmor:unconfined
ulimits:
nofile:
soft: 65536
hard: 65536
volumes:
- ipfs:/data/ipfs
restart: always
- ssl-certs:/certs:ro
registrator:
build:
args:
@ -122,6 +85,7 @@ services:
- GIT_AUTHOR_EMAIL=${GIT_AUTHOR_EMAIL}
context: ../..
dockerfile: docker/registrator/Dockerfile
container_name: ${COMPOSE_PROJECT_NAME_NODE}_registrator
image: ${DOCKER_REPOSITORY_NODE}/registrator:${DOCKER_IMAGE_TAG}
command: -internal -cleanup -deregister always -resync=30 -useIpFromNetwork "${DOCKER_NETWORK_PUBLIC}" -useIpFromLabel SERVICE_ADDRESS consul://consul:8500
depends_on:
@ -129,7 +93,7 @@ services:
environment:
- CONSUL_HTTP_TOKEN=${REGISTRATOR_CONSUL_HTTP_TOKEN}
extra_hosts:
- consul:${DOCKER_HOST_INET}
- consul:${DOCKER_INTERNAL_DOCKER_HOST}
hostname: ${HOSTNAME}
network_mode: host
restart: always
@ -138,8 +102,10 @@ services:
volumes:
consul:
ipfs:
name: ${COMPOSE_PROJECT_NAME_NODE}_consul
ssl-certs:
external: true
name: ${COMPOSE_PROJECT_NAME_NODE}_ssl-certs
networks:
public:

View File

@ -5,10 +5,11 @@ services:
build:
args:
- DOCKER_BUILD_DIR=docker/pdns-server
context: ../../..
context: ../..
dockerfile: docker/pdns-server/Dockerfile
command: /usr/local/sbin/pdns_recursor --local-address='192.168.0.1:53' --allow-from='127.0.0.0/8, 192.168.1.0/24, 172.16.0.0/12'
image: ${DOCKER_REPOSITORY}/pdns-recursor:${DOCKER_IMAGE_TAG}
container_name: ${COMPOSE_PROJECT_NAME_NODE}_pdns-recursor
hostname: ${HOSTNAME}
image: ${DOCKER_REPOSITORY_NODE}/pdns-recursor:${DOCKER_IMAGE_TAG}
network_mode: host
restart: always

View File

@ -5,10 +5,11 @@ services:
build:
args:
- DOCKER_BUILD_DIR=docker/vsftpd-s3
context: ../../..
context: ../..
dockerfile: docker/vsftpd-s3/Dockerfile
cap_add:
- sys_admin
container_name: ${COMPOSE_PROJECT_NAME_NODE}_vsftpd-s3
devices:
- /dev/fuse
environment:
@ -23,14 +24,14 @@ services:
- FTPD_USERS=${VSFTPD_S3_FTPD_USERS}
- PASV_MAX_PORT=${VSFTPD_S3_PASV_MAX_PORT}
- PASV_MIN_PORT=${VSFTPD_S3_PASV_MIN_PORT}
image: ${DOCKER_REPOSITORY}/vsftpd-s3:${DOCKER_IMAGE_TAG}
hostname: ${HOSTNAME}
image: ${DOCKER_REPOSITORY_NODE}/vsftpd-s3:${DOCKER_IMAGE_TAG}
labels:
- SERVICE_21_CHECK_TCP=true
- SERVICE_21_NAME=${COMPOSE_SERVICE_NAME}-vsftpd-s3:21
- SERVICE_21_NAME=${COMPOSE_SERVICE_NAME_NODE}-vsftpd-s3:21
- SERVICE_22_CHECK_TCP=true
- SERVICE_22_NAME=${COMPOSE_SERVICE_NAME}-vsftpd-s3:22
- SERVICE_22_NAME=${COMPOSE_SERVICE_NAME_NODE}-vsftpd-s3:22
- SERVICE_65000_IGNORE=true
hostname: ${HOSTNAME}
security_opt:
- apparmor:unconfined
network_mode: host

View File

@ -1,6 +1,6 @@
RC_ATTACH_SCREEN=false
RC_ATTACH_TMUX=false
RC_CUSTOM_PROMPT=false
RC_CUSTOM_PS1=true
RC_SSH_AGENT=false
RC_PROMPT_SET=false
RC_PS1_SET=true
RC_SCREEN_ATTACH=false
RC_SSH_ADD=false
RC_TMUX_ATTACH=false
THEIA_SERVICE_3000_TAGS=urlprefix-theia.${USER}.${APP_DOMAIN}/

View File

@ -12,14 +12,14 @@ services:
environment:
- ENV=${ENV}
- MONOREPO_DIR=${MONOREPO_DIR}
- RC_01_CUSTOM_PS1=${RC_CUSTOM_PS1}
- RC_02_CUSTOM_PROMPT=${RC_CUSTOM_PROMPT}
- RC_03_SSH_AGENT=${RC_SSH_AGENT}
- RC_04_ATTACH_TMUX=${RC_ATTACH_TMUX}
- RC_05_ATTACH_SCREEN=${RC_ATTACH_SCREEN}
- RC_01_PS1_SET=${RC_PS1_SET}
- RC_02_PROMPT_SET=${RC_PROMPT_SET}
- RC_03_SSH_ADD=${RC_SSH_ADD}
- RC_04_TMUX_ATTACH=${RC_TMUX_ATTACH}
- RC_05_SCREEN_ATTACH=${RC_SCREEN_ATTACH}
- SHELL=${DOCKER_SHELL}
- SSH_AUTH_SOCK=/tmp/ssh-agent/socket
- WORKSPACE_DIR=/Sources/${MONOREPO}
- WORKSPACE_DIR=/Sources
image: ${DOCKER_REPOSITORY}/theia:${DOCKER_IMAGE_TAG}
labels:
- SERVICE_3000_CHECK_TCP=true
@ -30,7 +30,7 @@ services:
- public
restart: always
volumes:
- monorepo:/Sources/${MONOREPO}:cached
- monorepo:/Sources:cached
- ssh-agent:/tmp/ssh-agent:ro
- /var/run/docker.sock:/var/run/docker.sock
@ -43,7 +43,7 @@ volumes:
o: bind
ssh-agent:
external:
name: ${DOCKER_VOLUME_SSH}
name: ${DOCKER_VOLUME}
networks:
private:

View File

@ -31,7 +31,6 @@ services:
- shared:/shared:cached
- shm:/dev/shm:delegated
volumes:
home:
shared:

8
stack/zen.mk Normal file
View File

@ -0,0 +1,8 @@
ifneq ($(filter zen,$(STACK)),)
ifeq ($(filter User/ipfs,$(STACK)),)
STACK += User/ipfs
endif
ifeq ($(filter User/ipfs,$(User)),)
User += User/ipfs
endif
endif

52
stack/zen/zen.yml Normal file
View File

@ -0,0 +1,52 @@
version: '3.6'
services:
zen:
build:
args:
- DOCKER_BUILD_DIR=docker/zen
- GID=${GID}
- GIT_AUTHOR_NAME=${GIT_AUTHOR_NAME}
- GIT_AUTHOR_EMAIL=${GIT_AUTHOR_EMAIL}
- IPFS_VERSION=0.13.0
- UID=${UID}
- USER=${USER}
context: ../..
dockerfile: docker/zen/Dockerfile
depends_on:
- ipfs
environment:
- ENV=${ENV}
- SHELL=${DOCKER_SHELL}
- SSH_AUTH_SOCK=/tmp/ssh-agent/socket
image: ${DOCKER_REPOSITORY}/zen:${DOCKER_IMAGE_TAG}
networks:
- private
restart: always
user: ${UID}:${GID}
volumes:
- astroport:${HOME}/astroport:cached
- ipfs:${HOME}/.ipfs:ro
- zen:${HOME}/.zen:delegated
- ssh-agent:/tmp/ssh-agent:ro
working_dir: ${HOME}/.zen
volumes:
astroport:
ipfs:
external: true
name: ${COMPOSE_PROJECT_NAME_USER}_ipfs
ssh-agent:
external: true
name: ${DOCKER_VOLUME}
zen:
driver: local
driver_opts:
type: none
device: ${HOME}/.zen
o: bind
networks:
private:
external: true
name: ${DOCKER_NETWORK_PRIVATE}