Skip to content

Commit 8a85bed

Browse files
authored
Merge pull request #4 from derekenos/digitalocean-helpers
Digitalocean helpers
2 parents eab9577 + 924b1b1 commit 8a85bed

File tree

2 files changed

+220
-4
lines changed

2 files changed

+220
-4
lines changed

Makefile

+112
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,115 @@ build-forem-selfhost-digitalocean:
7575

7676
deploy-to-digitalocean:
7777
@docker run forem-selfhost-digitalocean
78+
79+
80+
###############################################################################
81+
# DigitalOcean helpers
82+
###############################################################################
83+
84+
# Return the public IP of the DigitalOcean Droplet tagged "forem"
85+
digitalocean_get_ip = \
86+
`docker run forem-selfhost-digitalocean \
87+
doctl compute droplet list --tag-name forem --no-header --format PublicIPv4`
88+
89+
# Return the command for SSHing into the DigitalOcean Droplet
90+
digitalocean_ssh_command = \
91+
docker run -it forem-selfhost \
92+
ssh -t -o "StrictHostKeyChecking=no" -i /home/$(USER)/.ssh/forem \
93+
core@$(call digitalocean_get_ip) $(1)
94+
95+
# Return the command to execute a command within a container
96+
# args: ( <user>, <container-name>, <command> )
97+
digitalocean_podman_exec = \
98+
"sudo podman exec -u $1 -it \$$(sudo podman ps -q -f name=$2) $3"
99+
100+
# Return the command to execute a command within a container
101+
# args: ( <container-name>, )
102+
digitalocean_podman_logs = \
103+
"sudo podman logs -f \$$(sudo podman ps -q -f name=$1)"
104+
105+
106+
###############################################################################
107+
# Show DigitalOcean Droplet IP
108+
###############################################################################
109+
110+
digitalocean-ip:
111+
@echo $(call digitalocean_get_ip)
112+
113+
114+
###############################################################################
115+
# SSH into the DigitalOcean Droplet
116+
###############################################################################
117+
118+
digitalocean-shell:
119+
@$(call digitalocean_ssh_command)
120+
121+
122+
###############################################################################
123+
# Connect to the DigitalOcean Droplet PostgreSQL DB
124+
###############################################################################
125+
126+
digitalocean-db-shell:
127+
@$(call digitalocean_ssh_command,\
128+
$(call digitalocean_podman_exec,"postgres","postgres","psql -Uforem_production"))
129+
130+
131+
###############################################################################
132+
# Services admin
133+
###############################################################################
134+
135+
# Status
136+
digitalocean-service-status:
137+
@$(call digitalocean_ssh_command, "sudo systemctl list-units forem*")
138+
139+
# Restarts
140+
digitalocean-service-restart-forem:
141+
@$(call digitalocean_ssh_command, "sudo systemctl restart forem")
142+
143+
digitalocean-service-restart-traefik:
144+
@$(call digitalocean_ssh_command, "sudo systemctl restart forem-traefik")
145+
146+
147+
###############################################################################
148+
# Container utilities
149+
###############################################################################
150+
151+
# List containers
152+
digitalocean-container-list:
153+
@$(call digitalocean_ssh_command, "sudo podman ps")
154+
155+
# Tail container logs
156+
digitalocean-container-imgproxy-logs:
157+
@$(call digitalocean_ssh_command,\
158+
$(call digitalocean_podman_logs,"imgproxy"))\
159+
|| exit 0
160+
161+
digitalocean-container-openresty-logs:
162+
@$(call digitalocean_ssh_command,\
163+
$(call digitalocean_podman_logs,"openresty"))\
164+
|| exit 0
165+
166+
digitalocean-container-postgres-logs:
167+
@$(call digitalocean_ssh_command,\
168+
$(call digitalocean_podman_logs,"postgres"))\
169+
|| exit 0
170+
171+
digitalocean-container-rails-logs:
172+
@$(call digitalocean_ssh_command,\
173+
$(call digitalocean_podman_logs,"rails"))\
174+
|| exit 0
175+
176+
digitalocean-container-redis-logs:
177+
@$(call digitalocean_ssh_command,\
178+
$(call digitalocean_podman_logs,"redis"))\
179+
|| exit 0
180+
181+
digitalocean-container-traefik-logs:
182+
@$(call digitalocean_ssh_command,\
183+
$(call digitalocean_podman_logs,"traefik"))\
184+
|| exit 0
185+
186+
digitalocean-container-worker-logs:
187+
@$(call digitalocean_ssh_command,\
188+
$(call digitalocean_podman_logs,"worker"))\
189+
|| exit 0

README.md

