Draft Forbes Group Website (Build by Nikola). The official site is hosted at:
License: GPL3
ubuntu2004
Some notes about using Docker to host various applications like Heptapod, Discourse, CoCalc etc. on Linux and AWS.
Docker
Several packages (such as Heptapod and CoCalc) require a rather complete system, so are easiest to install using Docker containers. Here we discuss how to set these up. Where possible, we try to use Rootless mode, which prevents the need for providing docker with root access, but has limitations. Currently, Rootless works for Heptapod, but causes problems with CoCalc.
Docker Account
We generally work with a docker
user, and keep all docker-specific files for this account:
On my machine, I then add a swandocker
alias to my ~/.ssh/config
file, e.g.:
All of the following is done in this account:
Installing Docker (With Root Access)
Installing Docker Rootless
Note: Be sure to completely purge any previous root-enabled version of Docker before proceeding.
To actually install rootless, run the following script, downloaded with curl:
This will put everything in ~/bin
This allows the docker
user to add processes to start services that will start at login.
Add the appropriate environmental variables to ~docker/.bashrc
:
Docker Cheatsheet
Here are some useful commands:
docker pull
: Pulls an image.docker create
: Creates a container from an image.docker start
: Starts running a container.docker stop
: Stops ...docker attach
: Attach to a running container.docker log
: See logs for specified container.docker ps -a
: List all containers (both running and stopped).docker images
: List all images.docker rm
: Remove a container.docker rmi
: Remove an image.docker inspect
: Lots of information about a container.docker exec -it <name> /bin/bash
: Connect to the specified container and runbash
(like ssh-ing into the VM).docker info
: Information about the install. You can use this to see if theoverlay2
storage driver is used, for example.
These appear in documentation, but I do not use them:
docker run
: This is equivalent todocker create
+docker start
+docker attach
. This can only be executed once. After the container is created, one cannot use subsequent calls torun
to change, for example, port assignments. It is probably most useful for short foreground processes in conjunction with the--rm
option.
Issues: I originally had a bunch of errors because of interference with the previously installed docker version (not rootless). These went away once I did sudo apt-get purge docker docker.io
.
Aborting because rootful Docker is running and accessible. Set FORCE_ROOTLESS_INSTALL=1 to ignore.
Failed to start docker.service: Unit docker.socket failed to load: No such file or directory.
So I stopped the root docker service (from a previous install) and removed this file:
After resolving these issues, I was having the following issue when trying to run the server with systemctl
:
Limiting Resouces
It can be useful to limit the resources available to Docker containers. To do this, you must enable cgroup swapping. This can be done by adding the following to /etc/default/grub
:
then running sudo update-grub
. Once this is done, you can limit the resources used by Docker containers with flags like:
etc.
Docker Compose
Sometimes you must run several processes and have them interact. For example, heptapod generally requires a mail-server like sendmail
, but the omnibus docker image does not contain sendmail. To combine two containers in a single environment, one typically uses docker compose... but this does not seem to work with rootless.
Heptapod
Heptapod is a service providing Mercurial access to GitLab CE. When running the public server, we host it here:
Here we describe how to run Heptapod in a Docker container. This is a service based on GitLab CE that provides a backend with issue tracking etc. for Mercurial. As above, I have created a docker
user account on swan
. First I login to this, then make some directories for the server data in /data2/docker/heptapod
. Then I pull the docker image.
Now we pull the heptapod image and start a couple of containers:
heptapod-local
: Only listens on local ports. To use this, users must login with ssh and forward ports appropriately so they can connect (see below).heptapod-public
: Listens on public ports. This exposes Heptapod to the world, which may be a security risk. We do this to allow "weak" collaborators access, or to enable transferring repositories from Bitbucket.
Now we can run whichever one we want:
Once started, I initialized a mercurial repository in the configuration directory so I can keep track of configuration changes:
Debugging
Look at the current logs with the following:
Heptapod Backup (incomplete)
The recommended way to transfer a Heptapod/GitLab server is backup/restore.
To do this:
Login to your host and find the name of your heptapod container:
or
First make sure both instances are running the same version:
If not, update and migrate until they match, converting the database as needed.
Create the backup on the source:
Backup the configuration files:
Copy everything over to new server:
Another option is to backup the repositories, I use rclone
to copy these to my Google Drive to a remote called gwsu_backups
from my docker
account on swan
using the root_folder_id
corresponding to a folder My Drive/backups/RClone/swan/repo_backup
.
$ ssh swandocker docker@swan:~$ docker ps CONTAINER ID IMAGE ... PORTS NAMES 638b8e2d6535 octobus/heptapod 0.0.0.0:11022->22/tcp, 0.0.0.0:11080->80/tcp, 0.0.0.0:11443->443/tcp heptapod-public docker@swan:~$ export heptapod_id=heptapod-public docker@swan:~$ docker exec -t ${heptapod_id} gitlab-rake gitlab:env:info System information System: Current User: git Using RVM: no Ruby Version: 2.6.6p146 Gem Version: 2.7.10 Bundler Version:1.17.3 Rake Version: 12.3.3 Redis Version: 5.0.9 Git Version: 2.28.0 Sidekiq Version:5.2.9 Go Version: unknown GitLab information Version: 13.4.6 Revision: 7ea571d2b76a Directory: /opt/gitlab/embedded/service/gitlab-rails DB Adapter: PostgreSQL DB Version: 11.9 URL: http://swan.physics.wsu.edu HTTP Clone URL: http://swan.physics.wsu.edu/some-group/some-project.git SSH Clone URL: ssh://[email protected]:11022/some-group/some-project.git Using LDAP: no Using Omniauth: yes Omniauth Providers: bitbucket GitLab Shell Version: 13.7.0 Repository storage paths: - default: /var/opt/gitlab/git-data/repositories GitLab Shell path: /opt/gitlab/embedded/service/gitlab-shell Git: /opt/gitlab/embedded/bin/git docker@swan:~$ docker exec -t ${heptapod_id} gitlab-backup create docker@swan:~$ docker exec -t ${heptapod_id} gitlab-backup create 2020-12-04 08:17:52 +0000 -- Dumping database ... Dumping PostgreSQL database gitlabhq_production ... [DONE] 2020-12-04 08:17:57 +0000 -- done 2020-12-04 08:17:57 +0000 -- Dumping namespaces (Mercurial specific) ... Calling tar czf /var/opt/gitlab/backups/namespaces.tar.gz -C /var/opt/gitlab/backups/namespaces . output=, status=0 2020-12-04 08:17:59 +0000 -- done 2020-12-04 08:17:59 +0000 -- Dumping repositories ... * mforbes/pymmf (@hashed/6b/...) ... * mforbes/pymmf (@hashed/6b/...) ... [DONE] * mforbes/pymmf (@hashed/6b/...) ... [DONE] Wiki * mforbes/kzsolve (@hashed/d4/...) ... ... * mforbes/zdk_phys_final_eos_fast (@hashed/52/...) ... * mforbes/zdk_phys_final_eos_fast (@hashed/52/...) ... [DONE] * mforbes/zdk_phys_final_eos_fast (@hashed/52/...) ... [SKIPPED] Wiki 2020-12-04 08:25:57 +0000 -- done 2020-12-04 08:25:57 +0000 -- Dumping uploads ... 2020-12-04 08:25:58 +0000 -- done 2020-12-04 08:25:58 +0000 -- Dumping builds ... 2020-12-04 08:25:58 +0000 -- done 2020-12-04 08:25:58 +0000 -- Dumping artifacts ... 2020-12-04 08:25:58 +0000 -- done 2020-12-04 08:25:58 +0000 -- Dumping pages ... 2020-12-04 08:25:58 +0000 -- done 2020-12-04 08:25:58 +0000 -- Dumping lfs objects ... 2020-12-04 08:25:58 +0000 -- done 2020-12-04 08:25:58 +0000 -- Dumping container registry images ... 2020-12-04 08:25:58 +0000 -- [DISABLED] Creating backup archive: 1607070358_2020_12_04_13.4.6_gitlab_backup.tar ... done Uploading backup archive to remote storage ... skipped Deleting tmp directories ... done done ... Deleting old backups ... skipping Warning: Your gitlab.rb and gitlab-secrets.json files contain sensitive data and are not included in this backup. You will need these files to restore a backup. Please back them up manually. Backup task is done.
$ ssh aws-hg [ec2-user@ip-10-147-105-73 ~]$ docker ps CONTAINER ID ... PORTS NAMES 650311e25626 ... 0.0.0.0:80->80/tcp, 22/tcp, 0.0.0.0:443->443/tcp ecs-heptapod-11-heptapod-f0effff7e3cddbc38001 ... [ec2-user@... ~]$ export heptapod_id="ecs-heptapod-11-heptapod-f0effff7e3cddbc38001" [ec2-user@... ~]$ docker exec -it ${heptapod_id} gitlab-rake gitlab:env:info System information System: Current User: git Using RVM: no Ruby Version: 2.6.6p146 Gem Version: 2.7.10 Bundler Version:1.17.3 Rake Version: 12.3.3 Redis Version: 5.0.9 Git Version: 2.28.0 Sidekiq Version:5.2.9 Go Version: unknown GitLab information Version: 13.3.5 Revision: 11c5a0a148c9 Directory: /opt/gitlab/embedded/service/gitlab-rails DB Adapter: PostgreSQL DB Version: 11.7 URL: http://650311e25626 HTTP Clone URL: http://650311e25626/some-group/some-project.git SSH Clone URL: ssh://git@650311e25626/some-group/some-project.git Using LDAP: no Using Omniauth: yes Omniauth Providers: GitLab Shell Version: 13.6.0 Repository storage paths: - default: /var/opt/gitlab/git-data/repositories GitLab Shell path: /opt/gitlab/embedded/service/gitlab-shell Git: /opt/gitlab/embedded/bin/git
HTTP Redirect
Note: SSL does not yet work with non-standard ports... so I am using HTTP only. I have randomly chosen ports 11080, 11443 and 11022 for HTTP, HTTPS, and SSH access. These are not very memorable, so it would be nice to redirect https://swan.physics.wsu.edu/heptapod
to https://swan.physics.wsu.edu:11443
. To do this, we simply add a Redirect /heptapod https://swan.physics.wsu.edu:11443/
statement to one of the Apache config files:
Don't forget to restart the server:
Bitbucket Import
Enable OAuth2 integration on Bitbucket. I used my public settings
http://swan.physics.wsu.edu/heptapod/users/sign_in
.
Note: I had issues resulting in redirect_uri
issue because I was using my alias http://swan.physics.wsu.edu/heptapod/users/auth
but in my configuration, I used the http://swan.physics.wsu.edu:9080/users/auth
form. If you look at the URL sent, it includes the redirect_uri
which must match.
Edit the
/etc/gitlab/gitlab.rb
file on the server. Since we mapped/etc/gitlab
to~docker/srv/config
, we can edit it there without connecting.
Start the public server, or reconfigure GitLab:
or
Register for an account on our Heptapod instance.
Login.
Import new project from Bitbucket Cloud.
References
Omnibus GitLab Instructions: These are the instructions for running the GitLab Docker container. The Heptapod container is based on this, so should function similarly.
Heptapod as a Bitbucket replacement: Instructions on how to import projects from bitbucket.
Backup/Restore: Also the way to migrate from one server to another.
Issues
Some imports are broken.
Cloning links are incorrect:
http://swan.physics.wsu.edu/mforbes/mmfutils mmfutils_heptapod
. Probably need to update the hostname to include the port and/or the/heptapode
alias.Cloning from
http://swan.physics.wsu.edu:9080/mforbes/mmfutils mmfutils_heptapod
does not work.Cloning from
ssh://[email protected]:9022/mforbes/mmfutils
works onswan
but not from outside.Cloning from
ssh://git@localhost:9022/mforbes/mmfutils
works with SSH tunnel.
Password Changes
On swan, we do not have a mail server setup, so if you want to recover a password, then you need to follow this procedure:
Upgrades/Migration
GitLab does not allow you to jump to much between versions, so you might need to specify an upgrade path. This means you should recreate the container with a sequence of images, then let the backend migration take place. Here is an example:
To see if the migration is done:
Discourse
Edit the generated containers/app.yml
file. I am trying to use Gmail with a custom alias [email protected]
which I registered under my Gmail account settings.
Mailjet: I managed to
Notes:
I could not use
[email protected]
as the SMTP user here since I cannot login to gmail with this.Gmail did not work: probably have to use an App password since two-factor authentication is enabled.
I had to use an absolute path for the host
/home/docker
:~
did not work.I also tried using Mailjet with
- exec: rails r "SiteSetting.notification_email='[email protected]'"
but this did not seem to activate either (I was expecting Mailjet to send me an activation email to make sure...)
After editing these, I was able to continue after making these directories:
Not Working: Discourse is running, but not able to send emails.
HTTP Redirect
I have randomly chosen ports 10080 and 10433 for HTTP and HTTPS access. These are not very memorable, so it would be nice to redirect https://swan.physics.wsu.edu/discourse
to https://swan.physics.wsu.edu:10443
. To do this, we simply add a Redirect /discourse https://swan.physics.wsu.edu:10443/
statement to one of the Apache config files:
Don't forget to restart the server:
References:
CoCalc
CoCalc can also be installed with docker. I created the images with the following file:
These listen on port 9443. Note: you must connect with https://localhost:9443, not with HTTP.
Launch with:
Now you can connect with appropriately forwarded ports. Make sure you have something like this in your ~/.ssh/config
file:
Start this connection:
Now visit the server on your local computer with https://localhost:9443.
Toubleshooting
See the logs:
Make a user Admin:
Issues
New project stuck on "Loading..." when running Rootless. Works when running Docker as root. See:
The Docker interface does not have GUI support for setting SSH keys, so you must manually create them in each project. (Use a Linux Terminal for example.)
In our
initialize_cocalc.sh
we forward the SSH port 22 on the container to port 9022 on the host (but only listen locally for security), so you can connect in two ways:Connect to the host with SSH, forwarding ports 9443 and 9022 to your local machine. Then you can connect to the web interface from your computer at https://localhost:9443 and you can SSH to the container by connecting to your local computer on port 9022. (Tested and works.)
Connect to the container by using SSH directly to connect first to the host, then to the container. (Not tested yet.)
Nextcloud (incomplete)
Open source replacement for Google Cloud etc. There is a docker image.
Incomplete because this needs MySQL etc. and I don't want to figure this out yet.
Let's Encrypt and Certbot
Let's Encrypt uses Certbot as a tool for enabling free site certification. This requires using a supported Ubuntu release.
The commented out commands were needed earlier (pre Ubuntu 19.10) but should no longer be needed. Without removing this repo I ran into the following error) during apt update
:
With BitBucket "sunsetting" their support for Mercurial, we needed to find a new option. Here we explore options for self-hosting.
Version Control Hosting
Kallithea (incomplete)
Kallithea needs a database, so we make a directory for this in /data/kalithea
and store it there.
This runs Kallithea on port 5000 which could be accessed by users with ssh tunelling.
Another alternative is Heptapod. This is a mercurial interface to a friendly fork of GitLab CE intended to ultimately bring mercurial support to GitLab. This can be installed with Docker as discussed below.
As of 1 July 2020: This is my primary alternative to Bitbucket hosted as discussed below. We will probably ultimately host this on an AWS instance.
As of 14 March 2020:
Heptapod is implemented under the hood with git.
Heptapod 0.8 supports import of Bitbucket Pull Requests.
Podman
An alternative to Docker is Podman. This behaves very similarly to Docker, but runs rootless natively.