[lemmy]
# define the username and hostname that you use for ssh connection, and specify the domain
-myuser@example.com domain=example.com letsencrypt_contact_email=your@email.com smtp_server=smtp@example.com smtp_login=your@email.com smtp_password=pass smtp_from_address="Example.com Admin <notifications@example.com>"
+myuser@example.com domain=example.com letsencrypt_contact_email=your@email.com
[all:vars]
ansible_connection=ssh
vars:
postgres_password: "{{ lookup('password', 'passwords/{{ inventory_hostname }}/postgres chars=ascii_letters,digits') }}"
jwt_password: "{{ lookup('password', 'passwords/{{ inventory_hostname }}/jwt chars=ascii_letters,digits') }}"
+ lemmy_docker_image: "dessalines/lemmy:{{ lookup('file', 'VERSION') }}"
- name: enable and start docker service
systemd:
--- /dev/null
+---
+- hosts: all
+ vars:
+ lemmy_docker_image: "lemmy:dev"
+
+ # Install python if required
+ # https://www.josharcher.uk/code/ansible-python-connection-failure-ubuntu-server-1604/
+ gather_facts: False
+ pre_tasks:
+ - name: install python for Ansible
+ raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal python-setuptools)
+ args:
+ executable: /bin/bash
+ register: output
+ changed_when: output.stdout != ""
+ - setup: # gather facts
+
+ tasks:
+ - name: install dependencies
+ apt:
+ pkg: ['nginx', 'docker-compose', 'docker.io', 'certbot', 'python-certbot-nginx']
+
+ - name: request initial letsencrypt certificate
+ command: certbot certonly --nginx --agree-tos -d '{{ domain }}' -m '{{ letsencrypt_contact_email }}'
+ args:
+ creates: '/etc/letsencrypt/live/{{domain}}/privkey.pem'
+
+ - name: create lemmy folder
+ file: path={{item.path}} state=directory
+ with_items:
+ - { path: '/lemmy/' }
+ - { path: '/lemmy/volumes/' }
+
+ - block:
+ - name: add template files
+ template: src={{item.src}} dest={{item.dest}} mode={{item.mode}}
+ with_items:
+ - { src: 'templates/docker-compose.yml', dest: '/lemmy/docker-compose.yml', mode: '0600' }
+ - { src: 'templates/nginx.conf', dest: '/etc/nginx/sites-enabled/lemmy.conf', mode: '0644' }
+
+ - name: add config file (only during initial setup)
+ template: src='templates/config.hjson' dest='/lemmy/lemmy.hjson' mode='0600' force='no' owner='1000' group='1000'
+ vars:
+ postgres_password: "{{ lookup('password', 'passwords/{{ inventory_hostname }}/postgres chars=ascii_letters,digits') }}"
+ jwt_password: "{{ lookup('password', 'passwords/{{ inventory_hostname }}/jwt chars=ascii_letters,digits') }}"
+
+ - name: build the dev docker image
+ local_action: shell cd .. && sudo docker build . -f docker/dev/Dockerfile -t lemmy:dev
+ register: image_build
+
+ - name: find hash of the new docker image
+ set_fact:
+ image_hash: "{{ image_build.stdout | regex_search('(?<=Successfully built )[0-9a-f]{12}') }}"
+
+ # this does not use become so that the output file is written as non-root user and is easy to delete later
+ - name: save dev docker image to file
+ local_action: shell sudo docker save lemmy:dev > lemmy-dev.tar
+
+ - name: copy dev docker image to server
+ copy: src=lemmy-dev.tar dest=/lemmy/lemmy-dev.tar
+
+ - name: import docker image
+ docker_image:
+ name: lemmy
+ tag: dev
+ load_path: /lemmy/lemmy-dev.tar
+ source: load
+ force_source: yes
+ register: image_import
+
+ - name: delete remote image file
+ file: path=/lemmy/lemmy-dev.tar state=absent
+
+ - name: delete local image file
+ local_action: file path=lemmy-dev.tar state=absent
+
+ - name: enable and start docker service
+ systemd:
+ name: docker
+ enabled: yes
+ state: started
+
+ # cant pull here because that fails due to lemmy:dev (without dessalines/) not being on docker hub, but that shouldnt
+ # be a problem for testing
+ - name: start docker-compose
+ docker_compose:
+ project_src: /lemmy/
+ state: present
+ recreate: always
+ ignore_errors: yes
+
+ - name: reload nginx with new config
+ shell: nginx -s reload
+
+ - name: certbot renewal cronjob
+ cron:
+ special_time=daily
+ name=certbot-renew-lemmy
+ user=root
+ job="certbot certonly --nginx -d '{{ domain }}' --deploy-hook 'docker-compose -f /peertube/docker-compose.yml exec nginx nginx -s reload'"
jwt_secret: "{{ jwt_password }}"
front_end_dir: "/app/dist"
email: {
- smtp_server: "{{ smtp_server }}"
- smtp_login: "{{ smtp_login }}"
- smtp_password: "{{ smtp_password }}"
- smtp_from_address: "{{ smtp_from_address }}"
+ smtp_server: "postfix:25"
+ smtp_from_address: "noreply@{{ domain }}"
+ use_tls: false
}
}
services:
lemmy:
- image: dessalines/lemmy:v0.6.9
+ image: {{ lemmy_docker_image }}
ports:
- "127.0.0.1:8536:8536"
restart: always
- lemmy_pictshare:/usr/share/nginx/html/data
restart: always
+ postfix:
+ image: mwader/postfix-relay
+ environment:
+ - POSTFIX_myhostname={{ domain }}
+ restart: "always"
volumes:
lemmy_db:
lemmy_pictshare:
}
log_format main '$remote_addr_anon - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" "$http_user_agent"';
-access_log /dev/stdout main;
+access_log /var/log/nginx/access.log main;
# Setting the version on the backend
echo "pub const VERSION: &str = \"$(git describe --tags)\";" > "server/src/version.rs"
git add "server/src/version.rs"
+# Setting the version for Ansible
+git describe --tags > "ansible/VERSION"
+git add "ansible/VERSION"
cd docker/dev
use lettre::smtp::authentication::{Credentials, Mechanism};
use lettre::smtp::extension::ClientId;
use lettre::smtp::ConnectionReuseParameters;
-use lettre::{SmtpClient, Transport};
+use lettre::{ClientSecurity, SmtpClient, Transport};
use lettre_email::Email;
use rand::distributions::Alphanumeric;
use rand::{thread_rng, Rng};
let email = Email::builder()
.to((to_email, to_username))
- .from((
- email_config.smtp_login.to_owned(),
- email_config.smtp_from_address.to_owned(),
- ))
+ .from(email_config.smtp_from_address.to_owned())
.subject(subject)
.html(html)
.build()
.unwrap();
- let mut mailer = SmtpClient::new_simple(&email_config.smtp_server)
- .unwrap()
- .hello_name(ClientId::Domain(Settings::get().hostname.to_owned()))
- .credentials(Credentials::new(
- email_config.smtp_login.to_owned(),
- email_config.smtp_password.to_owned(),
- ))
- .smtp_utf8(true)
- .authentication_mechanism(Mechanism::Plain)
- .connection_reuse(ConnectionReuseParameters::ReuseUnlimited)
- .transport();
-
- let result = mailer.send(email.into());
+ let mailer = if email_config.use_tls {
+ SmtpClient::new_simple(&email_config.smtp_server).unwrap()
+ } else {
+ SmtpClient::new(&email_config.smtp_server, ClientSecurity::None).unwrap()
+ }
+ .hello_name(ClientId::Domain(Settings::get().hostname.to_owned()))
+ .smtp_utf8(true)
+ .authentication_mechanism(Mechanism::Plain)
+ .connection_reuse(ConnectionReuseParameters::ReuseUnlimited);
+ let mailer = if let (Some(login), Some(password)) =
+ (&email_config.smtp_login, &email_config.smtp_password)
+ {
+ mailer.credentials(Credentials::new(login.to_owned(), password.to_owned()))
+ } else {
+ mailer
+ };
- mailer.close();
+ let mut transport = mailer.transport();
+ let result = transport.send(email.into());
+ transport.close();
match result {
Ok(_) => Ok(()),
- Err(_) => Err("no_email_setup".to_string()),
+ Err(e) => Err(e.to_string()),
}
}
#[derive(Debug, Deserialize)]
pub struct EmailConfig {
pub smtp_server: String,
- pub smtp_login: String,
- pub smtp_password: String,
+ pub smtp_login: Option<String>,
+ pub smtp_password: Option<String>,
pub smtp_from_address: String,
+ pub use_tls: bool,
}
#[derive(Debug, Deserialize)]