+108-4
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,123 @@ forem.pub
5050
setup.yml
5151
```
5252

53-
### Deploy to DigitalOcean
53+
### Deploying to DigitalOcean
5454

5555
[Create an auth token](https://docs.digitalocean.com/reference/api/create-personal-access-token/) and store it in a local (to this repo) file called `.digitalocean-access-token`
5656

57-
#### Build the DigitalOcean deployment Image
57+
#### Build the DigitalOcean deployment image
5858

5959
```
6060
make build-forem-selfhost-digitalocean
6161
```
6262

63-
#### Deploy to DigitalOcean
64-
63+
#### Do the deploy
6564
```
6665
make deploy-to-digitalocean
6766
```
6867

68+
#### Update your DNS and restart the traefik service
69+
70+
Complete [steps 10 & 11 in the Quick Start guide](https://github.com/forem/selfhost/blob/5e5ce60a5df738cd36261c80e94dac917e78868f/README.md#quick-start):
71+
> 10. 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.
72+
> 11. 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.
73+
74+
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!
75+
76+
77+
#### Interact with the server
78+
79+
##### Show the IP address
80+
```
81+
make digitalocean-ip
82+
```
83+
84+
##### Start an SSH session
85+
```
86+
make digitalocean-shell
87+
```
88+
89+
##### Connect to the PostgreSQL console
90+
```
91+
make digitalocean-db-shell
92+
```
93+
94+
##### Show the status of related services
95+
```
96+
make digitalocean-service-status
97+
```
98+
99+
##### Restart a service
100+
```
101+
make digitalocean-service-restart-forem
102+
```
103+
```
104+
make digitalocean-service-restart-traefik
105+
```
106+
107+
##### List all of the containers
108+
```
109+
make digitalocean-container-list
110+
```
111+
112+
##### Tail the logs of a specific container
113+
```
114+
make digitalocean-container-imgproxy-logs
115+
```
116+
```
117+
make digitalocean-container-openresty-logs
118+
```
119+
```
120+
make digitalocean-container-postgres-logs
121+
```
122+
```
123+
make digitalocean-container-rails-logs
124+
```
125+
```
126+
make digitalocean-container-redis-logs
127+
```
128+
```
129+
make digitalocean-container-traefik-logs
130+
```
131+
```
132+
make digitalocean-container-worker-logs
133+
```
134+
135+
#### Some notes about my experience
136+
137+
##### Failed initial traefik restart
138+
139+
If the `traefik` service restart fails, run `make digitalocean-service-status` to see how things look.
140+
141+
A normal, healthy state looks like:
142+
143+
```
144+
UNIT LOAD ACTIVE SUB DESCRIPTION
145+
forem-imgproxy.service loaded active running Forem Imgproxy Service
146+
forem-openresty.service loaded active running Forem OpenResty Service
147+
forem-pod.service loaded active running Forem pod service
148+
forem-postgresql.service loaded active running Forem Postgresql Service
149+
forem-rails.service loaded active running Forem Rails Service
150+
forem-redis.service loaded active running Forem Redis Service
151+
forem-traefik.service loaded active running Forem Traefik Service
152+
forem-worker.service loaded active running Forem Worker Service
153+
forem.service loaded active exited Forem Service
154+
```
155+
156+
An unhealthy state shows `inactive`s and `dead`s.
157+
158+
There was a bug ([which looks to have been fixed](https://github.com/forem/selfhost/commit/ccd1063e0a27f26e784d25fe22cbc51d7eea4e53)) 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`
159+
160+
##### HTTPS-only caused problems with SSL certificate registration
161+
162+
As I understand it, the `traefik` service attempts to register an SSL cert via Let's Encrypt in order to enable HTTPS.
163+
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.
164+
165+
In Cloudflare, I fixed this as follows:
166+
167+
- In `SSL/TLS` -> `Edge Certificates`:
168+
- Disable `Always use HTTPs`![Screenshot from 2021-08-19 16-44-44](https://user-images.githubusercontent.com/585182/130141521-e0c5f8df-9110-49c5-98b3-08a2eb13848d.png)
169+
- Disable `Automatic HTTPS Rewrites` (maybe not necessary?)![Screenshot from 2021-08-19 16-47-10](https://user-images.githubusercontent.com/585182/130141714-2660d183-77de-4132-a404-d381cd84bda0.png)
170+
- In `Rules`
171+
- Create two rules - one to prevent SSL on the `acme-challenge` path, and another to enforce `HTTPS` everywhere else![Screenshot from 2021-08-19 16-49-21](https://user-images.githubusercontent.com/585182/130141991-1b87beea-5829-4f8f-8826-708172202280.png)
172+

0 commit comments

Comments
 (0)