A Dockerization of the deployment steps detailed in forem/selfhost/README.md
Developed using Make 4.1
and Docker 20.10.5
on Ubuntu 18.04
Replace the <...>
s with your own values and execute this to build the Docker image:
make \
-e FOREM_DOMAIN_NAME=<DOMAIN_NAME> \
-e FOREM_SUBDOMAIN_NAME=<SUBDOMAIN_NAME_OR_BLANK> \
-e FOREM_DEFAULT_EMAIL=<EMAIL_ADDRESS> \
build-forem-selfhost
See the Makefile for more information about the build-forem-selfhost
target.
- an SSH key will be generated
- the Forem repo will be cloned and default
setup.yml
created setup.yml
will be injected with the configuration values- an Ansible Vault password will be automatically generated
- all required secret values will be automatically generated and injected into
setup.yml
Note that the automatically generated secret values you need to administer your Forem services (e.g. Vault password, vault_secret_key_base
, etc.)
and eventually access your deployment machine (e.g. SSH key) now exist exclusively within the Docker image you just created, so you should maybe:
- not share the Docker image with anyone, lest they get your secretz
- copy those values out of the image and store them somewhere safe (see "Extract the secrets")
Use extract-secrets
to copy the secret files automatically generated during the Docker image build process to
your local filesystem and store them somewhere safe.
make extract-secrets
This will create a local directory called secrets
with the contents:
forem
forem.pub
.forem_selfhost_ansible_vault_password
setup.yml
Create an auth token and store it in a local (to this repo) file called .digitalocean-access-token
make build-forem-selfhost-digitalocean
make deploy-to-digitalocean
Complete steps 10 & 11 in the Quick Start guide:
- Once your Forem VM is set up with your chosen cloud provider, you will need to point DNS at the IP address that is output at the end of the provider playbook.
- Once DNS is pointed at your Forem VM, you will need to restart the Forem Traefik service (sudo systemctl restart forem-traefik.service) via SSH on your Forem server to generate a TLS cert.
You can use make digitalocean-service-restart-traefik
to do the restart, after which you should be able to surf over to your domain and see something cool!
make digitalocean-ip
make digitalocean-shell
make digitalocean-db-shell
make digitalocean-service-status
make digitalocean-service-restart-forem
make digitalocean-service-restart-traefik
make digitalocean-container-list
make digitalocean-container-imgproxy-logs
make digitalocean-container-openresty-logs
make digitalocean-container-postgres-logs
make digitalocean-container-rails-logs
make digitalocean-container-redis-logs
make digitalocean-container-traefik-logs
make digitalocean-container-worker-logs
If the traefik
service restart fails, run make digitalocean-service-status
to see how things look.
A normal, healthy state looks like:
UNIT LOAD ACTIVE SUB DESCRIPTION
forem-imgproxy.service loaded active running Forem Imgproxy Service
forem-openresty.service loaded active running Forem OpenResty Service
forem-pod.service loaded active running Forem pod service
forem-postgresql.service loaded active running Forem Postgresql Service
forem-rails.service loaded active running Forem Rails Service
forem-redis.service loaded active running Forem Redis Service
forem-traefik.service loaded active running Forem Traefik Service
forem-worker.service loaded active running Forem Worker Service
forem.service loaded active exited Forem Service
An unhealthy state shows inactive
s and dead
s.
There was a bug (which looks to have been fixed) in which the container
service didn't do what it was supposed to. I was able to resolve this by SSHing in and doing a sudo systemctl start forem-container.service
As I understand it, the traefik
service attempts to register an SSL cert via Let's Encrypt in order to enable HTTPS.
The problem is that, during the registration process, Let's Encrypt needs to be able to access the /.well-known/acme-challenge/
path on your site using plain ol' HTTP. If you have something like "Always use HTTP" (e.g. on Cloudflare) enabled, it's not going to work.
In Cloudflare, I fixed this as follows: