Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • lupa/compose.libre.sh
  • libre.sh/compose.libre.sh
  • ecobytes/compose.libre.sh
  • jordan.mitchell/compose.libre.sh
  • timothee/compose.libre.sh
5 results
Show changes
Showing
with 47 additions and 412 deletions
# Migration procedure version 0.3
## Web application (simplistic procedure)
* The old hoster puts the site in read-only mode by changing the permissions of the database user to read-only
* The old hoster creates the migration archive as per the IndieHosters migration format (see below)
* The old hoster sends the migration archive to the new hoster
* The new hoster imports the migration archive
* Once DNR, DNS, and TLS have also been migrated, the old hoster terminates the service.
## Web application (advanced procedure)
* The TLS certificate is sent ahead first
* The old hoster programmatically creates the migration archive, and immediately *posts* it to the new hoster via a webhook
* The webhook programmatically imports the migration archive, and returns the IP address
* The old hoster programmatically configures the new hoster's public IP address into their load balancer
* The old hoster's load balancer now forwards (at the TCP level) all traffic to this new IP address
* Once DNR and DNS transfer are complete, the old hoster terminates the TCP forwarding service.
## IndieHosters migration format, version 0.3
### General
An IndieHosters migration archive is a directory structure (probably packaged up as a tar file or zip file).
There should be an 'indiehosters.json' file in the root of the archive. It should contain at least the following fields:
* format: the URL of this spec (probably https://indiehosters.net/spec/0.3)
* application: a string, which determines what the rest of the folder contents should be imported into.
### Known
When migrating a Known application, the 'indiehosters.json' file should furthermore contain the following fields:
* application: 'known'
* version: the version of Known as a string, for instance '0.6.5'
* database:
* engine: the database engine used, either 'mysql' or 'mongodb'
* name: the database name inside the dump file, for instance 'known'
* file: the database dump file inside the archive, for instance 'dump.sql'
* uploads: the uploads folder name inside the archive, for instance 'uploads/'
* plugins: the folder with any non-standard plugins for instance 'plugins/'
### WordPress
(to be determined)
[Unit]
Description=Back up domain data to a git repo and push it out
[Service]
Type=oneshot
ExecStartPre=-/usr/bin/docker kill mysqldump-%i
ExecStartPre=-/usr/bin/docker rm mysqldump-%i
ExecStartPre=/bin/bash -euxc ' \
if [ -d /data/domains/%i/mysql ]; then \
echo "Backing up mysql databases for %i"; \
mysql_passwd=`cat /data/domains/%i/mysql/.env | cut -d= -f2`; \
/usr/bin/docker run \
--rm \
--name mysqldump-%i \
--link mysql-%i:db \
--env-file /data/domains/%i/mysql/.env \
indiehosters/mysql \
mysqldump \
--all-databases \
--events \
-uadmin \
-p$mysql_passwd \
-h db > /data/domains/%i/mysql/dump.sql; \
fi'
ExecStart=/bin/bash -euxc ' \
echo "Committing everything"; \
cd /data/domains/%i/; \
git add *; \
git status; \
git commit --allow-empty -am"backup %i @ `hostname` - `date`"; \
git push origin master'
[Service]
Type=oneshot
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/bin
ExecStart=/opt/bin/dump_all.sh
[Unit]
Description=Hourly backup of www and mysql content to a git repo
Description=Run dump all dayly
[Timer]
OnActiveSec=20
OnUnitActiveSec=60min
OnCalendar=*-*-* 00:15:30
[Install]
WantedBy=timers.target
[Unit]
Description=%p
# Requirements
Requires=docker.service
Requires=etcd.service
# Dependency ordering
After=docker.service
After=etcd.service
Before=haproxy.service
[Service]
Restart=always
ExecStartPre=-/usr/bin/docker kill %p
ExecStartPre=-/usr/bin/docker rm %p
ExecStart=/usr/bin/docker run \
--name %p \
-v /data/runtime/haproxy/:/etc/haproxy/ \
-v /data/indiehosters/confd/:/etc/confd/ \
-v /var/run/docker.sock:/var/run/docker.sock \
indiehosters/confd
ExecReload=/usr/bin/docker restart %p
ExecStop=/usr/bin/docker stop %p
[Install]
WantedBy=multi-user.target
[Path]
PathExists=/data/runtime/haproxy/haproxy.cfg
[Install]
WantedBy=multi-user.target
[Unit]
Description=Initializer
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStartPre=/bin/bash -euxc ' \
BACKUP_DESTINATION=`cat /data/BACKUP_DESTINATION`; \
echo "Intitializing backups with $BACKUP_DESTINATION"; \
if [ ! -d /data/domains/%i/.git ]; then \
if [ `ssh $BACKUP_DESTINATION "test -d %i"; echo $?` -eq 0 ]; then \
git clone $BACKUP_DESTINATION:%i /data/domains/%i; \
cd /data/domains/%i; \
else \
ssh $BACKUP_DESTINATION "mkdir -p %i;cd %i;git init --bare;"; \
if [ ! -d /data/domains/%i ]; then \
mkdir /data/domains/%i; \
fi; \
cd /data/domains/%i; \
git init; \
git remote add origin $BACKUP_DESTINATION:%i; \
fi; \
git config --local user.email "backups@`hostname`"; \
git config --local user.name "`hostname` hourly backups"; \
fi'
ExecStart=/bin/bash -euxc ' \
if [ -d /data/import/%i ]; then \
cp -r /data/import/%i/* /data/domains/%i; \
rm -rf /data/import/%i; \
fi'
[Unit]
Description=%p for %i etcd registration
# Requirements
Requires=etcd.service
# Dependency ordering
After=etcd.service
After=known@%i.service
# Dependency binding
BindsTo=known@%i.service
[Service]
# Start
## Test whether service is accessible and then register useful information
ExecStart=/bin/bash -c ' \
sleep 30; \
while true; do \
app=`echo %p | cut -d"-" -f1`; \
ip=`docker inspect --format \'{{.NetworkSettings.IPAddress}}\' $app-%i`; \
curl -f $ip; \
if [ $? -eq 0 ]; then \
etcdctl set /services/$app/%i \'{"ip":"\'$ip\'", "port":"80"}\' --ttl 60; \
else \
etcdctl rm /services/$app/%i; \
fi; \
sleep 50; \
done'
# Stop
ExecStop=-/bin/bash -euxc ' \
app=`echo %p | cut -d"-" -f1`; \
/usr/bin/etcdctl rm /services/$app/%i
[Unit]
Description=WordPress importer
# Requirements
Requires=init@%i.service
# Dependency ordering
After=init@%i.service
After=mysql@%i.service
Before=known@%i.service
Before=backup@%i.timer
# Dependency binding
BindsTo=known@%i.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash -euxc ' \
cp /data/domains/%i/TLS/%i.pem /data/runtime/haproxy/approved-certs/%i.pem; \
known_folder=/data/domains/%i/known; \
if [ ! -d $known_folder/known-content ]; then \
mkdir -p $known_folder; \
cd $known_folder; \
tar xvzf /data/indiehosters/blueprints/known-0.6.5.tgz; \
touch .htaccess; \
fi; \
cat /data/domains/%i/mysql/.env | sed s/MYSQL_PASS/DB_PASS/ > $known_folder/.env'
[Install]
WantedBy=known@%i.service
[Unit]
Description=%p-%i
# Requirements
Requires=docker.service
Requires=etcd.service
Requires=mysql@%i.service
Requires=%p-importer@%i.service
Requires=%p-discovery@%i.service
Requires=backup@%i.timer
# Dependency ordering
After=docker.service
After=mysql@%i.service
After=%p-importer@%i.service
Before=%p-discovery@%i.service
# Dependency binding
BindsTo=mysql@%i.service
[Service]
Restart=always
ExecStartPre=-/usr/bin/docker kill %p-%i
ExecStartPre=-/usr/bin/docker rm %p-%i
ExecStart=/usr/bin/docker run \
--name %p-%i \
--link mysql-%i:db \
-v /data/domains/%i/%p/known-content:/app/known-content \
-v /data/domains/%i/%p/.htaccess:/app/.htaccess \
--env-file /data/domains/%i/%p/.env \
indiehosters/known
ExecReload=/usr/bin/docker restart %p-%i
ExecStop=/usr/bin/docker stop %p-%i
[Install]
WantedBy=multi-user.target
[Service]
Type=oneshot
ExecStart=/libre.sh/utils/mail-mon.sh
[Unit]
Description=Run mail mon hourly and on boot
[Timer]
OnBootSec=15min
OnUnitActiveSec=1h
[Install]
WantedBy=timers.target
[Unit]
Description=MySQL importer
# Dependency ordering
After=init@%i.service
Before=mysql@%i.service
# Dependency binding
BindsTo=mysql@%i.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash -euxc ' \
mysql_folder=/data/domains/%i/mysql; \
if [ ! -d /data/runtime/domains/%i/mysql ]; then \
if [ ! -d $mysql_folder ]; then \
mkdir -p $mysql_folder; \
pass=`echo $RANDOM ${date} | md5sum | base64 | cut -c-10`; \
echo MYSQL_PASS=$pass > $mysql_folder/.env; \
mkdir -p /data/runtime/domains/%i/mysql; \
fi; \
fi'
[Install]
WantedBy=mysql@%i.service
[Unit]
Description=%p-%i
# Requirements
Requires=docker.service
Requires=%p-importer@%i.service
# Dependency ordering
After=docker.service
After=%p-importer@%i.service
Before=backup@%i.timer
[Service]
Restart=always
ExecStartPre=-/usr/bin/docker kill %p-%i
ExecStartPre=-/usr/bin/docker rm %p-%i
ExecStart=/usr/bin/docker run \
--name %p-%i \
-v /data/runtime/domains/%i/%p/db_files:/var/lib/mysql \
-e STARTUP_SQL="/data/domains/%i/%p/dump.sql" \
--env-file /data/domains/%i/%p/.env \
indiehosters/mysql
ExecReload=/usr/bin/docker restart %p-%i
ExecStop=/usr/bin/docker stop %p-%i
[Install]
WantedBy=multi-user.target
[Unit]
Description=%p
Description=%p-%i
# Requirements
Requires=docker.service
......@@ -9,15 +9,15 @@ After=docker.service
[Service]
Restart=always
ExecStartPre=-/usr/bin/docker kill %p
ExecStartPre=-/usr/bin/docker rm %p
ExecStart=/usr/bin/docker run \
--name %p \
-v /data/runtime/postfix/:/data \
-p 25:25 \
indiehosters/postfix-forwarder
ExecReload=/usr/bin/docker restart %p
ExecStop=/usr/bin/docker stop %p
RestartSec=10
TimeoutStartSec=60
TimeoutStopSec=15
EnvironmentFile=-/system/%i/env
Environment=HOSTNAME=%H
WorkingDirectory=/system/%i/
ExecStartPre=-docker-compose rm -f
ExecStart=/bin/bash -euxc "docker-compose up"
ExecStop=docker-compose stop
[Install]
WantedBy=multi-user.target
[Unit]
Description=%p for %i etcd registration
# Requirements
Requires=etcd.service
# Dependency ordering
After=etcd.service
After=static@%i.service
# Dependency binding
BindsTo=static@%i.service
[Service]
# Start
## Test whether service is accessible and then register useful information
ExecStart=/bin/bash -c ' \
sleep 3; \
while true; do \
app=`echo %p | cut -d"-" -f1`; \
ip=`docker inspect --format \'{{.NetworkSettings.IPAddress}}\' $app-%i`; \
curl -f $ip; \
if [ $? -eq 0 ]; then \
etcdctl set /services/$app/%i \'{"ip":"\'$ip\'", "port":"80"}\' --ttl 60; \
else \
etcdctl rm /services/$app/%i; \
fi; \
sleep 50; \
done'
# Stop
ExecStop=-/bin/bash -euxc ' \
app=`echo %p | cut -d"-" -f1`; \
/usr/bin/etcdctl rm /services/$app/%i
[Unit]
Description=%p for %i etcd registration
# Requirements
Requires=etcd.service
# Dependency ordering
After=etcd.service
After=static-git@%i.service
# Dependency binding
BindsTo=static-git@%i.service
[Service]
# Start
## Test whether service is accessible and then register useful information
ExecStart=/bin/bash -c ' \
sleep 3; \
while true; do \
app=`echo %p | cut -d"-" -f1,2`; \
ip=`docker inspect --format \'{{.NetworkSettings.IPAddress}}\' $app-%i`; \
curl -f $ip; \
if [ $? -eq 0 ]; then \
etcdctl set /services/$app/%i \'{"ip":"\'$ip\'", "port":"80"}\' --ttl 60; \
else \
etcdctl rm /services/$app/%i; \
fi; \
sleep 50; \
done'
# Stop
ExecStop=-/bin/bash -euxc ' \
app=`echo %p | cut -d"-" -f1`; \
/usr/bin/etcdctl rm /services/$app/%i
[Unit]
Description=static importer
# Requirements
Requires=init@%i.service
# Dependency ordering
After=init@%i.service
Before=static-git@%i.service
Before=backup@%i.timer
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash -euxc ' \
cp /data/domains/%i/TLS/%i.pem /data/runtime/haproxy/approved-certs/%i.pem; \
git_folder=/data/runtime/domains/%i/static-git; \
if [ ! -d $git_folder/www-content/.git ]; then \
mkdir -p $git_folder; \
git clone `cat /data/domains/%i/static-git/GITURL` $git_folder/www-content; \
fi;'
[Install]
WantedBy=static-git@%i.service
[Unit]
Description=git puller
# Dependency ordering
After=static-git-importer@%i.service
[Service]
Type=oneshot
ExecStart=/bin/bash -euxc ' \
app=`echo %p | cut -d"-" -f1,2`; \
cd /data/runtime/domains/%i/$app/www-content; \
git pull'
[Unit]
Description=Run git puller service every 10 minutes
# Dependency binding
BindsTo=static-git@%i.service
[Timer]
OnActiveSec=0
OnUnitActiveSec=10min
[Install]
WantedBy=timers.target